diff options
Diffstat (limited to 'platform/windows')
-rw-r--r-- | platform/windows/SCsub | 24 | ||||
-rw-r--r-- | platform/windows/context_gl_win.cpp | 25 | ||||
-rw-r--r-- | platform/windows/crash_handler_win.cpp | 3 | ||||
-rw-r--r-- | platform/windows/detect.py | 44 | ||||
-rw-r--r-- | platform/windows/export/export.cpp | 16 | ||||
-rw-r--r-- | platform/windows/godot_win.cpp | 4 | ||||
-rw-r--r-- | platform/windows/joypad.cpp | 4 | ||||
-rw-r--r-- | platform/windows/lang_table.h | 1 | ||||
-rw-r--r-- | platform/windows/logo.png | bin | 1882 -> 1536 bytes | |||
-rw-r--r-- | platform/windows/os_windows.cpp | 607 | ||||
-rw-r--r-- | platform/windows/os_windows.h | 8 | ||||
-rw-r--r-- | platform/windows/platform_windows_builders.py | 22 |
12 files changed, 475 insertions, 283 deletions
diff --git a/platform/windows/SCsub b/platform/windows/SCsub index ed3827353d..586533e817 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -3,17 +3,11 @@ import os Import('env') -def make_debug_mingw(target, source, env): - mingw_prefix = "" - if (env["bits"] == "32"): - mingw_prefix = env["mingw_prefix_32"] - else: - mingw_prefix = env["mingw_prefix_64"] - os.system(mingw_prefix + 'objcopy --only-keep-debug {0} {0}.debugsymbols'.format(target[0])) - os.system(mingw_prefix + 'strip --strip-debug --strip-unneeded {0}'.format(target[0])) - os.system(mingw_prefix + 'objcopy --add-gnu-debuglink={0}.debugsymbols {0}'.format(target[0])) +from platform_methods import run_in_subprocess +import platform_windows_builders common_win = [ + "godot_win.cpp", "context_gl_win.cpp", "crash_handler_win.cpp", "os_windows.cpp", @@ -24,20 +18,20 @@ common_win = [ "windows_terminal_logger.cpp" ] -restarget = "godot_res" + env["OBJSUFFIX"] +res_file = 'godot_res.rc' -obj = env.RES(restarget, 'godot_res.rc') +res_target = "godot_res" + env["OBJSUFFIX"] -common_win.append(obj) +res_obj = env.RES(res_target, res_file) -prog = env.add_program('#bin/godot', ['godot_win.cpp'] + common_win, PROGSUFFIX=env["PROGSUFFIX"]) +prog = env.add_program('#bin/godot', common_win + res_obj, PROGSUFFIX=env["PROGSUFFIX"]) # Microsoft Visual Studio Project Generation if env['vsproj']: - env.vs_srcs = env.vs_srcs + ["platform/windows/godot_win.cpp"] + env.vs_srcs = env.vs_srcs + ["platform/windows/" + res_file] for x in common_win: env.vs_srcs = env.vs_srcs + ["platform/windows/" + str(x)] if not os.getenv("VCINSTALLDIR"): if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes") and env["separate_debug_symbols"]: - env.AddPostAction(prog, make_debug_mingw) + env.AddPostAction(prog, run_in_subprocess(platform_windows_builders.make_debug_mingw)) diff --git a/platform/windows/context_gl_win.cpp b/platform/windows/context_gl_win.cpp index d312fbcb12..794f6df31f 100644 --- a/platform/windows/context_gl_win.cpp +++ b/platform/windows/context_gl_win.cpp @@ -68,20 +68,6 @@ void ContextGL_Win::swap_buffers() { SwapBuffers(hDC); } -/* -static GLWrapperFuncPtr wrapper_get_proc_address(const char* p_function) { - - print_line(String()+"getting proc of: "+p_function); - GLWrapperFuncPtr func=(GLWrapperFuncPtr)get_gl_proc_address(p_function); - if (!func) { - print_line("Couldn't find function: "+String(p_function)); - print_line("error: "+itos(GetLastError())); - } - return func; - -} -*/ - void ContextGL_Win::set_use_vsync(bool p_use) { if (wglSwapIntervalEXT) { @@ -106,9 +92,9 @@ Error ContextGL_Win::initialize() { PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, - 24, + OS::get_singleton()->is_layered_allowed() ? 32 : 24, 0, 0, 0, 0, 0, 0, // Color Bits Ignored - 0, // No Alpha Buffer + OS::get_singleton()->is_layered_allowed() ? 8 : 0, // Alpha Buffer 0, // Shift Bit Ignored 0, // No Accumulation Buffer 0, 0, 0, 0, // Accumulation Bits Ignored @@ -122,28 +108,24 @@ Error ContextGL_Win::initialize() { hDC = GetDC(hWnd); if (!hDC) { - MessageBox(NULL, "Can't Create A GL Device Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return ERR_CANT_CREATE; // Return FALSE } pixel_format = ChoosePixelFormat(hDC, &pfd); if (!pixel_format) // Did Windows Find A Matching Pixel Format? { - MessageBox(NULL, "Can't Find A Suitable pixel_format.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return ERR_CANT_CREATE; // Return FALSE } BOOL ret = SetPixelFormat(hDC, pixel_format, &pfd); if (!ret) // Are We Able To Set The Pixel Format? { - MessageBox(NULL, "Can't Set The pixel_format.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return ERR_CANT_CREATE; // Return FALSE } hRC = wglCreateContext(hDC); if (!hRC) // Are We Able To Get A Rendering Context? { - MessageBox(NULL, "Can't Create A Temporary GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return ERR_CANT_CREATE; // Return FALSE } @@ -165,7 +147,6 @@ Error ContextGL_Win::initialize() { if (wglCreateContextAttribsARB == NULL) //OpenGL 3.0 is not supported { - MessageBox(NULL, "Cannot get Proc Address for CreateContextAttribs", "ERROR", MB_OK | MB_ICONEXCLAMATION); wglDeleteContext(hRC); return ERR_CANT_CREATE; } @@ -173,7 +154,6 @@ Error ContextGL_Win::initialize() { HGLRC new_hRC = wglCreateContextAttribsARB(hDC, 0, attribs); if (!new_hRC) { wglDeleteContext(hRC); - MessageBox(NULL, "Can't Create An OpenGL 3.3 Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return ERR_CANT_CREATE; // Return false } wglMakeCurrent(hDC, NULL); @@ -182,7 +162,6 @@ Error ContextGL_Win::initialize() { if (!wglMakeCurrent(hDC, hRC)) // Try To Activate The Rendering Context { - MessageBox(NULL, "Can't Activate The GL 3.3 Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return ERR_CANT_CREATE; // Return FALSE } } diff --git a/platform/windows/crash_handler_win.cpp b/platform/windows/crash_handler_win.cpp index 804c2d44eb..76a227c608 100644 --- a/platform/windows/crash_handler_win.cpp +++ b/platform/windows/crash_handler_win.cpp @@ -124,6 +124,9 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) { fprintf(stderr, "%s: Program crashed\n", __FUNCTION__); + if (OS::get_singleton()->get_main_loop()) + OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH); + // Load the symbols: if (!SymInitialize(process, NULL, false)) return EXCEPTION_CONTINUE_SEARCH; diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 05806d2fe8..150d418502 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -166,20 +166,22 @@ def configure_msvc(env, manual_msvc_config): # Build type if (env["target"] == "release"): - env.Append(CCFLAGS=['/O2']) + if (env["optimize"] == "speed"): #optimize for speed (default) + env.Append(CCFLAGS=['/O2']) + else: # optimize for size + env.Append(CCFLAGS=['/O1']) env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS']) env.Append(LINKFLAGS=['/ENTRY:mainCRTStartup']) + env.Append(LINKFLAGS=['/OPT:REF']) elif (env["target"] == "release_debug"): - env.Append(CCFLAGS=['/O2']) + if (env["optimize"] == "speed"): #optimize for speed (default) + env.Append(CCFLAGS=['/O2']) + else: # optimize for size + env.Append(CCFLAGS=['/O1']) env.AppendUnique(CPPDEFINES = ['DEBUG_ENABLED']) env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE']) - - elif (env["target"] == "debug_release"): - env.Append(CCFLAGS=['/Z7', '/Od']) - env.Append(LINKFLAGS=['/DEBUG']) - env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS']) - env.Append(LINKFLAGS=['/ENTRY:mainCRTStartup']) + env.Append(LINKFLAGS=['/OPT:REF']) elif (env["target"] == "debug"): env.AppendUnique(CCFLAGS=['/Z7', '/Od', '/EHsc']) @@ -188,6 +190,10 @@ def configure_msvc(env, manual_msvc_config): env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE']) env.Append(LINKFLAGS=['/DEBUG']) + if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes"): + env.AppendUnique(CCFLAGS=['/Z7']) + env.AppendUnique(LINKFLAGS=['/DEBUG']) + ## Compile/link flags env.AppendUnique(CCFLAGS=['/MT', '/Gd', '/GR', '/nologo']) @@ -200,9 +206,11 @@ def configure_msvc(env, manual_msvc_config): env.AppendUnique(CPPDEFINES = ['WINDOWS_ENABLED', 'OPENGL_ENABLED', 'RTAUDIO_ENABLED', 'WASAPI_ENABLED', - 'TYPED_METHOD_BIND', 'WIN32', 'MSVC', + 'WINMIDI_ENABLED', 'TYPED_METHOD_BIND', + 'WIN32', 'MSVC', {'WINVER' : '$target_win_version', '_WIN32_WINNT': '$target_win_version'}]) + env.AppendUnique(CPPDEFINES=['NOMINMAX']) # disable bogus min/max WinDef.h macros if env["bits"] == "64": env.AppendUnique(CPPDEFINES=['_WIN64']) @@ -247,10 +255,14 @@ def configure_mingw(env): if (env["target"] == "release"): env.Append(CCFLAGS=['-msse2']) - if (env["bits"] == "64"): - env.Append(CCFLAGS=['-O3']) - else: - env.Append(CCFLAGS=['-O2']) + if (env["optimize"] == "speed"): #optimize for speed (default) + if (env["bits"] == "64"): + env.Append(CCFLAGS=['-O3']) + else: + env.Append(CCFLAGS=['-O2']) + else: #optimize for size + env.Prepend(CCFLAGS=['-Os']) + env.Append(LINKFLAGS=['-Wl,--subsystem,windows']) @@ -265,7 +277,11 @@ def configure_mingw(env): env.Prepend(CCFLAGS=['-g1']) if (env["debug_symbols"] == "full"): env.Prepend(CCFLAGS=['-g2']) - + if (env["optimize"] == "speed"): #optimize for speed (default) + env.Append(CCFLAGS=['-O2']) + else: #optimize for size + env.Prepend(CCFLAGS=['-Os']) + elif (env["target"] == "debug"): env.Append(CCFLAGS=['-g3', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp index 97544c18f5..38fd6366c7 100644 --- a/platform/windows/export/export.cpp +++ b/platform/windows/export/export.cpp @@ -137,14 +137,14 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_options) { EditorExportPlatformPC::get_export_options(r_options); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_GLOBAL_FILE, "*.ico"), String())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version"), String())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version"), String())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/company_name"), String())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_name"), String())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_description"), String())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), String())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), String())); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_GLOBAL_FILE, "*.ico"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/company_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Company Name"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_description"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), "")); } void register_windows_exporter() { diff --git a/platform/windows/godot_win.cpp b/platform/windows/godot_win.cpp index 80f53dd1a1..504a9a0380 100644 --- a/platform/windows/godot_win.cpp +++ b/platform/windows/godot_win.cpp @@ -176,8 +176,8 @@ int _main() { } int main(int _argc, char **_argv) { -// _argc and _argv are ignored -// we are going to use the WideChar version of them instead + // _argc and _argv are ignored + // we are going to use the WideChar version of them instead #ifdef CRASH_HANDLER_EXCEPTION __try { diff --git a/platform/windows/joypad.cpp b/platform/windows/joypad.cpp index 796531fe24..b56fb6509e 100644 --- a/platform/windows/joypad.cpp +++ b/platform/windows/joypad.cpp @@ -540,9 +540,7 @@ void JoypadWindows::load_xinput() { } if (!xinput_dll) { - if (OS::get_singleton()->is_stdout_verbose()) { - print_line("Could not find XInput, using DirectInput only"); - } + print_verbose("Could not find XInput, using DirectInput only"); return; } diff --git a/platform/windows/lang_table.h b/platform/windows/lang_table.h index 1a966b502a..78bfadfeae 100644 --- a/platform/windows/lang_table.h +++ b/platform/windows/lang_table.h @@ -186,6 +186,7 @@ static const _WinLocale _win_locales[] = { { "zh_CN", LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED }, { "zh_HK", LANG_CHINESE, SUBLANG_CHINESE_HONGKONG }, { "zh_SG", LANG_CHINESE, SUBLANG_CHINESE_SINGAPORE }, + { "zh_TW", LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL }, { 0, 0, 0 }, }; diff --git a/platform/windows/logo.png b/platform/windows/logo.png Binary files differindex 4376abd563..f06b463850 100644 --- a/platform/windows/logo.png +++ b/platform/windows/logo.png diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index ca6c793d5d..88793386ab 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -70,6 +70,30 @@ __attribute__((visibility("default"))) DWORD NvOptimusEnablement = 0x00000001; #define WM_TOUCH 576 #endif +typedef struct { + int count; + int screen; + Size2 size; +} EnumSizeData; + +typedef struct { + int count; + int screen; + Point2 pos; +} EnumPosData; + +static BOOL CALLBACK _MonitorEnumProcSize(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { + + EnumSizeData *data = (EnumSizeData *)dwData; + if (data->count == data->screen) { + data->size.x = lprcMonitor->right - lprcMonitor->left; + data->size.y = lprcMonitor->bottom - lprcMonitor->top; + } + + data->count++; + return TRUE; +} + static String format_error_message(DWORD id) { LPWSTR messageBuffer = NULL; @@ -225,7 +249,11 @@ bool OS_Windows::can_draw() const { #define MI_WP_SIGNATURE 0xFF515700 #define SIGNATURE_MASK 0xFFFFFF00 +// Keeping the name suggested by Microsoft, but this macro really answers: +// Is this mouse event emulated from touch or pen input? #define IsPenEvent(dw) (((dw)&SIGNATURE_MASK) == MI_WP_SIGNATURE) +// This one tells whether the event comes from touchscreen (and not from pen) +#define IsTouchEvent(dw) (IsPenEvent(dw) && ((dw)&0x80)) void OS_Windows::_touch_event(bool p_pressed, float p_x, float p_y, int idx) { @@ -363,12 +391,89 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) input->set_mouse_in_window(false); } break; + case WM_INPUT: { + if (mouse_mode != MOUSE_MODE_CAPTURED || !use_raw_input) { + break; + } + + UINT dwSize; + + GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)); + LPBYTE lpb = new BYTE[dwSize]; + if (lpb == NULL) { + return 0; + } + + if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize) + OutputDebugString(TEXT("GetRawInputData does not return correct size !\n")); + + RAWINPUT *raw = (RAWINPUT *)lpb; + + if (raw->header.dwType == RIM_TYPEMOUSE) { + Ref<InputEventMouseMotion> mm; + mm.instance(); + + mm->set_control(control_mem); + mm->set_shift(shift_mem); + mm->set_alt(alt_mem); + + mm->set_button_mask(last_button_state); + + Point2i c(video_mode.width / 2, video_mode.height / 2); + + // centering just so it works as before + POINT pos = { (int)c.x, (int)c.y }; + ClientToScreen(hWnd, &pos); + SetCursorPos(pos.x, pos.y); + + mm->set_position(c); + mm->set_global_position(c); + input->set_mouse_position(c); + mm->set_speed(Vector2(0, 0)); + + if (raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE) { + mm->set_relative(Vector2(raw->data.mouse.lLastX, raw->data.mouse.lLastY)); + + } else if (raw->data.mouse.usFlags == MOUSE_MOVE_ABSOLUTE) { + + int nScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN); + int nScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN); + int nScreenLeft = GetSystemMetrics(SM_XVIRTUALSCREEN); + int nScreenTop = GetSystemMetrics(SM_YVIRTUALSCREEN); + + Vector2 abs_pos( + (double(raw->data.mouse.lLastX) - 65536.0 / (nScreenWidth)) * nScreenWidth / 65536.0 + nScreenLeft, + (double(raw->data.mouse.lLastY) - 65536.0 / (nScreenHeight)) * nScreenHeight / 65536.0 + nScreenTop); + + POINT coords; //client coords + coords.x = abs_pos.x; + coords.y = abs_pos.y; + + ScreenToClient(hWnd, &coords); + + mm->set_relative(Vector2(coords.x - old_x, coords.y - old_y)); + old_x = coords.x; + old_y = coords.y; + + /*Input.mi.dx = (int)((((double)(pos.x)-nScreenLeft) * 65536) / nScreenWidth + 65536 / (nScreenWidth)); + Input.mi.dy = (int)((((double)(pos.y)-nScreenTop) * 65536) / nScreenHeight + 65536 / (nScreenHeight)); + */ + } + + if (window_has_focus && main_loop) + input->parse_input_event(mm); + } + delete[] lpb; + } break; case WM_MOUSEMOVE: { + if (mouse_mode == MOUSE_MODE_CAPTURED && use_raw_input) { + break; + } if (input->is_emulating_mouse_from_touch()) { // Universal translation enabled; ignore OS translation LPARAM extra = GetMessageExtraInfo(); - if (IsPenEvent(extra)) { + if (IsTouchEvent(extra)) { break; } } @@ -410,11 +515,12 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) bmask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0; bmask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0; bmask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0; + bmask |= (wParam & MK_XBUTTON1) ? (1 << 7) : 0; + bmask |= (wParam & MK_XBUTTON2) ? (1 << 8) : 0; mm->set_button_mask(bmask); last_button_state = mm->get_button_mask(); - /*mm->get_button_mask()|=(wParam&MK_XBUTTON1)?(1<<5):0; - mm->get_button_mask()|=(wParam&MK_XBUTTON2)?(1<<6):0;*/ + mm->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); mm->set_global_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); @@ -455,6 +561,13 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } break; case WM_LBUTTONDOWN: case WM_LBUTTONUP: + if (input->is_emulating_mouse_from_touch()) { + // Universal translation enabled; ignore OS translations for left button + LPARAM extra = GetMessageExtraInfo(); + if (IsTouchEvent(extra)) { + break; + } + } case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_RBUTTONDOWN: @@ -464,161 +577,168 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: - /*case WM_XBUTTONDOWN: - case WM_XBUTTONUP: */ { - - if (input->is_emulating_mouse_from_touch()) { - // Universal translation enabled; ignore OS translation - LPARAM extra = GetMessageExtraInfo(); - if (IsPenEvent(extra)) { - break; - } - } + case WM_XBUTTONDBLCLK: + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: { - Ref<InputEventMouseButton> mb; - mb.instance(); - - switch (uMsg) { - case WM_LBUTTONDOWN: { - mb->set_pressed(true); - mb->set_button_index(1); - } break; - case WM_LBUTTONUP: { - mb->set_pressed(false); - mb->set_button_index(1); - } break; - case WM_MBUTTONDOWN: { - mb->set_pressed(true); - mb->set_button_index(3); - - } break; - case WM_MBUTTONUP: { - mb->set_pressed(false); - mb->set_button_index(3); - } break; - case WM_RBUTTONDOWN: { - mb->set_pressed(true); - mb->set_button_index(2); - } break; - case WM_RBUTTONUP: { - mb->set_pressed(false); - mb->set_button_index(2); - } break; - case WM_LBUTTONDBLCLK: { - - mb->set_pressed(true); - mb->set_button_index(1); - mb->set_doubleclick(true); - } break; - case WM_RBUTTONDBLCLK: { - - mb->set_pressed(true); - mb->set_button_index(2); - mb->set_doubleclick(true); - } break; - case WM_MBUTTONDBLCLK: { - - mb->set_pressed(true); - mb->set_button_index(3); - mb->set_doubleclick(true); - } break; - case WM_MOUSEWHEEL: { - - mb->set_pressed(true); - int motion = (short)HIWORD(wParam); - if (!motion) - return 0; - - if (motion > 0) - mb->set_button_index(BUTTON_WHEEL_UP); - else - mb->set_button_index(BUTTON_WHEEL_DOWN); - - } break; - case WM_MOUSEHWHEEL: { - - mb->set_pressed(true); - int motion = (short)HIWORD(wParam); - if (!motion) - return 0; - - if (motion < 0) { - mb->set_button_index(BUTTON_WHEEL_LEFT); - mb->set_factor(fabs((double)motion / (double)WHEEL_DELTA)); - } else { - mb->set_button_index(BUTTON_WHEEL_RIGHT); - mb->set_factor(fabs((double)motion / (double)WHEEL_DELTA)); - } - } break; - /* - case WM_XBUTTONDOWN: { - mb->is_pressed()=true; - mb->get_button_index()=(HIWORD(wParam)==XBUTTON1)?6:7; + Ref<InputEventMouseButton> mb; + mb.instance(); + + switch (uMsg) { + case WM_LBUTTONDOWN: { + mb->set_pressed(true); + mb->set_button_index(1); } break; - case WM_XBUTTONUP: - mb->is_pressed()=true; - mb->get_button_index()=(HIWORD(wParam)==XBUTTON1)?6:7; - } break;*/ - default: { return 0; } - } + case WM_LBUTTONUP: { + mb->set_pressed(false); + mb->set_button_index(1); + } break; + case WM_MBUTTONDOWN: { + mb->set_pressed(true); + mb->set_button_index(3); - mb->set_control((wParam & MK_CONTROL) != 0); - mb->set_shift((wParam & MK_SHIFT) != 0); - mb->set_alt(alt_mem); - //mb->get_alt()=(wParam&MK_MENU)!=0; - int bmask = 0; - bmask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0; - bmask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0; - bmask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0; - mb->set_button_mask(bmask); - - last_button_state = mb->get_button_mask(); - /* - mb->get_button_mask()|=(wParam&MK_XBUTTON1)?(1<<5):0; - mb->get_button_mask()|=(wParam&MK_XBUTTON2)?(1<<6):0;*/ - mb->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); - - if (mouse_mode == MOUSE_MODE_CAPTURED) { - - mb->set_position(Vector2(old_x, old_y)); - } + } break; + case WM_MBUTTONUP: { + mb->set_pressed(false); + mb->set_button_index(3); + } break; + case WM_RBUTTONDOWN: { + mb->set_pressed(true); + mb->set_button_index(2); + } break; + case WM_RBUTTONUP: { + mb->set_pressed(false); + mb->set_button_index(2); + } break; + case WM_LBUTTONDBLCLK: { + + mb->set_pressed(true); + mb->set_button_index(1); + mb->set_doubleclick(true); + } break; + case WM_RBUTTONDBLCLK: { - if (uMsg != WM_MOUSEWHEEL && uMsg != WM_MOUSEHWHEEL) { - if (mb->is_pressed()) { + mb->set_pressed(true); + mb->set_button_index(2); + mb->set_doubleclick(true); + } break; + case WM_MBUTTONDBLCLK: { - if (++pressrc > 0) - SetCapture(hWnd); - } else { + mb->set_pressed(true); + mb->set_button_index(3); + mb->set_doubleclick(true); + } break; + case WM_MOUSEWHEEL: { - if (--pressrc <= 0) { - ReleaseCapture(); - pressrc = 0; - } + mb->set_pressed(true); + int motion = (short)HIWORD(wParam); + if (!motion) + return 0; + + if (motion > 0) + mb->set_button_index(BUTTON_WHEEL_UP); + else + mb->set_button_index(BUTTON_WHEEL_DOWN); + + } break; + case WM_MOUSEHWHEEL: { + + mb->set_pressed(true); + int motion = (short)HIWORD(wParam); + if (!motion) + return 0; + + if (motion < 0) { + mb->set_button_index(BUTTON_WHEEL_LEFT); + mb->set_factor(fabs((double)motion / (double)WHEEL_DELTA)); + } else { + mb->set_button_index(BUTTON_WHEEL_RIGHT); + mb->set_factor(fabs((double)motion / (double)WHEEL_DELTA)); } - } else if (mouse_mode != MOUSE_MODE_CAPTURED) { - // for reasons unknown to mankind, wheel comes in screen cordinates - POINT coords; - coords.x = mb->get_position().x; - coords.y = mb->get_position().y; + } break; + case WM_XBUTTONDOWN: { - ScreenToClient(hWnd, &coords); + mb->set_pressed(true); + if (HIWORD(wParam) == XBUTTON1) + mb->set_button_index(BUTTON_XBUTTON1); + else + mb->set_button_index(BUTTON_XBUTTON2); + } break; + case WM_XBUTTONUP: { - mb->set_position(Vector2(coords.x, coords.y)); - } + mb->set_pressed(false); + if (HIWORD(wParam) == XBUTTON1) + mb->set_button_index(BUTTON_XBUTTON1); + else + mb->set_button_index(BUTTON_XBUTTON2); + } break; + case WM_XBUTTONDBLCLK: { - mb->set_global_position(mb->get_position()); + mb->set_pressed(true); + if (HIWORD(wParam) == XBUTTON1) + mb->set_button_index(BUTTON_XBUTTON1); + else + mb->set_button_index(BUTTON_XBUTTON2); + mb->set_doubleclick(true); + } break; + default: { return 0; } + } - if (main_loop) { - input->parse_input_event(mb); - if (mb->is_pressed() && mb->get_button_index() > 3) { - //send release for mouse wheel - Ref<InputEventMouseButton> mbd = mb->duplicate(); - mbd->set_pressed(false); - input->parse_input_event(mbd); + mb->set_control((wParam & MK_CONTROL) != 0); + mb->set_shift((wParam & MK_SHIFT) != 0); + mb->set_alt(alt_mem); + //mb->get_alt()=(wParam&MK_MENU)!=0; + int bmask = 0; + bmask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0; + bmask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0; + bmask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0; + bmask |= (wParam & MK_XBUTTON1) ? (1 << 7) : 0; + bmask |= (wParam & MK_XBUTTON2) ? (1 << 8) : 0; + mb->set_button_mask(bmask); + + last_button_state = mb->get_button_mask(); + mb->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); + + if (mouse_mode == MOUSE_MODE_CAPTURED) { + + mb->set_position(Vector2(old_x, old_y)); + } + + if (uMsg != WM_MOUSEWHEEL && uMsg != WM_MOUSEHWHEEL) { + if (mb->is_pressed()) { + + if (++pressrc > 0) + SetCapture(hWnd); + } else { + + if (--pressrc <= 0) { + ReleaseCapture(); + pressrc = 0; } } + } else if (mouse_mode != MOUSE_MODE_CAPTURED) { + // for reasons unknown to mankind, wheel comes in screen cordinates + POINT coords; + coords.x = mb->get_position().x; + coords.y = mb->get_position().y; + + ScreenToClient(hWnd, &coords); + + mb->set_position(Vector2(coords.x, coords.y)); } - break; + + mb->set_global_position(mb->get_position()); + + if (main_loop) { + input->parse_input_event(mb); + if (mb->is_pressed() && mb->get_button_index() > 3 && mb->get_button_index() < 8) { + //send release for mouse wheel + Ref<InputEventMouseButton> mbd = mb->duplicate(); + mbd->set_pressed(false); + input->parse_input_event(mbd); + } + } + } break; case WM_SIZE: { int window_w = LOWORD(lParam); @@ -715,14 +835,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (ke.uMsg == WM_SYSKEYUP) ke.uMsg = WM_KEYUP; - /*if (ke.uMsg==WM_KEYDOWN && alt_mem && uMsg!=WM_SYSKEYDOWN) { - //altgr hack for intl keyboards, not sure how good it is - //windows is weeeeird - ke.mod_state.alt=false; - ke.mod_state.control=false; - print_line("") - }*/ - ke.wParam = wParam; ke.lParam = lParam; key_event_buffer[key_event_pos++] = ke; @@ -730,7 +842,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } break; case WM_INPUTLANGCHANGEREQUEST: { - print_line("input lang change"); + // FIXME: Do something? } break; case WM_TOUCH: { @@ -742,13 +854,18 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (GetTouchInputInfo((HTOUCHINPUT)lParam, cInputs, pInputs, sizeof(TOUCHINPUT))) { for (UINT i = 0; i < cInputs; i++) { TOUCHINPUT ti = pInputs[i]; + POINT touch_pos = { + TOUCH_COORD_TO_PIXEL(ti.x), + TOUCH_COORD_TO_PIXEL(ti.y), + }; + ScreenToClient(hWnd, &touch_pos); //do something with each touch input entry if (ti.dwFlags & TOUCHEVENTF_MOVE) { - _drag_event(ti.x / 100.0f, ti.y / 100.0f, ti.dwID); + _drag_event(touch_pos.x, touch_pos.y, ti.dwID); } else if (ti.dwFlags & (TOUCHEVENTF_UP | TOUCHEVENTF_DOWN)) { - _touch_event(ti.dwFlags & TOUCHEVENTF_DOWN, ti.x / 100.0f, ti.y / 100.0f, ti.dwID); + _touch_event(ti.dwFlags & TOUCHEVENTF_DOWN, touch_pos.x, touch_pos.y, ti.dwID); }; } bHandled = TRUE; @@ -968,6 +1085,10 @@ typedef enum _SHC_PROCESS_DPI_AWARENESS { SHC_PROCESS_PER_MONITOR_DPI_AWARE = 2 } SHC_PROCESS_DPI_AWARENESS; +int OS_Windows::get_current_video_driver() const { + return video_driver_index; +} + Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { main_loop = NULL; @@ -1017,9 +1138,24 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int return ERR_UNAVAILABLE; } + use_raw_input = true; + + RAWINPUTDEVICE Rid[1]; + + Rid[0].usUsagePage = 0x01; + Rid[0].usUsage = 0x02; + Rid[0].dwFlags = 0; + Rid[0].hwndTarget = 0; + + if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) == FALSE) { + //registration failed. + use_raw_input = false; + } + pre_fs_valid = true; if (video_mode.fullscreen) { + /* this returns DPI unaware size, commenting DEVMODE current; memset(¤t, 0, sizeof(current)); EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, ¤t); @@ -1027,6 +1163,14 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int WindowRect.right = current.dmPelsWidth; WindowRect.bottom = current.dmPelsHeight; + */ + + EnumSizeData data = { 0, 0, Size2() }; + EnumDisplayMonitors(NULL, NULL, _MonitorEnumProcSize, (LPARAM)&data); + + WindowRect.right = data.size.width; + WindowRect.bottom = data.size.height; + /* DEVMODE dmScreenSettings; memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); dmScreenSettings.dmSize=sizeof(dmScreenSettings); @@ -1111,20 +1255,75 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int } #if defined(OPENGL_ENABLED) + + bool gles3_context = true; if (p_video_driver == VIDEO_DRIVER_GLES2) { - gl_context = memnew(ContextGL_Win(hWnd, false)); - gl_context->initialize(); + gles3_context = false; + } - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - } else { - gl_context = memnew(ContextGL_Win(hWnd, true)); - gl_context->initialize(); + bool editor = Engine::get_singleton()->is_editor_hint(); + bool gl_initialization_error = false; - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); + gl_context = NULL; + while (!gl_context) { + gl_context = memnew(ContextGL_Win(hWnd, gles3_context)); + + if (gl_context->initialize() != OK) { + memdelete(gl_context); + gl_context = NULL; + + if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) { + if (p_video_driver == VIDEO_DRIVER_GLES2) { + gl_initialization_error = true; + break; + } + + p_video_driver = VIDEO_DRIVER_GLES2; + gles3_context = false; + } else { + gl_initialization_error = true; + break; + } + } } + while (true) { + if (gles3_context) { + if (RasterizerGLES3::is_viable() == OK) { + RasterizerGLES3::register_config(); + RasterizerGLES3::make_current(); + break; + } else { + if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) { + p_video_driver = VIDEO_DRIVER_GLES2; + gles3_context = false; + continue; + } else { + gl_initialization_error = true; + break; + } + } + } else { + if (RasterizerGLES2::is_viable() == OK) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + break; + } else { + gl_initialization_error = true; + break; + } + } + } + + if (gl_initialization_error) { + OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n" + "Please update your drivers or if you have a very old or integrated GPU upgrade it.", + "Unable to initialize Video driver"); + return ERR_UNAVAILABLE; + } + + video_driver_index = p_video_driver; + gl_context->set_use_vsync(video_mode.use_vsync); #endif @@ -1285,6 +1484,10 @@ void OS_Windows::set_main_loop(MainLoop *p_main_loop) { void OS_Windows::finalize() { +#ifdef WINMIDI_ENABLED + driver_midi.close(); +#endif + if (main_loop) memdelete(main_loop); @@ -1304,12 +1507,6 @@ void OS_Windows::finalize() { if (user_proc) { SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)user_proc); }; - - /* - if (debugger_connection_console) { - memdelete(debugger_connection_console); - } - */ } void OS_Windows::finalize_core() { @@ -1451,12 +1648,6 @@ void OS_Windows::set_current_screen(int p_screen) { set_window_position(ofs + get_screen_position(p_screen)); } -typedef struct { - int count; - int screen; - Point2 pos; -} EnumPosData; - static BOOL CALLBACK _MonitorEnumProcPos(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { EnumPosData *data = (EnumPosData *)dwData; @@ -1476,24 +1667,6 @@ Point2 OS_Windows::get_screen_position(int p_screen) const { return data.pos; } -typedef struct { - int count; - int screen; - Size2 size; -} EnumSizeData; - -static BOOL CALLBACK _MonitorEnumProcSize(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { - - EnumSizeData *data = (EnumSizeData *)dwData; - if (data->count == data->screen) { - data->size.x = lprcMonitor->right - lprcMonitor->left; - data->size.y = lprcMonitor->bottom - lprcMonitor->top; - } - - data->count++; - return TRUE; -} - Size2 OS_Windows::get_screen_size(int p_screen) const { EnumSizeData data = { 0, p_screen == -1 ? get_current_screen() : p_screen, Size2() }; @@ -1553,16 +1726,16 @@ Size2 OS_Windows::get_real_window_size() const { } void OS_Windows::set_window_size(const Size2 p_size) { - video_mode.width = p_size.width; - video_mode.height = p_size.height; + int w = p_size.width; + int h = p_size.height; + + video_mode.width = w; + video_mode.height = h; if (video_mode.fullscreen) { return; } - int w = p_size.width; - int h = p_size.height; - RECT rect; GetWindowRect(hWnd, &rect); @@ -1597,9 +1770,6 @@ void OS_Windows::set_window_fullscreen(bool p_enabled) { if (pre_fs_valid) { GetWindowRect(hWnd, &pre_fs_rect); - //print_line("A: "+itos(pre_fs_rect.left)+","+itos(pre_fs_rect.top)+","+itos(pre_fs_rect.right-pre_fs_rect.left)+","+itos(pre_fs_rect.bottom-pre_fs_rect.top)); - //MapWindowPoints(hWnd, GetParent(hWnd), (LPPOINT) &pre_fs_rect, 2); - //print_line("B: "+itos(pre_fs_rect.left)+","+itos(pre_fs_rect.top)+","+itos(pre_fs_rect.right-pre_fs_rect.left)+","+itos(pre_fs_rect.bottom-pre_fs_rect.top)); } int cs = get_current_screen(); @@ -2082,7 +2252,9 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap } ERR_FAIL_COND(!texture.is_valid()); + ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0); ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256); + ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height); image = texture->get_data(); @@ -2253,7 +2425,7 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, Vector<CharType> modstr; //windows wants to change this no idea why modstr.resize(cmdline.size()); for (int i = 0; i < cmdline.size(); i++) - modstr[i] = cmdline[i]; + modstr.write[i] = cmdline[i]; int ret = CreateProcessW(NULL, modstr.ptrw(), NULL, NULL, 0, NORMAL_PRIORITY_CLASS, NULL, NULL, si_w, &pi.pi); ERR_FAIL_COND_V(ret == 0, ERR_CANT_FORK); @@ -2263,6 +2435,8 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, if (r_exitcode) *r_exitcode = ret; + CloseHandle(pi.pi.hProcess); + CloseHandle(pi.pi.hThread); } else { ProcessID pid = pi.pi.dwProcessId; @@ -2276,17 +2450,15 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, Error OS_Windows::kill(const ProcessID &p_pid) { - HANDLE h; + ERR_FAIL_COND_V(!process_map->has(p_pid), FAILED); - if (process_map->has(p_pid)) { - h = (*process_map)[p_pid].pi.hProcess; - process_map->erase(p_pid); - } else { + const PROCESS_INFORMATION pi = (*process_map)[p_pid].pi; + process_map->erase(p_pid); - ERR_FAIL_COND_V(!process_map->has(p_pid), FAILED); - }; + const int ret = TerminateProcess(pi.hProcess, 0); - int ret = TerminateProcess(h, 0); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); return ret != 0 ? OK : FAILED; }; @@ -2324,7 +2496,7 @@ void OS_Windows::set_icon(const Ref<Image> &p_icon) { int icon_len = 40 + h * w * 4; Vector<BYTE> v; v.resize(icon_len); - BYTE *icon_bmp = &v[0]; + BYTE *icon_bmp = v.ptrw(); encode_uint32(40, &icon_bmp[0]); encode_uint32(w, &icon_bmp[4]); @@ -2731,7 +2903,7 @@ int OS_Windows::get_power_percent_left() { bool OS_Windows::_check_internal_feature_support(const String &p_feature) { - return p_feature == "pc" || p_feature == "s3tc"; + return p_feature == "pc" || p_feature == "s3tc" || p_feature == "bptc"; } void OS_Windows::disable_crash_handler() { @@ -2743,10 +2915,9 @@ bool OS_Windows::is_disable_crash_handler() const { } Error OS_Windows::move_to_trash(const String &p_path) { - SHFILEOPSTRUCTA sf; - TCHAR *from = new TCHAR[p_path.length() + 2]; - strcpy(from, p_path.utf8().get_data()); - from[p_path.length()] = 0; + SHFILEOPSTRUCTW sf; + WCHAR *from = new WCHAR[p_path.length() + 2]; + wcscpy(from, p_path.c_str()); from[p_path.length() + 1] = 0; sf.hwnd = hWnd; @@ -2758,7 +2929,7 @@ Error OS_Windows::move_to_trash(const String &p_path) { sf.hNameMappings = NULL; sf.lpszProgressTitle = NULL; - int ret = SHFileOperation(&sf); + int ret = SHFileOperationW(&sf); delete[] from; if (ret) { diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 19af63bae0..c9fa46052a 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -35,6 +35,7 @@ #include "crash_handler_win.h" #include "drivers/rtaudio/audio_driver_rtaudio.h" #include "drivers/wasapi/audio_driver_wasapi.h" +#include "drivers/winmidi/win_midi.h" #include "os/input.h" #include "os/os.h" #include "power_windows.h" @@ -124,6 +125,7 @@ class OS_Windows : public OS { bool force_quit; bool window_has_focus; uint32_t last_button_state; + bool use_raw_input; HCURSOR cursors[CURSOR_MAX] = { NULL }; CursorShape cursor_shape; @@ -134,6 +136,7 @@ class OS_Windows : public OS { PowerWindows *power_manager; + int video_driver_index; #ifdef WASAPI_ENABLED AudioDriverWASAPI driver_wasapi; #endif @@ -143,6 +146,9 @@ class OS_Windows : public OS { #ifdef XAUDIO2_ENABLED AudioDriverXAudio2 driver_xaudio2; #endif +#ifdef WINMIDI_ENABLED + MIDIDriverWinMidi driver_midi; +#endif CrashHandler crash_handler; @@ -153,6 +159,8 @@ class OS_Windows : public OS { // functions used by main to initialize/deintialize the OS protected: + virtual int get_current_video_driver() const; + virtual void initialize_core(); virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); diff --git a/platform/windows/platform_windows_builders.py b/platform/windows/platform_windows_builders.py new file mode 100644 index 0000000000..a1ad3b8b50 --- /dev/null +++ b/platform/windows/platform_windows_builders.py @@ -0,0 +1,22 @@ +"""Functions used to generate source files during build time + +All such functions are invoked in a subprocess on Windows to prevent build flakiness. + +""" +import os +from platform_methods import subprocess_main + + +def make_debug_mingw(target, source, env): + mingw_prefix = "" + if (env["bits"] == "32"): + mingw_prefix = env["mingw_prefix_32"] + else: + mingw_prefix = env["mingw_prefix_64"] + os.system(mingw_prefix + 'objcopy --only-keep-debug {0} {0}.debugsymbols'.format(target[0])) + os.system(mingw_prefix + 'strip --strip-debug --strip-unneeded {0}'.format(target[0])) + os.system(mingw_prefix + 'objcopy --add-gnu-debuglink={0}.debugsymbols {0}'.format(target[0])) + + +if __name__ == '__main__': + subprocess_main(globals()) |