diff options
Diffstat (limited to 'platform/windows')
-rw-r--r-- | platform/windows/SCsub | 6 | ||||
-rw-r--r-- | platform/windows/detect.py | 44 | ||||
-rw-r--r-- | platform/windows/export/export.cpp | 12 | ||||
-rw-r--r-- | platform/windows/key_mapping_windows.cpp | 164 | ||||
-rw-r--r-- | platform/windows/key_mapping_windows.h | 1 | ||||
-rw-r--r--[-rwxr-xr-x] | platform/windows/os_windows.cpp | 241 | ||||
-rw-r--r-- | platform/windows/os_windows.h | 28 | ||||
-rw-r--r-- | platform/windows/platform_config.h | 5 | ||||
-rw-r--r-- | platform/windows/power_windows.cpp | 131 | ||||
-rw-r--r-- | platform/windows/vulkan_context_win.cpp | 57 | ||||
-rw-r--r-- | platform/windows/vulkan_context_win.h (renamed from platform/windows/power_windows.h) | 30 | ||||
-rw-r--r-- | platform/windows/windows_terminal_logger.cpp | 68 |
12 files changed, 441 insertions, 346 deletions
diff --git a/platform/windows/SCsub b/platform/windows/SCsub index 892d734734..8e94c7b35d 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -8,13 +8,13 @@ import platform_windows_builders common_win = [ "godot_windows.cpp", - "context_gl_windows.cpp", "crash_handler_windows.cpp", "os_windows.cpp", "key_mapping_windows.cpp", "joypad_windows.cpp", - "power_windows.cpp", - "windows_terminal_logger.cpp" + "windows_terminal_logger.cpp", + "vulkan_context_win.cpp", + "context_gl_windows.cpp" ] res_file = 'godot_res.rc' diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 500736bd3f..cc859c0339 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -1,6 +1,9 @@ import methods import os +# To match other platforms +STACK_SIZE = 8388608 + def is_active(): return True @@ -207,7 +210,7 @@ def configure_msvc(env, manual_msvc_config): else: print("Missing environment variable: WindowsSdkDir") - env.AppendUnique(CPPDEFINES = ['WINDOWS_ENABLED', 'OPENGL_ENABLED', + env.AppendUnique(CPPDEFINES = ['WINDOWS_ENABLED', 'WASAPI_ENABLED', 'WINMIDI_ENABLED', 'TYPED_METHOD_BIND', 'WIN32', 'MSVC', @@ -219,10 +222,20 @@ def configure_msvc(env, manual_msvc_config): ## Libs - LIBS = ['winmm', 'opengl32', 'dsound', 'kernel32', 'ole32', 'oleaut32', + LIBS = ['winmm', 'dsound', 'kernel32', 'ole32', 'oleaut32', 'user32', 'gdi32', 'IPHLPAPI', 'Shlwapi', 'wsock32', 'Ws2_32', - 'shell32', 'advapi32', 'dinput8', 'dxguid', 'imm32', 'bcrypt','Avrt', + 'shell32', 'advapi32', 'dinput8', 'dxguid', 'imm32', 'bcrypt', 'Avrt', 'dwmapi'] + + env.AppendUnique(CPPDEFINES=['VULKAN_ENABLED']) + if not env['builtin_vulkan']: + LIBS += ['vulkan'] + else: + LIBS += ['cfgmgr32'] + + #env.AppendUnique(CPPDEFINES = ['OPENGL_ENABLED']) + LIBS += ['opengl32'] + env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS]) if manual_msvc_config: @@ -249,6 +262,8 @@ def configure_msvc(env, manual_msvc_config): env['BUILDERS']['ProgramOriginal'] = env['BUILDERS']['Program'] env['BUILDERS']['Program'] = methods.precious_program + env.AppendUnique(LINKFLAGS=['/STACK:' + str(STACK_SIZE)]) + def configure_mingw(env): # Workaround for MinGW. See: # http://www.scons.org/wiki/LongCmdLinesOnWin32 @@ -293,12 +308,7 @@ def configure_mingw(env): ## Compiler configuration - if (os.name == "nt"): - # Force splitting libmodules.a in multiple chunks to work around - # issues reaching the linker command line size limit, which also - # seem to induce huge slowdown for 'ar' (GH-30892). - env['split_libmodules'] = True - else: + if os.name != "nt": env["PROGSUFFIX"] = env["PROGSUFFIX"] + ".exe" # for linux cross-compilation if (env["bits"] == "default"): @@ -346,13 +356,25 @@ def configure_mingw(env): env.Append(CCFLAGS=['-flto']) env.Append(LINKFLAGS=['-flto']) + env.Append(LINKFLAGS=['-Wl,--stack,' + str(STACK_SIZE)]) ## Compile flags env.Append(CCFLAGS=['-mwindows']) - env.Append(CPPDEFINES=['WINDOWS_ENABLED', 'OPENGL_ENABLED', 'WASAPI_ENABLED', 'WINMIDI_ENABLED']) + + env.Append(CPPDEFINES=['WINDOWS_ENABLED', 'WASAPI_ENABLED', 'WINMIDI_ENABLED']) env.Append(CPPDEFINES=[('WINVER', env['target_win_version']), ('_WIN32_WINNT', env['target_win_version'])]) - env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt', 'avrt', 'uuid', 'dwmapi']) + env.Append(LIBS=['mingw32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt', 'avrt', 'uuid', 'dwmapi']) + + env.Append(CPPDEFINES=['VULKAN_ENABLED']) + if not env['builtin_vulkan']: + env.Append(LIBS=['vulkan']) + else: + env.Append(LIBS=['cfgmgr32']) + + ## TODO !!! Reenable when OpenGLES Rendering Device is implemented !!! + #env.Append(CPPDEFINES=['OPENGL_ENABLED']) + env.Append(LIBS=['opengl32']) env.Append(CPPDEFINES=['MINGW_ENABLED', ('MINGW_HAS_SECURE_API', 1)]) diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp index 34d66ecd79..78a3fc8f79 100644 --- a/platform/windows/export/export.cpp +++ b/platform/windows/export/export.cpp @@ -85,7 +85,7 @@ void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_optio r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/timestamp_server_url"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/digest_algorithm", PROPERTY_HINT_ENUM, "SHA1,SHA256"), 1)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/description"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::POOL_STRING_ARRAY, "codesign/custom_options"), PoolStringArray())); + r_options->push_back(ExportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "codesign/custom_options"), PackedStringArray())); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), "")); @@ -105,7 +105,7 @@ void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> } if (!FileAccess::exists(rcedit_path)) { - ERR_PRINTS("Could not find rcedit executable at " + rcedit_path + ", no icon or app information data will be included."); + ERR_PRINT("Could not find rcedit executable at " + rcedit_path + ", no icon or app information data will be included."); return; } @@ -114,7 +114,7 @@ void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> String wine_path = EditorSettings::get_singleton()->get("export/windows/wine"); if (wine_path != String() && !FileAccess::exists(wine_path)) { - ERR_PRINTS("Could not find wine executable at " + wine_path + ", no icon or app information data will be included."); + ERR_PRINT("Could not find wine executable at " + wine_path + ", no icon or app information data will be included."); return; } @@ -188,7 +188,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p #ifdef WINDOWS_ENABLED String signtool_path = EditorSettings::get_singleton()->get("export/windows/signtool"); if (signtool_path != String() && !FileAccess::exists(signtool_path)) { - ERR_PRINTS("Could not find signtool executable at " + signtool_path + ", aborting."); + ERR_PRINT("Could not find signtool executable at " + signtool_path + ", aborting."); return ERR_FILE_NOT_FOUND; } if (signtool_path == String()) { @@ -197,7 +197,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p #else String signtool_path = EditorSettings::get_singleton()->get("export/windows/osslsigncode"); if (signtool_path != String() && !FileAccess::exists(signtool_path)) { - ERR_PRINTS("Could not find osslsigncode executable at " + signtool_path + ", aborting."); + ERR_PRINT("Could not find osslsigncode executable at " + signtool_path + ", aborting."); return ERR_FILE_NOT_FOUND; } if (signtool_path == String()) { @@ -297,7 +297,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p } //user options - PoolStringArray user_args = p_preset->get("codesign/custom_options"); + PackedStringArray user_args = p_preset->get("codesign/custom_options"); for (int i = 0; i < user_args.size(); i++) { String user_arg = user_args[i].strip_edges(); if (!user_arg.empty()) { diff --git a/platform/windows/key_mapping_windows.cpp b/platform/windows/key_mapping_windows.cpp index c76b31ca9c..da63e92622 100644 --- a/platform/windows/key_mapping_windows.cpp +++ b/platform/windows/key_mapping_windows.cpp @@ -238,6 +238,104 @@ VK_PA1 (0xFD) VK_OEM_CLEAR (0xFE) */ +static _WinTranslatePair _scancode_to_keycode[] = { + + { KEY_ESCAPE, 0x01 }, + { KEY_1, 0x02 }, + { KEY_2, 0x03 }, + { KEY_3, 0x04 }, + { KEY_4, 0x05 }, + { KEY_5, 0x06 }, + { KEY_6, 0x07 }, + { KEY_7, 0x08 }, + { KEY_8, 0x09 }, + { KEY_9, 0x0A }, + { KEY_0, 0x0B }, + { KEY_MINUS, 0x0C }, + { KEY_EQUAL, 0x0D }, + { KEY_BACKSPACE, 0x0E }, + { KEY_TAB, 0x0F }, + { KEY_Q, 0x10 }, + { KEY_W, 0x11 }, + { KEY_E, 0x12 }, + { KEY_R, 0x13 }, + { KEY_T, 0x14 }, + { KEY_Y, 0x15 }, + { KEY_U, 0x16 }, + { KEY_I, 0x17 }, + { KEY_O, 0x18 }, + { KEY_P, 0x19 }, + { KEY_BRACELEFT, 0x1A }, + { KEY_BRACERIGHT, 0x1B }, + { KEY_ENTER, 0x1C }, + { KEY_CONTROL, 0x1D }, + { KEY_A, 0x1E }, + { KEY_S, 0x1F }, + { KEY_D, 0x20 }, + { KEY_F, 0x21 }, + { KEY_G, 0x22 }, + { KEY_H, 0x23 }, + { KEY_J, 0x24 }, + { KEY_K, 0x25 }, + { KEY_L, 0x26 }, + { KEY_SEMICOLON, 0x27 }, + { KEY_APOSTROPHE, 0x28 }, + { KEY_QUOTELEFT, 0x29 }, + { KEY_SHIFT, 0x2A }, + { KEY_BACKSLASH, 0x2B }, + { KEY_Z, 0x2C }, + { KEY_X, 0x2D }, + { KEY_C, 0x2E }, + { KEY_V, 0x2F }, + { KEY_B, 0x30 }, + { KEY_N, 0x31 }, + { KEY_M, 0x32 }, + { KEY_COMMA, 0x33 }, + { KEY_PERIOD, 0x34 }, + { KEY_SLASH, 0x35 }, + { KEY_SHIFT, 0x36 }, + { KEY_PRINT, 0x37 }, + { KEY_ALT, 0x38 }, + { KEY_SPACE, 0x39 }, + { KEY_CAPSLOCK, 0x3A }, + { KEY_F1, 0x3B }, + { KEY_F2, 0x3C }, + { KEY_F3, 0x3D }, + { KEY_F4, 0x3E }, + { KEY_F5, 0x3F }, + { KEY_F6, 0x40 }, + { KEY_F7, 0x41 }, + { KEY_F8, 0x42 }, + { KEY_F9, 0x43 }, + { KEY_F10, 0x44 }, + { KEY_NUMLOCK, 0x45 }, + { KEY_SCROLLLOCK, 0x46 }, + { KEY_HOME, 0x47 }, + { KEY_UP, 0x48 }, + { KEY_PAGEUP, 0x49 }, + { KEY_KP_SUBTRACT, 0x4A }, + { KEY_LEFT, 0x4B }, + { KEY_KP_5, 0x4C }, + { KEY_RIGHT, 0x4D }, + { KEY_KP_ADD, 0x4E }, + { KEY_END, 0x4F }, + { KEY_DOWN, 0x50 }, + { KEY_PAGEDOWN, 0x51 }, + { KEY_INSERT, 0x52 }, + { KEY_DELETE, 0x53 }, + //{ KEY_???, 0x56 }, //NON US BACKSLASH + { KEY_F11, 0x57 }, + { KEY_F12, 0x58 }, + { KEY_META, 0x5B }, + { KEY_META, 0x5C }, + { KEY_MENU, 0x5D }, + { KEY_F13, 0x64 }, + { KEY_F14, 0x65 }, + { KEY_F15, 0x66 }, + { KEY_F16, 0x67 }, + { KEY_UNKNOWN, 0 } +}; + unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) { for (int i = 0; _vk_to_keycode[i].keysym != KEY_UNKNOWN; i++) { @@ -251,3 +349,69 @@ unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) { return KEY_UNKNOWN; } + +unsigned int KeyMappingWindows::get_scansym(unsigned int p_code, bool p_extended) { + unsigned int keycode = KEY_UNKNOWN; + for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) { + + if (_scancode_to_keycode[i].keycode == p_code) { + keycode = _scancode_to_keycode[i].keysym; + break; + } + } + + if (p_extended) { + switch (keycode) { + case KEY_ENTER: { + keycode = KEY_KP_ENTER; + } break; + case KEY_SLASH: { + keycode = KEY_KP_DIVIDE; + } break; + case KEY_CAPSLOCK: { + keycode = KEY_KP_ADD; + } break; + } + } else { + switch (keycode) { + case KEY_NUMLOCK: { + keycode = KEY_PAUSE; + } break; + case KEY_HOME: { + keycode = KEY_KP_7; + } break; + case KEY_UP: { + keycode = KEY_KP_8; + } break; + case KEY_PAGEUP: { + keycode = KEY_KP_9; + } break; + case KEY_LEFT: { + keycode = KEY_KP_4; + } break; + case KEY_RIGHT: { + keycode = KEY_KP_6; + } break; + case KEY_END: { + keycode = KEY_KP_1; + } break; + case KEY_DOWN: { + keycode = KEY_KP_2; + } break; + case KEY_PAGEDOWN: { + keycode = KEY_KP_3; + } break; + case KEY_INSERT: { + keycode = KEY_KP_0; + } break; + case KEY_DELETE: { + keycode = KEY_KP_PERIOD; + } break; + case KEY_PRINT: { + keycode = KEY_KP_MULTIPLY; + } break; + } + } + + return keycode; +} diff --git a/platform/windows/key_mapping_windows.h b/platform/windows/key_mapping_windows.h index 0f9bdecde1..3361ad397f 100644 --- a/platform/windows/key_mapping_windows.h +++ b/platform/windows/key_mapping_windows.h @@ -43,6 +43,7 @@ class KeyMappingWindows { public: static unsigned int get_keysym(unsigned int p_code); + static unsigned int get_scansym(unsigned int p_code, bool p_extended); }; #endif // KEY_MAPPING_WINDOWS_H diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index a6977a7a86..041a5bffa6 100755..100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -33,15 +33,22 @@ #include "os_windows.h" +#include "core/debugger/engine_debugger.h" +#include "core/debugger/script_debugger.h" #include "core/io/marshalls.h" #include "core/version_generated.gen.h" + +#if defined(OPENGL_ENABLED) #include "drivers/gles2/rasterizer_gles2.h" -#include "drivers/gles3/rasterizer_gles3.h" +#endif + +#if defined(VULKAN_ENABLED) +#include "servers/visual/rasterizer_rd/rasterizer_rd.h" +#endif + #include "drivers/windows/dir_access_windows.h" #include "drivers/windows/file_access_windows.h" -#include "drivers/windows/mutex_windows.h" #include "drivers/windows/rw_lock_windows.h" -#include "drivers/windows/semaphore_windows.h" #include "drivers/windows/thread_windows.h" #include "joypad_windows.h" #include "lang_table.h" @@ -188,13 +195,13 @@ void RedirectIOToConsole() { } BOOL WINAPI HandlerRoutine(_In_ DWORD dwCtrlType) { - if (ScriptDebugger::get_singleton() == NULL) + if (!EngineDebugger::is_active()) return FALSE; switch (dwCtrlType) { case CTRL_C_EVENT: - ScriptDebugger::get_singleton()->set_depth(-1); - ScriptDebugger::get_singleton()->set_lines_left(1); + EngineDebugger::get_script_debugger()->set_depth(-1); + EngineDebugger::get_script_debugger()->set_lines_left(1); return TRUE; default: return FALSE; @@ -221,8 +228,6 @@ void OS_Windows::initialize_core() { borderless = false; ThreadWindows::make_default(); - SemaphoreWindows::make_default(); - MutexWindows::make_default(); RWLockWindows::make_default(); FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES); @@ -701,7 +706,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; } } - FALLTHROUGH; + [[fallthrough]]; case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_RBUTTONDOWN: @@ -893,6 +898,11 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) preserve_window_size = false; set_window_size(Size2(video_mode.width, video_mode.height)); } +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->window_resize(0, video_mode.width, video_mode.height); + } +#endif } if (wParam == SIZE_MAXIMIZED) { @@ -971,7 +981,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (wParam==VK_WIN) TODO wtf is this? meta_mem=uMsg==WM_KEYDOWN; */ - FALLTHROUGH; + [[fallthrough]]; } case WM_CHAR: { @@ -1122,7 +1132,8 @@ void OS_Windows::process_key_events() { k->set_control(ke.control); k->set_metakey(ke.meta); k->set_pressed(true); - k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam)); + k->set_keycode(KeyMappingWindows::get_keysym(ke.wParam)); + k->set_physical_keycode(KeyMappingWindows::get_scansym((ke.lParam >> 16) & 0xFF, ke.lParam & (1 << 24))); k->set_unicode(ke.wParam); if (k->get_unicode() && gr_mem) { k->set_alt(false); @@ -1152,11 +1163,13 @@ void OS_Windows::process_key_events() { if ((ke.lParam & (1 << 24)) && (ke.wParam == VK_RETURN)) { // Special case for Numpad Enter key - k->set_scancode(KEY_KP_ENTER); + k->set_keycode(KEY_KP_ENTER); } else { - k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam)); + k->set_keycode(KeyMappingWindows::get_keysym(ke.wParam)); } + k->set_physical_keycode(KeyMappingWindows::get_scansym((ke.lParam >> 16) & 0xFF, ke.lParam & (1 << 24))); + if (i + 1 < key_event_pos && key_event_buffer[i + 1].uMsg == WM_CHAR) { k->set_unicode(key_event_buffer[i + 1].wParam); } @@ -1416,78 +1429,58 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int SetWindowPos(hWnd, video_mode.always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } -#if defined(OPENGL_ENABLED) - - bool gles3_context = true; - if (p_video_driver == VIDEO_DRIVER_GLES2) { - gles3_context = false; - } - - bool editor = Engine::get_singleton()->is_editor_hint(); - bool gl_initialization_error = false; - - gl_context = NULL; - while (!gl_context) { - gl_context = memnew(ContextGL_Windows(hWnd, gles3_context)); + //!!!!!!!!!!!!!!!!!!!!!!!!!! + //TODO - do Vulkan and GLES2 support checks, driver selection and fallback + video_driver_index = p_video_driver; + print_verbose("Driver: " + String(get_video_driver_name(video_driver_index)) + " [" + itos(video_driver_index) + "]"); + //!!!!!!!!!!!!!!!!!!!!!!!!!! - if (gl_context->initialize() != OK) { - memdelete(gl_context); - gl_context = NULL; + // Init context and rendering device +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2") || editor) { - if (p_video_driver == VIDEO_DRIVER_GLES2) { - gl_initialization_error = true; - break; - } + context_gles2 = memnew(ContextGL_Windows(hWnd, false)); - p_video_driver = VIDEO_DRIVER_GLES2; - gles3_context = false; - } else { - gl_initialization_error = true; - break; - } + if (context_gles2->initialize() != OK) { + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); } - } - while (true) { - if (gles3_context) { - if (RasterizerGLES3::is_viable() == OK) { - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - break; - } else { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2") || editor) { - p_video_driver = VIDEO_DRIVER_GLES2; - gles3_context = false; - continue; - } else { - gl_initialization_error = true; - break; - } - } + context_gles2->set_use_vsync(video_mode.use_vsync); + set_vsync_via_compositor(video_mode.vsync_via_compositor); + + if (RasterizerGLES2::is_viable() == OK) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); } else { - if (RasterizerGLES2::is_viable() == OK) { - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - break; - } else { - gl_initialization_error = true; - break; - } + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); } } +#endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + + context_vulkan = memnew(VulkanContextWindows); + if (context_vulkan->initialize() != OK) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } + if (context_vulkan->window_create(hWnd, hInstance, get_video_mode().width, get_video_mode().height) == -1) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } - 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; + //temporary + rendering_device_vulkan = memnew(RenderingDeviceVulkan); + rendering_device_vulkan->initialize(context_vulkan); - gl_context->set_use_vsync(video_mode.use_vsync); - set_vsync_via_compositor(video_mode.vsync_via_compositor); + RasterizerRD::make_current(); + } #endif visual_server = memnew(VisualServerRaster); @@ -1500,8 +1493,6 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int input = memnew(InputDefault); joypad = memnew(JoypadWindows(input, &hWnd)); - power_manager = memnew(PowerWindows); - AudioDriverManager::initialize(p_audio_driver); TRACKMOUSEEVENT tme; @@ -1660,9 +1651,25 @@ void OS_Windows::finalize() { cursors_cache.clear(); visual_server->finish(); memdelete(visual_server); -#ifdef OPENGL_ENABLED - if (gl_context) - memdelete(gl_context); + +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + + if (context_gles2) + memdelete(context_gles2); + } +#endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + + if (rendering_device_vulkan) { + rendering_device_vulkan->finalize(); + memdelete(rendering_device_vulkan); + } + + if (context_vulkan) + memdelete(context_vulkan); + } #endif if (user_proc) { @@ -1964,6 +1971,11 @@ void OS_Windows::set_window_size(const Size2 p_size) { video_mode.width = w; video_mode.height = h; +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->window_resize(0, video_mode.width, video_mode.height); + } +#endif if (video_mode.fullscreen) { return; @@ -2506,7 +2518,7 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap if (p_cursor.is_valid()) { - Map<CursorShape, Vector<Variant> >::Element *cursor_c = cursors_cache.find(p_shape); + Map<CursorShape, Vector<Variant>>::Element *cursor_c = cursors_cache.find(p_shape); if (cursor_c) { if (cursor_c->get()[0] == p_cursor && cursor_c->get()[1] == p_hotspot) { @@ -2517,7 +2529,7 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap cursors_cache.erase(p_shape); } - Ref<Texture> texture = p_cursor; + Ref<Texture2D> texture = p_cursor; Ref<AtlasTexture> atlas_texture = p_cursor; Ref<Image> image; Size2 texture_size; @@ -2556,7 +2568,6 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap // Create the BITMAP with alpha channel COLORREF *buffer = (COLORREF *)memalloc(sizeof(COLORREF) * image_size); - image->lock(); for (UINT index = 0; index < image_size; index++) { int row_index = floor(index / texture_size.width) + atlas_rect.position.y; int column_index = (index % int(texture_size.width)) + atlas_rect.position.x; @@ -2568,7 +2579,6 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap *(buffer + index) = image->get_pixel(column_index, row_index).to_argb32(); } - image->unlock(); // Using 4 channels, so 4 * 8 bits HBITMAP bitmap = CreateBitmap(texture_size.width, texture_size.height, 1, 4 * 8, buffer); @@ -2713,7 +2723,7 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, if (p_pipe_mutex) { p_pipe_mutex->lock(); } - (*r_pipe) += buf; + (*r_pipe) += String::utf8(buf); if (p_pipe_mutex) { p_pipe_mutex->unlock(); } @@ -2854,7 +2864,7 @@ void OS_Windows::set_native_icon(const String &p_filename) { ERR_FAIL_COND_MSG(big_icon_index == -1, "No valid icons found!"); if (small_icon_index == -1) { - WARN_PRINTS("No small icon found, reusing " + itos(big_icon_width) + "x" + itos(big_icon_width) + " @" + itos(big_icon_cc) + " icon!"); + WARN_PRINT("No small icon found, reusing " + itos(big_icon_width) + "x" + itos(big_icon_width) + " @" + itos(big_icon_cc) + " icon!"); small_icon_index = big_icon_index; small_icon_cc = big_icon_cc; } @@ -2923,7 +2933,7 @@ void OS_Windows::set_icon(const Ref<Image> &p_icon) { encode_uint32(0, &icon_bmp[36]); uint8_t *wr = &icon_bmp[40]; - PoolVector<uint8_t>::Read r = icon->get_data().read(); + const uint8_t *r = icon->get_data().ptr(); for (int i = 0; i < h; i++) { @@ -3121,18 +3131,32 @@ OS::LatinKeyboardVariant OS_Windows::get_latin_keyboard_variant() const { } void OS_Windows::release_rendering_thread() { - - gl_context->release_current(); +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->release_current(); + } +#endif } void OS_Windows::make_rendering_thread() { - - gl_context->make_current(); +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->make_current(); + } +#endif } void OS_Windows::swap_buffers() { - - gl_context->swap_buffers(); +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->swap_buffers(); + } +#endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->swap_buffers(); + } +#endif } void OS_Windows::force_process_input() { @@ -3299,29 +3323,12 @@ String OS_Windows::get_joy_guid(int p_device) const { } void OS_Windows::_set_use_vsync(bool p_enable) { - - if (gl_context) - gl_context->set_use_vsync(p_enable); -} -/* -bool OS_Windows::is_vsync_enabled() const { - - if (gl_context) - return gl_context->is_using_vsync(); - - return true; -}*/ - -OS::PowerState OS_Windows::get_power_state() { - return power_manager->get_power_state(); -} - -int OS_Windows::get_power_seconds_left() { - return power_manager->get_power_seconds_left(); -} - -int OS_Windows::get_power_percent_left() { - return power_manager->get_power_percent_left(); +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + if (context_gles2) + context_gles2->set_use_vsync(p_enable); + } +#endif } bool OS_Windows::_check_internal_feature_support(const String &p_feature) { @@ -3363,7 +3370,7 @@ Error OS_Windows::move_to_trash(const String &p_path) { delete[] from; if (ret) { - ERR_PRINTS("SHFileOperation error: " + itos(ret)); + ERR_PRINT("SHFileOperation error: " + itos(ret)); return FAILED; } diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index cf16295a70..8506aa7b20 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -31,7 +31,6 @@ #ifndef OS_WINDOWS_H #define OS_WINDOWS_H -#include "context_gl_windows.h" #include "core/os/input.h" #include "core/os/os.h" #include "core/project_settings.h" @@ -41,7 +40,6 @@ #include "drivers/winmidi/midi_driver_winmidi.h" #include "key_mapping_windows.h" #include "main/input_default.h" -#include "power_windows.h" #include "servers/audio_server.h" #include "servers/visual/rasterizer.h" #include "servers/visual_server.h" @@ -49,6 +47,15 @@ #include "drivers/xaudio2/audio_driver_xaudio2.h" #endif +#if defined(OPENGL_ENABLED) +#include "context_gl_windows.h" +#endif + +#if defined(VULKAN_ENABLED) +#include "drivers/vulkan/rendering_device_vulkan.h" +#include "platform/windows/vulkan_context_win.h" +#endif + #include <fcntl.h> #include <io.h> #include <stdio.h> @@ -170,9 +177,16 @@ class OS_Windows : public OS { bool outside; int old_x, old_y; Point2i center; + #if defined(OPENGL_ENABLED) - ContextGL_Windows *gl_context; + ContextGL_Windows *context_gles2; +#endif + +#if defined(VULKAN_ENABLED) + VulkanContextWindows *context_vulkan; + RenderingDeviceVulkan *rendering_device_vulkan; #endif + VisualServer *visual_server; int pressrc; HINSTANCE hInstance; // Holds The Instance Of The Application @@ -218,14 +232,12 @@ class OS_Windows : public OS { HCURSOR cursors[CURSOR_MAX] = { NULL }; CursorShape cursor_shape; - Map<CursorShape, Vector<Variant> > cursors_cache; + Map<CursorShape, Vector<Variant>> cursors_cache; InputDefault *input; JoypadWindows *joypad; Map<int, Vector2> touch_state; - PowerWindows *power_manager; - int video_driver_index; #ifdef WASAPI_ENABLED AudioDriverWASAPI driver_wasapi; @@ -418,10 +430,6 @@ public: virtual void _set_use_vsync(bool p_enable); //virtual bool is_vsync_enabled() const; - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - virtual bool _check_internal_feature_support(const String &p_feature); void disable_crash_handler(); diff --git a/platform/windows/platform_config.h b/platform/windows/platform_config.h index 04653ee56c..290decac5f 100644 --- a/platform/windows/platform_config.h +++ b/platform/windows/platform_config.h @@ -29,8 +29,5 @@ /*************************************************************************/ #include <malloc.h> -//#else -//#include <alloca.h> -//#endif -#define GLES3_INCLUDE_H "thirdparty/glad/glad/glad.h" + #define GLES2_INCLUDE_H "thirdparty/glad/glad/glad.h" diff --git a/platform/windows/power_windows.cpp b/platform/windows/power_windows.cpp deleted file mode 100644 index aea06da413..0000000000 --- a/platform/windows/power_windows.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/*************************************************************************/ -/* power_windows.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 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. */ -/*************************************************************************/ - -/* -Adapted from corresponding SDL 2.0 code. -*/ - -/* - Simple DirectMedia Layer - Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "power_windows.h" - -// CODE CHUNK IMPORTED FROM SDL 2.0 - -bool PowerWindows::GetPowerInfo_Windows() { - SYSTEM_POWER_STATUS status; - bool need_details = FALSE; - - /* This API should exist back to Win95. */ - if (!GetSystemPowerStatus(&status)) { - /* !!! FIXME: push GetLastError() into GetError() */ - power_state = OS::POWERSTATE_UNKNOWN; - } else if (status.BatteryFlag == 0xFF) { /* unknown state */ - power_state = OS::POWERSTATE_UNKNOWN; - } else if (status.BatteryFlag & (1 << 7)) { /* no battery */ - power_state = OS::POWERSTATE_NO_BATTERY; - } else if (status.BatteryFlag & (1 << 3)) { /* charging */ - power_state = OS::POWERSTATE_CHARGING; - need_details = TRUE; - } else if (status.ACLineStatus == 1) { - power_state = OS::POWERSTATE_CHARGED; /* on AC, not charging. */ - need_details = TRUE; - } else { - power_state = OS::POWERSTATE_ON_BATTERY; /* not on AC. */ - need_details = TRUE; - } - - percent_left = -1; - nsecs_left = -1; - if (need_details) { - const int pct = (int)status.BatteryLifePercent; - const int secs = (int)status.BatteryLifeTime; - - if (pct != 255) { /* 255 == unknown */ - percent_left = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ - } - if (secs != (int)0xFFFFFFFF) { /* ((DWORD)-1) == unknown */ - nsecs_left = secs; - } - } - - return TRUE; /* always the definitive answer on Windows. */ -} - -OS::PowerState PowerWindows::get_power_state() { - if (GetPowerInfo_Windows()) { - return power_state; - } else { - return OS::POWERSTATE_UNKNOWN; - } -} - -int PowerWindows::get_power_seconds_left() { - if (GetPowerInfo_Windows()) { - return nsecs_left; - } else { - return -1; - } -} - -int PowerWindows::get_power_percent_left() { - if (GetPowerInfo_Windows()) { - return percent_left; - } else { - return -1; - } -} - -PowerWindows::PowerWindows() : - nsecs_left(-1), - percent_left(-1), - power_state(OS::POWERSTATE_UNKNOWN) { -} - -PowerWindows::~PowerWindows() { -} diff --git a/platform/windows/vulkan_context_win.cpp b/platform/windows/vulkan_context_win.cpp new file mode 100644 index 0000000000..20e1b46682 --- /dev/null +++ b/platform/windows/vulkan_context_win.cpp @@ -0,0 +1,57 @@ +/*************************************************************************/ +/* vulkan_context_win.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 "vulkan_context_win.h" +#include <vulkan/vulkan_win32.h> + +const char *VulkanContextWindows::_get_platform_surface_extension() const { + return VK_KHR_WIN32_SURFACE_EXTENSION_NAME; +} + +int VulkanContextWindows::window_create(HWND p_window, HINSTANCE p_instance, int p_width, int p_height) { + + VkWin32SurfaceCreateInfoKHR createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.hinstance = p_instance; + createInfo.hwnd = p_window; + + VkSurfaceKHR surface; + VkResult err = vkCreateWin32SurfaceKHR(_get_instance(), &createInfo, NULL, &surface); + ERR_FAIL_COND_V(err, -1); + return _window_create(surface, p_width, p_height); +} + +VulkanContextWindows::VulkanContextWindows() { +} + +VulkanContextWindows::~VulkanContextWindows() { +} diff --git a/platform/windows/power_windows.h b/platform/windows/vulkan_context_win.h index 80d86a12c5..1289f2a299 100644 --- a/platform/windows/power_windows.h +++ b/platform/windows/vulkan_context_win.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* power_windows.h */ +/* vulkan_context_win.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,31 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef POWER_WINDOWS_H -#define POWER_WINDOWS_H - -#include "core/os/dir_access.h" -#include "core/os/file_access.h" -#include "core/os/os.h" +#ifndef VULKAN_DEVICE_WIN_H +#define VULKAN_DEVICE_WIN_H +#include "drivers/vulkan/vulkan_context.h" #include <windows.h> -class PowerWindows { - -private: - int nsecs_left; - int percent_left; - OS::PowerState power_state; +class VulkanContextWindows : public VulkanContext { - bool GetPowerInfo_Windows(); + virtual const char *_get_platform_surface_extension() const; public: - PowerWindows(); - virtual ~PowerWindows(); + int window_create(HWND p_window, HINSTANCE p_instance, int p_width, int p_height); - OS::PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); + VulkanContextWindows(); + ~VulkanContextWindows(); }; -#endif // POWER_WINDOWS_H +#endif // VULKAN_DEVICE_WIN_H diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp index 8eb6adc27b..520b654b94 100644 --- a/platform/windows/windows_terminal_logger.cpp +++ b/platform/windows/windows_terminal_logger.cpp @@ -85,7 +85,6 @@ void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file CONSOLE_SCREEN_BUFFER_INFO sbi; //original GetConsoleScreenBufferInfo(hCon, &sbi); - WORD current_fg = sbi.wAttributes & (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); WORD current_bg = sbi.wAttributes & (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY); uint32_t basecol = 0; @@ -98,53 +97,34 @@ void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file basecol |= current_bg; - if (p_rationale && p_rationale[0]) { - - SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY); - switch (p_type) { - case ERR_ERROR: logf("ERROR: "); break; - case ERR_WARNING: logf("WARNING: "); break; - case ERR_SCRIPT: logf("SCRIPT ERROR: "); break; - case ERR_SHADER: logf("SHADER ERROR: "); break; - } - - SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY); - logf("%s\n", p_rationale); + SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY); + switch (p_type) { + case ERR_ERROR: logf("ERROR:"); break; + case ERR_WARNING: logf("WARNING:"); break; + case ERR_SCRIPT: logf("SCRIPT ERROR:"); break; + case ERR_SHADER: logf("SHADER ERROR:"); break; + } - SetConsoleTextAttribute(hCon, basecol); - switch (p_type) { - case ERR_ERROR: logf(" At: "); break; - case ERR_WARNING: logf(" At: "); break; - case ERR_SCRIPT: logf(" At: "); break; - case ERR_SHADER: logf(" At: "); break; - } + SetConsoleTextAttribute(hCon, basecol); + if (p_rationale && p_rationale[0]) { + logf(" %s\n", p_rationale); + } else { + logf(" %s\n", p_code); + } - SetConsoleTextAttribute(hCon, current_fg | current_bg); - logf("%s:%i\n", p_file, p_line); + // `FOREGROUND_INTENSITY` alone results in gray text. + SetConsoleTextAttribute(hCon, FOREGROUND_INTENSITY); + switch (p_type) { + case ERR_ERROR: logf(" at: "); break; + case ERR_WARNING: logf(" at: "); break; + case ERR_SCRIPT: logf(" at: "); break; + case ERR_SHADER: logf(" at: "); break; + } + if (p_rationale && p_rationale[0]) { + logf("(%s:%i)\n", p_file, p_line); } else { - - SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY); - switch (p_type) { - case ERR_ERROR: logf("ERROR: %s: ", p_function); break; - case ERR_WARNING: logf("WARNING: %s: ", p_function); break; - case ERR_SCRIPT: logf("SCRIPT ERROR: %s: ", p_function); break; - case ERR_SHADER: logf("SCRIPT ERROR: %s: ", p_function); break; - } - - SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY); - logf("%s\n", p_code); - - SetConsoleTextAttribute(hCon, basecol); - switch (p_type) { - case ERR_ERROR: logf(" At: "); break; - case ERR_WARNING: logf(" At: "); break; - case ERR_SCRIPT: logf(" At: "); break; - case ERR_SHADER: logf(" At: "); break; - } - - SetConsoleTextAttribute(hCon, current_fg | current_bg); - logf("%s:%i\n", p_file, p_line); + logf("%s (%s:%i)\n", p_function, p_file, p_line); } SetConsoleTextAttribute(hCon, sbi.wAttributes); |