diff --git a/src/duckstation-nogui/CMakeLists.txt b/src/duckstation-nogui/CMakeLists.txt index 4a063ba65..bb59fa149 100644 --- a/src/duckstation-nogui/CMakeLists.txt +++ b/src/duckstation-nogui/CMakeLists.txt @@ -10,7 +10,7 @@ add_executable(duckstation-nogui ) target_include_directories(duckstation-nogui PRIVATE ${SDL2_INCLUDE_DIRS}) -target_link_libraries(duckstation-nogui PRIVATE core common imgui nativefiledialog glad frontend-common scmversion vulkan-loader ${SDL2_LIBRARIES}) +target_link_libraries(duckstation-nogui PRIVATE core common imgui glad frontend-common scmversion vulkan-loader ${SDL2_LIBRARIES}) if(WIN32) target_sources(duckstation-nogui PRIVATE diff --git a/src/duckstation-sdl/CMakeLists.txt b/src/duckstation-sdl/CMakeLists.txt index d96c6da08..31f137b87 100644 --- a/src/duckstation-sdl/CMakeLists.txt +++ b/src/duckstation-sdl/CMakeLists.txt @@ -1,17 +1,7 @@ add_executable(duckstation-sdl - imgui_impl_sdl.cpp - imgui_impl_sdl.h main.cpp - sdl_host_interface.cpp - sdl_host_interface.h - sdl_key_names.h - sdl_util.cpp - sdl_util.h ) -target_include_directories(duckstation-sdl PRIVATE ${SDL2_INCLUDE_DIRS}) -target_link_libraries(duckstation-sdl PRIVATE core common imgui nativefiledialog glad frontend-common scmversion vulkan-loader ${SDL2_LIBRARIES}) - if(WIN32) target_sources(duckstation-sdl PRIVATE duckstation-sdl.manifest diff --git a/src/duckstation-sdl/duckstation-sdl.vcxproj b/src/duckstation-sdl/duckstation-sdl.vcxproj index a54a380d5..40699f49d 100644 --- a/src/duckstation-sdl/duckstation-sdl.vcxproj +++ b/src/duckstation-sdl/duckstation-sdl.vcxproj @@ -51,37 +51,10 @@ - - {bb08260f-6fbc-46af-8924-090ee71360c6} - - - {ace32f47-2960-4fb3-9f77-2c375625bf61} - - - {ee054e08-3799-4a59-a422-18259c105ffd} - - - {868b98c8-65a1-494b-8346-250a73a48c0a} - - - {6245dec8-d2da-47ee-a373-cbd6fcf3ece6} - - - {075ced82-6a20-46df-94c7-9624ac9ddbeb} - - - - - - - - - - @@ -99,9 +72,6 @@ 10.0 - - - Application true @@ -301,10 +271,10 @@ Level4 Disabled - WITH_DISCORD_PRESENCE=1;WITH_SDL2=1;WITH_IMGUI=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true ProgramDatabase - $(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories) + $(SolutionDir)src;%(AdditionalIncludeDirectories) true false stdcpp17 @@ -314,7 +284,6 @@ Windows true - SDL2.lib;SDL2main.lib;dxgi.lib;d3d11.lib;%(AdditionalDependencies) @@ -323,10 +292,10 @@ Level4 Disabled - WITH_DISCORD_PRESENCE=1;WITH_SDL2=1;WITH_IMGUI=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true ProgramDatabase - $(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories) + $(SolutionDir)src;%(AdditionalIncludeDirectories) true false stdcpp17 @@ -336,7 +305,6 @@ Windows true - SDL2.lib;SDL2main.lib;dxgi.lib;d3d11.lib;%(AdditionalDependencies) @@ -345,10 +313,10 @@ Level4 Disabled - WITH_DISCORD_PRESENCE=1;WITH_SDL2=1;WITH_IMGUI=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true ProgramDatabase - $(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories) + $(SolutionDir)src;%(AdditionalIncludeDirectories) true false stdcpp17 @@ -358,7 +326,6 @@ Windows true - SDL2.lib;SDL2main.lib;dxgi.lib;d3d11.lib;%(AdditionalDependencies) @@ -367,10 +334,10 @@ Level4 Disabled - WITH_DISCORD_PRESENCE=1;WITH_SDL2=1;WITH_IMGUI=1;_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + _ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true ProgramDatabase - $(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories) + $(SolutionDir)src;%(AdditionalIncludeDirectories) Default true false @@ -383,7 +350,6 @@ Windows true - SDL2.lib;SDL2main.lib;dxgi.lib;d3d11.lib;%(AdditionalDependencies) @@ -392,10 +358,10 @@ Level4 Disabled - WITH_DISCORD_PRESENCE=1;WITH_SDL2=1;WITH_IMGUI=1;_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + _ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true ProgramDatabase - $(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories) + $(SolutionDir)src;%(AdditionalIncludeDirectories) Default true false @@ -408,7 +374,6 @@ Windows true - SDL2.lib;SDL2main.lib;dxgi.lib;d3d11.lib;%(AdditionalDependencies) @@ -417,10 +382,10 @@ Level4 Disabled - WITH_DISCORD_PRESENCE=1;WITH_SDL2=1;WITH_IMGUI=1;_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + _ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true ProgramDatabase - $(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories) + $(SolutionDir)src;%(AdditionalIncludeDirectories) Default true false @@ -433,7 +398,6 @@ Windows true - SDL2.lib;SDL2main.lib;dxgi.lib;d3d11.lib;%(AdditionalDependencies) @@ -443,8 +407,8 @@ MaxSpeed true - WITH_DISCORD_PRESENCE=1;WITH_SDL2=1;WITH_IMGUI=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - $(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + $(SolutionDir)src;%(AdditionalIncludeDirectories) true false stdcpp17 @@ -456,7 +420,6 @@ true true true - SDL2.lib;SDL2main.lib;dxgi.lib;d3d11.lib;%(AdditionalDependencies) Default @@ -467,8 +430,8 @@ MaxSpeed true - WITH_DISCORD_PRESENCE=1;WITH_SDL2=1;WITH_IMGUI=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - $(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + $(SolutionDir)src;%(AdditionalIncludeDirectories) true true stdcpp17 @@ -481,7 +444,6 @@ true true true - SDL2.lib;SDL2main.lib;dxgi.lib;d3d11.lib;%(AdditionalDependencies) UseLinkTimeCodeGeneration @@ -492,8 +454,8 @@ MaxSpeed true - WITH_DISCORD_PRESENCE=1;WITH_SDL2=1;WITH_IMGUI=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - $(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + $(SolutionDir)src;%(AdditionalIncludeDirectories) true false stdcpp17 @@ -505,7 +467,6 @@ true true true - SDL2.lib;SDL2main.lib;dxgi.lib;d3d11.lib;%(AdditionalDependencies) Default @@ -516,8 +477,8 @@ MaxSpeed true - WITH_DISCORD_PRESENCE=1;WITH_SDL2=1;WITH_IMGUI=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - $(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + $(SolutionDir)src;%(AdditionalIncludeDirectories) true false stdcpp17 @@ -529,7 +490,6 @@ true true true - SDL2.lib;SDL2main.lib;dxgi.lib;d3d11.lib;%(AdditionalDependencies) Default @@ -540,8 +500,8 @@ MaxSpeed true - WITH_DISCORD_PRESENCE=1;WITH_SDL2=1;WITH_IMGUI=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - $(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + $(SolutionDir)src;%(AdditionalIncludeDirectories) true true stdcpp17 @@ -554,7 +514,6 @@ true true true - SDL2.lib;SDL2main.lib;dxgi.lib;d3d11.lib;%(AdditionalDependencies) UseLinkTimeCodeGeneration @@ -565,8 +524,8 @@ MaxSpeed true - WITH_DISCORD_PRESENCE=1;WITH_SDL2=1;WITH_IMGUI=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - $(SolutionDir)dep\msvc\include;$(SolutionDir)dep\msvc\include\SDL;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\nativefiledialog\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\simpleini\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + $(SolutionDir)src;%(AdditionalIncludeDirectories) true true stdcpp17 @@ -579,7 +538,6 @@ true true true - SDL2.lib;SDL2main.lib;dxgi.lib;d3d11.lib;%(AdditionalDependencies) UseLinkTimeCodeGeneration diff --git a/src/duckstation-sdl/duckstation-sdl.vcxproj.filters b/src/duckstation-sdl/duckstation-sdl.vcxproj.filters index a54cb633f..25355ee58 100644 --- a/src/duckstation-sdl/duckstation-sdl.vcxproj.filters +++ b/src/duckstation-sdl/duckstation-sdl.vcxproj.filters @@ -2,16 +2,9 @@ - - - - - - - diff --git a/src/duckstation-sdl/imgui_impl_sdl.cpp b/src/duckstation-sdl/imgui_impl_sdl.cpp deleted file mode 100644 index 60a8e88b2..000000000 --- a/src/duckstation-sdl/imgui_impl_sdl.cpp +++ /dev/null @@ -1,260 +0,0 @@ -// dear imgui: Platform Binding for SDL2 -// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) -// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.) -// (Requires: SDL 2.0. Prefer SDL 2.0.4+ for full feature support.) - -// Implemented features: -// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. -// [X] Platform: Clipboard support. -// [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. ImGui::IsKeyPressed(SDL_SCANCODE_SPACE). -// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. -// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. -// Missing features: -// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME. -// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows). - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -// CHANGELOG -// (minor and older changes stripped away, please see git history for details) -// 2019-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. -// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter. -// 2019-04-23: Inputs: Added support for SDL_GameController (if ImGuiConfigFlags_NavEnableGamepad is set by user application). -// 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized. -// 2018-12-21: Inputs: Workaround for Android/iOS which don't seem to handle focus related calls. -// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. -// 2018-11-14: Changed the signature of ImGui_ImplSDL2_ProcessEvent() to take a 'const SDL_Event*'. -// 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls. -// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. -// 2018-06-08: Misc: Extracted imgui_impl_sdl.cpp/.h away from the old combined SDL2+OpenGL/Vulkan examples. -// 2018-06-08: Misc: ImGui_ImplSDL2_InitForOpenGL() now takes a SDL_GLContext parameter. -// 2018-05-09: Misc: Fixed clipboard paste memory leak (we didn't call SDL_FreeMemory on the data returned by SDL_GetClipboardText). -// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag. -// 2018-02-16: Inputs: Added support for mouse cursors, honoring ImGui::GetMouseCursor() value. -// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. -// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. -// 2018-02-05: Misc: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS). -// 2018-02-05: Inputs: Keyboard mapping is using scancodes everywhere instead of a confusing mixture of keycodes and scancodes. -// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. -// 2018-01-19: Inputs: When available (SDL 2.0.4+) using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. Otherwise (SDL 2.0.3 and before) testing for SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS. -// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. -// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). -// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers. - -#include "imgui.h" -#include "imgui_impl_sdl.h" - -// SDL -// (the multi-viewports feature requires SDL features supported from SDL 2.0.4+. SDL 2.0.5+ is highly recommended) -#include -#include -#if defined(__APPLE__) -#include "TargetConditionals.h" -#endif - -#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE SDL_VERSION_ATLEAST(2,0,4) -#define SDL_HAS_WINDOW_ALPHA SDL_VERSION_ATLEAST(2,0,5) -#define SDL_HAS_ALWAYS_ON_TOP SDL_VERSION_ATLEAST(2,0,5) -#define SDL_HAS_USABLE_DISPLAY_BOUNDS SDL_VERSION_ATLEAST(2,0,5) -#define SDL_HAS_PER_MONITOR_DPI SDL_VERSION_ATLEAST(2,0,4) -#define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6) -#define SDL_HAS_MOUSE_FOCUS_CLICKTHROUGH SDL_VERSION_ATLEAST(2,0,5) -#if !SDL_HAS_VULKAN -static const Uint32 SDL_WINDOW_VULKAN = 0x10000000; -#endif - -// Data -static SDL_Window* g_Window = NULL; -static Uint64 g_Time = 0; -static bool g_MousePressed[3] = { false, false, false }; -static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; -static char* g_ClipboardTextData = NULL; - -static const char* ImGui_ImplSDL2_GetClipboardText(void*) -{ - if (g_ClipboardTextData) - SDL_free(g_ClipboardTextData); - g_ClipboardTextData = SDL_GetClipboardText(); - return g_ClipboardTextData; -} - -static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text) -{ - SDL_SetClipboardText(text); -} - -// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. -// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. -// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. -// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. -// If you have multiple SDL events and some of them are not meant to be used by dear imgui, you may need to filter events based on their windowID field. -bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) -{ - ImGuiIO& io = ImGui::GetIO(); - switch (event->type) - { - case SDL_MOUSEWHEEL: - { - if (event->wheel.x > 0) io.MouseWheelH += 1; - if (event->wheel.x < 0) io.MouseWheelH -= 1; - if (event->wheel.y > 0) io.MouseWheel += 1; - if (event->wheel.y < 0) io.MouseWheel -= 1; - return true; - } - case SDL_MOUSEBUTTONDOWN: - { - if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; - if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; - if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; - return true; - } - case SDL_TEXTINPUT: - { - io.AddInputCharactersUTF8(event->text.text); - return true; - } - case SDL_KEYDOWN: - case SDL_KEYUP: - { - int key = event->key.keysym.scancode; - IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown)); - io.KeysDown[key] = (event->type == SDL_KEYDOWN); - io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); - io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); - io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); - io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); - return true; - } - } - return false; -} - -bool ImGui_ImplSDL2_Init(SDL_Window* window) -{ - g_Window = window; - - // Setup back-end capabilities flags - ImGuiIO& io = ImGui::GetIO(); - io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) - io.BackendPlatformName = "imgui_impl_sdl"; - - // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array. - io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB; - io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; - io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; - io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; - io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; - io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; - io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; - io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; - io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; - io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT; - io.KeyMap[ImGuiKey_Delete] = SDL_SCANCODE_DELETE; - io.KeyMap[ImGuiKey_Backspace] = SDL_SCANCODE_BACKSPACE; - io.KeyMap[ImGuiKey_Space] = SDL_SCANCODE_SPACE; - io.KeyMap[ImGuiKey_Enter] = SDL_SCANCODE_RETURN; - io.KeyMap[ImGuiKey_Escape] = SDL_SCANCODE_ESCAPE; - io.KeyMap[ImGuiKey_KeyPadEnter] = SDL_SCANCODE_RETURN2; - io.KeyMap[ImGuiKey_A] = SDL_SCANCODE_A; - io.KeyMap[ImGuiKey_C] = SDL_SCANCODE_C; - io.KeyMap[ImGuiKey_V] = SDL_SCANCODE_V; - io.KeyMap[ImGuiKey_X] = SDL_SCANCODE_X; - io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y; - io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z; - - io.SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText; - io.ClipboardUserData = NULL; - - g_MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); - g_MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); - g_MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); - g_MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); - g_MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); - g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); - g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); - g_MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); - return true; -} - -void ImGui_ImplSDL2_Shutdown() -{ - g_Window = NULL; - - // Destroy last known clipboard data - if (g_ClipboardTextData) - SDL_free(g_ClipboardTextData); - g_ClipboardTextData = NULL; - - // Destroy SDL mouse cursors - for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) - SDL_FreeCursor(g_MouseCursors[cursor_n]); - memset(g_MouseCursors, 0, sizeof(g_MouseCursors)); -} - -// This code is incredibly messy because some of the functions we need for full viewport support are not available in SDL < 2.0.4. -static void ImGui_ImplSDL2_UpdateMousePosAndButtons() -{ - ImGuiIO& io = ImGui::GetIO(); - - // [1] - // Only when requested by io.WantSetMousePos: set OS mouse pos from Dear ImGui mouse pos. - // (rarely used, mostly when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) - if (io.WantSetMousePos) - { - SDL_WarpMouseInWindow(g_Window, (int)io.MousePos.x, (int)io.MousePos.y); - } - else - { - io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - } - - // [2] - // Set Dear ImGui mouse pos from OS mouse pos + get buttons. (this is the common behavior) - int mouse_x_local, mouse_y_local; - Uint32 mouse_buttons = SDL_GetMouseState(&mouse_x_local, &mouse_y_local); - io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; - io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; - g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; - - // SDL 2.0.3 and before: single-viewport only - if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS) - io.MousePos = ImVec2((float)mouse_x_local, (float)mouse_y_local); -} - -static void ImGui_ImplSDL2_UpdateMouseCursor() -{ - ImGuiIO& io = ImGui::GetIO(); - if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) - return; - - ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); - if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None) - { - // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor - SDL_ShowCursor(SDL_FALSE); - } - else - { - // Show OS mouse cursor - SDL_SetCursor(g_MouseCursors[imgui_cursor] ? g_MouseCursors[imgui_cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]); - SDL_ShowCursor(SDL_TRUE); - } -} - -void ImGui_ImplSDL2_NewFrame() -{ - ImGuiIO& io = ImGui::GetIO(); - - // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution) - static Uint64 frequency = SDL_GetPerformanceFrequency(); - Uint64 current_time = SDL_GetPerformanceCounter(); - io.DeltaTime = g_Time > 0 ? (float)((double)(current_time - g_Time) / frequency) : (float)(1.0f / 60.0f); - g_Time = current_time; - - ImGui_ImplSDL2_UpdateMousePosAndButtons(); - ImGui_ImplSDL2_UpdateMouseCursor(); -} diff --git a/src/duckstation-sdl/imgui_impl_sdl.h b/src/duckstation-sdl/imgui_impl_sdl.h deleted file mode 100644 index 0728620a4..000000000 --- a/src/duckstation-sdl/imgui_impl_sdl.h +++ /dev/null @@ -1,28 +0,0 @@ -// dear imgui: Platform Binding for SDL2 -// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) -// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.) - -// Implemented features: -// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. -// [X] Platform: Clipboard support. -// [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. ImGui::IsKeyPressed(SDL_SCANCODE_SPACE). -// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. -// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. -// Missing features: -// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME. -// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows). - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#pragma once -#include "imgui.h" - -struct SDL_Window; -typedef union SDL_Event SDL_Event; - -IMGUI_IMPL_API bool ImGui_ImplSDL2_Init(SDL_Window* window); -IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown(); -IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame(); -IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event); diff --git a/src/duckstation-sdl/main.cpp b/src/duckstation-sdl/main.cpp index 1f48cf920..66b7830ae 100644 --- a/src/duckstation-sdl/main.cpp +++ b/src/duckstation-sdl/main.cpp @@ -1,48 +1,27 @@ -#include "common/assert.h" -#include "common/log.h" -#include "core/system.h" -#include "frontend-common/sdl_initializer.h" -#include "sdl_host_interface.h" -#include +#ifdef _WIN32 +#include "common/windows_headers.h" +#endif + #include #include +static const char message[] = "The DuckStation SDL frontend has been removed and replaced with the Fullscreen UI.\n\n" + "Please use duckstation-qt instead."; + +#ifdef _WIN32 + +int WinMain(HINSTANCE, HINSTANCE, LPSTR, int) +{ + MessageBoxA(nullptr, message, "DuckStation", MB_OK | MB_ICONERROR); + return -1; +} + +#else + int main(int argc, char* argv[]) { - FrontendCommon::EnsureSDLInitialized(); - - std::unique_ptr host_interface = SDLHostInterface::Create(); - std::unique_ptr boot_params; - if (!host_interface->ParseCommandLineParameters(argc, argv, &boot_params)) - { - SDL_Quit(); - return EXIT_FAILURE; - } - - if (!host_interface->Initialize()) - { - host_interface->Shutdown(); - SDL_Quit(); - return EXIT_FAILURE; - } - - if (boot_params) - { - if (!host_interface->BootSystem(*boot_params) && host_interface->InBatchMode()) - { - host_interface->Shutdown(); - host_interface.reset(); - SDL_Quit(); - return EXIT_FAILURE; - } - - boot_params.reset(); - } - - host_interface->Run(); - host_interface->Shutdown(); - host_interface.reset(); - - SDL_Quit(); - return EXIT_SUCCESS; + std::fputs(message, stderr); + return -1; } + +#endif diff --git a/src/duckstation-sdl/sdl_host_interface.cpp b/src/duckstation-sdl/sdl_host_interface.cpp deleted file mode 100644 index a3f1e239b..000000000 --- a/src/duckstation-sdl/sdl_host_interface.cpp +++ /dev/null @@ -1,1889 +0,0 @@ -#include "sdl_host_interface.h" -#include "common/assert.h" -#include "common/byte_stream.h" -#include "common/file_system.h" -#include "common/log.h" -#include "common/make_array.h" -#include "common/string_util.h" -#include "core/cheats.h" -#include "core/controller.h" -#include "core/cpu_core.h" -#include "core/gpu.h" -#include "core/host_display.h" -#include "core/system.h" -#include "frontend-common/icon.h" -#include "frontend-common/imgui_styles.h" -#include "frontend-common/ini_settings_interface.h" -#include "frontend-common/opengl_host_display.h" -#include "frontend-common/sdl_audio_stream.h" -#include "frontend-common/sdl_controller_interface.h" -#include "frontend-common/vulkan_host_display.h" -#include "imgui_impl_sdl.h" -#include "scmversion/scmversion.h" -#include "sdl_key_names.h" -#include "sdl_util.h" -#include -#include -#include -#include -#include -Log_SetChannel(SDLHostInterface); - -#ifdef WIN32 -#include "frontend-common/d3d11_host_display.h" -#endif - -SDLHostInterface::SDLHostInterface() -{ - m_run_later_event_id = SDL_RegisterEvents(1); -} - -SDLHostInterface::~SDLHostInterface() = default; - -const char* SDLHostInterface::GetFrontendName() const -{ - return "DuckStation SDL/ImGui Frontend"; -} - -ALWAYS_INLINE static TinyString GetWindowTitle() -{ - return TinyString::FromFormat("DuckStation %s (%s)", g_scm_tag_str, g_scm_branch_str); -} - -bool SDLHostInterface::CreateSDLWindow() -{ - static constexpr u32 DEFAULT_WINDOW_WIDTH = 900; - static constexpr u32 DEFAULT_WINDOW_HEIGHT = 700; - - // Create window. - const u32 window_flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; - - u32 window_width = DEFAULT_WINDOW_WIDTH; - u32 window_height = DEFAULT_WINDOW_HEIGHT; - - // macOS does DPI scaling differently.. -#ifndef __APPLE__ - { - // scale by default monitor's DPI - float scale = SDLUtil::GetDPIScaleFactor(nullptr); - window_width = static_cast(std::round(static_cast(window_width) * scale)); - window_height = static_cast(std::round(static_cast(window_height) * scale)); - } -#endif - - m_window = SDL_CreateWindow(GetWindowTitle(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, window_width, - window_height, window_flags); - if (!m_window) - return false; - - // Set window icon. - SDL_Surface* icon_surface = - SDL_CreateRGBSurfaceFrom(const_cast(WINDOW_ICON_DATA), WINDOW_ICON_WIDTH, WINDOW_ICON_HEIGHT, 32, - WINDOW_ICON_WIDTH * sizeof(u32), UINT32_C(0x000000FF), UINT32_C(0x0000FF00), - UINT32_C(0x00FF0000), UINT32_C(0xFF000000)); - if (icon_surface) - { - SDL_SetWindowIcon(m_window, icon_surface); - SDL_FreeSurface(icon_surface); - } - - if (m_fullscreen) - SDL_SetWindowFullscreen(m_window, SDL_WINDOW_FULLSCREEN_DESKTOP); - - // Process events so that we have everything sorted out before creating a child window for the GL context (X11). - SDL_PumpEvents(); - return true; -} - -void SDLHostInterface::DestroySDLWindow() -{ - SDL_DestroyWindow(m_window); - m_window = nullptr; -} - -bool SDLHostInterface::CreateDisplay() -{ - std::optional wi = SDLUtil::GetWindowInfoForSDLWindow(m_window); - if (!wi.has_value()) - { - ReportError("Failed to get window info from SDL window"); - return false; - } - - std::unique_ptr display; - switch (g_settings.gpu_renderer) - { - case GPURenderer::HardwareVulkan: - display = std::make_unique(); - break; - - case GPURenderer::HardwareOpenGL: -#ifndef WIN32 - default: -#endif - display = std::make_unique(); - break; - -#ifdef WIN32 - case GPURenderer::HardwareD3D11: - default: - display = std::make_unique(); - break; -#endif - } - - Assert(display); - if (!display->CreateRenderDevice(wi.value(), g_settings.gpu_adapter, g_settings.gpu_use_debug_device, - g_settings.gpu_threaded_presentation) || - !display->InitializeRenderDevice(GetShaderCacheBasePath(), g_settings.gpu_use_debug_device, - g_settings.gpu_threaded_presentation)) - { - ReportError("Failed to create/initialize display render device"); - return false; - } - - if (!ImGui_ImplSDL2_Init(m_window) || !display->CreateImGuiContext()) - { - ReportError("Failed to initialize ImGui SDL2 wrapper"); - ImGui_ImplSDL2_Shutdown(); - display->DestroyRenderDevice(); - return false; - } - - m_app_icon_texture = display->CreateTexture(APP_ICON_WIDTH, APP_ICON_HEIGHT, 1, 1, 1, HostDisplayPixelFormat::RGBA8, - APP_ICON_DATA, APP_ICON_WIDTH * sizeof(u32)); - if (!display->UpdateImGuiFontTexture() || !m_app_icon_texture) - { - ReportError("Failed to upload textures"); - display->DestroyImGuiContext(); - ImGui_ImplSDL2_Shutdown(); - display->DestroyRenderDevice(); - return false; - } - - display->SetDisplayTopMargin(m_fullscreen ? 0 : static_cast(20.0f * ImGui::GetIO().DisplayFramebufferScale.x)); - m_display = std::move(display); - return true; -} - -void SDLHostInterface::DestroyDisplay() -{ - m_app_icon_texture.reset(); - m_display->DestroyImGuiContext(); - m_display->DestroyRenderDevice(); - m_display.reset(); -} - -void SDLHostInterface::CreateImGuiContext() -{ - const float framebuffer_scale = SDLUtil::GetDPIScaleFactor(m_window); - - ImGui::CreateContext(); - ImGui::GetIO().IniFilename = nullptr; - ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; - ImGui::GetIO().DisplayFramebufferScale.x = framebuffer_scale; - ImGui::GetIO().DisplayFramebufferScale.y = framebuffer_scale; - ImGui::GetStyle().ScaleAllSizes(framebuffer_scale); - - ImGui::StyleColorsDarker(); - ImGui::AddRobotoRegularFont(15.0f * framebuffer_scale); -} - -void SDLHostInterface::UpdateFramebufferScale() -{ - const float framebuffer_scale = SDLUtil::GetDPIScaleFactor(m_window); - ImGui::GetIO().DisplayFramebufferScale.x = framebuffer_scale; - ImGui::GetIO().DisplayFramebufferScale.y = framebuffer_scale; -} - -bool SDLHostInterface::AcquireHostDisplay() -{ - // Handle renderer switch if required. - const HostDisplay::RenderAPI render_api = m_display->GetRenderAPI(); - bool needs_switch = false; - switch (g_settings.gpu_renderer) - { -#ifdef WIN32 - case GPURenderer::HardwareD3D11: - needs_switch = (render_api != HostDisplay::RenderAPI::D3D11); - break; -#endif - - case GPURenderer::HardwareVulkan: - needs_switch = (render_api != HostDisplay::RenderAPI::Vulkan); - break; - - case GPURenderer::HardwareOpenGL: - needs_switch = (render_api != HostDisplay::RenderAPI::OpenGL && render_api != HostDisplay::RenderAPI::OpenGLES); - break; - - case GPURenderer::Software: - default: - needs_switch = false; - break; - } - - if (needs_switch) - { - ImGui::EndFrame(); - DestroyDisplay(); - - // We need to recreate the window, otherwise bad things happen... - DestroySDLWindow(); - if (!CreateSDLWindow()) - Panic("Failed to recreate SDL window on GPU renderer switch"); - - if (!CreateDisplay()) - Panic("Failed to recreate display on GPU renderer switch"); - - ImGui::NewFrame(); - } - - if (!CreateHostDisplayResources()) - return false; - - return true; -} - -void SDLHostInterface::ReleaseHostDisplay() -{ - ReleaseHostDisplayResources(); - - if (m_fullscreen) - SetFullscreen(false); - - // restore vsync, since we don't want to burn cycles at the menu - m_display->SetVSync(true); -} - -std::optional SDLHostInterface::GetHostKeyCode(const std::string_view key_code) const -{ - const std::optional code = SDLKeyNames::ParseKeyString(key_code); - if (!code) - return std::nullopt; - - return static_cast(*code); -} - -void SDLHostInterface::UpdateInputMap() -{ - CommonHostInterface::UpdateInputMap(*m_settings_interface.get()); -} - -void SDLHostInterface::OnSystemCreated() -{ - CommonHostInterface::OnSystemCreated(); - - ClearImGuiFocus(); -} - -void SDLHostInterface::OnSystemPaused(bool paused) -{ - CommonHostInterface::OnSystemPaused(paused); - - if (!paused) - ClearImGuiFocus(); -} - -void SDLHostInterface::OnSystemDestroyed() -{ - CommonHostInterface::OnSystemDestroyed(); - ReportFormattedMessage("System shut down."); -} - -void SDLHostInterface::OnRunningGameChanged() -{ - CommonHostInterface::OnRunningGameChanged(); - - Settings old_settings(std::move(g_settings)); - CommonHostInterface::LoadSettings(*m_settings_interface.get()); - CommonHostInterface::ApplyGameSettings(true); - CommonHostInterface::FixIncompatibleSettings(true); - CheckForSettingsChanges(old_settings); - - if (!System::GetRunningTitle().empty()) - SDL_SetWindowTitle(m_window, System::GetRunningTitle().c_str()); - else - SDL_SetWindowTitle(m_window, GetWindowTitle()); -} - -void SDLHostInterface::RequestExit() -{ - m_quit_request = true; -} - -void SDLHostInterface::RunLater(std::function callback) -{ - SDL_Event ev = {}; - ev.type = SDL_USEREVENT; - ev.user.code = m_run_later_event_id; - ev.user.data1 = new std::function(std::move(callback)); - SDL_PushEvent(&ev); -} - -void SDLHostInterface::SaveAndUpdateSettings() -{ - m_settings_copy.Save(*m_settings_interface.get()); - - ApplySettings(false); - - m_settings_interface->Save(); -} - -void SDLHostInterface::ApplySettings(bool display_osd_messages) -{ - Settings old_settings(std::move(g_settings)); - CommonHostInterface::LoadSettings(*m_settings_interface.get()); - CommonHostInterface::ApplyGameSettings(display_osd_messages); - CommonHostInterface::FixIncompatibleSettings(display_osd_messages); - CheckForSettingsChanges(old_settings); -} - -bool SDLHostInterface::IsFullscreen() const -{ - return m_fullscreen; -} - -bool SDLHostInterface::SetFullscreen(bool enabled) -{ - if (m_fullscreen == enabled) - return true; - - SDL_SetWindowFullscreen(m_window, enabled ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - - // We set the margin only in windowed mode, the menu bar is not drawn fullscreen. - m_display->SetDisplayTopMargin(enabled ? 0 : static_cast(20.0f * ImGui::GetIO().DisplayFramebufferScale.x)); - - int window_width, window_height; - SDL_GetWindowSize(m_window, &window_width, &window_height); - m_display->ResizeRenderWindow(window_width, window_height); - - if (!System::IsShutdown()) - g_gpu->UpdateResolutionScale(); - - m_fullscreen = enabled; - return true; -} - -std::unique_ptr SDLHostInterface::Create() -{ - return std::make_unique(); -} - -bool SDLHostInterface::Initialize() -{ - if (!CommonHostInterface::Initialize()) - return false; - - // Change to the user directory so that all default/relative paths in the config are after this. - if (!FileSystem::SetWorkingDirectory(m_user_directory.c_str())) - Log_ErrorPrintf("Failed to set working directory to '%s'", m_user_directory.c_str()); - - if (!CreateSDLWindow()) - { - Log_ErrorPrintf("Failed to create SDL window"); - return false; - } - - CreateImGuiContext(); - if (!CreateDisplay()) - { - Log_ErrorPrintf("Failed to create host display"); - return false; - } - - ImGui::NewFrame(); - - // process events to pick up controllers before updating input map - ProcessEvents(); - UpdateInputMap(); - return true; -} - -void SDLHostInterface::Shutdown() -{ - DestroySystem(); - - CommonHostInterface::Shutdown(); - - if (m_display) - { - DestroyDisplay(); - ImGui::DestroyContext(); - } - - if (m_window) - DestroySDLWindow(); -} - -std::string SDLHostInterface::GetStringSettingValue(const char* section, const char* key, - const char* default_value /*= ""*/) -{ - return m_settings_interface->GetStringValue(section, key, default_value); -} - -bool SDLHostInterface::GetBoolSettingValue(const char* section, const char* key, bool default_value /* = false */) -{ - return m_settings_interface->GetBoolValue(section, key, default_value); -} - -int SDLHostInterface::GetIntSettingValue(const char* section, const char* key, int default_value /* = 0 */) -{ - return m_settings_interface->GetIntValue(section, key, default_value); -} - -float SDLHostInterface::GetFloatSettingValue(const char* section, const char* key, float default_value /* = 0.0f */) -{ - return m_settings_interface->GetFloatValue(section, key, default_value); -} - -bool SDLHostInterface::RequestRenderWindowSize(s32 new_window_width, s32 new_window_height) -{ - if (new_window_width <= 0 || new_window_height <= 0 || m_fullscreen) - return false; - - // use imgui scale as the dpr - const float dpi_scale = ImGui::GetIO().DisplayFramebufferScale.x; - const s32 scaled_width = - std::max(static_cast(std::ceil(static_cast(new_window_width) * dpi_scale)), 1); - const s32 scaled_height = std::max( - static_cast(std::ceil(static_cast(new_window_height) * dpi_scale)) + m_display->GetDisplayTopMargin(), - 1); - - SDL_SetWindowSize(m_window, scaled_width, scaled_height); - - s32 window_width, window_height; - SDL_GetWindowSize(m_window, &window_width, &window_height); - m_display->ResizeRenderWindow(window_width, window_height); - - UpdateFramebufferScale(); - - if (!System::IsShutdown()) - g_gpu->UpdateResolutionScale(); - - return true; -} - -void SDLHostInterface::LoadSettings() -{ - // Settings need to be loaded prior to creating the window for OpenGL bits. - m_settings_interface = std::make_unique(GetSettingsFileName()); - m_settings_copy.Load(*m_settings_interface); - CommonHostInterface::LoadSettings(*m_settings_interface.get()); - CommonHostInterface::FixIncompatibleSettings(false); -} - -void SDLHostInterface::ReportError(const char* message) -{ - const bool was_fullscreen = IsFullscreen(); - if (was_fullscreen) - SetFullscreen(false); - - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "DuckStation", message, m_window); - - if (was_fullscreen) - SetFullscreen(true); -} - -void SDLHostInterface::ReportMessage(const char* message) -{ - AddOSDMessage(message, 2.0f); -} - -bool SDLHostInterface::ConfirmMessage(const char* message) -{ - const bool was_fullscreen = IsFullscreen(); - if (was_fullscreen) - SetFullscreen(false); - - SDL_MessageBoxData mbd = {}; - mbd.flags = SDL_MESSAGEBOX_INFORMATION; - mbd.window = m_window; - mbd.title = "DuckStation"; - mbd.message = message; - mbd.numbuttons = 2; - - // Why the heck these are reversed I have no idea... - SDL_MessageBoxButtonData buttons[2] = {}; - buttons[1].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; - buttons[1].buttonid = 0; - buttons[1].text = "Yes"; - buttons[0].flags = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT; - buttons[0].buttonid = 1; - buttons[0].text = "No"; - mbd.buttons = buttons; - mbd.numbuttons = countof(buttons); - - int button_id = 0; - SDL_ShowMessageBox(&mbd, &button_id); - const bool result = (button_id == 0); - - if (was_fullscreen) - SetFullscreen(true); - - return result; -} - -void SDLHostInterface::HandleSDLEvent(const SDL_Event* event) -{ - ImGui_ImplSDL2_ProcessEvent(event); - - if (m_controller_interface && - static_cast(m_controller_interface.get())->ProcessSDLEvent(event)) - { - return; - } - - switch (event->type) - { - case SDL_WINDOWEVENT: - { - if (event->window.event == SDL_WINDOWEVENT_RESIZED) - { - m_display->ResizeRenderWindow(event->window.data1, event->window.data2); - UpdateFramebufferScale(); - - if (!System::IsShutdown()) - g_gpu->UpdateResolutionScale(); - } - else if (event->window.event == SDL_WINDOWEVENT_MOVED) - { - UpdateFramebufferScale(); - } - } - break; - - case SDL_QUIT: - m_quit_request = true; - break; - - case SDL_KEYDOWN: - case SDL_KEYUP: - { - if (!ImGui::GetIO().WantCaptureKeyboard && event->key.repeat == 0) - { - const HostKeyCode code = static_cast(SDLKeyNames::KeyEventToInt(event)); - const bool pressed = (event->type == SDL_KEYDOWN); - HandleHostKeyEvent(code, pressed); - } - } - break; - - case SDL_MOUSEMOTION: - { - m_display->SetMousePosition(event->motion.x, event->motion.y); - } - break; - - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - { - if (!ImGui::GetIO().WantCaptureMouse) - { - const s32 button = static_cast(ZeroExtend32(event->button.button)); - const bool pressed = (event->type == SDL_MOUSEBUTTONDOWN); - HandleHostMouseEvent(button, pressed); - } - } - break; - - case SDL_USEREVENT: - { - if (static_cast(event->user.code) == m_run_later_event_id) - { - std::function* callback = static_cast*>(event->user.data1); - Assert(callback); - (*callback)(); - delete callback; - } - } - break; - } -} - -void SDLHostInterface::PollAndUpdate() -{ - CommonHostInterface::PollAndUpdate(); - ProcessEvents(); -} - -void SDLHostInterface::ProcessEvents() -{ - for (;;) - { - SDL_Event ev; - if (SDL_PollEvent(&ev)) - HandleSDLEvent(&ev); - else - break; - } -} - -void SDLHostInterface::DrawImGuiWindows() -{ - if (!m_fullscreen) - DrawMainMenuBar(); - - CommonHostInterface::DrawImGuiWindows(); - - if (System::IsShutdown()) - DrawPoweredOffWindow(); - - if (m_settings_window_open) - DrawSettingsWindow(); - - if (m_about_window_open) - DrawAboutWindow(); - - ImGui::Render(); -} - -void SDLHostInterface::DrawMainMenuBar() -{ - if (!ImGui::BeginMainMenuBar()) - return; - - const bool system_enabled = static_cast(!System::IsShutdown()); - - if (ImGui::BeginMenu("System")) - { - if (ImGui::MenuItem("Start Disc", nullptr, false, !system_enabled)) - { - RunLater([this]() { DoStartDisc(); }); - ClearImGuiFocus(); - } - if (ImGui::MenuItem("Start BIOS", nullptr, false, !system_enabled)) - { - RunLater([this]() { - SystemBootParameters boot_params; - BootSystem(boot_params); - }); - ClearImGuiFocus(); - } - - ImGui::Separator(); - - if (ImGui::MenuItem("Power Off", nullptr, false, system_enabled)) - { - RunLater([this]() { - if (g_settings.save_state_on_exit) - SaveResumeSaveState(); - PowerOffSystem(); - }); - ClearImGuiFocus(); - } - - if (ImGui::MenuItem("Reset", nullptr, false, system_enabled)) - { - RunLater([this]() { ResetSystem(); }); - ClearImGuiFocus(); - } - - if (ImGui::MenuItem("Pause", nullptr, System::IsPaused(), system_enabled)) - { - RunLater([this]() { PauseSystem(!System::IsPaused()); }); - ClearImGuiFocus(); - } - - ImGui::Separator(); - - if (ImGui::MenuItem("Change Disc", nullptr, false, system_enabled)) - { - RunLater([this]() { DoChangeDisc(); }); - ClearImGuiFocus(); - } - - if (ImGui::MenuItem("Remove Disc", nullptr, false, system_enabled)) - { - RunLater([this]() { System::RemoveMedia(); }); - ClearImGuiFocus(); - } - - if (ImGui::MenuItem("Frame Step", nullptr, false, system_enabled)) - { - RunLater([this]() { DoFrameStep(); }); - ClearImGuiFocus(); - } - - ImGui::Separator(); - - if (ImGui::BeginMenu("Load State")) - { - for (u32 i = 1; i <= GLOBAL_SAVE_STATE_SLOTS; i++) - { - char buf[16]; - std::snprintf(buf, sizeof(buf), "State %u", i); - if (ImGui::MenuItem(buf)) - { - RunLater([this, i]() { LoadState(true, i); }); - ClearImGuiFocus(); - } - } - ImGui::EndMenu(); - } - - if (ImGui::BeginMenu("Save State", system_enabled)) - { - for (u32 i = 1; i <= GLOBAL_SAVE_STATE_SLOTS; i++) - { - char buf[16]; - std::snprintf(buf, sizeof(buf), "State %u", i); - if (ImGui::MenuItem(buf)) - { - RunLater([this, i]() { SaveState(true, i); }); - ClearImGuiFocus(); - } - } - ImGui::EndMenu(); - } - - ImGui::Separator(); - - if (ImGui::BeginMenu("Cheats", system_enabled)) - { - const bool has_cheat_file = System::HasCheatList(); - - if (ImGui::MenuItem("Load Cheats...")) - { - nfdchar_t* path = nullptr; - if (NFD_OpenDialog("cht", nullptr, &path) && path && std::strlen(path) > 0) - LoadCheatList(path); - } - - if (ImGui::MenuItem("Save Cheats...", nullptr, false, has_cheat_file)) - { - nfdchar_t* path = nullptr; - if (NFD_SaveDialog("cht", nullptr, &path) && path && std::strlen(path) > 0) - SaveCheatList(path); - } - - if (ImGui::BeginMenu("Enabled Cheats", has_cheat_file)) - { - CheatList* cl = System::GetCheatList(); - for (u32 i = 0; i < cl->GetCodeCount(); i++) - { - const CheatCode& cc = cl->GetCode(i); - if (ImGui::MenuItem(cc.description.c_str(), nullptr, cc.enabled, true)) - SetCheatCodeState(i, !cc.enabled, g_settings.auto_load_cheats); - } - - ImGui::EndMenu(); - } - - if (ImGui::BeginMenu("Apply Cheat", has_cheat_file)) - { - CheatList* cl = System::GetCheatList(); - for (u32 i = 0; i < cl->GetCodeCount(); i++) - { - const CheatCode& cc = cl->GetCode(i); - if (ImGui::MenuItem(cc.description.c_str())) - ApplyCheatCode(i); - } - - ImGui::EndMenu(); - } - - ImGui::EndMenu(); - } - - ImGui::Separator(); - - if (ImGui::MenuItem("Exit")) - m_quit_request = true; - - ImGui::EndMenu(); - } - - if (ImGui::BeginMenu("Settings")) - { - if (ImGui::MenuItem("Change Settings...")) - m_settings_window_open = true; - - ImGui::Separator(); - - DrawQuickSettingsMenu(); - ImGui::EndMenu(); - } - - if (ImGui::BeginMenu("Debug")) - { - DrawDebugMenu(); - ImGui::EndMenu(); - } - - if (ImGui::BeginMenu("Help")) - { - if (ImGui::MenuItem("GitHub Repository")) - { - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Add URL Opener", "https://github.com/stenzek/duckstation", - m_window); - } - - ImGui::Separator(); - - if (ImGui::MenuItem("About")) - m_about_window_open = true; - - ImGui::EndMenu(); - } - - if (!System::IsShutdown()) - { - const float framebuffer_scale = ImGui::GetIO().DisplayFramebufferScale.x; - - if (System::IsPaused()) - { - ImGui::SetCursorPosX(ImGui::GetIO().DisplaySize.x - (50.0f * framebuffer_scale)); - ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Paused"); - } - else - { - ImGui::SetCursorPosX(ImGui::GetIO().DisplaySize.x - (420.0f * framebuffer_scale)); - ImGui::Text("Average: %.2fms", System::GetAverageFrameTime()); - - ImGui::SetCursorPosX(ImGui::GetIO().DisplaySize.x - (310.0f * framebuffer_scale)); - ImGui::Text("Worst: %.2fms", System::GetWorstFrameTime()); - - ImGui::SetCursorPosX(ImGui::GetIO().DisplaySize.x - (210.0f * framebuffer_scale)); - - const float speed = System::GetEmulationSpeed(); - const u32 rounded_speed = static_cast(std::round(speed)); - if (speed < 90.0f) - ImGui::TextColored(ImVec4(1.0f, 0.4f, 0.4f, 1.0f), "%u%%", rounded_speed); - else if (speed < 110.0f) - ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), "%u%%", rounded_speed); - else - ImGui::TextColored(ImVec4(0.4f, 1.0f, 0.4f, 1.0f), "%u%%", rounded_speed); - - ImGui::SetCursorPosX(ImGui::GetIO().DisplaySize.x - (165.0f * framebuffer_scale)); - ImGui::Text("FPS: %.2f", System::GetFPS()); - - ImGui::SetCursorPosX(ImGui::GetIO().DisplaySize.x - (80.0f * framebuffer_scale)); - ImGui::Text("VPS: %.2f", System::GetVPS()); - } - } - - ImGui::EndMainMenuBar(); -} - -void SDLHostInterface::DrawQuickSettingsMenu() -{ - bool settings_changed = false; - - if (ImGui::BeginMenu("CPU Execution Mode")) - { - const CPUExecutionMode current = m_settings_copy.cpu_execution_mode; - for (u32 i = 0; i < static_cast(CPUExecutionMode::Count); i++) - { - if (ImGui::MenuItem(Settings::GetCPUExecutionModeDisplayName(static_cast(i)), nullptr, - i == static_cast(current))) - { - m_settings_copy.cpu_execution_mode = static_cast(i); - settings_changed = true; - } - } - - ImGui::EndMenu(); - } - - if (ImGui::MenuItem("CPU Clock Control", nullptr, &m_settings_copy.cpu_overclock_enable)) - { - settings_changed = true; - m_settings_copy.UpdateOverclockActive(); - } - - if (ImGui::BeginMenu("CPU Clock Speed")) - { - static constexpr auto values = make_array(10u, 25u, 50u, 75u, 100u, 125u, 150u, 175u, 200u, 225u, 250u, 275u, 300u, - 350u, 400u, 450u, 500u, 600u, 700u, 800u); - const u32 percent = m_settings_copy.GetCPUOverclockPercent(); - for (u32 value : values) - { - if (ImGui::MenuItem(TinyString::FromFormat("%u%%", value), nullptr, percent == value)) - { - m_settings_copy.SetCPUOverclockPercent(value); - m_settings_copy.UpdateOverclockActive(); - settings_changed = true; - } - } - - ImGui::EndMenu(); - } - - settings_changed |= - ImGui::MenuItem("Recompiler Memory Exceptions", nullptr, &m_settings_copy.cpu_recompiler_memory_exceptions); - if (ImGui::BeginMenu("Recompiler Fastmem")) - { - for (u32 i = 0; i < static_cast(CPUFastmemMode::Count); i++) - { - if (ImGui::MenuItem(Settings::GetCPUFastmemModeDisplayName(static_cast(i)), nullptr, - m_settings_copy.cpu_fastmem_mode == static_cast(i))) - { - m_settings_copy.cpu_fastmem_mode = static_cast(i); - settings_changed = true; - } - } - - ImGui::EndMenu(); - } - - settings_changed |= ImGui::MenuItem("Recompiler ICache", nullptr, &m_settings_copy.cpu_recompiler_icache); - - ImGui::Separator(); - - if (ImGui::BeginMenu("Renderer")) - { - const GPURenderer current = m_settings_copy.gpu_renderer; - for (u32 i = 0; i < static_cast(GPURenderer::Count); i++) - { - if (ImGui::MenuItem(Settings::GetRendererDisplayName(static_cast(i)), nullptr, - i == static_cast(current))) - { - m_settings_copy.gpu_renderer = static_cast(i); - settings_changed = true; - } - } - - settings_changed |= ImGui::MenuItem("GPU on Thread", nullptr, &m_settings_copy.gpu_use_thread); - - ImGui::EndMenu(); - } - - bool fullscreen = m_fullscreen; - if (ImGui::MenuItem("Fullscreen", nullptr, &fullscreen)) - RunLater([this, fullscreen] { SetFullscreen(fullscreen); }); - - if (ImGui::BeginMenu("Resize to Game", System::IsValid())) - { - static constexpr auto scales = make_array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); - for (const u32 scale : scales) - { - if (ImGui::MenuItem(TinyString::FromFormat("%ux Scale", scale))) - RunLater([this, scale]() { RequestRenderWindowScale(static_cast(scale)); }); - } - - ImGui::EndMenu(); - } - - settings_changed |= ImGui::MenuItem("VSync", nullptr, &m_settings_copy.video_sync_enabled); - - ImGui::Separator(); - - if (ImGui::BeginMenu("Resolution Scale")) - { - const u32 current_internal_resolution = m_settings_copy.gpu_resolution_scale; - for (u32 scale = 1; scale <= GPU::MAX_RESOLUTION_SCALE; scale++) - { - char buf[32]; - std::snprintf(buf, sizeof(buf), "%ux (%ux%u)", scale, scale * VRAM_WIDTH, scale * VRAM_HEIGHT); - - if (ImGui::MenuItem(buf, nullptr, current_internal_resolution == scale)) - { - m_settings_copy.gpu_resolution_scale = scale; - settings_changed = true; - } - } - - ImGui::EndMenu(); - } - - if (ImGui::BeginMenu("Multisampling")) - { - const u32 current_multisamples = m_settings_copy.gpu_multisamples; - const bool current_ssaa = m_settings_copy.gpu_per_sample_shading; - - if (ImGui::MenuItem("None", nullptr, (current_multisamples == 1))) - { - m_settings_copy.gpu_multisamples = 1; - m_settings_copy.gpu_per_sample_shading = false; - settings_changed = true; - } - - for (u32 i = 2; i <= 32; i *= 2) - { - char buf[32]; - std::snprintf(buf, sizeof(buf), "%ux MSAA", i); - - if (ImGui::MenuItem(buf, nullptr, (current_multisamples == i && !current_ssaa))) - { - m_settings_copy.gpu_multisamples = i; - m_settings_copy.gpu_per_sample_shading = false; - settings_changed = true; - } - } - - for (u32 i = 2; i <= 32; i *= 2) - { - char buf[32]; - std::snprintf(buf, sizeof(buf), "%ux SSAA", i); - - if (ImGui::MenuItem(buf, nullptr, (current_multisamples == i && current_ssaa))) - { - m_settings_copy.gpu_multisamples = i; - m_settings_copy.gpu_per_sample_shading = true; - settings_changed = true; - } - } - - ImGui::EndMenu(); - } - - if (ImGui::BeginMenu("PGXP")) - { - settings_changed |= ImGui::MenuItem("PGXP Enabled", nullptr, &m_settings_copy.gpu_pgxp_enable); - settings_changed |= - ImGui::MenuItem("PGXP Culling", nullptr, &m_settings_copy.gpu_pgxp_culling, m_settings_copy.gpu_pgxp_enable); - settings_changed |= ImGui::MenuItem("PGXP Texture Correction", nullptr, - &m_settings_copy.gpu_pgxp_texture_correction, m_settings_copy.gpu_pgxp_enable); - settings_changed |= ImGui::MenuItem("PGXP Vertex Cache", nullptr, &m_settings_copy.gpu_pgxp_vertex_cache, - m_settings_copy.gpu_pgxp_enable); - settings_changed |= - ImGui::MenuItem("PGXP CPU Instructions", nullptr, &m_settings_copy.gpu_pgxp_cpu, m_settings_copy.gpu_pgxp_enable); - settings_changed |= ImGui::MenuItem("PGXP Preserve Projection Precision", nullptr, - &m_settings_copy.gpu_pgxp_preserve_proj_fp, m_settings_copy.gpu_pgxp_enable); - settings_changed |= ImGui::MenuItem("PGXP Depth Buffer", nullptr, &m_settings_copy.gpu_pgxp_depth_buffer, - m_settings_copy.gpu_pgxp_enable); - ImGui::EndMenu(); - } - - settings_changed |= ImGui::MenuItem("True (24-Bit) Color", nullptr, &m_settings_copy.gpu_true_color); - settings_changed |= ImGui::MenuItem("Scaled Dithering", nullptr, &m_settings_copy.gpu_scaled_dithering); - - if (ImGui::BeginMenu("Texture Filtering")) - { - const GPUTextureFilter current = m_settings_copy.gpu_texture_filter; - for (u32 i = 0; i < static_cast(GPUTextureFilter::Count); i++) - { - if (ImGui::MenuItem(Settings::GetTextureFilterDisplayName(static_cast(i)), nullptr, - i == static_cast(current))) - { - m_settings_copy.gpu_texture_filter = static_cast(i); - settings_changed = true; - } - } - - ImGui::EndMenu(); - } - - ImGui::Separator(); - - settings_changed |= ImGui::MenuItem("Disable Interlacing", nullptr, &m_settings_copy.gpu_disable_interlacing); - settings_changed |= ImGui::MenuItem("Widescreen Hack", nullptr, &m_settings_copy.gpu_widescreen_hack); - settings_changed |= ImGui::MenuItem("Force NTSC Timings", nullptr, &m_settings_copy.gpu_force_ntsc_timings); - settings_changed |= ImGui::MenuItem("24-Bit Chroma Smoothing", nullptr, &m_settings_copy.gpu_24bit_chroma_smoothing); - - ImGui::Separator(); - - settings_changed |= ImGui::MenuItem("Display Linear Filtering", nullptr, &m_settings_copy.display_linear_filtering); - settings_changed |= ImGui::MenuItem("Display Integer Scaling", nullptr, &m_settings_copy.display_integer_scaling); - - if (ImGui::BeginMenu("Aspect Ratio")) - { - for (u32 i = 0; i < static_cast(DisplayAspectRatio::Count); i++) - { - if (ImGui::MenuItem(Settings::GetDisplayAspectRatioName(static_cast(i)), nullptr, - m_settings_copy.display_aspect_ratio == static_cast(i))) - { - m_settings_copy.display_aspect_ratio = static_cast(i); - settings_changed = true; - } - } - - ImGui::EndMenu(); - } - - if (ImGui::BeginMenu("Crop Mode")) - { - for (u32 i = 0; i < static_cast(DisplayCropMode::Count); i++) - { - if (ImGui::MenuItem(Settings::GetDisplayCropModeDisplayName(static_cast(i)), nullptr, - m_settings_copy.display_crop_mode == static_cast(i))) - { - m_settings_copy.display_crop_mode = static_cast(i); - settings_changed = true; - } - } - - ImGui::EndMenu(); - } - - if (ImGui::BeginMenu("Downsample Mode")) - { - for (u32 i = 0; i < static_cast(GPUDownsampleMode::Count); i++) - { - if (ImGui::MenuItem(Settings::GetDownsampleModeDisplayName(static_cast(i)), nullptr, - m_settings_copy.gpu_downsample_mode == static_cast(i))) - { - m_settings_copy.gpu_downsample_mode = static_cast(i); - settings_changed = true; - } - } - - ImGui::EndMenu(); - } - - settings_changed |= ImGui::MenuItem("Force 4:3 For 24-bit", nullptr, &m_settings_copy.display_force_4_3_for_24bit); - - ImGui::Separator(); - - if (ImGui::MenuItem("Dump Audio", nullptr, IsDumpingAudio(), System::IsValid())) - { - if (!IsDumpingAudio()) - StartDumpingAudio(); - else - StopDumpingAudio(); - } - - if (ImGui::MenuItem("Save Screenshot")) - RunLater([this]() { SaveScreenshot(); }); - - if (settings_changed) - RunLater([this]() { SaveAndUpdateSettings(); }); -} - -void SDLHostInterface::DrawDebugMenu() -{ - const bool system_valid = System::IsValid(); - Settings::DebugSettings& debug_settings = g_settings.debugging; - bool settings_changed = false; - - if (ImGui::BeginMenu("Log Level")) - { - for (u32 i = LOGLEVEL_NONE; i < LOGLEVEL_COUNT; i++) - { - if (ImGui::MenuItem(Settings::GetLogLevelDisplayName(static_cast(i)), nullptr, - g_settings.log_level == static_cast(i))) - { - m_settings_copy.log_level = static_cast(i); - settings_changed = true; - } - } - - ImGui::EndMenu(); - } - - settings_changed |= ImGui::MenuItem("Log To Console", nullptr, &m_settings_copy.log_to_console); - settings_changed |= ImGui::MenuItem("Log To Debug", nullptr, &m_settings_copy.log_to_debug); - settings_changed |= ImGui::MenuItem("Log To File", nullptr, &m_settings_copy.log_to_file); - - ImGui::Separator(); - - settings_changed |= ImGui::MenuItem("Disable All Enhancements", nullptr, &m_settings_copy.disable_all_enhancements); - settings_changed |= ImGui::MenuItem("Dump CPU to VRAM Copies", nullptr, &debug_settings.dump_cpu_to_vram_copies); - settings_changed |= ImGui::MenuItem("Dump VRAM to CPU Copies", nullptr, &debug_settings.dump_vram_to_cpu_copies); - - if (ImGui::MenuItem("CPU Trace Logging", nullptr, CPU::IsTraceEnabled())) - { - if (!CPU::IsTraceEnabled()) - CPU::StartTrace(); - else - CPU::StopTrace(); - } - - if (ImGui::MenuItem("Dump RAM...", nullptr, nullptr, system_valid)) - DoDumpRAM(); - - ImGui::Separator(); - - settings_changed |= ImGui::MenuItem("Show VRAM", nullptr, &debug_settings.show_vram); - settings_changed |= ImGui::MenuItem("Show GPU State", nullptr, &debug_settings.show_gpu_state); - settings_changed |= ImGui::MenuItem("Show CDROM State", nullptr, &debug_settings.show_cdrom_state); - settings_changed |= ImGui::MenuItem("Show SPU State", nullptr, &debug_settings.show_spu_state); - settings_changed |= ImGui::MenuItem("Show Timers State", nullptr, &debug_settings.show_timers_state); - settings_changed |= ImGui::MenuItem("Show MDEC State", nullptr, &debug_settings.show_mdec_state); - settings_changed |= ImGui::MenuItem("Show DMA State", nullptr, &debug_settings.show_dma_state); - - if (settings_changed) - { - // have to apply it to the copy too, otherwise it won't save - Settings::DebugSettings& debug_settings_copy = m_settings_copy.debugging; - debug_settings_copy.show_gpu_state = debug_settings.show_gpu_state; - debug_settings_copy.show_vram = debug_settings.show_vram; - debug_settings_copy.dump_cpu_to_vram_copies = debug_settings.dump_cpu_to_vram_copies; - debug_settings_copy.dump_vram_to_cpu_copies = debug_settings.dump_vram_to_cpu_copies; - debug_settings_copy.show_cdrom_state = debug_settings.show_cdrom_state; - debug_settings_copy.show_spu_state = debug_settings.show_spu_state; - debug_settings_copy.show_timers_state = debug_settings.show_timers_state; - debug_settings_copy.show_mdec_state = debug_settings.show_mdec_state; - debug_settings_copy.show_dma_state = debug_settings.show_dma_state; - RunLater([this]() { SaveAndUpdateSettings(); }); - } -} - -void SDLHostInterface::DrawPoweredOffWindow() -{ - static constexpr int WINDOW_WIDTH = 400; - static constexpr int WINDOW_HEIGHT = 650; - static constexpr int BUTTON_WIDTH = 200; - static constexpr int BUTTON_HEIGHT = 40; - const float framebuffer_scale = ImGui::GetIO().DisplayFramebufferScale.x; - - ImGui::SetNextWindowSize(ImVec2(static_cast(WINDOW_WIDTH) * framebuffer_scale, - static_cast(WINDOW_HEIGHT) * framebuffer_scale)); - ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x * 0.5f, ImGui::GetIO().DisplaySize.y * 0.5f), - ImGuiCond_Always, ImVec2(0.5f, 0.5f)); - - if (!ImGui::Begin("Powered Off", nullptr, - ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse | - ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoResize | - ImGuiWindowFlags_NoBringToFrontOnFocus)) - { - ImGui::End(); - } - - ImGui::SetCursorPosX(static_cast((WINDOW_WIDTH - APP_ICON_WIDTH) / 2) * framebuffer_scale); - ImGui::Image(m_app_icon_texture->GetHandle(), ImVec2(static_cast(APP_ICON_WIDTH) * framebuffer_scale, - static_cast(APP_ICON_HEIGHT) * framebuffer_scale)); - ImGui::SetCursorPosY(static_cast(APP_ICON_HEIGHT + 32) * framebuffer_scale); - - const ImVec2 button_size(static_cast(BUTTON_WIDTH) * framebuffer_scale, - static_cast(BUTTON_HEIGHT) * framebuffer_scale); - const float button_left = static_cast((WINDOW_WIDTH - BUTTON_WIDTH) / 2) * framebuffer_scale; - - ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 8.0f * framebuffer_scale); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f * framebuffer_scale); - ImGui::PushStyleColor(ImGuiCol_Button, 0xFF202020); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, 0xFF808080); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, 0xFF575757); - - ImGui::SetCursorPosX(button_left); - if (ImGui::Button("Resume", button_size)) - { - RunLater([this]() { ResumeSystemFromMostRecentState(); }); - ClearImGuiFocus(); - } - ImGui::NewLine(); - - ImGui::SetCursorPosX(button_left); - if (ImGui::Button("Start Disc", button_size)) - { - RunLater([this]() { DoStartDisc(); }); - ClearImGuiFocus(); - } - ImGui::NewLine(); - - ImGui::SetCursorPosX(button_left); - if (ImGui::Button("Start BIOS", button_size)) - { - RunLater([this]() { - SystemBootParameters boot_params; - BootSystem(boot_params); - }); - ClearImGuiFocus(); - } - ImGui::NewLine(); - - ImGui::SetCursorPosX(button_left); - if (ImGui::Button("Load State", button_size)) - ImGui::OpenPopup("PowerOffWindow_LoadStateMenu"); - if (ImGui::BeginPopup("PowerOffWindow_LoadStateMenu")) - { - for (u32 i = 1; i <= GLOBAL_SAVE_STATE_SLOTS; i++) - { - char buf[16]; - std::snprintf(buf, sizeof(buf), "State %u", i); - if (ImGui::MenuItem(buf)) - { - RunLater([this, i]() { LoadState(true, i); }); - ClearImGuiFocus(); - } - } - ImGui::EndPopup(); - } - ImGui::NewLine(); - - ImGui::SetCursorPosX(button_left); - if (ImGui::Button("Settings", button_size)) - m_settings_window_open = true; - ImGui::NewLine(); - - ImGui::SetCursorPosX(button_left); - if (ImGui::Button("Exit", button_size)) - m_quit_request = true; - - ImGui::NewLine(); - - ImGui::PopStyleColor(3); - ImGui::PopStyleVar(2); - - ImGui::End(); -} - -static bool DrawSettingsSectionHeader(const char* title) -{ - return ImGui::CollapsingHeader(title, ImGuiTreeNodeFlags_DefaultOpen /* | ImGuiTreeNodeFlags_Leaf*/); -} - -void SDLHostInterface::DrawSettingsWindow() -{ - const float framebuffer_scale = ImGui::GetIO().DisplayFramebufferScale.x; - - ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x * 0.5f, ImGui::GetIO().DisplaySize.y * 0.5f), - ImGuiCond_FirstUseEver, ImVec2(0.5f, 0.5f)); - ImGui::SetNextWindowSize(ImVec2(500 * framebuffer_scale, 400.0f * framebuffer_scale), ImGuiCond_FirstUseEver); - - if (!ImGui::Begin("Settings", &m_settings_window_open, ImGuiWindowFlags_NoResize)) - { - ImGui::End(); - return; - } - - bool settings_changed = false; - - if (ImGui::BeginTabBar("SettingsTabBar", 0)) - { - const float indent = 150.0f * framebuffer_scale; - - if (ImGui::BeginTabItem("General")) - { - if (DrawSettingsSectionHeader("Console")) - { - ImGui::Text("Region:"); - ImGui::SameLine(indent); - - int region = static_cast(m_settings_copy.region); - if (ImGui::Combo( - "##region", ®ion, - [](void*, int index, const char** out_text) { - *out_text = Settings::GetConsoleRegionDisplayName(static_cast(index)); - return true; - }, - nullptr, static_cast(ConsoleRegion::Count))) - { - m_settings_copy.region = static_cast(region); - settings_changed = true; - } - - settings_changed |= ImGui::Checkbox("Enable TTY Output", &m_settings_copy.bios_patch_tty_enable); - settings_changed |= ImGui::Checkbox("Fast Boot", &m_settings_copy.bios_patch_fast_boot); - } - - ImGui::NewLine(); - if (DrawSettingsSectionHeader("Behavior")) - { - ImGui::Text("Emulation Speed:"); - ImGui::SameLine(indent); - - settings_changed |= ImGui::SliderFloat("##speed", &m_settings_copy.emulation_speed, 0.25f, 5.0f); - settings_changed |= ImGui::Checkbox("Increase Timer Resolution", &m_settings_copy.increase_timer_resolution); - settings_changed |= ImGui::Checkbox("Pause On Start", &m_settings_copy.start_paused); - settings_changed |= ImGui::Checkbox("Start Fullscreen", &m_settings_copy.start_fullscreen); - settings_changed |= ImGui::Checkbox("Save State On Exit", &m_settings_copy.save_state_on_exit); - settings_changed |= ImGui::Checkbox("Apply Game Settings", &m_settings_copy.apply_game_settings); - settings_changed |= ImGui::Checkbox("Automatically Load Cheats", &m_settings_copy.auto_load_cheats); - settings_changed |= - ImGui::Checkbox("Load Devices From Save States", &m_settings_copy.load_devices_from_save_states); - } - - ImGui::NewLine(); - if (DrawSettingsSectionHeader("CDROM Emulation")) - { - settings_changed |= ImGui::Checkbox("Use Read Thread (Asynchronous)", &m_settings_copy.cdrom_read_thread); - settings_changed |= ImGui::Checkbox("Enable Region Check", &m_settings_copy.cdrom_region_check); - settings_changed |= ImGui::Checkbox("Preload Image To RAM", &m_settings_copy.cdrom_load_image_to_ram); - } - - ImGui::NewLine(); - if (DrawSettingsSectionHeader("Audio")) - { - ImGui::Text("Backend:"); - ImGui::SameLine(indent); - - int backend = static_cast(m_settings_copy.audio_backend); - if (ImGui::Combo( - "##backend", &backend, - [](void*, int index, const char** out_text) { - *out_text = Settings::GetAudioBackendDisplayName(static_cast(index)); - return true; - }, - nullptr, static_cast(AudioBackend::Count))) - { - m_settings_copy.audio_backend = static_cast(backend); - settings_changed = true; - } - - settings_changed |= ImGui::Checkbox("Output Sync", &m_settings_copy.audio_sync_enabled); - settings_changed |= ImGui::Checkbox("Start Dumping On Boot", &m_settings_copy.audio_dump_on_boot); - settings_changed |= ImGui::Checkbox("Mute CD Audio", &m_settings_copy.cdrom_mute_cd_audio); - } - - ImGui::EndTabItem(); - } - - if (ImGui::BeginTabItem("Ports")) - { - for (int i = 0; i < 2; i++) - { - char buf[32]; - std::snprintf(buf, sizeof(buf), "Front Port %d", 1 + i); - - if (DrawSettingsSectionHeader(buf)) - { - ImGui::Text("Controller:"); - ImGui::SameLine(indent); - - int controller_type = static_cast(m_settings_copy.controller_types[i]); - if (ImGui::Combo( - TinyString::FromFormat("##controller_type%d", i), &controller_type, - [](void*, int index, const char** out_text) { - *out_text = Settings::GetControllerTypeDisplayName(static_cast(index)); - return true; - }, - nullptr, static_cast(ControllerType::Count))) - { - m_settings_copy.controller_types[i] = static_cast(controller_type); - settings_changed = true; - } - - ImGui::Text("Memory Card Type:"); - ImGui::SameLine(indent); - - int memory_card_type = static_cast(m_settings_copy.memory_card_types[i]); - if (ImGui::Combo( - TinyString::FromFormat("##memory_card_type%d", i), &memory_card_type, - [](void*, int index, const char** out_text) { - *out_text = Settings::GetMemoryCardTypeDisplayName(static_cast(index)); - return true; - }, - nullptr, static_cast(MemoryCardType::Count))) - { - m_settings_copy.memory_card_types[i] = static_cast(memory_card_type); - settings_changed = true; - } - - ImGui::Text("Shared Card Path:"); - ImGui::SameLine(indent); - - std::string* path_ptr = &m_settings_copy.memory_card_paths[i]; - std::snprintf(buf, sizeof(buf), "##memcard_%c_path", 'a' + i); - settings_changed |= DrawFileChooser(buf, path_ptr); - } - - ImGui::NewLine(); - } - - ImGui::EndTabItem(); - } - - if (ImGui::BeginTabItem("CPU")) - { - ImGui::Text("Execution Mode:"); - ImGui::SameLine(indent); - - int execution_mode = static_cast(m_settings_copy.cpu_execution_mode); - if (ImGui::Combo( - "##execution_mode", &execution_mode, - [](void*, int index, const char** out_text) { - *out_text = Settings::GetCPUExecutionModeDisplayName(static_cast(index)); - return true; - }, - nullptr, static_cast(CPUExecutionMode::Count))) - { - m_settings_copy.cpu_execution_mode = static_cast(execution_mode); - settings_changed = true; - } - - settings_changed |= ImGui::Checkbox("Enable CPU Clock Control", &m_settings_copy.cpu_overclock_enable); - if (m_settings_copy.cpu_overclock_enable) - { - ImGui::Text("Overclock:"); - ImGui::SameLine(indent); - - int overclock_percent = static_cast(m_settings_copy.GetCPUOverclockPercent()); - if (ImGui::SliderInt("##overclock_percent", &overclock_percent, 1, 1000, "%d%%")) - { - m_settings_copy.SetCPUOverclockPercent(static_cast(overclock_percent)); - settings_changed = true; - } - } - - settings_changed |= - ImGui::Checkbox("Enable Recompiler Memory Exceptions", &m_settings_copy.cpu_recompiler_memory_exceptions); - - settings_changed |= ImGui::Checkbox("Enable Recompiler ICache", &m_settings_copy.cpu_recompiler_icache); - - ImGui::EndTabItem(); - } - - if (ImGui::BeginTabItem("GPU")) - { - if (DrawSettingsSectionHeader("Basic")) - { - ImGui::Text("Renderer:"); - ImGui::SameLine(indent); - - int gpu_renderer = static_cast(m_settings_copy.gpu_renderer); - if (ImGui::Combo( - "##gpu_renderer", &gpu_renderer, - [](void*, int index, const char** out_text) { - *out_text = Settings::GetRendererDisplayName(static_cast(index)); - return true; - }, - nullptr, static_cast(GPURenderer::Count))) - { - m_settings_copy.gpu_renderer = static_cast(gpu_renderer); - settings_changed = true; - } - } - - ImGui::NewLine(); - - if (DrawSettingsSectionHeader("Display Output")) - { - ImGui::Text("Aspect Ratio:"); - ImGui::SameLine(indent); - int display_aspect_ratio = static_cast(m_settings_copy.display_aspect_ratio); - if (ImGui::Combo( - "##display_aspect_ratio", &display_aspect_ratio, - [](void*, int index, const char** out_text) { - *out_text = Settings::GetDisplayAspectRatioName(static_cast(index)); - return true; - }, - nullptr, static_cast(DisplayAspectRatio::Count))) - { - m_settings_copy.display_aspect_ratio = static_cast(display_aspect_ratio); - settings_changed = true; - } - - ImGui::Text("Crop:"); - ImGui::SameLine(indent); - - int display_crop_mode = static_cast(m_settings_copy.display_crop_mode); - if (ImGui::Combo( - "##display_crop_mode", &display_crop_mode, - [](void*, int index, const char** out_text) { - *out_text = Settings::GetDisplayCropModeDisplayName(static_cast(index)); - return true; - }, - nullptr, static_cast(DisplayCropMode::Count))) - { - m_settings_copy.display_crop_mode = static_cast(display_crop_mode); - settings_changed = true; - } - - ImGui::Text("Downsample Mode:"); - ImGui::SameLine(indent); - int gpu_downsample_mode = static_cast(m_settings_copy.gpu_downsample_mode); - if (ImGui::Combo( - "##gpu_downsample_mode", &gpu_downsample_mode, - [](void*, int index, const char** out_text) { - *out_text = Settings::GetDownsampleModeDisplayName(static_cast(index)); - return true; - }, - nullptr, static_cast(GPUDownsampleMode::Count))) - { - m_settings_copy.gpu_downsample_mode = static_cast(gpu_downsample_mode); - settings_changed = true; - } - - settings_changed |= ImGui::Checkbox("Use Debug Device", &m_settings_copy.gpu_use_debug_device); - settings_changed |= ImGui::Checkbox("Linear Filtering", &m_settings_copy.display_linear_filtering); - settings_changed |= ImGui::Checkbox("Integer Scaling", &m_settings_copy.display_integer_scaling); - settings_changed |= ImGui::Checkbox("VSync", &m_settings_copy.video_sync_enabled); - } - - ImGui::NewLine(); - - if (DrawSettingsSectionHeader("Enhancements")) - { - ImGui::Text("Resolution Scale:"); - ImGui::SameLine(indent); - - static constexpr std::array resolutions = {{ - "1x (1024x512 VRAM)", - "2x (2048x1024 VRAM)", - "3x (3072x1536 VRAM)", - "4x (4096x2048 VRAM)", - "5x (5120x2560 VRAM)", - "6x (6144x3072 VRAM)", - "7x (7168x3584 VRAM)", - "8x (8192x4096 VRAM)", - "9x (9216x4608 VRAM)", - "10x (10240x5120 VRAM)", - "11x (11264x5632 VRAM)", - "12x (12288x6144 VRAM)", - "13x (13312x6656 VRAM)", - "14x (14336x7168 VRAM)", - "15x (15360x7680 VRAM)", - "16x (16384x8192 VRAM)", - }}; - - int current_resolution_index = static_cast(m_settings_copy.gpu_resolution_scale) - 1; - if (ImGui::Combo("##gpu_resolution_scale", ¤t_resolution_index, resolutions.data(), - static_cast(resolutions.size()))) - { - m_settings_copy.gpu_resolution_scale = static_cast(current_resolution_index + 1); - settings_changed = true; - } - - ImGui::Text("Texture Filtering:"); - ImGui::SameLine(indent); - int gpu_texture_filter = static_cast(m_settings_copy.gpu_texture_filter); - if (ImGui::Combo( - "##gpu_texture_filter", &gpu_texture_filter, - [](void*, int index, const char** out_text) { - *out_text = Settings::GetTextureFilterDisplayName(static_cast(index)); - return true; - }, - nullptr, static_cast(GPUTextureFilter::Count))) - { - m_settings_copy.gpu_texture_filter = static_cast(gpu_texture_filter); - settings_changed = true; - } - - settings_changed |= ImGui::Checkbox("True 24-bit Color (disables dithering)", &m_settings_copy.gpu_true_color); - settings_changed |= ImGui::Checkbox("Disable Interlacing", &m_settings_copy.gpu_disable_interlacing); - settings_changed |= ImGui::Checkbox("Force NTSC Timings", &m_settings_copy.gpu_force_ntsc_timings); - settings_changed |= ImGui::Checkbox("Widescreen Hack", &m_settings_copy.gpu_widescreen_hack); - settings_changed |= - ImGui::Checkbox("Force 4:3 For 24-Bit Display", &m_settings_copy.display_force_4_3_for_24bit); - settings_changed |= ImGui::Checkbox("24-Bit Chroma Smoothing", &m_settings_copy.gpu_24bit_chroma_smoothing); - - settings_changed |= ImGui::Checkbox("PGXP Enabled", &m_settings_copy.gpu_pgxp_enable); - settings_changed |= ImGui::Checkbox("PGXP Culling", &m_settings_copy.gpu_pgxp_culling); - settings_changed |= ImGui::Checkbox("PGXP Texture Correction", &m_settings_copy.gpu_pgxp_texture_correction); - settings_changed |= ImGui::Checkbox("PGXP Vertex Cache", &m_settings_copy.gpu_pgxp_vertex_cache); - settings_changed |= ImGui::Checkbox("PGXP CPU Instructions", &m_settings_copy.gpu_pgxp_cpu); - settings_changed |= ImGui::Checkbox("PGXP Preserve Projection Precision", &m_settings_copy.gpu_pgxp_enable); - settings_changed |= ImGui::Checkbox("PGXP Depth Buffer", &m_settings_copy.gpu_pgxp_depth_buffer); - - ImGui::Text("PGXP Depth Clear Threshold:"); - ImGui::SameLine(indent); - - float depth_clear_threshold = m_settings_copy.GetPGXPDepthClearThreshold(); - if (ImGui::SliderFloat("##clear_threshold", &depth_clear_threshold, 0.0f, 4096.0f)) - { - m_settings_copy.SetPGXPDepthClearThreshold(depth_clear_threshold); - settings_changed = true; - } - } - - ImGui::EndTabItem(); - } - - if (ImGui::BeginTabItem("Advanced")) - { - ImGui::Text("These options are tweakable to improve performance/game compatibility."); - ImGui::Text("Use at your own risk, modified values will not be supported."); - ImGui::NewLine(); - - ImGui::Text("DMA Max Slice Ticks:"); - ImGui::SameLine(indent); - - int dma_max_slice_ticks = static_cast(m_settings_copy.dma_max_slice_ticks); - if (ImGui::SliderInt("##dma_max_slice_ticks", &dma_max_slice_ticks, 100, 10000)) - { - m_settings_copy.dma_max_slice_ticks = dma_max_slice_ticks; - settings_changed = true; - } - - ImGui::Text("DMA Halt Ticks:"); - ImGui::SameLine(indent); - - int dma_halt_ticks = static_cast(m_settings_copy.dma_halt_ticks); - if (ImGui::SliderInt("##dma_halt_ticks", &dma_halt_ticks, 100, 10000)) - { - m_settings_copy.dma_halt_ticks = dma_halt_ticks; - settings_changed = true; - } - - ImGui::Text("FIFO Size:"); - ImGui::SameLine(indent); - - int gpu_fifo_size = static_cast(m_settings_copy.gpu_fifo_size); - if (ImGui::SliderInt("##gpu_fifo_size", &gpu_fifo_size, 16, GPU::MAX_FIFO_SIZE)) - { - m_settings_copy.gpu_fifo_size = gpu_fifo_size; - settings_changed = true; - } - - ImGui::Text("Max Run-Ahead:"); - ImGui::SameLine(indent); - - int gpu_max_run_ahead = static_cast(m_settings_copy.gpu_max_run_ahead); - if (ImGui::SliderInt("##gpu_max_run_ahead", &gpu_max_run_ahead, 0, 1000)) - { - m_settings_copy.gpu_max_run_ahead = gpu_max_run_ahead; - settings_changed = true; - } - - if (ImGui::Button("Reset")) - { - m_settings_copy.dma_max_slice_ticks = static_cast(Settings::DEFAULT_DMA_MAX_SLICE_TICKS); - m_settings_copy.dma_halt_ticks = static_cast(Settings::DEFAULT_DMA_HALT_TICKS); - m_settings_copy.gpu_fifo_size = Settings::DEFAULT_GPU_FIFO_SIZE; - m_settings_copy.gpu_max_run_ahead = static_cast(Settings::DEFAULT_GPU_MAX_RUN_AHEAD); - settings_changed = true; - } - - ImGui::EndTabItem(); - } - - ImGui::EndTabBar(); - } - - ImGui::End(); - - if (settings_changed) - RunLater([this]() { SaveAndUpdateSettings(); }); -} - -void SDLHostInterface::DrawAboutWindow() -{ - const float framebuffer_scale = ImGui::GetIO().DisplayFramebufferScale.x; - - ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x * 0.5f, ImGui::GetIO().DisplaySize.y * 0.5f), - ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); - - ImGui::OpenPopup("About DuckStation"); - if (!ImGui::BeginPopupModal("About DuckStation", &m_about_window_open, ImGuiWindowFlags_NoResize)) - return; - - ImGui::Text("DuckStation"); - ImGui::NewLine(); - ImGui::Text("Authors:"); - ImGui::Text(" Connor McLaughlin "); - ImGui::NewLine(); - ImGui::Text("Uses Dear ImGui (https://github.com/ocornut/imgui)"); - ImGui::Text("Uses libcue (https://github.com/lipnitsk/libcue)"); - ImGui::Text("Uses stb_image_write (https://github.com/nothings/stb)"); - ImGui::Text("Uses simpleini (https://github.com/brofield/simpleini)"); - ImGui::NewLine(); - ImGui::Text("Duck icon by icons8 (https://icons8.com/icon/74847/platforms.undefined.short-title)"); - - ImGui::NewLine(); - - ImGui::SetCursorPosX((ImGui::GetWindowSize().x - (60.0f * framebuffer_scale)) / 2.0f); - if (ImGui::Button("Close", ImVec2(60.0f * framebuffer_scale, 20.0f * framebuffer_scale))) - m_about_window_open = false; - - ImGui::EndPopup(); -} - -bool SDLHostInterface::DrawFileChooser(const char* label, std::string* path, const char* filter /* = nullptr */) -{ - const float framebuffer_scale = ImGui::GetIO().DisplayFramebufferScale.x; - - ImGui::SetNextItemWidth(ImGui::CalcItemWidth() - (50.0f * framebuffer_scale)); - bool result = ImGui::InputText(label, path); - ImGui::SameLine(); - - ImGui::SetNextItemWidth(50.0f * framebuffer_scale); - if (ImGui::Button("...")) - { - nfdchar_t* out_path = nullptr; - nfdresult_t nfd_result = NFD_OpenDialog(filter, path->c_str(), &out_path); - if (nfd_result == NFD_ERROR) - { - // try without the path - it might not be valid - nfd_result = NFD_OpenDialog(filter, nullptr, &out_path); - } - if (nfd_result == NFD_OKAY) - { - path->assign(out_path); - result = true; - } - } - - return result; -} - -void SDLHostInterface::ClearImGuiFocus() -{ - ImGui::SetWindowFocus(nullptr); -} - -void SDLHostInterface::DoStartDisc() -{ - Assert(System::IsShutdown()); - - nfdchar_t* path = nullptr; - if (!NFD_OpenDialog("bin,img,iso,cue,chd,exe,psexe,psf,minipsf", nullptr, &path) || !path || std::strlen(path) == 0) - return; - - AddFormattedOSDMessage(2.0f, "Starting disc from '%s'...", path); - - SystemBootParameters boot_params; - boot_params.filename = path; - BootSystem(boot_params); -} - -void SDLHostInterface::DoChangeDisc() -{ - Assert(!System::IsShutdown()); - - nfdchar_t* path = nullptr; - if (!NFD_OpenDialog("bin,img,iso,cue,chd", nullptr, &path) || !path || std::strlen(path) == 0) - return; - - if (System::InsertMedia(path)) - AddFormattedOSDMessage(2.0f, "Switched CD to '%s'", path); - else - AddOSDMessage("Failed to switch CD. The log may contain further information."); - - System::ResetPerformanceCounters(); -} - -void SDLHostInterface::DoDumpRAM() -{ - Assert(!System::IsShutdown()); - - nfdchar_t* path = nullptr; - if (!NFD_SaveDialog("bin", nullptr, &path) || !path || std::strlen(path) == 0) - return; - - if (System::DumpRAM(path)) - AddFormattedOSDMessage(5.0f, "Dumped RAM to '%s'", path); - else - AddFormattedOSDMessage(10.0f, "Failed to dump RAM to '%s'", path); - - System::ResetPerformanceCounters(); -} - -void SDLHostInterface::Run() -{ - while (!m_quit_request) - { - PollAndUpdate(); - - if (System::IsRunning()) - { - if (m_display_all_frames) - System::RunFrame(); - else - System::RunFrames(); - - UpdateControllerRumble(); - if (m_frame_step_request) - { - m_frame_step_request = false; - PauseSystem(true); - } - } - - // rendering - { - DrawImGuiWindows(); - - m_display->Render(); - ImGui_ImplSDL2_NewFrame(); - ImGui::NewFrame(); - - if (System::IsRunning()) - { - System::UpdatePerformanceCounters(); - - if (m_throttler_enabled) - System::Throttle(); - } - } - } - - // Save state on exit so it can be resumed - if (!System::IsShutdown()) - { - if (g_settings.save_state_on_exit) - SaveResumeSaveState(); - DestroySystem(); - } -} diff --git a/src/duckstation-sdl/sdl_host_interface.h b/src/duckstation-sdl/sdl_host_interface.h deleted file mode 100644 index c915400e5..000000000 --- a/src/duckstation-sdl/sdl_host_interface.h +++ /dev/null @@ -1,108 +0,0 @@ -#pragma once -#include "common/gl/program.h" -#include "common/gl/texture.h" -#include "core/host_display.h" -#include "core/host_interface.h" -#include "frontend-common/common_host_interface.h" -#include -#include -#include -#include -#include -#include -#include - -class AudioStream; - -class INISettingsInterface; - -class SDLHostInterface final : public CommonHostInterface -{ -public: - SDLHostInterface(); - ~SDLHostInterface(); - - static std::unique_ptr Create(); - - const char* GetFrontendName() const override; - - void ReportError(const char* message) override; - void ReportMessage(const char* message) override; - bool ConfirmMessage(const char* message) override; - - bool Initialize() override; - void Shutdown() override; - - std::string GetStringSettingValue(const char* section, const char* key, const char* default_value = "") override; - bool GetBoolSettingValue(const char* section, const char* key, bool default_value = false) override; - int GetIntSettingValue(const char* section, const char* key, int default_value = 0) override; - float GetFloatSettingValue(const char* section, const char* key, float default_value = 0.0f) override; - - bool RequestRenderWindowSize(s32 new_window_width, s32 new_window_height) override; - - bool IsFullscreen() const override; - bool SetFullscreen(bool enabled) override; - - void RunLater(std::function callback) override; - void ApplySettings(bool display_osd_messages) override; - - void Run(); - -protected: - void LoadSettings() override; - - bool AcquireHostDisplay() override; - void ReleaseHostDisplay() override; - - void OnSystemCreated() override; - void OnSystemPaused(bool paused) override; - void OnSystemDestroyed() override; - void OnRunningGameChanged() override; - - void RequestExit() override; - void PollAndUpdate() override; - - std::optional GetHostKeyCode(const std::string_view key_code) const override; - void UpdateInputMap() override; - -private: - bool CreateSDLWindow(); - void DestroySDLWindow(); - bool CreateDisplay(); - void DestroyDisplay(); - void CreateImGuiContext(); - void UpdateFramebufferScale(); - - void SaveAndUpdateSettings(); - - // We only pass mouse input through if it's grabbed - void DrawImGuiWindows() override; - void DoStartDisc(); - void DoChangeDisc(); - void DoDumpRAM(); - - void HandleSDLEvent(const SDL_Event* event); - void ProcessEvents(); - - void DrawMainMenuBar(); - void DrawQuickSettingsMenu(); - void DrawDebugMenu(); - void DrawPoweredOffWindow(); - void DrawSettingsWindow(); - void DrawAboutWindow(); - bool DrawFileChooser(const char* label, std::string* path, const char* filter = nullptr); - void ClearImGuiFocus(); - - SDL_Window* m_window = nullptr; - std::unique_ptr m_app_icon_texture; - std::unique_ptr m_settings_interface; - u32 m_run_later_event_id = 0; - - bool m_fullscreen = false; - bool m_quit_request = false; - bool m_settings_window_open = false; - bool m_about_window_open = false; - - // this copy of the settings is modified by imgui - Settings m_settings_copy; -}; diff --git a/src/duckstation-sdl/sdl_key_names.h b/src/duckstation-sdl/sdl_key_names.h deleted file mode 100644 index c8d744c3e..000000000 --- a/src/duckstation-sdl/sdl_key_names.h +++ /dev/null @@ -1,353 +0,0 @@ -#pragma once -#include "common/string.h" -#include "common/types.h" -#include -#include -#include -#include -#include -#include - -namespace SDLKeyNames { - -static const std::map s_sdl_key_names = {{SDLK_RETURN, "Return"}, - {SDLK_ESCAPE, "Escape"}, - {SDLK_BACKSPACE, "Backspace"}, - {SDLK_TAB, "Tab"}, - {SDLK_SPACE, "Space"}, - {SDLK_EXCLAIM, "Exclam"}, - {SDLK_QUOTEDBL, "QuoteDbl"}, - {SDLK_HASH, "Hash"}, - {SDLK_PERCENT, "Percent"}, - {SDLK_DOLLAR, "Dollar"}, - {SDLK_AMPERSAND, "Ampersand"}, - {SDLK_QUOTE, "Apostrophe"}, - {SDLK_LEFTPAREN, "ParenLeft"}, - {SDLK_RIGHTPAREN, "ParenRight"}, - {SDLK_ASTERISK, "Asterisk"}, - {SDLK_PLUS, "PLus"}, - {SDLK_COMMA, "Comma"}, - {SDLK_MINUS, "Minus"}, - {SDLK_PERIOD, "Period"}, - {SDLK_SLASH, "Slash"}, - {SDLK_0, "0"}, - {SDLK_1, "1"}, - {SDLK_2, "2"}, - {SDLK_3, "3"}, - {SDLK_4, "4"}, - {SDLK_5, "5"}, - {SDLK_6, "6"}, - {SDLK_7, "7"}, - {SDLK_8, "8"}, - {SDLK_9, "9"}, - {SDLK_COLON, "Colon"}, - {SDLK_SEMICOLON, "Semcolon"}, - {SDLK_LESS, "Less"}, - {SDLK_EQUALS, "Equal"}, - {SDLK_GREATER, "Greater"}, - {SDLK_QUESTION, "Question"}, - {SDLK_AT, "AT"}, - {SDLK_LEFTBRACKET, "BracketLeft"}, - {SDLK_BACKSLASH, "Backslash"}, - {SDLK_RIGHTBRACKET, "BracketRight"}, - {SDLK_CARET, "Caret"}, - {SDLK_UNDERSCORE, "Underscore"}, - {SDLK_BACKQUOTE, "Backquote"}, - {SDLK_a, "A"}, - {SDLK_b, "B"}, - {SDLK_c, "C"}, - {SDLK_d, "D"}, - {SDLK_e, "E"}, - {SDLK_f, "F"}, - {SDLK_g, "G"}, - {SDLK_h, "H"}, - {SDLK_i, "I"}, - {SDLK_j, "J"}, - {SDLK_k, "K"}, - {SDLK_l, "L"}, - {SDLK_m, "M"}, - {SDLK_n, "N"}, - {SDLK_o, "O"}, - {SDLK_p, "P"}, - {SDLK_q, "Q"}, - {SDLK_r, "R"}, - {SDLK_s, "S"}, - {SDLK_t, "T"}, - {SDLK_u, "U"}, - {SDLK_v, "V"}, - {SDLK_w, "W"}, - {SDLK_x, "X"}, - {SDLK_y, "Y"}, - {SDLK_z, "Z"}, - {SDLK_CAPSLOCK, "CapsLock"}, - {SDLK_F1, "F1"}, - {SDLK_F2, "F2"}, - {SDLK_F3, "F3"}, - {SDLK_F4, "F4"}, - {SDLK_F5, "F5"}, - {SDLK_F6, "F6"}, - {SDLK_F7, "F7"}, - {SDLK_F8, "F8"}, - {SDLK_F9, "F9"}, - {SDLK_F10, "F10"}, - {SDLK_F11, "F11"}, - {SDLK_F12, "F12"}, - {SDLK_PRINTSCREEN, "Print"}, - {SDLK_SCROLLLOCK, "ScrollLock"}, - {SDLK_PAUSE, "Pause"}, - {SDLK_INSERT, "Insert"}, - {SDLK_HOME, "Home"}, - {SDLK_PAGEUP, "PageUp"}, - {SDLK_DELETE, "Delete"}, - {SDLK_END, "End"}, - {SDLK_PAGEDOWN, "PageDown"}, - {SDLK_RIGHT, "Right"}, - {SDLK_LEFT, "Left"}, - {SDLK_DOWN, "Down"}, - {SDLK_UP, "Up"}, - {SDLK_NUMLOCKCLEAR, "NumLock"}, - {SDLK_KP_DIVIDE, "Keypad+Divide"}, - {SDLK_KP_MULTIPLY, "Keypad+Multiply"}, - {SDLK_KP_MINUS, "Keypad+Minus"}, - {SDLK_KP_PLUS, "Keypad+Plus"}, - {SDLK_KP_ENTER, "Keypad+Return"}, - {SDLK_KP_1, "Keypad+1"}, - {SDLK_KP_2, "Keypad+2"}, - {SDLK_KP_3, "Keypad+3"}, - {SDLK_KP_4, "Keypad+4"}, - {SDLK_KP_5, "Keypad+5"}, - {SDLK_KP_6, "Keypad+6"}, - {SDLK_KP_7, "Keypad+7"}, - {SDLK_KP_8, "Keypad+8"}, - {SDLK_KP_9, "Keypad+9"}, - {SDLK_KP_0, "Keypad+0"}, - {SDLK_KP_PERIOD, "Keypad+Period"}, - {SDLK_APPLICATION, "Application"}, - {SDLK_POWER, "Power"}, - {SDLK_KP_EQUALS, "Keypad+Equal"}, - {SDLK_F13, "F13"}, - {SDLK_F14, "F14"}, - {SDLK_F15, "F15"}, - {SDLK_F16, "F16"}, - {SDLK_F17, "F17"}, - {SDLK_F18, "F18"}, - {SDLK_F19, "F19"}, - {SDLK_F20, "F20"}, - {SDLK_F21, "F21"}, - {SDLK_F22, "F22"}, - {SDLK_F23, "F23"}, - {SDLK_F24, "F24"}, - {SDLK_EXECUTE, "Execute"}, - {SDLK_HELP, "Help"}, - {SDLK_MENU, "Menu"}, - {SDLK_SELECT, "Select"}, - {SDLK_STOP, "Stop"}, - {SDLK_AGAIN, "Again"}, - {SDLK_UNDO, "Undo"}, - {SDLK_CUT, "Cut"}, - {SDLK_COPY, "Copy"}, - {SDLK_PASTE, "Paste"}, - {SDLK_FIND, "Find"}, - {SDLK_MUTE, "Mute"}, - {SDLK_VOLUMEUP, "VolumeUp"}, - {SDLK_VOLUMEDOWN, "VolumeDown"}, - {SDLK_KP_COMMA, "Keypad+Comma"}, - {SDLK_KP_EQUALSAS400, "Keypad+EqualAS400"}, - {SDLK_ALTERASE, "AltErase"}, - {SDLK_SYSREQ, "SysReq"}, - {SDLK_CANCEL, "Cancel"}, - {SDLK_CLEAR, "Clear"}, - {SDLK_PRIOR, "Prior"}, - {SDLK_RETURN2, "Return2"}, - {SDLK_SEPARATOR, "Separator"}, - {SDLK_OUT, "Out"}, - {SDLK_OPER, "Oper"}, - {SDLK_CLEARAGAIN, "ClearAgain"}, - {SDLK_CRSEL, "CrSel"}, - {SDLK_EXSEL, "ExSel"}, - {SDLK_KP_00, "Keypad+00"}, - {SDLK_KP_000, "Keypad+000"}, - {SDLK_THOUSANDSSEPARATOR, "ThousandsSeparator"}, - {SDLK_DECIMALSEPARATOR, "DecimalSeparator"}, - {SDLK_CURRENCYUNIT, "CurrencyUnit"}, - {SDLK_CURRENCYSUBUNIT, "CurrencySubunit"}, - {SDLK_KP_LEFTPAREN, "Keypad+ParenLeft"}, - {SDLK_KP_RIGHTPAREN, "Keypad+ParenRight"}, - {SDLK_KP_LEFTBRACE, "Keypad+LeftBrace"}, - {SDLK_KP_RIGHTBRACE, "Keypad+RightBrace"}, - {SDLK_KP_TAB, "Keypad+Tab"}, - {SDLK_KP_BACKSPACE, "Keypad+Backspace"}, - {SDLK_KP_A, "Keypad+A"}, - {SDLK_KP_B, "Keypad+B"}, - {SDLK_KP_C, "Keypad+C"}, - {SDLK_KP_D, "Keypad+D"}, - {SDLK_KP_E, "Keypad+E"}, - {SDLK_KP_F, "Keypad+F"}, - {SDLK_KP_XOR, "Keypad+XOR"}, - {SDLK_KP_POWER, "Keypad+Power"}, - {SDLK_KP_PERCENT, "Keypad+Percent"}, - {SDLK_KP_LESS, "Keypad+Less"}, - {SDLK_KP_GREATER, "Keypad+Greater"}, - {SDLK_KP_AMPERSAND, "Keypad+Ampersand"}, - {SDLK_KP_DBLAMPERSAND, "Keypad+AmpersandDbl"}, - {SDLK_KP_VERTICALBAR, "Keypad+Bar"}, - {SDLK_KP_DBLVERTICALBAR, "Keypad+BarDbl"}, - {SDLK_KP_COLON, "Keypad+Colon"}, - {SDLK_KP_HASH, "Keypad+Hash"}, - {SDLK_KP_SPACE, "Keypad+Space"}, - {SDLK_KP_AT, "Keypad+At"}, - {SDLK_KP_EXCLAM, "Keypad+Exclam"}, - {SDLK_KP_MEMSTORE, "Keypad+MemStore"}, - {SDLK_KP_MEMRECALL, "Keypad+MemRecall"}, - {SDLK_KP_MEMCLEAR, "Keypad+MemClear"}, - {SDLK_KP_MEMADD, "Keypad+MemAdd"}, - {SDLK_KP_MEMSUBTRACT, "Keypad+MemSubtract"}, - {SDLK_KP_MEMMULTIPLY, "Keypad+MemMultiply"}, - {SDLK_KP_MEMDIVIDE, "Keypad+MemDivide"}, - {SDLK_KP_PLUSMINUS, "Keypad+PlusMinus"}, - {SDLK_KP_CLEAR, "Keypad+Clear"}, - {SDLK_KP_CLEARENTRY, "Keypad+ClearEntry"}, - {SDLK_KP_BINARY, "Keypad+Binary"}, - {SDLK_KP_OCTAL, "Keypad+Octal"}, - {SDLK_KP_DECIMAL, "Keypad+Decimal"}, - {SDLK_KP_HEXADECIMAL, "Keypad+Hexadecimal"}, - {SDLK_LCTRL, "LeftControl"}, - {SDLK_LSHIFT, "LeftShift"}, - {SDLK_LALT, "LeftAlt"}, - {SDLK_LGUI, "Super_L"}, - {SDLK_RCTRL, "RightCtrl"}, - {SDLK_RSHIFT, "RightShift"}, - {SDLK_RALT, "RightAlt"}, - {SDLK_RGUI, "RightSuper"}, - {SDLK_MODE, "Mode"}, - {SDLK_AUDIONEXT, "MediaNext"}, - {SDLK_AUDIOPREV, "MediaPrevious"}, - {SDLK_AUDIOSTOP, "MediaStop"}, - {SDLK_AUDIOPLAY, "MediaPlay"}, - {SDLK_AUDIOMUTE, "VolumeMute"}, - {SDLK_MEDIASELECT, "MediaSelect"}, - {SDLK_WWW, "WWW"}, - {SDLK_MAIL, "Mail"}, - {SDLK_CALCULATOR, "Calculator"}, - {SDLK_COMPUTER, "Computer"}, - {SDLK_AC_SEARCH, "Search"}, - {SDLK_AC_HOME, "Home"}, - {SDLK_AC_BACK, "Back"}, - {SDLK_AC_FORWARD, "Forward"}, - {SDLK_AC_STOP, "Stop"}, - {SDLK_AC_REFRESH, "Refresh"}, - {SDLK_AC_BOOKMARKS, "Bookmarks"}, - {SDLK_BRIGHTNESSDOWN, "BrightnessDown"}, - {SDLK_BRIGHTNESSUP, "BrightnessUp"}, - {SDLK_DISPLAYSWITCH, "DisplaySwitch"}, - {SDLK_KBDILLUMTOGGLE, "IllumToggle"}, - {SDLK_KBDILLUMDOWN, "IllumDown"}, - {SDLK_KBDILLUMUP, "IllumUp"}, - {SDLK_EJECT, "Eject"}, - {SDLK_SLEEP, "Sleep"}, - {SDLK_APP1, "App1"}, - {SDLK_APP2, "App2"}, - {SDLK_AUDIOREWIND, "MediaRewind"}, - {SDLK_AUDIOFASTFORWARD, "MediaFastForward"}}; - -struct SDLKeyModifierEntry -{ - SDL_Keymod mod; - SDL_Keymod mod_mask; - SDL_Keycode key_left; - SDL_Keycode key_right; - const char* name; -}; - -static const std::array s_sdl_key_modifiers = { - {{KMOD_LSHIFT, static_cast(KMOD_LSHIFT | KMOD_RSHIFT), SDLK_LSHIFT, SDLK_RSHIFT, "Shift"}, - {KMOD_LCTRL, static_cast(KMOD_LCTRL | KMOD_LCTRL), SDLK_LCTRL, SDLK_RCTRL, "Control"}, - {KMOD_LALT, static_cast(KMOD_LALT | KMOD_RALT), SDLK_LALT, SDLK_RALT, "Alt"}, - {KMOD_LGUI, static_cast(KMOD_LGUI | KMOD_RGUI), SDLK_LGUI, SDLK_RGUI, "Meta"}}}; - -const char* GetKeyName(SDL_Keycode key) -{ - const auto it = s_sdl_key_names.find(key); - return it == s_sdl_key_names.end() ? nullptr : it->second; -} - -std::optional GetKeyCodeForName(const std::string_view key_name) -{ - for (const auto& it : s_sdl_key_names) - { - if (key_name == it.second) - return it.first; - } - - return std::nullopt; -} - -u32 KeyEventToInt(const SDL_Event* event) -{ - u32 code = static_cast(event->key.keysym.sym); - - const SDL_Keymod mods = static_cast(event->key.keysym.mod); - if (mods & (KMOD_LSHIFT | KMOD_RSHIFT)) - code |= static_cast(KMOD_LSHIFT) << 16; - if (mods & (KMOD_LCTRL | KMOD_RCTRL)) - code |= static_cast(KMOD_LCTRL) << 16; - if (mods & (KMOD_LALT | KMOD_RALT)) - code |= static_cast(KMOD_LALT) << 16; - if (mods & (KMOD_LGUI | KMOD_RGUI)) - code |= static_cast(KMOD_LGUI) << 16; - - return code; -} - -bool KeyEventToString(const SDL_Event* event, String& out_string) -{ - const SDL_Keycode key = event->key.keysym.sym; - const SDL_Keymod mods = static_cast(event->key.keysym.mod); - const char* key_name = GetKeyName(event->key.keysym.sym); - if (!key_name) - return false; - - out_string.Clear(); - - for (const SDLKeyModifierEntry& mod : s_sdl_key_modifiers) - { - if (mods & mod.mod_mask && key != mod.key_left && key != mod.key_right) - { - out_string.AppendString(mod.name); - out_string.AppendCharacter('+'); - } - } - - out_string.AppendString(key_name); - return true; -} - -std::optional ParseKeyString(const std::string_view key_str) -{ - u32 modifiers = 0; - std::string_view::size_type pos = 0; - for (;;) - { - std::string_view::size_type plus_pos = key_str.find('+', pos); - if (plus_pos == std::string_view::npos) - break; - - const std::string_view mod_part = key_str.substr(pos, plus_pos - pos); - for (const SDLKeyModifierEntry& mod : s_sdl_key_modifiers) - { - if (mod_part == mod.name) - { - modifiers |= static_cast(mod.mod); - break; - } - } - pos = plus_pos + 1; - } - - std::optional key_code = GetKeyCodeForName(key_str.substr(pos)); - if (!key_code) - return std::nullopt; - - return static_cast(key_code.value()) | (modifiers << 16); -} -} // namespace SDLKeyNames \ No newline at end of file diff --git a/src/duckstation-sdl/sdl_util.cpp b/src/duckstation-sdl/sdl_util.cpp deleted file mode 100644 index 318afab3c..000000000 --- a/src/duckstation-sdl/sdl_util.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include "sdl_util.h" -#include "common/log.h" -#include -Log_SetChannel(SDLUtil); - -#ifdef __APPLE__ -#include -struct NSView; - -static NSView* GetContentViewFromWindow(NSWindow* window) -{ - // window.contentView - return reinterpret_cast(objc_msgSend)(reinterpret_cast(window), sel_getUid("contentView")); -} -#endif - -namespace SDLUtil { - -std::optional GetWindowInfoForSDLWindow(SDL_Window* window) -{ - SDL_SysWMinfo syswm = {}; - SDL_VERSION(&syswm.version); - if (!SDL_GetWindowWMInfo(window, &syswm)) - { - Log_ErrorPrintf("SDL_GetWindowWMInfo failed"); - return std::nullopt; - } - - int window_width, window_height; - SDL_GetWindowSize(window, &window_width, &window_height); - - WindowInfo wi; - wi.surface_width = static_cast(window_width); - wi.surface_height = static_cast(window_height); - wi.surface_scale = GetDPIScaleFactor(window); - wi.surface_format = WindowInfo::SurfaceFormat::RGB8; - - switch (syswm.subsystem) - { -#ifdef SDL_VIDEO_DRIVER_WINDOWS - case SDL_SYSWM_WINDOWS: - wi.type = WindowInfo::Type::Win32; - wi.window_handle = syswm.info.win.window; - break; -#endif - -#ifdef SDL_VIDEO_DRIVER_COCOA - case SDL_SYSWM_COCOA: - wi.type = WindowInfo::Type::MacOS; - wi.window_handle = GetContentViewFromWindow(syswm.info.cocoa.window); - break; -#endif - -#ifdef SDL_VIDEO_DRIVER_X11 - case SDL_SYSWM_X11: - wi.type = WindowInfo::Type::X11; - wi.window_handle = reinterpret_cast(static_cast(syswm.info.x11.window)); - wi.display_connection = syswm.info.x11.display; - break; -#endif - -#ifdef SDL_VIDEO_DRIVER_WAYLAND - case SDL_SYSWM_WAYLAND: - wi.type = WindowInfo::Type::Wayland; - wi.window_handle = syswm.info.wl.surface; - wi.display_connection = syswm.info.wl.display; - break; -#endif - - default: - Log_ErrorPrintf("Unhandled syswm subsystem %u", static_cast(syswm.subsystem)); - return std::nullopt; - } - - return wi; -} - -float GetDPIScaleFactor(SDL_Window* window) -{ -#ifdef __APPLE__ - static constexpr float DEFAULT_DPI = 72.0f; -#else - static constexpr float DEFAULT_DPI = 96.0f; -#endif - - if (!window) - { - SDL_Window* dummy_window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1, 1, - SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_HIDDEN); - if (!dummy_window) - return 1.0f; - - const float scale = GetDPIScaleFactor(dummy_window); - - SDL_DestroyWindow(dummy_window); - - return scale; - } - - int display_index = SDL_GetWindowDisplayIndex(window); - float display_dpi = DEFAULT_DPI; - if (SDL_GetDisplayDPI(display_index, &display_dpi, nullptr, nullptr) != 0) - return 1.0f; - - return display_dpi / DEFAULT_DPI; -} -} // namespace SDLUtil \ No newline at end of file diff --git a/src/duckstation-sdl/sdl_util.h b/src/duckstation-sdl/sdl_util.h deleted file mode 100644 index 685df5e25..000000000 --- a/src/duckstation-sdl/sdl_util.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include "common/types.h" -#include "common/window_info.h" -#include - -struct SDL_Window; - -namespace SDLUtil { -std::optional GetWindowInfoForSDLWindow(SDL_Window* window); -float GetDPIScaleFactor(SDL_Window* window); -} \ No newline at end of file