diff options
Diffstat (limited to 'platform/windows')
-rw-r--r-- | platform/windows/SCsub | 25 | ||||
-rw-r--r-- | platform/windows/console_wrapper_windows.cpp | 181 | ||||
-rw-r--r-- | platform/windows/detect.py | 12 | ||||
-rw-r--r-- | platform/windows/display_server_windows.cpp | 99 | ||||
-rw-r--r-- | platform/windows/display_server_windows.h | 8 | ||||
-rw-r--r-- | platform/windows/export/export_plugin.cpp | 58 | ||||
-rw-r--r-- | platform/windows/export/export_plugin.h | 3 | ||||
-rw-r--r-- | platform/windows/gl_manager_windows.cpp | 10 | ||||
-rw-r--r-- | platform/windows/gl_manager_windows.h | 3 | ||||
-rw-r--r-- | platform/windows/godot_res_wrap.rc | 31 | ||||
-rw-r--r-- | platform/windows/joypad_windows.cpp | 2 | ||||
-rw-r--r-- | platform/windows/os_windows.cpp | 21 | ||||
-rw-r--r-- | platform/windows/os_windows.h | 4 | ||||
-rw-r--r-- | platform/windows/platform_config.h | 2 | ||||
-rw-r--r-- | platform/windows/vulkan_context_win.h | 4 |
15 files changed, 383 insertions, 80 deletions
diff --git a/platform/windows/SCsub b/platform/windows/SCsub index 7e412b140f..efbb47d965 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -19,19 +19,44 @@ common_win = [ "gl_manager_windows.cpp", ] +common_win_wrap = [ + "console_wrapper_windows.cpp", +] + res_file = "godot_res.rc" res_target = "godot_res" + env["OBJSUFFIX"] res_obj = env.RES(res_target, res_file) prog = env.add_program("#bin/godot", common_win + res_obj, PROGSUFFIX=env["PROGSUFFIX"]) +# Build console wrapper app. +if env["windows_subsystem"] == "gui": + env_wrap = env.Clone() + res_wrap_file = "godot_res_wrap.rc" + res_wrap_target = "godot_res_wrap" + env["OBJSUFFIX"] + res_wrap_obj = env_wrap.RES(res_wrap_target, res_wrap_file) + + if env.msvc: + env_wrap.Append(LINKFLAGS=["/SUBSYSTEM:CONSOLE"]) + env_wrap.Append(LINKFLAGS=["version.lib"]) + else: + env_wrap.Append(LINKFLAGS=["-Wl,--subsystem,console"]) + env_wrap.Append(LIBS=["version"]) + + prog_wrap = env_wrap.add_program("#bin/godot", common_win_wrap + res_wrap_obj, PROGSUFFIX=env["PROGSUFFIX_WRAP"]) + # Microsoft Visual Studio Project Generation if env["vsproj"]: env.vs_srcs += ["platform/windows/" + res_file] env.vs_srcs += ["platform/windows/godot.natvis"] for x in common_win: env.vs_srcs += ["platform/windows/" + str(x)] + if env["windows_subsystem"] == "gui": + for x in common_win_wrap: + env.vs_srcs += ["platform/windows/" + str(x)] if not os.getenv("VCINSTALLDIR"): if env["debug_symbols"] and env["separate_debug_symbols"]: env.AddPostAction(prog, run_in_subprocess(platform_windows_builders.make_debug_mingw)) + if env["windows_subsystem"] == "gui": + env.AddPostAction(prog_wrap, run_in_subprocess(platform_windows_builders.make_debug_mingw)) diff --git a/platform/windows/console_wrapper_windows.cpp b/platform/windows/console_wrapper_windows.cpp new file mode 100644 index 0000000000..258176426b --- /dev/null +++ b/platform/windows/console_wrapper_windows.cpp @@ -0,0 +1,181 @@ +/*************************************************************************/ +/* console_wrapper_windows.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include <windows.h> + +#include <shlwapi.h> +#include <stdio.h> +#include <stdlib.h> + +#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING +#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4 +#endif + +int main(int argc, char *argv[]) { + // Get executable name. + WCHAR exe_name[MAX_PATH] = {}; + if (!GetModuleFileNameW(nullptr, exe_name, MAX_PATH)) { + wprintf(L"GetModuleFileName failed, error %d\n", GetLastError()); + return -1; + } + + // Get product name from the resources and set console title. + DWORD ver_info_handle = 0; + DWORD ver_info_size = GetFileVersionInfoSizeW(exe_name, &ver_info_handle); + if (ver_info_size > 0) { + LPBYTE ver_info = (LPBYTE)malloc(ver_info_size); + if (ver_info) { + if (GetFileVersionInfoW(exe_name, ver_info_handle, ver_info_size, ver_info)) { + LPCWSTR text_ptr = nullptr; + UINT text_size = 0; + if (VerQueryValueW(ver_info, L"\\StringFileInfo\\040904b0\\ProductName", (void **)&text_ptr, &text_size) && (text_size > 0)) { + SetConsoleTitleW(text_ptr); + } + } + free(ver_info); + } + } + + // Enable virtual terminal sequences processing. + HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD out_mode = ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING; + SetConsoleMode(stdout_handle, out_mode); + + // Find main executable name and check if it exist. + static PCWSTR exe_renames[] = { + L".console.exe", + L"_console.exe", + L" console.exe", + L"console.exe", + nullptr, + }; + + bool rename_found = false; + for (int i = 0; exe_renames[i]; i++) { + PWSTR c = StrRStrIW(exe_name, nullptr, exe_renames[i]); + if (c) { + CopyMemory(c, L".exe", sizeof(WCHAR) * 5); + rename_found = true; + break; + } + } + if (!rename_found) { + wprintf(L"Invalid wrapper executable name.\n"); + return -1; + } + + DWORD file_attrib = GetFileAttributesW(exe_name); + if (file_attrib == INVALID_FILE_ATTRIBUTES || (file_attrib & FILE_ATTRIBUTE_DIRECTORY)) { + wprintf(L"Main executable %ls not found.\n", exe_name); + return -1; + } + + // Create job to monitor process tree. + HANDLE job_handle = CreateJobObjectW(nullptr, nullptr); + if (!job_handle) { + wprintf(L"CreateJobObject failed, error %d\n", GetLastError()); + return -1; + } + + HANDLE io_port_handle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 1); + if (!io_port_handle) { + wprintf(L"CreateIoCompletionPort failed, error %d\n", GetLastError()); + return -1; + } + + JOBOBJECT_ASSOCIATE_COMPLETION_PORT compl_port; + ZeroMemory(&compl_port, sizeof(compl_port)); + compl_port.CompletionKey = job_handle; + compl_port.CompletionPort = io_port_handle; + + if (!SetInformationJobObject(job_handle, JobObjectAssociateCompletionPortInformation, &compl_port, sizeof(compl_port))) { + wprintf(L"SetInformationJobObject(AssociateCompletionPortInformation) failed, error %d\n", GetLastError()); + return -1; + } + + JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli; + ZeroMemory(&jeli, sizeof(jeli)); + jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + + if (!SetInformationJobObject(job_handle, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli))) { + wprintf(L"SetInformationJobObject(ExtendedLimitInformation) failed, error %d\n", GetLastError()); + return -1; + } + + // Start the main process. + PROCESS_INFORMATION pi; + ZeroMemory(&pi, sizeof(pi)); + + STARTUPINFOW si; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + + WCHAR new_command_line[32767]; + _snwprintf_s(new_command_line, 32767, _TRUNCATE, L"%ls %ls", exe_name, PathGetArgsW(GetCommandLineW())); + + if (!CreateProcessW(nullptr, new_command_line, nullptr, nullptr, true, CREATE_SUSPENDED, nullptr, nullptr, &si, &pi)) { + wprintf(L"CreateProcess failed, error %d\n", GetLastError()); + return -1; + } + + if (!AssignProcessToJobObject(job_handle, pi.hProcess)) { + wprintf(L"AssignProcessToJobObject failed, error %d\n", GetLastError()); + return -1; + } + + ResumeThread(pi.hThread); + CloseHandle(pi.hThread); + + // Wait until main process and all of its children are finished. + DWORD completion_code = 0; + ULONG_PTR completion_key = 0; + LPOVERLAPPED overlapped = nullptr; + + while (GetQueuedCompletionStatus(io_port_handle, &completion_code, &completion_key, &overlapped, INFINITE)) { + if ((HANDLE)completion_key == job_handle && completion_code == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO) { + break; + } + } + + CloseHandle(job_handle); + CloseHandle(io_port_handle); + + // Get exit code of the main process. + DWORD exit_code = 0; + GetExitCodeProcess(pi.hProcess, &exit_code); + + CloseHandle(pi.hProcess); + + return exit_code; +} + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { + return main(0, nullptr); +} diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 74868fc6a2..705e83dace 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -582,12 +582,14 @@ def configure_mingw(env): ] ) - env.Append(CPPDEFINES=["VULKAN_ENABLED"]) - if not env["use_volk"]: - env.Append(LIBS=["vulkan"]) + if env["vulkan"]: + env.Append(CPPDEFINES=["VULKAN_ENABLED"]) + if not env["use_volk"]: + env.Append(LIBS=["vulkan"]) - env.Append(CPPDEFINES=["GLES3_ENABLED"]) - env.Append(LIBS=["opengl32"]) + if env["opengl3"]: + env.Append(CPPDEFINES=["GLES3_ENABLED"]) + env.Append(LIBS=["opengl32"]) env.Append(CPPDEFINES=["MINGW_ENABLED", ("MINGW_HAS_SECURE_API", 1)]) diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 3b773685c3..af80a07da9 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -741,9 +741,20 @@ int64_t DisplayServerWindows::window_get_native_handle(HandleType p_handle_type, case WINDOW_HANDLE: { return (int64_t)windows[p_window].hWnd; } +#if defined(GLES3_ENABLED) case WINDOW_VIEW: { - return 0; // Not supported. + if (gl_manager) { + return (int64_t)gl_manager->get_hdc(p_window); + } + return 0; + } + case OPENGL_CONTEXT: { + if (gl_manager) { + return (int64_t)gl_manager->get_hglrc(p_window); + } + return 0; } +#endif default: { return 0; } @@ -1881,7 +1892,7 @@ void DisplayServerWindows::set_native_icon(const String &p_filename) { pos += sizeof(WORD); f->seek(pos); - icon_dir = (ICONDIR *)memrealloc(icon_dir, 3 * sizeof(WORD) + icon_dir->idCount * sizeof(ICONDIRENTRY)); + icon_dir = (ICONDIR *)memrealloc(icon_dir, sizeof(ICONDIR) - sizeof(ICONDIRENTRY) + icon_dir->idCount * sizeof(ICONDIRENTRY)); f->get_buffer((uint8_t *)&icon_dir->idEntries[0], icon_dir->idCount * sizeof(ICONDIRENTRY)); int small_icon_index = -1; // Select 16x16 with largest color count. @@ -2444,10 +2455,16 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA return 0; // Jump back. } case WM_MOUSELEAVE: { - old_invalid = true; - windows[window_id].mouse_outside = true; + if (window_mouseover_id == window_id) { + old_invalid = true; + window_mouseover_id = INVALID_WINDOW_ID; - _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT); + _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT); + } else if (window_mouseover_id != INVALID_WINDOW_ID) { + // This is reached during drag and drop, after dropping in a different window. + // Once-off notification, must call again. + track_mouse_leave_event(windows[window_mouseover_id].hWnd); + } } break; case WM_INPUT: { @@ -2678,17 +2695,21 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } } - if (windows[window_id].mouse_outside) { + if (window_mouseover_id != window_id) { // Mouse enter. if (mouse_mode != MOUSE_MODE_CAPTURED) { + if (window_mouseover_id != INVALID_WINDOW_ID) { + // Leave previous window. + _send_window_event(windows[window_mouseover_id], WINDOW_EVENT_MOUSE_EXIT); + } _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER); } CursorShape c = cursor_shape; cursor_shape = CURSOR_MAX; cursor_set_shape(c); - windows[window_id].mouse_outside = false; + window_mouseover_id = window_id; // Once-off notification, must call again. track_mouse_leave_event(hWnd); @@ -2779,17 +2800,29 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } } - if (windows[window_id].mouse_outside) { + DisplayServer::WindowID over_id = get_window_at_screen_position(mouse_get_position()); + if (!Rect2(window_get_position(over_id), Point2(windows[over_id].width, windows[over_id].height)).has_point(mouse_get_position())) { + // Don't consider the windowborder as part of the window. + over_id = INVALID_WINDOW_ID; + } + if (window_mouseover_id != over_id) { // Mouse enter. if (mouse_mode != MOUSE_MODE_CAPTURED) { - _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER); + if (window_mouseover_id != INVALID_WINDOW_ID) { + // Leave previous window. + _send_window_event(windows[window_mouseover_id], WINDOW_EVENT_MOUSE_EXIT); + } + + if (over_id != INVALID_WINDOW_ID) { + _send_window_event(windows[over_id], WINDOW_EVENT_MOUSE_ENTER); + } } CursorShape c = cursor_shape; cursor_shape = CURSOR_MAX; cursor_set_shape(c); - windows[window_id].mouse_outside = false; + window_mouseover_id = over_id; // Once-off notification, must call again. track_mouse_leave_event(hWnd); @@ -2800,9 +2833,13 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA break; } + DisplayServer::WindowID receiving_window_id = _get_focused_window_or_popup(); + if (receiving_window_id == INVALID_WINDOW_ID) { + receiving_window_id = window_id; + } Ref<InputEventMouseMotion> mm; mm.instantiate(); - mm->set_window_id(window_id); + mm->set_window_id(receiving_window_id); mm->set_ctrl_pressed((wParam & MK_CONTROL) != 0); mm->set_shift_pressed((wParam & MK_SHIFT) != 0); mm->set_alt_pressed(alt_mem); @@ -2859,9 +2896,14 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y))); old_x = mm->get_position().x; old_y = mm->get_position().y; - if (windows[window_id].window_has_focus || window_get_active_popup() == window_id) { - Input::get_singleton()->parse_input_event(mm); + + if (!windows[receiving_window_id].window_has_focus) { + // In case of unfocused Popups, adjust event position. + Point2i pos = mm->get_position() - window_get_position(receiving_window_id) + window_get_position(window_id); + mm->set_position(pos); + mm->set_global_position(pos); } + Input::get_singleton()->parse_input_event(mm); } break; case WM_LBUTTONDOWN: @@ -3087,7 +3129,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA rect_changed = true; } #if defined(VULKAN_ENABLED) - if (context_vulkan && window_created) { + if (context_vulkan && window.context_created) { // Note: Trigger resize event to update swapchains when window is minimized/restored, even if size is not changed. context_vulkan->window_resize(window_id, window.width, window.height); } @@ -3547,6 +3589,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, windows.erase(id); ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Failed to create Vulkan Window."); } + wd.context_created = true; } #endif @@ -3703,7 +3746,7 @@ void DisplayServerWindows::tablet_set_current_driver(const String &p_driver) { } } -DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { +DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) { drop_events = false; key_event_pos = 0; @@ -3855,6 +3898,10 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win (screen_get_size(0).width - p_resolution.width) / 2, (screen_get_size(0).height - p_resolution.height) / 2); + if (p_position != nullptr) { + window_position = *p_position; + } + WindowID main_window = _create_window(p_mode, p_vsync_mode, 0, Rect2i(window_position, p_resolution)); ERR_FAIL_COND_MSG(main_window == INVALID_WINDOW_ID, "Failed to create main window."); @@ -3918,12 +3965,24 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() { return drivers; } -DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { - DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error)); +DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) { + DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error)); if (r_error != OK) { - OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan or OpenGL versions.\n" - "Please update your drivers or if you have a very old or integrated GPU upgrade it.", - "Unable to initialize Video driver"); + if (p_rendering_driver == "vulkan") { + String executable_name = OS::get_singleton()->get_executable_path().get_file(); + OS::get_singleton()->alert("Your video card driver does not support the selected Vulkan version.\n" + "Please try updating your GPU driver or try using the OpenGL 3 driver.\n" + "You can enable the OpenGL 3 driver by starting the engine from the\n" + "command line with the command:\n'./" + + executable_name + " --rendering-driver opengl3'.\n " + "If you have updated your graphics drivers recently, try rebooting.", + "Unable to initialize Video driver"); + } else { + OS::get_singleton()->alert("Your video card driver does not support the selected OpenGL version.\n" + "Please try updating your GPU driver.\n" + "If you have updated your graphics drivers recently, try rebooting.", + "Unable to initialize Video driver"); + } } return ds; } diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 6403b57d8d..8ac0086d69 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -323,6 +323,8 @@ class DisplayServerWindows : public DisplayServer { LPARAM lParam; }; + WindowID window_mouseover_id = INVALID_WINDOW_ID; + KeyEvent key_event_buffer[KEY_EVENT_BUFFER_SIZE]; int key_event_pos; @@ -369,6 +371,7 @@ class DisplayServerWindows : public DisplayServer { bool no_focus = false; bool window_has_focus = false; bool exclusive = false; + bool context_created = false; // Used to transfer data between events using timer. WPARAM saved_wparam; @@ -397,7 +400,6 @@ class DisplayServerWindows : public DisplayServer { Size2 window_rect; Point2 last_pos; - bool mouse_outside = true; ObjectID instance_id; @@ -622,11 +624,11 @@ public: virtual void set_context(Context p_context) override; - static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error); + static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error); static Vector<String> get_rendering_drivers_func(); static void register_windows_driver(); - DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error); + DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error); ~DisplayServerWindows(); }; diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp index 016d201f2c..d15380ac7a 100644 --- a/platform/windows/export/export_plugin.cpp +++ b/platform/windows/export/export_plugin.cpp @@ -41,24 +41,13 @@ Error EditorExportPlatformWindows::sign_shared_object(const Ref<EditorExportPres } } -Error EditorExportPlatformWindows::_export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path) { - Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE); - if (f.is_null()) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Script Export"), vformat(TTR("Could not open file \"%s\"."), p_path)); - return ERR_CANT_CREATE; - } - - f->store_line("@echo off"); - f->store_line("title \"" + p_app_name + "\""); - f->store_line("\"%~dp0" + p_pkg_name + "\" \"%*\""); - f->store_line("pause > nul"); - - return OK; -} - Error EditorExportPlatformWindows::modify_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { if (p_preset->get("application/modify_resources")) { - _rcedit_add_data(p_preset, p_path); + _rcedit_add_data(p_preset, p_path, true); + String wrapper_path = p_path.get_basename() + ".console.exe"; + if (FileAccess::exists(wrapper_path)) { + _rcedit_add_data(p_preset, wrapper_path, false); + } } return OK; } @@ -71,6 +60,10 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> Error err = EditorExportPlatformPC::export_project(p_preset, p_debug, pck_path, p_flags); if (p_preset->get("codesign/enable") && err == OK) { _code_sign(p_preset, pck_path); + String wrapper_path = p_path.get_basename() + ".console.exe"; + if (FileAccess::exists(wrapper_path)) { + _code_sign(p_preset, wrapper_path); + } } if (p_preset->get("binary_format/embed_pck") && err == OK) { @@ -81,25 +74,6 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> } } - String app_name; - if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "") { - app_name = String(ProjectSettings::get_singleton()->get("application/config/name")); - } else { - app_name = "Unnamed"; - } - app_name = OS::get_singleton()->get_safe_dir_name(app_name); - - // Save console script. - if (err == OK) { - int con_scr = p_preset->get("debug/export_console_script"); - if ((con_scr == 1 && p_debug) || (con_scr == 2)) { - String scr_path = p_path.get_basename() + ".cmd"; - if (_export_debug_script(p_preset, app_name, p_path.get_file(), scr_path) != OK) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Script Export"), TTR("Could not create console script.")); - } - } - } - return err; } @@ -146,8 +120,8 @@ void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_optio r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), "")); } -Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path) { - String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit"); +Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path, bool p_set_icon) { + String rcedit_path = EDITOR_GET("export/windows/rcedit"); if (rcedit_path != String() && !FileAccess::exists(rcedit_path)) { add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), vformat(TTR("Could not find rcedit executable at \"%s\"."), rcedit_path)); @@ -160,7 +134,7 @@ Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset #ifndef WINDOWS_ENABLED // On non-Windows we need WINE to run rcedit - String wine_path = EditorSettings::get_singleton()->get("export/windows/wine"); + String wine_path = EDITOR_GET("export/windows/wine"); if (!wine_path.is_empty() && !FileAccess::exists(wine_path)) { add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), vformat(TTR("Could not find wine executable at \"%s\"."), wine_path)); @@ -184,7 +158,7 @@ Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset List<String> args; args.push_back(p_path); - if (!icon_path.is_empty()) { + if (!icon_path.is_empty() && p_set_icon) { args.push_back("--set-icon"); args.push_back(icon_path); } @@ -248,7 +222,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p List<String> args; #ifdef WINDOWS_ENABLED - String signtool_path = EditorSettings::get_singleton()->get("export/windows/signtool"); + String signtool_path = EDITOR_GET("export/windows/signtool"); if (!signtool_path.is_empty() && !FileAccess::exists(signtool_path)) { add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("Could not find signtool executable at \"%s\"."), signtool_path)); return ERR_FILE_NOT_FOUND; @@ -257,7 +231,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p signtool_path = "signtool"; // try to run signtool from PATH } #else - String signtool_path = EditorSettings::get_singleton()->get("export/windows/osslsigncode"); + String signtool_path = EDITOR_GET("export/windows/osslsigncode"); if (!signtool_path.is_empty() && !FileAccess::exists(signtool_path)) { add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("Could not find osslsigncode executable at \"%s\"."), signtool_path)); return ERR_FILE_NOT_FOUND; @@ -420,7 +394,7 @@ bool EditorExportPlatformWindows::has_valid_export_configuration(const Ref<Edito String err = ""; bool valid = EditorExportPlatformPC::has_valid_export_configuration(p_preset, err, r_missing_templates); - String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit"); + String rcedit_path = EDITOR_GET("export/windows/rcedit"); if (p_preset->get("application/modify_resources") && rcedit_path.is_empty()) { err += TTR("The rcedit tool must be configured in the Editor Settings (Export > Windows > rcedit) to change the icon or app information data.") + "\n"; } diff --git a/platform/windows/export/export_plugin.h b/platform/windows/export/export_plugin.h index f85331c898..ec3b60aa76 100644 --- a/platform/windows/export/export_plugin.h +++ b/platform/windows/export/export_plugin.h @@ -38,9 +38,8 @@ #include "platform/windows/logo.gen.h" class EditorExportPlatformWindows : public EditorExportPlatformPC { - Error _rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path); + Error _rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path, bool p_set_icon); Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path); - Error _export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path); public: virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; diff --git a/platform/windows/gl_manager_windows.cpp b/platform/windows/gl_manager_windows.cpp index 7689751f1b..900bca8258 100644 --- a/platform/windows/gl_manager_windows.cpp +++ b/platform/windows/gl_manager_windows.cpp @@ -339,6 +339,16 @@ bool GLManager_Windows::is_using_vsync() const { return use_vsync; } +HDC GLManager_Windows::get_hdc(DisplayServer::WindowID p_window_id) { + return get_window(p_window_id).hDC; +} + +HGLRC GLManager_Windows::get_hglrc(DisplayServer::WindowID p_window_id) { + const GLWindow &win = get_window(p_window_id); + const GLDisplay &disp = get_display(win.gldisplay_id); + return disp.hRC; +} + GLManager_Windows::GLManager_Windows(ContextType p_context_type) { context_type = p_context_type; diff --git a/platform/windows/gl_manager_windows.h b/platform/windows/gl_manager_windows.h index 5e43a3de2a..c6d5f9f855 100644 --- a/platform/windows/gl_manager_windows.h +++ b/platform/windows/gl_manager_windows.h @@ -113,6 +113,9 @@ public: void set_use_vsync(bool p_use); bool is_using_vsync() const; + HDC get_hdc(DisplayServer::WindowID p_window_id); + HGLRC get_hglrc(DisplayServer::WindowID p_window_id); + GLManager_Windows(ContextType p_context_type); ~GLManager_Windows(); }; diff --git a/platform/windows/godot_res_wrap.rc b/platform/windows/godot_res_wrap.rc new file mode 100644 index 0000000000..ed93bb1ec3 --- /dev/null +++ b/platform/windows/godot_res_wrap.rc @@ -0,0 +1,31 @@ +#include "core/version.h" +#ifndef _STR +#define _STR(m_x) #m_x +#define _MKSTR(m_x) _STR(m_x) +#endif + +1 VERSIONINFO +FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,0 +PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,0 +FILEOS 4 +FILETYPE 1 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Godot Engine" + VALUE "FileDescription", VERSION_NAME " (Console)" + VALUE "FileVersion", VERSION_NUMBER + VALUE "ProductName", VERSION_NAME " (Console)" + VALUE "Licence", "MIT" + VALUE "LegalCopyright", "Copyright (c) 2007-" _MKSTR(VERSION_YEAR) " Juan Linietsky, Ariel Manzur and contributors" + VALUE "Info", "https://godotengine.org" + VALUE "ProductVersion", VERSION_FULL_BUILD + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp index d039fd13a7..2b5c8cad48 100644 --- a/platform/windows/joypad_windows.cpp +++ b/platform/windows/joypad_windows.cpp @@ -167,7 +167,7 @@ bool JoypadWindows::setup_dinput_joypad(const DIDEVICEINSTANCE *instance) { const GUID &guid = instance->guidProduct; char uid[128]; - ERR_FAIL_COND_V_MSG(memcmp(&guid.Data4[2], "PIDVID", 6), false, "DirectInput device not recognised."); + ERR_FAIL_COND_V_MSG(memcmp(&guid.Data4[2], "PIDVID", 6), false, "DirectInput device not recognized."); WORD type = BSWAP16(0x03); WORD vendor = BSWAP16(LOWORD(guid.Data1)); WORD product = BSWAP16(HIWORD(guid.Data1)); diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 5ca064e523..08897bb190 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -103,8 +103,6 @@ void RedirectIOToConsole() { RedirectStream("CONIN$", "r", stdin, STD_INPUT_HANDLE); RedirectStream("CONOUT$", "w", stdout, STD_OUTPUT_HANDLE); RedirectStream("CONOUT$", "w", stderr, STD_ERROR_HANDLE); - - printf("\n"); // Make sure our output is starting from the new line. } } @@ -311,6 +309,10 @@ String OS_Windows::get_version() const { } Vector<String> OS_Windows::get_video_adapter_driver_info() const { + if (RenderingServer::get_singleton()->get_rendering_device() == nullptr) { + return Vector<String>(); + } + REFCLSID clsid = CLSID_WbemLocator; // Unmarshaler CLSID REFIID uuid = IID_IWbemLocator; // Interface UUID IWbemLocator *wbemLocator = NULL; // to get the services @@ -1153,11 +1155,11 @@ String OS_Windows::get_system_dir(SystemDir p_dir, bool p_shared_storage) const } String OS_Windows::get_user_data_dir() const { - String appname = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/name")); + String appname = get_safe_dir_name(GLOBAL_GET("application/config/name")); if (!appname.is_empty()) { - bool use_custom_dir = ProjectSettings::get_singleton()->get("application/config/use_custom_user_dir"); + bool use_custom_dir = GLOBAL_GET("application/config/use_custom_user_dir"); if (use_custom_dir) { - String custom_dir = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/custom_user_dir_name"), true); + String custom_dir = get_safe_dir_name(GLOBAL_GET("application/config/custom_user_dir_name"), true); if (custom_dir.is_empty()) { custom_dir = appname; } @@ -1177,7 +1179,14 @@ String OS_Windows::get_unique_id() const { } bool OS_Windows::_check_internal_feature_support(const String &p_feature) { - return p_feature == "pc"; + if (p_feature == "system_fonts") { + return true; + } + if (p_feature == "pc") { + return true; + } + + return false; } void OS_Windows::disable_crash_handler() { diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index bf934bce64..6f89be699a 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -63,6 +63,10 @@ #define WINDOWS_DEBUG_OUTPUT_ENABLED #endif +#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING +#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4 +#endif + template <class T> class ComAutoreleaseRef { public: diff --git a/platform/windows/platform_config.h b/platform/windows/platform_config.h index 8e80f8cacb..7f0042d76f 100644 --- a/platform/windows/platform_config.h +++ b/platform/windows/platform_config.h @@ -30,4 +30,4 @@ #include <malloc.h> -#define OPENGL_INCLUDE_H "thirdparty/glad/glad/glad.h" +#define OPENGL_INCLUDE_H "thirdparty/glad/glad/gl.h" diff --git a/platform/windows/vulkan_context_win.h b/platform/windows/vulkan_context_win.h index 2ecdfc8f3f..9dedcabb2b 100644 --- a/platform/windows/vulkan_context_win.h +++ b/platform/windows/vulkan_context_win.h @@ -31,6 +31,8 @@ #ifndef VULKAN_CONTEXT_WIN_H #define VULKAN_CONTEXT_WIN_H +#ifdef VULKAN_ENABLED + #include "drivers/vulkan/vulkan_context.h" #define WIN32_LEAN_AND_MEAN @@ -46,4 +48,6 @@ public: ~VulkanContextWindows(); }; +#endif // VULKAN_ENABLED + #endif // VULKAN_CONTEXT_WIN_H |