diff --git a/core/debug/debug_agent.h b/core/debug/debug_agent.h index 849afac15..78d05ee9f 100644 --- a/core/debug/debug_agent.h +++ b/core/debug/debug_agent.h @@ -247,7 +247,7 @@ public: void restart() { emu.unloadGame(); - emu.loadGame(settings.content.path); + emu.loadGame(settings.content.path.c_str()); emu.start(); } diff --git a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp index 0f2fa337b..609fa9de3 100644 --- a/core/linux-dist/main.cpp +++ b/core/linux-dist/main.cpp @@ -399,21 +399,19 @@ int main(int argc, char* argv[]) mainui_loop(); - flycast_term(); - - os_UninstallFaultHandler(); - #if defined(USE_EVDEV) input_evdev_close(); #endif - #if defined(SUPPORT_X11) x11_window_destroy(); #endif - #if defined(USE_SDL) sdl_window_destroy(); #endif + + flycast_term(); + os_UninstallFaultHandler(); + #if defined(__SWITCH__) socketExit(); #endif diff --git a/core/linux-dist/x11.cpp b/core/linux-dist/x11.cpp index cd98131f7..e9e1a2d39 100644 --- a/core/linux-dist/x11.cpp +++ b/core/linux-dist/x11.cpp @@ -279,7 +279,7 @@ void x11_window_create() int x11Screen = XDefaultScreen(x11_disp); float xdpi = (float)DisplayWidth(x11_disp, x11Screen) / DisplayWidthMM(x11_disp, x11Screen) * 25.4; float ydpi = (float)DisplayHeight(x11_disp, x11Screen) / DisplayHeightMM(x11_disp, x11Screen) * 25.4; - screen_dpi = std::max(xdpi, ydpi); + settings.display.dpi = std::max(xdpi, ydpi); int depth = CopyFromParent; diff --git a/core/lua/lua.cpp b/core/lua/lua.cpp index 6a3268264..291ed99b8 100644 --- a/core/lua/lua.cpp +++ b/core/lua/lua.cpp @@ -366,7 +366,7 @@ static void beginWindow(const char *title, int x, int y, int w, int h) ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0); ImGui::SetNextWindowPos(ImVec2(x, y)); - ImGui::SetNextWindowSize(ImVec2(w * scaling, h * scaling)); + ImGui::SetNextWindowSize(ImVec2(w * settings.display.uiScale, h * settings.display.uiScale)); ImGui::SetNextWindowBgAlpha(0.7f); ImGui::Begin(title, NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus); ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.557f, 0.268f, 0.965f, 1.f)); @@ -392,7 +392,7 @@ static void uiTextRightAligned(const std::string& text) static void uiBargraph(float v) { - ImGui::ProgressBar(v, ImVec2(-1, 10.f * scaling), ""); + ImGui::ProgressBar(v, ImVec2(-1, 10.f * settings.display.uiScale), ""); } static int uiButton(lua_State *L) diff --git a/core/network/ggpo.cpp b/core/network/ggpo.cpp index df0d8290b..e56c286c4 100644 --- a/core/network/ggpo.cpp +++ b/core/network/ggpo.cpp @@ -818,14 +818,14 @@ void displayStats() ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0); ImGui::SetNextWindowPos(ImVec2(10, 10)); - ImGui::SetNextWindowSize(ImVec2(95 * scaling, 0)); + ImGui::SetNextWindowSize(ImVec2(95 * settings.display.uiScale, 0)); ImGui::SetNextWindowBgAlpha(0.7f); ImGui::Begin("##ggpostats", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs); ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.557f, 0.268f, 0.965f, 1.f)); // Send Queue ImGui::Text("Send Q"); - ImGui::ProgressBar(stats.network.send_queue_len / 10.f, ImVec2(-1, 10.f * scaling), ""); + ImGui::ProgressBar(stats.network.send_queue_len / 10.f, ImVec2(-1, 10.f * settings.display.uiScale), ""); // Frame Delay ImGui::Text("Delay"); @@ -847,7 +847,7 @@ void displayStats() // yellow ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(.9f, .9f, .1f, 1)); ImGui::Text("Predicted"); - ImGui::ProgressBar(stats.sync.predicted_frames / 7.f, ImVec2(-1, 10.f * scaling), ""); + ImGui::ProgressBar(stats.sync.predicted_frames / 7.f, ImVec2(-1, 10.f * settings.display.uiScale), ""); if (stats.sync.predicted_frames >= 5) ImGui::PopStyleColor(); @@ -856,7 +856,7 @@ void displayStats() if (timesync > 0) ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1, 0, 0, 1)); ImGui::Text("Behind"); - ImGui::ProgressBar(0.5f + stats.timesync.local_frames_behind / 16.f, ImVec2(-1, 10.f * scaling), ""); + ImGui::ProgressBar(0.5f + stats.timesync.local_frames_behind / 16.f, ImVec2(-1, 10.f * settings.display.uiScale), ""); if (timesync > 0) { ImGui::PopStyleColor(); diff --git a/core/nullDC.cpp b/core/nullDC.cpp index fc173c92f..87cb2d108 100644 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -44,7 +44,7 @@ int flycast_init(int argc, char* argv[]) LogManager::Init(); config::Settings::instance().load(false); } - + gui_init(); os_CreateWindow(); os_SetupInput(); @@ -76,6 +76,7 @@ void flycast_term() gui_cancel_load(); lua::term(); emu.term(); + gui_term(); } void dc_savestate(int index) diff --git a/core/rend/dx11/dx11_driver.h b/core/rend/dx11/dx11_driver.h index d382f27b7..939f713c7 100644 --- a/core/rend/dx11/dx11_driver.h +++ b/core/rend/dx11/dx11_driver.h @@ -25,6 +25,14 @@ class DX11Driver final : public ImGuiDriver { public: + DX11Driver(ID3D11Device* device, ID3D11DeviceContext* deviceContext) { + ImGui_ImplDX11_Init(device, deviceContext); + } + + ~DX11Driver() { + ImGui_ImplDX11_Shutdown(); + } + void newFrame() override { ImGui_ImplDX11_NewFrame(); } diff --git a/core/rend/dx11/dx11_overlay.cpp b/core/rend/dx11/dx11_overlay.cpp index 6e16b7e71..eea4c4254 100644 --- a/core/rend/dx11/dx11_overlay.cpp +++ b/core/rend/dx11/dx11_overlay.cpp @@ -20,22 +20,16 @@ #include "rend/osd.h" #ifdef LIBRETRO #include "vmu_xhair.h" -#else -#include "rend/gui.h" #endif void DX11Overlay::draw(u32 width, u32 height, bool vmu, bool crosshair) { -#ifdef LIBRETRO - const float scaling = 1; -#endif - RECT rect { 0, 0, (LONG)width, (LONG)height }; deviceContext->RSSetScissorRects(1, &rect); if (vmu) { - float vmu_padding = 8.f * scaling; - float vmu_height = 70.f * scaling; + float vmu_padding = 8.f * settings.display.uiScale; + float vmu_height = 70.f * settings.display.uiScale; float vmu_width = 48.f / 32.f * vmu_height; #ifndef LIBRETRO @@ -178,7 +172,7 @@ void DX11Overlay::draw(u32 width, u32 height, bool vmu, bool crosshair) #ifdef LIBRETRO float halfWidth = LIGHTGUN_CROSSHAIR_SIZE / 2.f; #else - float halfWidth = XHAIR_WIDTH * gui_get_scaling() / 2.f; + float halfWidth = XHAIR_WIDTH * settings.display.uiScale / 2.f; #endif D3D11_VIEWPORT vp{}; vp.TopLeftX = x - halfWidth; diff --git a/core/rend/dx11/dx11context.cpp b/core/rend/dx11/dx11context.cpp index ed05693f2..c7b6e3592 100644 --- a/core/rend/dx11/dx11context.cpp +++ b/core/rend/dx11/dx11context.cpp @@ -18,7 +18,6 @@ */ #include "dx11context.h" #ifndef LIBRETRO -#include "rend/gui.h" #include "rend/osd.h" #ifdef USE_SDL #include "sdl/sdl.h" @@ -26,6 +25,7 @@ #include "hw/pvr/Renderer_if.h" #include "emulator.h" #include "dx11_driver.h" +#include "imgui_impl_dx11.h" #ifdef TARGET_UWP #include #include @@ -53,12 +53,10 @@ bool DX11Context::init(bool keepCurrentWindow) settings.display.height = displayMode->ResolutionHeightInRawPixels; if (settings.display.width == 3840) // 4K - scaling = 2.8f; + settings.display.uiScale = 2.8f; else - scaling = 1.4f; + settings.display.uiScale = 1.4f; } - else - scaling = 1.f; #endif D3D_FEATURE_LEVEL featureLevels[] = @@ -158,12 +156,12 @@ bool DX11Context::init(bool keepCurrentWindow) NOTICE_LOG(RENDERER, "No system-provided shader cache"); } - imguiDriver = std::unique_ptr(new DX11Driver()); + imguiDriver = std::unique_ptr(new DX11Driver(pDevice, pDeviceContext)); resize(); - gui_init(); shaders.init(pDevice, &D3DCompile); overlay.init(pDevice, pDeviceContext, &shaders, &samplers); - return ImGui_ImplDX11_Init(pDevice, pDeviceContext); + + return true; } void DX11Context::term() @@ -174,8 +172,6 @@ void DX11Context::term() samplers.term(); shaders.term(); imguiDriver.reset(); - ImGui_ImplDX11_Shutdown(); - gui_term(); renderTargetView.reset(); swapchain1.reset(); swapchain.reset(); diff --git a/core/rend/dx11/dx11context.h b/core/rend/dx11/dx11context.h index 4d734f689..5861d21b1 100644 --- a/core/rend/dx11/dx11context.h +++ b/core/rend/dx11/dx11context.h @@ -25,7 +25,6 @@ #include #include #include -#include "imgui_impl_dx11.h" #include "windows/comptr.h" #include "dx11_overlay.h" #include "wsi/context.h" diff --git a/core/rend/dx9/d3d_overlay.cpp b/core/rend/dx9/d3d_overlay.cpp index c90d53c51..c183c7dae 100644 --- a/core/rend/dx9/d3d_overlay.cpp +++ b/core/rend/dx9/d3d_overlay.cpp @@ -18,7 +18,6 @@ */ #include "d3d_overlay.h" #include "rend/osd.h" -#include "rend/gui.h" #include #include @@ -39,8 +38,8 @@ void D3DOverlay::draw(u32 width, u32 height, bool vmu, bool crosshair) setupRenderState(width, height); if (vmu) { - float vmu_padding = 8.f * scaling; - float vmu_height = 70.f * scaling; + float vmu_padding = 8.f * settings.display.uiScale; + float vmu_height = 70.f * settings.display.uiScale; float vmu_width = 48.f / 32.f * vmu_height; for (size_t i = 0; i < vmuTextures.size(); i++) @@ -118,7 +117,7 @@ void D3DOverlay::draw(u32 width, u32 height, bool vmu, bool crosshair) float x, y; std::tie(x, y) = getCrosshairPosition(i); - float halfWidth = XHAIR_WIDTH * gui_get_scaling() / 2.f; + float halfWidth = XHAIR_WIDTH * settings.display.uiScale / 2.f; RECT rect { (long) (x - halfWidth), (long) (y - halfWidth), (long) (x + halfWidth), (long) (y + halfWidth) }; D3DCOLOR color = (config::CrosshairColor[i] & 0xFF00FF00) | ((config::CrosshairColor[i] >> 16) & 0xFF) diff --git a/core/rend/dx9/dx9_driver.h b/core/rend/dx9/dx9_driver.h index deb27c5cd..c018dd352 100644 --- a/core/rend/dx9/dx9_driver.h +++ b/core/rend/dx9/dx9_driver.h @@ -24,7 +24,15 @@ class DX9Driver final : public ImGuiDriver { public: - void newFrame() override { + DX9Driver(IDirect3DDevice9* device) { + ImGui_ImplDX9_Init(device); + } + + ~DX9Driver() { + ImGui_ImplDX9_Shutdown(); + } + + void newFrame() override { ImGui_ImplDX9_NewFrame(); } diff --git a/core/rend/dx9/dxcontext.cpp b/core/rend/dx9/dxcontext.cpp index 98d93c735..b3bc17260 100644 --- a/core/rend/dx9/dxcontext.cpp +++ b/core/rend/dx9/dxcontext.cpp @@ -18,7 +18,6 @@ */ #include "dxcontext.h" #include "d3d_renderer.h" -#include "rend/gui.h" #include "rend/osd.h" #ifdef USE_SDL #include "sdl/sdl.h" @@ -26,6 +25,7 @@ #include "hw/pvr/Renderer_if.h" #include "emulator.h" #include "dx9_driver.h" +#include "imgui_impl_dx9.h" DXContext theDXContext; @@ -74,10 +74,10 @@ bool DXContext::init(bool keepCurrentWindow) if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, (HWND)window, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &pDevice.get()))) return false; - imguiDriver = std::unique_ptr(new DX9Driver()); - gui_init(); + imguiDriver = std::unique_ptr(new DX9Driver(pDevice)); overlay.init(pDevice); - return ImGui_ImplDX9_Init(pDevice.get()); + + return true; } void DXContext::term() @@ -85,8 +85,6 @@ void DXContext::term() GraphicsContext::instance = nullptr; overlay.term(); imguiDriver.reset(); - ImGui_ImplDX9_Shutdown(); - gui_term(); pDevice.reset(); pD3D.reset(); } diff --git a/core/rend/dx9/dxcontext.h b/core/rend/dx9/dxcontext.h index 9f10a5d10..58044c2c5 100644 --- a/core/rend/dx9/dxcontext.h +++ b/core/rend/dx9/dxcontext.h @@ -22,7 +22,6 @@ #include "types.h" #include #include -#include "imgui_impl_dx9.h" #include "windows/comptr.h" #include "d3d_overlay.h" #include "wsi/context.h" diff --git a/core/rend/gles/opengl_driver.cpp b/core/rend/gles/opengl_driver.cpp index 816dc386a..90a07ead9 100644 --- a/core/rend/gles/opengl_driver.cpp +++ b/core/rend/gles/opengl_driver.cpp @@ -76,9 +76,9 @@ void OpenGLDriver::displayVmus() ImGui::Begin("vmu-window", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoFocusOnAppearing); - const float width = VMU_WIDTH * scaling; - const float height = VMU_HEIGHT * scaling; - const float padding = VMU_PADDING * scaling; + const float width = VMU_WIDTH * settings.display.uiScale; + const float height = VMU_HEIGHT * settings.display.uiScale; + const float padding = VMU_PADDING * settings.display.uiScale; for (int i = 0; i < 8; i++) { if (!vmu_lcd_status[i]) @@ -137,9 +137,9 @@ void OpenGLDriver::displayCrosshairs() ImVec2 pos; std::tie(pos.x, pos.y) = getCrosshairPosition(i); - pos.x -= (XHAIR_WIDTH * scaling) / 2.f; - pos.y += (XHAIR_WIDTH * scaling) / 2.f; - ImVec2 pos_b(pos.x + XHAIR_WIDTH * scaling, pos.y - XHAIR_HEIGHT * scaling); + pos.x -= (XHAIR_WIDTH * settings.display.uiScale) / 2.f; + pos.y += (XHAIR_WIDTH * settings.display.uiScale) / 2.f; + ImVec2 pos_b(pos.x + XHAIR_WIDTH * settings.display.uiScale, pos.y - XHAIR_HEIGHT * settings.display.uiScale); ImGui::GetWindowDrawList()->AddImage(crosshairTexId, pos, pos_b, ImVec2(0, 1), ImVec2(1, 0), config::CrosshairColor[i]); } diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index cf4fa4c36..2ddbc9860 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -47,12 +47,10 @@ static bool game_started; -int screen_dpi = 96; int insetLeft, insetRight, insetTop, insetBottom; std::unique_ptr imguiDriver; static bool inited = false; -float scaling = 1; GuiState gui_state = GuiState::Main; static bool commandLineStart; static u32 mouseButtons; @@ -138,7 +136,19 @@ void gui_init() #if defined(__ANDROID__) || defined(TARGET_IPHONE) ImGui::GetStyle().TouchExtraPadding = ImVec2(1, 1); // from 0,0 #endif + EventManager::listen(Event::Resume, emuEventCallback); + EventManager::listen(Event::Start, emuEventCallback); + EventManager::listen(Event::Terminate, emuEventCallback); + ggpo::receiveChatMessages([](int playerNum, const std::string& msg) { chat.receive(playerNum, msg); }); +} +void gui_initFonts() +{ + static float uiScale; + + verify(inited); + if (settings.display.uiScale == uiScale && ImGui::GetIO().Fonts->IsBuilt()) + return; // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. @@ -153,14 +163,15 @@ void gui_init() //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != NULL); -#if !defined(_WIN32) && !defined(__SWITCH__) - scaling = std::max(1.f, screen_dpi / 100.f * 0.75f); +#if !defined(TARGET_UWP) && !defined(__SWITCH__) + settings.display.uiScale = std::max(1.f, settings.display.dpi / 100.f * 0.75f); // Limit scaling on small low-res screens if (settings.display.width <= 640 || settings.display.height <= 480) - scaling = std::min(1.2f, scaling); + settings.display.uiScale = std::min(1.4f, settings.display.uiScale); #endif - if (scaling > 1) - ImGui::GetStyle().ScaleAllSizes(scaling); + uiScale = settings.display.uiScale; + if (settings.display.uiScale > 1) + ImGui::GetStyle().ScaleAllSizes(settings.display.uiScale); static const ImWchar ranges[] = { @@ -168,7 +179,10 @@ void gui_init() 0, }; - io.Fonts->AddFontFromMemoryCompressedTTF(roboto_medium_compressed_data, roboto_medium_compressed_size, 17.f * scaling, nullptr, ranges); + ImGuiIO& io = ImGui::GetIO(); + io.Fonts->Clear(); + const float fontSize = 17.f * settings.display.uiScale; + io.Fonts->AddFontFromMemoryCompressedTTF(roboto_medium_compressed_data, roboto_medium_compressed_size, fontSize, nullptr, ranges); ImFontConfig font_cfg; font_cfg.MergeMode = true; #ifdef _WIN32 @@ -179,33 +193,33 @@ void gui_init() case 932: // Japanese { font_cfg.FontNo = 2; // UIGothic - ImFont* font = io.Fonts->AddFontFromFileTTF((fontDir + "msgothic.ttc").c_str(), 17.f * scaling, &font_cfg, io.Fonts->GetGlyphRangesJapanese()); + ImFont* font = io.Fonts->AddFontFromFileTTF((fontDir + "msgothic.ttc").c_str(), fontSize, &font_cfg, io.Fonts->GetGlyphRangesJapanese()); font_cfg.FontNo = 2; // Meiryo UI if (font == nullptr) - io.Fonts->AddFontFromFileTTF((fontDir + "Meiryo.ttc").c_str(), 17.f * scaling, &font_cfg, io.Fonts->GetGlyphRangesJapanese()); + io.Fonts->AddFontFromFileTTF((fontDir + "Meiryo.ttc").c_str(), fontSize, &font_cfg, io.Fonts->GetGlyphRangesJapanese()); } break; case 949: // Korean { - ImFont* font = io.Fonts->AddFontFromFileTTF((fontDir + "Malgun.ttf").c_str(), 17.f * scaling, &font_cfg, io.Fonts->GetGlyphRangesKorean()); + ImFont* font = io.Fonts->AddFontFromFileTTF((fontDir + "Malgun.ttf").c_str(), fontSize, &font_cfg, io.Fonts->GetGlyphRangesKorean()); if (font == nullptr) { font_cfg.FontNo = 2; // Dotum - io.Fonts->AddFontFromFileTTF((fontDir + "Gulim.ttc").c_str(), 17.f * scaling, &font_cfg, io.Fonts->GetGlyphRangesKorean()); + io.Fonts->AddFontFromFileTTF((fontDir + "Gulim.ttc").c_str(), fontSize, &font_cfg, io.Fonts->GetGlyphRangesKorean()); } } break; case 950: // Traditional Chinese { font_cfg.FontNo = 1; // Microsoft JhengHei UI Regular - ImFont* font = io.Fonts->AddFontFromFileTTF((fontDir + "Msjh.ttc").c_str(), 17.f * scaling, &font_cfg, GetGlyphRangesChineseTraditionalOfficial()); + ImFont* font = io.Fonts->AddFontFromFileTTF((fontDir + "Msjh.ttc").c_str(), fontSize, &font_cfg, GetGlyphRangesChineseTraditionalOfficial()); font_cfg.FontNo = 0; if (font == nullptr) - io.Fonts->AddFontFromFileTTF((fontDir + "MSJH.ttf").c_str(), 17.f * scaling, &font_cfg, GetGlyphRangesChineseTraditionalOfficial()); + io.Fonts->AddFontFromFileTTF((fontDir + "MSJH.ttf").c_str(), fontSize, &font_cfg, GetGlyphRangesChineseTraditionalOfficial()); } break; case 936: // Simplified Chinese - io.Fonts->AddFontFromFileTTF((fontDir + "Simsun.ttc").c_str(), 17.f * scaling, &font_cfg, GetGlyphRangesChineseSimplifiedOfficial()); + io.Fonts->AddFontFromFileTTF((fontDir + "Simsun.ttc").c_str(), fontSize, &font_cfg, GetGlyphRangesChineseSimplifiedOfficial()); break; default: break; @@ -218,19 +232,19 @@ void gui_init() if (locale.find("ja") == 0) // Japanese { - io.Fonts->AddFontFromFileTTF((fontDir + "ヒラギノ角ゴシック W4.ttc").c_str(), 17.f * scaling, &font_cfg, io.Fonts->GetGlyphRangesJapanese()); + io.Fonts->AddFontFromFileTTF((fontDir + "ヒラギノ角ゴシック W4.ttc").c_str(), fontSize, &font_cfg, io.Fonts->GetGlyphRangesJapanese()); } else if (locale.find("ko") == 0) // Korean { - io.Fonts->AddFontFromFileTTF((fontDir + "AppleSDGothicNeo.ttc").c_str(), 17.f * scaling, &font_cfg, io.Fonts->GetGlyphRangesKorean()); + io.Fonts->AddFontFromFileTTF((fontDir + "AppleSDGothicNeo.ttc").c_str(), fontSize, &font_cfg, io.Fonts->GetGlyphRangesKorean()); } else if (locale.find("zh-Hant") == 0) // Traditional Chinese { - io.Fonts->AddFontFromFileTTF((fontDir + "PingFang.ttc").c_str(), 17.f * scaling, &font_cfg, GetGlyphRangesChineseTraditionalOfficial()); + io.Fonts->AddFontFromFileTTF((fontDir + "PingFang.ttc").c_str(), fontSize, &font_cfg, GetGlyphRangesChineseTraditionalOfficial()); } else if (locale.find("zh-Hans") == 0) // Simplified Chinese { - io.Fonts->AddFontFromFileTTF((fontDir + "PingFang.ttc").c_str(), 17.f * scaling, &font_cfg, GetGlyphRangesChineseSimplifiedOfficial()); + io.Fonts->AddFontFromFileTTF((fontDir + "PingFang.ttc").c_str(), fontSize, &font_cfg, GetGlyphRangesChineseSimplifiedOfficial()); } #elif defined(__ANDROID__) if (getenv("FLYCAST_LOCALE") != nullptr) @@ -248,17 +262,12 @@ void gui_init() glyphRanges = GetGlyphRangesChineseSimplifiedOfficial(); if (glyphRanges != nullptr) - io.Fonts->AddFontFromFileTTF("/system/fonts/NotoSansCJK-Regular.ttc", 17.f * scaling, &font_cfg, glyphRanges); + io.Fonts->AddFontFromFileTTF("/system/fonts/NotoSansCJK-Regular.ttc", fontSize, &font_cfg, glyphRanges); } // TODO Linux, iOS, ... #endif - NOTICE_LOG(RENDERER, "Screen DPI is %d, size %d x %d. Scaling by %.2f", screen_dpi, settings.display.width, settings.display.height, scaling); - - EventManager::listen(Event::Resume, emuEventCallback); - EventManager::listen(Event::Start, emuEventCallback); - EventManager::listen(Event::Terminate, emuEventCallback); - ggpo::receiveChatMessages([](int playerNum, const std::string& msg) { chat.receive(playerNum, msg); }); + NOTICE_LOG(RENDERER, "Screen DPI is %.0f, size %d x %d. Scaling by %.2f", settings.display.dpi, settings.display.width, settings.display.height, settings.display.uiScale); } void gui_keyboard_input(u16 wc) @@ -490,7 +499,7 @@ static void gui_display_commands() imguiDriver->displayVmus(); centerNextWindow(); - ImGui::SetNextWindowSize(ImVec2(330 * scaling, 0)); + ImGui::SetNextWindowSize(ScaledVec2(330, 0)); ImGui::Begin("##commands", NULL, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize); @@ -502,7 +511,7 @@ static void gui_display_commands() } // Load State - if (ImGui::Button("Load State", ImVec2(110 * scaling, 50 * scaling)) && !loadSaveStateDisabled) + if (ImGui::Button("Load State", ScaledVec2(110, 50)) && !loadSaveStateDisabled) { gui_state = GuiState::Closed; dc_loadstate(config::SavestateSlot); @@ -511,7 +520,7 @@ static void gui_display_commands() // Slot # std::string slot = "Slot " + std::to_string((int)config::SavestateSlot + 1); - if (ImGui::Button(slot.c_str(), ImVec2(80 * scaling - ImGui::GetStyle().FramePadding.x, 50 * scaling))) + if (ImGui::Button(slot.c_str(), ImVec2(80 * settings.display.uiScale - ImGui::GetStyle().FramePadding.x, 50 * settings.display.uiScale))) ImGui::OpenPopup("slot_select_popup"); if (ImGui::BeginPopup("slot_select_popup")) { @@ -526,7 +535,7 @@ static void gui_display_commands() ImGui::SameLine(); // Save State - if (ImGui::Button("Save State", ImVec2(110 * scaling, 50 * scaling)) && !loadSaveStateDisabled) + if (ImGui::Button("Save State", ScaledVec2(110, 50)) && !loadSaveStateDisabled) { gui_state = GuiState::Closed; dc_savestate(config::SavestateSlot); @@ -540,12 +549,12 @@ static void gui_display_commands() ImGui::Columns(2, "buttons", false); // Settings - if (ImGui::Button("Settings", ImVec2(150 * scaling, 50 * scaling))) + if (ImGui::Button("Settings", ScaledVec2(150, 50))) { gui_state = GuiState::Settings; } ImGui::NextColumn(); - if (ImGui::Button("Resume", ImVec2(150 * scaling, 50 * scaling))) + if (ImGui::Button("Resume", ScaledVec2(150, 50))) { GamepadDevice::load_system_mappings(); gui_state = GuiState::Closed; @@ -555,7 +564,7 @@ static void gui_display_commands() // Insert/Eject Disk const char *disk_label = libGDR_GetDiscType() == Open ? "Insert Disk" : "Eject Disk"; - if (ImGui::Button(disk_label, ImVec2(150 * scaling, 50 * scaling))) + if (ImGui::Button(disk_label, ScaledVec2(150, 50))) { if (libGDR_GetDiscType() == Open) { @@ -575,7 +584,7 @@ static void gui_display_commands() ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); } - if (ImGui::Button("Cheats", ImVec2(150 * scaling, 50 * scaling)) && !settings.network.online) + if (ImGui::Button("Cheats", ScaledVec2(150, 50)) && !settings.network.online) { gui_state = GuiState::Cheats; } @@ -587,8 +596,8 @@ static void gui_display_commands() ImGui::Columns(1, nullptr, false); // Exit - if (ImGui::Button("Exit", ImVec2(300 * scaling + ImGui::GetStyle().ColumnsMinSpacing + ImGui::GetStyle().FramePadding.x * 2 - 1, - 50 * scaling))) + if (ImGui::Button("Exit", ScaledVec2(300, 50) + + ImVec2(ImGui::GetStyle().ColumnsMinSpacing + ImGui::GetStyle().FramePadding.x * 2 - 1, 0))) { gui_stop_game(); } @@ -835,7 +844,7 @@ static DreamcastKey getOppositeDirectionKey(DreamcastKey key) } static void detect_input_popup(const Mapping *mapping) { - ImVec2 padding = ImVec2(20 * scaling, 20 * scaling); + ImVec2 padding = ScaledVec2(20, 20); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, padding); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, padding); if (ImGui::BeginPopupModal("Map Control", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove)) @@ -914,12 +923,13 @@ static void controller_mapping_popup(const std::shared_ptr& gamep const float col_width = (winWidth - style.GrabMinSize - style.ItemSpacing.x - (ImGui::CalcTextSize("Map").x + style.FramePadding.x * 2.0f + style.ItemSpacing.x) - (ImGui::CalcTextSize("Unmap").x + style.FramePadding.x * 2.0f + style.ItemSpacing.x)) / 2; + const float scaling = settings.display.uiScale; static int item_current_map_idx = 0; static int last_item_current_map_idx = 2; std::shared_ptr input_mapping = gamepad->get_input_mapping(); - if (input_mapping == NULL || ImGui::Button("Done", ImVec2(100 * scaling, 30 * scaling))) + if (input_mapping == NULL || ImGui::Button("Done", ScaledVec2(100, 30))) { ImGui::CloseCurrentPopup(); gamepad->save_mapping(map_system); @@ -964,7 +974,7 @@ static void controller_mapping_popup(const std::shared_ptr& gamep { if (gamepad->isPerGameMapping()) { - if (ImGui::Button("Delete Game Config", ImVec2(0, 30 * scaling))) + if (ImGui::Button("Delete Game Config", ScaledVec2(0, 30))) { gamepad->setPerGameMapping(false); if (!gamepad->find_mapping(map_system)) @@ -973,15 +983,15 @@ static void controller_mapping_popup(const std::shared_ptr& gamep } else { - if (ImGui::Button("Make Game Config", ImVec2(0, 30 * scaling))) + if (ImGui::Button("Make Game Config", ScaledVec2(0, 30))) gamepad->setPerGameMapping(true); } ImGui::SameLine(); } - if (ImGui::Button("Reset...", ImVec2(100 * scaling, 30 * scaling))) + if (ImGui::Button("Reset...", ScaledVec2(100, 30))) ImGui::OpenPopup("Confirm Reset"); - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20 * scaling, 20 * scaling)); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ScaledVec2(20, 20)); if (ImGui::BeginPopupModal("Confirm Reset", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove)) { ImGui::Text("Are you sure you want to reset the mappings to default?"); @@ -997,7 +1007,7 @@ static void controller_mapping_popup(const std::shared_ptr& gamep } ImGui::NewLine(); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(20 * scaling, ImGui::GetStyle().ItemSpacing.y)); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10 * scaling, 10 * scaling)); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ScaledVec2(10, 10)); if (ImGui::Button("Yes")) { gamepad->resetMappingToDefault(arcade_button_mode, !hitbox); @@ -1124,18 +1134,18 @@ void error_popup() { if (!error_msg_shown && !error_msg.empty()) { - ImVec2 padding = ImVec2(20 * scaling, 20 * scaling); + ImVec2 padding = ScaledVec2(20, 20); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, padding); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, padding); ImGui::OpenPopup("Error"); if (ImGui::BeginPopupModal("Error", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar)) { - ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + 400.f * scaling); + ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + 400.f * settings.display.uiScale); ImGui::TextWrapped("%s", error_msg.c_str()); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(16 * scaling, 3 * scaling)); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ScaledVec2(16, 3)); float currentwidth = ImGui::GetContentRegionAvail().x; - ImGui::SetCursorPosX((currentwidth - 80.f * scaling) / 2.f + ImGui::GetStyle().WindowPadding.x); - if (ImGui::Button("OK", ImVec2(80.f * scaling, 0.f))) + ImGui::SetCursorPosX((currentwidth - 80.f * settings.display.uiScale) / 2.f + ImGui::GetStyle().WindowPadding.x); + if (ImGui::Button("OK", ScaledVec2(80.f, 0))) { error_msg.clear(); ImGui::CloseCurrentPopup(); @@ -1160,12 +1170,12 @@ static void contentpath_warning_popup() ImGui::OpenPopup("Incorrect Content Location?"); if (ImGui::BeginPopupModal("Incorrect Content Location?", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove)) { - ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + 400.f * scaling); + ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + 400.f * settings.display.uiScale); ImGui::TextWrapped(" Scanned %d folders but no game can be found! ", scanner.empty_folders_scanned); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(16 * scaling, 3 * scaling)); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ScaledVec2(16, 3)); float currentwidth = ImGui::GetContentRegionAvail().x; - ImGui::SetCursorPosX((currentwidth - 100.f * scaling) / 2.f + ImGui::GetStyle().WindowPadding.x - 55.f * scaling); - if (ImGui::Button("Reselect", ImVec2(100.f * scaling, 0.f))) + ImGui::SetCursorPosX((currentwidth - 100.f * settings.display.uiScale) / 2.f + ImGui::GetStyle().WindowPadding.x - 55.f * settings.display.uiScale); + if (ImGui::Button("Reselect", ScaledVec2(100.f, 0))) { scanner.content_path_looks_incorrect = false; ImGui::CloseCurrentPopup(); @@ -1173,8 +1183,8 @@ static void contentpath_warning_popup() } ImGui::SameLine(); - ImGui::SetCursorPosX((currentwidth - 100.f * scaling) / 2.f + ImGui::GetStyle().WindowPadding.x + 55.f * scaling); - if (ImGui::Button("Cancel", ImVec2(100.f * scaling, 0.f))) + ImGui::SetCursorPosX((currentwidth - 100.f * settings.display.uiScale) / 2.f + ImGui::GetStyle().WindowPadding.x + 55.f * settings.display.uiScale); + if (ImGui::Button("Cancel", ScaledVec2(100.f, 0))) { scanner.content_path_looks_incorrect = false; ImGui::CloseCurrentPopup(); @@ -1215,7 +1225,7 @@ static void gui_display_settings() | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse); ImVec2 normal_padding = ImGui::GetStyle().FramePadding; - if (ImGui::Button("Done", ImVec2(100 * scaling, 30 * scaling))) + if (ImGui::Button("Done", ScaledVec2(100, 30))) { if (game_started) gui_state = GuiState::Commands; @@ -1235,10 +1245,10 @@ static void gui_display_settings() if (game_started) { ImGui::SameLine(); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(16 * scaling, normal_padding.y)); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(16 * settings.display.uiScale, normal_padding.y)); if (config::Settings::instance().hasPerGameConfig()) { - if (ImGui::Button("Delete Game Config", ImVec2(0, 30 * scaling))) + if (ImGui::Button("Delete Game Config", ScaledVec2(0, 30))) { config::Settings::instance().setPerGameConfig(false); config::Settings::instance().load(false); @@ -1247,13 +1257,13 @@ static void gui_display_settings() } else { - if (ImGui::Button("Make Game Config", ImVec2(0, 30 * scaling))) + if (ImGui::Button("Make Game Config", ScaledVec2(0, 30))) config::Settings::instance().setPerGameConfig(true); } ImGui::PopStyleVar(); } - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(16 * scaling, 6 * scaling)); // from 4, 3 + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ScaledVec2(16, 6)); if (ImGui::BeginTabBar("settings", ImGuiTabBarFlags_NoTooltip)) { @@ -1317,7 +1327,7 @@ static void gui_display_settings() to_delete = i; ImGui::PopID(); } - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(24 * scaling, 3 * scaling)); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ScaledVec2(24, 3)); if (ImGui::Button("Add")) ImGui::OpenPopup("Select Directory"); select_file_popup("Select Directory", [](bool cancelled, std::string selection) @@ -1450,9 +1460,9 @@ static void gui_display_settings() #endif if (gamepad->is_rumble_enabled()) { - ImGui::SameLine(0, 16 * scaling); + ImGui::SameLine(0, 16 * settings.display.uiScale); int power = gamepad->get_rumble_power(); - ImGui::SetNextItemWidth(150 * scaling); + ImGui::SetNextItemWidth(150 * settings.display.uiScale); if (ImGui::SliderInt("Rumble", &power, 0, 100)) gamepad->set_rumble_power(power); } @@ -2217,15 +2227,15 @@ static void gui_display_content() ImGui::Begin("##main", NULL, ImGuiWindowFlags_NoDecoration); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(20 * scaling, 8 * scaling)); // from 8, 4 + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ScaledVec2(20, 8)); ImGui::AlignTextToFramePadding(); - ImGui::Indent(10 * scaling); + ImGui::Indent(10 * settings.display.uiScale); ImGui::Text("GAMES"); - ImGui::Unindent(10 * scaling); + ImGui::Unindent(10 * settings.display.uiScale); static ImGuiTextFilter filter; #if !defined(__ANDROID__) && !defined(TARGET_IPHONE) && !defined(TARGET_UWP) - ImGui::SameLine(0, 32 * scaling); + ImGui::SameLine(0, 32 * settings.display.uiScale); filter.Draw("Filter"); #endif if (gui_state != GuiState::SelectDisk) @@ -2249,7 +2259,7 @@ static void gui_display_content() // Only if Filter and Settings aren't focused... ImGui::SetNextWindowFocus(); ImGui::BeginChild(ImGui::GetID("library"), ImVec2(0, 0), true, ImGuiWindowFlags_DragScrolling); { - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8 * scaling, 20 * scaling)); // from 8, 4 + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ScaledVec2(8, 20)); ImGui::PushID("bios"); if (ImGui::Selectable("Dreamcast BIOS")) @@ -2373,13 +2383,13 @@ static std::future networkStatus; static void gui_network_start() { centerNextWindow(); - ImGui::SetNextWindowSize(ImVec2(330 * scaling, 180 * scaling)); + ImGui::SetNextWindowSize(ScaledVec2(330, 180)); ImGui::Begin("##network", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(20 * scaling, 10 * scaling)); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ScaledVec2(20, 10)); ImGui::AlignTextToFramePadding(); - ImGui::SetCursorPosX(20.f * scaling); + ImGui::SetCursorPosX(20.f * settings.display.uiScale); if (networkStatus.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready) { @@ -2410,9 +2420,9 @@ static void gui_network_start() ImGui::Text("%s", get_notification().c_str()); float currentwidth = ImGui::GetContentRegionAvail().x; - ImGui::SetCursorPosX((currentwidth - 100.f * scaling) / 2.f + ImGui::GetStyle().WindowPadding.x); - ImGui::SetCursorPosY(126.f * scaling); - if (ImGui::Button("Cancel", ImVec2(100.f * scaling, 0.f))) + ImGui::SetCursorPosX((currentwidth - 100.f * settings.display.uiScale) / 2.f + ImGui::GetStyle().WindowPadding.x); + ImGui::SetCursorPosY(126.f * settings.display.uiScale); + if (ImGui::Button("Cancel", ScaledVec2(100.f, 0))) { NetworkHandshake::instance->stop(); try { @@ -2434,13 +2444,13 @@ static void gui_network_start() static void gui_display_loadscreen() { centerNextWindow(); - ImGui::SetNextWindowSize(ImVec2(330 * scaling, 180 * scaling)); + ImGui::SetNextWindowSize(ScaledVec2(330, 180)); ImGui::Begin("##loading", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(20 * scaling, 10 * scaling)); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ScaledVec2(20, 10)); ImGui::AlignTextToFramePadding(); - ImGui::SetCursorPosX(20.f * scaling); + ImGui::SetCursorPosX(20.f * settings.display.uiScale); try { if (gameLoader.ready()) { @@ -2462,13 +2472,13 @@ static void gui_display_loadscreen() label = "Loading..."; ImGui::Text("%s", label); ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.557f, 0.268f, 0.965f, 1.f)); - ImGui::ProgressBar(gameLoader.getProgress().progress, ImVec2(-1, 20.f * scaling), ""); + ImGui::ProgressBar(gameLoader.getProgress().progress, ImVec2(-1, 20.f * settings.display.uiScale), ""); ImGui::PopStyleColor(); float currentwidth = ImGui::GetContentRegionAvail().x; - ImGui::SetCursorPosX((currentwidth - 100.f * scaling) / 2.f + ImGui::GetStyle().WindowPadding.x); - ImGui::SetCursorPosY(126.f * scaling); - if (ImGui::Button("Cancel", ImVec2(100.f * scaling, 0.f))) + ImGui::SetCursorPosX((currentwidth - 100.f * settings.display.uiScale) / 2.f + ImGui::GetStyle().WindowPadding.x); + ImGui::SetCursorPosY(126.f * settings.display.uiScale); + if (ImGui::Button("Cancel", ScaledVec2(100.f, 0))) gameLoader.cancel(); } } catch (const FlycastException& ex) { @@ -2526,7 +2536,7 @@ void gui_display_ui() break; case GuiState::VJoyEditCommands: #ifdef __ANDROID__ - gui_display_vjoy_commands(scaling); + gui_display_vjoy_commands(); #endif break; case GuiState::SelectDisk: diff --git a/core/rend/gui.h b/core/rend/gui.h index 4a91ba48c..24967afb3 100644 --- a/core/rend/gui.h +++ b/core/rend/gui.h @@ -21,6 +21,7 @@ #include "cfg/option.h" void gui_init(); +void gui_initFonts(); void gui_open_settings(); void gui_display_ui(); void gui_display_notification(const char *msg, int duration); @@ -45,9 +46,6 @@ void gui_start_game(const std::string& path); void gui_error(const std::string& what); void gui_setOnScreenKeyboardCallback(void (*callback)(bool show)); -extern int screen_dpi; -extern float scaling; - enum class GuiState { Closed, Commands, @@ -71,6 +69,3 @@ static inline bool gui_is_content_browser() { return gui_state == GuiState::Main; } -static inline float gui_get_scaling() { - return scaling; -} diff --git a/core/rend/gui_android.cpp b/core/rend/gui_android.cpp index 1f3e358de..05fec1f3f 100644 --- a/core/rend/gui_android.cpp +++ b/core/rend/gui_android.cpp @@ -29,27 +29,27 @@ void vjoy_reset_editing(); void vjoy_stop_editing(bool canceled); -void gui_display_vjoy_commands(float scaling) +void gui_display_vjoy_commands() { centerNextWindow(); ImGui::Begin("Virtual Joystick", NULL, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar); - if (ImGui::Button("Save", ImVec2(150 * scaling, 50 * scaling))) + if (ImGui::Button("Save", ScaledVec2(150, 50))) { vjoy_stop_editing(false); gui_state = GuiState::Settings; } ImGui::SameLine(); - if (ImGui::Button("Reset", ImVec2(150 * scaling, 50 * scaling))) + if (ImGui::Button("Reset", ScaledVec2(150, 50))) { vjoy_reset_editing(); gui_state = GuiState::VJoyEdit; } ImGui::SameLine(); - if (ImGui::Button("Cancel", ImVec2(150 * scaling, 50 * scaling))) + if (ImGui::Button("Cancel", ScaledVec2(150, 50))) { vjoy_stop_editing(true); gui_state = GuiState::Settings; diff --git a/core/rend/gui_android.h b/core/rend/gui_android.h index bf8d5a2a3..68e5cc074 100644 --- a/core/rend/gui_android.h +++ b/core/rend/gui_android.h @@ -18,5 +18,5 @@ */ #pragma once -void gui_display_vjoy_commands(float scaling); +void gui_display_vjoy_commands(); void vjoy_start_editing(); diff --git a/core/rend/gui_chat.h b/core/rend/gui_chat.h index 78f67348c..3389e0908 100644 --- a/core/rend/gui_chat.h +++ b/core/rend/gui_chat.h @@ -56,8 +56,8 @@ public: ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0); - ImGui::SetNextWindowPos(ImVec2((settings.display.width - 400 * scaling) / 2, settings.display.height - 220 * scaling), ImGuiCond_FirstUseEver); - ImGui::SetNextWindowSize(ImVec2(400 * scaling, 220 * scaling), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(settings.display.width / 2, settings.display.height) - ScaledVec2(200.f, 220.f), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ScaledVec2(400, 220), ImGuiCond_FirstUseEver); ImGui::SetNextWindowBgAlpha(0.7f); ImGui::SetNextWindowFocus(); if (ImGui::Begin("Chat", &visible, ImGuiWindowFlags_NoScrollbar)) diff --git a/core/rend/gui_cheats.cpp b/core/rend/gui_cheats.cpp index 57e1bfe55..661cb6890 100644 --- a/core/rend/gui_cheats.cpp +++ b/core/rend/gui_cheats.cpp @@ -28,14 +28,14 @@ static void addCheat() static char cheatName[64]; static char cheatCode[128]; centerNextWindow(); - ImGui::SetNextWindowSize(ImVec2(std::min(ImGui::GetIO().DisplaySize.x, 600 * scaling), std::min(ImGui::GetIO().DisplaySize.y, 400 * scaling))); + ImGui::SetNextWindowSize(min(ImGui::GetIO().DisplaySize, ScaledVec2(600.f, 400.f))); ImGui::Begin("##main", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(20 * scaling, 8 * scaling)); // from 8, 4 + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ScaledVec2(20, 8)); ImGui::AlignTextToFramePadding(); - ImGui::Indent(10 * scaling); + ImGui::Indent(10 * settings.display.uiScale); ImGui::Text("ADD CHEAT"); ImGui::SameLine(ImGui::GetWindowContentRegionMax().x - ImGui::CalcTextSize("Cancel").x - ImGui::GetStyle().FramePadding.x * 4.f @@ -55,7 +55,7 @@ static void addCheat() } } - ImGui::Unindent(10 * scaling); + ImGui::Unindent(10 * settings.display.uiScale); ImGui::PopStyleVar(); ImGui::BeginChild(ImGui::GetID("input"), ImVec2(0, 0), true); @@ -75,14 +75,14 @@ void gui_cheats() return; } centerNextWindow(); - ImGui::SetNextWindowSize(ImVec2(std::min(ImGui::GetIO().DisplaySize.x, 600 * scaling), std::min(ImGui::GetIO().DisplaySize.y, 400 * scaling))); + ImGui::SetNextWindowSize(min(ImGui::GetIO().DisplaySize, ScaledVec2(600.f, 400.f))); ImGui::Begin("##main", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(20 * scaling, 8 * scaling)); // from 8, 4 + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ScaledVec2(20, 8)); ImGui::AlignTextToFramePadding(); - ImGui::Indent(10 * scaling); + ImGui::Indent(10 * settings.display.uiScale); ImGui::Text("CHEATS"); ImGui::SameLine(ImGui::GetWindowContentRegionMax().x - ImGui::CalcTextSize("Add").x - ImGui::CalcTextSize("Close").x - ImGui::GetStyle().FramePadding.x * 6.f @@ -103,7 +103,7 @@ void gui_cheats() if (ImGui::Button("Close")) gui_state = GuiState::Commands; - ImGui::Unindent(10 * scaling); + ImGui::Unindent(10 * settings.display.uiScale); ImGui::PopStyleVar(); ImGui::BeginChild(ImGui::GetID("cheats"), ImVec2(0, 0), true, ImGuiWindowFlags_DragScrolling); diff --git a/core/rend/gui_util.cpp b/core/rend/gui_util.cpp index 3a620a773..e74cd6cba 100644 --- a/core/rend/gui_util.cpp +++ b/core/rend/gui_util.cpp @@ -215,10 +215,10 @@ void select_file_popup(const char *prompt, StringCallback callback, } ImGui::Text("%s", error_message.empty() ? select_current_directory.c_str() : error_message.c_str()); - ImGui::BeginChild(ImGui::GetID("dir_list"), ImVec2(0, - 30 * gui_get_scaling() - ImGui::GetStyle().ItemSpacing.y), + ImGui::BeginChild(ImGui::GetID("dir_list"), ImVec2(0, - 30 * settings.display.uiScale - ImGui::GetStyle().ItemSpacing.y), true, ImGuiWindowFlags_DragScrolling); - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8 * gui_get_scaling(), 20 * gui_get_scaling())); // from 8, 4 + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ScaledVec2(8, 20)); for (const auto& name : subfolders) @@ -302,7 +302,7 @@ void select_file_popup(const char *prompt, StringCallback callback, ImGui::EndChild(); if (!selectFile) { - if (ImGui::Button("Select Current Directory", ImVec2(0, 30 * gui_get_scaling()))) + if (ImGui::Button("Select Current Directory", ScaledVec2(0, 30))) { if (callback(false, select_current_directory)) { @@ -312,7 +312,7 @@ void select_file_popup(const char *prompt, StringCallback callback, } ImGui::SameLine(); } - if (ImGui::Button("Cancel", ImVec2(0, 30 * gui_get_scaling()))) + if (ImGui::Button("Cancel", ScaledVec2(0, 30))) { subfolders_read = false; callback(true, ""); diff --git a/core/rend/gui_util.h b/core/rend/gui_util.h index 9ed997f3a..cfe29e46b 100644 --- a/core/rend/gui_util.h +++ b/core/rend/gui_util.h @@ -112,3 +112,21 @@ private: LoadProgress progress; std::future future; }; + +struct ScaledVec2 : public ImVec2 +{ + ScaledVec2() + : ImVec2() {} + ScaledVec2(float x, float y) + : ImVec2(x * settings.display.uiScale, y * settings.display.uiScale) {} +}; + +inline static ImVec2 min(const ImVec2& l, const ImVec2& r) { + return ImVec2(std::min(l.x, r.x), std::min(l.y, r.y)); +} +inline static ImVec2 operator+(const ImVec2& l, const ImVec2& r) { + return ImVec2(l.x + r.x, l.y + r.y); +} +inline static ImVec2 operator-(const ImVec2& l, const ImVec2& r) { + return ImVec2(l.x - r.x, l.y - r.y); +} diff --git a/core/rend/imgui_driver.h b/core/rend/imgui_driver.h index 284fb1800..eec8e2488 100644 --- a/core/rend/imgui_driver.h +++ b/core/rend/imgui_driver.h @@ -18,11 +18,15 @@ */ #pragma once #include "imgui/imgui.h" +#include "gui.h" #include class ImGuiDriver { public: + ImGuiDriver() { + gui_initFonts(); + } virtual ~ImGuiDriver() = default; virtual void newFrame() = 0; diff --git a/core/rend/vulkan/imgui_impl_vulkan.cpp b/core/rend/vulkan/imgui_impl_vulkan.cpp index 26464c2c6..5eb9f32f3 100644 --- a/core/rend/vulkan/imgui_impl_vulkan.cpp +++ b/core/rend/vulkan/imgui_impl_vulkan.cpp @@ -700,7 +700,7 @@ void ImGui_ImplVulkan_InvalidateDeviceObjects() } if (g_FontView) { vkDestroyImageView(g_Device, g_FontView, g_Allocator); g_FontView = VK_NULL_HANDLE; } - if (g_FontImage) { vkDestroyImage(g_Device, g_FontImage, g_Allocator); g_FontImage = VK_NULL_HANDLE; } + if (g_FontImage) { vkDestroyImage(g_Device, g_FontImage, g_Allocator); g_FontImage = VK_NULL_HANDLE; ImGui::GetIO().Fonts->SetTexID(NULL); } if (g_FontMemory) { vkFreeMemory(g_Device, g_FontMemory, g_Allocator); g_FontMemory = VK_NULL_HANDLE; } if (g_FontSampler) { vkDestroySampler(g_Device, g_FontSampler, g_Allocator); g_FontSampler = VK_NULL_HANDLE; } if (g_DescriptorSetLayout) { vkDestroyDescriptorSetLayout(g_Device, g_DescriptorSetLayout, g_Allocator); g_DescriptorSetLayout = VK_NULL_HANDLE; } diff --git a/core/rend/vulkan/vulkan_context.cpp b/core/rend/vulkan/vulkan_context.cpp index 271f2606c..4cc221a3e 100644 --- a/core/rend/vulkan/vulkan_context.cpp +++ b/core/rend/vulkan/vulkan_context.cpp @@ -279,7 +279,6 @@ bool VulkanContext::InitInstance(const char** extensions, uint32_t extensions_co void VulkanContext::InitImgui() { imguiDriver = std::unique_ptr(new VulkanDriver()); - gui_init(); ImGui_ImplVulkan_InitInfo initInfo = {}; initInfo.Instance = (VkInstance)*instance; initInfo.PhysicalDevice = (VkPhysicalDevice)physicalDevice; @@ -719,7 +718,7 @@ bool VulkanContext::init() settings.display.pointScale = (float)settings.display.width / w; float hdpi, vdpi; if (!SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(sdlWin), nullptr, &hdpi, &vdpi)) - screen_dpi = (int)roundf(std::max(hdpi, vdpi)); + settings.display.dpi = roundf(std::max(hdpi, vdpi)); #elif defined(_WIN32) vk::Win32SurfaceCreateInfoKHR createInfo(vk::Win32SurfaceCreateFlagsKHR(), GetModuleHandle(NULL), (HWND)window); surface = instance->createWin32SurfaceKHRUnique(createInfo); @@ -913,7 +912,7 @@ void VulkanContext::PresentFrame(vk::Image image, vk::ImageView imageView, const if (lastFrameView) // Might have been nullified if swap chain recreated DrawFrame(imageView, extent); - DrawOverlay(gui_get_scaling(), config::FloatVMUs, true); + DrawOverlay(settings.display.uiScale, config::FloatVMUs, true); renderer->DrawOSD(false); EndFrame(overlayCmdBuffer); } catch (const InvalidVulkanContext& err) { @@ -935,8 +934,6 @@ void VulkanContext::term() return; WaitIdle(); imguiDriver.reset(); - ImGui_ImplVulkan_Shutdown(); - gui_term(); if (device && pipelineCache) { std::vector cacheData = device->getPipelineCacheData(*pipelineCache); @@ -1176,7 +1173,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData *draw_data) vmuCmdBuffer = context->PrepareOverlay(true, false); context->BeginRenderPass(); context->PresentLastFrame(); - context->DrawOverlay(gui_get_scaling(), true, false); + context->DrawOverlay(settings.display.uiScale, true, false); } // Record Imgui Draw Data and draw funcs into command buffer ImGui_ImplVulkan_RenderDrawData(draw_data, (VkCommandBuffer)context->GetCurrentCommandBuffer()); diff --git a/core/rend/vulkan/vulkan_driver.h b/core/rend/vulkan/vulkan_driver.h index b3b52ed3a..a6f6b71d1 100644 --- a/core/rend/vulkan/vulkan_driver.h +++ b/core/rend/vulkan/vulkan_driver.h @@ -24,6 +24,10 @@ class VulkanDriver final : public ImGuiDriver { public: + ~VulkanDriver() { + ImGui_ImplVulkan_Shutdown(); + } + void newFrame() override { } diff --git a/core/sdl/sdl.cpp b/core/sdl/sdl.cpp index 162cc6424..283607ef7 100644 --- a/core/sdl/sdl.cpp +++ b/core/sdl/sdl.cpp @@ -467,11 +467,9 @@ bool sdl_recreate_window(u32 flags) if (SetProcessDpiAwareness) { SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE); - float ddpi; - if (SDL_GetDisplayDPI(0, &ddpi, NULL, NULL) != -1){ //SDL_WINDOWPOS_UNDEFINED is Display 0 + if (SDL_GetDisplayDPI(0, &settings.display.dpi, NULL, NULL) != -1){ //SDL_WINDOWPOS_UNDEFINED is Display 0 //When using HiDPI mode, set correct DPI scaling - scaling = ddpi/96.f; - hdpiScaling = scaling; + hdpiScaling = settings.display.dpi / 96.f; } } SDL_UnloadObject(shcoreDLL); @@ -484,13 +482,13 @@ bool sdl_recreate_window(u32 flags) { windowPos.w = 1280; windowPos.h = 720; - scaling = 1.5f; + settings.display.uiScale = 1.5f; } else { windowPos.w = 1920; windowPos.h = 1080; - scaling = 1.0f; + settings.display.uiScale = 1.4f; } #else windowPos.x = cfgLoadInt("window", "left", windowPos.x); diff --git a/core/sdl/sdl_gamepad.h b/core/sdl/sdl_gamepad.h index 2be1df345..0525bbeba 100644 --- a/core/sdl/sdl_gamepad.h +++ b/core/sdl/sdl_gamepad.h @@ -2,7 +2,6 @@ #include "input/mouse.h" #include "oslib/oslib.h" #include "sdl.h" -#include "rend/gui.h" template class DefaultInputMapping : public InputMapping diff --git a/core/types.h b/core/types.h index 8da7180ed..5fad8efa0 100644 --- a/core/types.h +++ b/core/types.h @@ -354,6 +354,8 @@ struct settings_t int height = 480; float pointScale = 1.f; float refreshRate = 0; + float dpi = 96.f; + float uiScale = 1.f; } display; struct diff --git a/core/windows/rawinput.h b/core/windows/rawinput.h index 66d2a5708..86b8b1cec 100644 --- a/core/windows/rawinput.h +++ b/core/windows/rawinput.h @@ -21,7 +21,6 @@ #include "input/gamepad_device.h" #include "input/keyboard_device.h" #include "input/mouse.h" -#include "rend/gui.h" #include #include diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index aeb8f6ed5..50d0463cb 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -877,10 +877,6 @@ int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi mainui_loop(); - flycast_term(); - - os_UninstallFaultHandler(); - #ifdef USE_SDL sdl_window_destroy(); #else @@ -894,6 +890,9 @@ int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi } #endif + flycast_term(); + os_UninstallFaultHandler(); + return 0; } diff --git a/core/windows/xinput_gamepad.h b/core/windows/xinput_gamepad.h index 987cdec1b..873fc17d7 100644 --- a/core/windows/xinput_gamepad.h +++ b/core/windows/xinput_gamepad.h @@ -1,6 +1,5 @@ #include "input/gamepad_device.h" #include "input/mouse.h" -#include "rend/gui.h" #include #include diff --git a/core/wsi/egl.cpp b/core/wsi/egl.cpp index 35a7e64af..36ede455b 100644 --- a/core/wsi/egl.cpp +++ b/core/wsi/egl.cpp @@ -175,8 +175,7 @@ bool EGLGraphicsContext::init() #ifdef TARGET_PANDORA fbdev = open("/dev/fb0", O_RDONLY); #else - swapOnVSync = config::VSync; - eglSwapInterval(display, (int)swapOnVSync); + setSwapInterval(); #endif postInit(); @@ -210,10 +209,19 @@ void EGLGraphicsContext::swap() { do_swap_automation(); if (swapOnVSync == (settings.input.fastForwardMode || !config::VSync)) - { - swapOnVSync = (!settings.input.fastForwardMode && config::VSync); - eglSwapInterval(display, (int)swapOnVSync); - } + setSwapInterval(); eglSwapBuffers(display, surface); } + +void EGLGraphicsContext::setSwapInterval() +{ + swapOnVSync = (!settings.input.fastForwardMode && config::VSync); + int swapInterval; + if (settings.display.refreshRate > 60.f) + swapInterval = settings.display.refreshRate / 60.f; + else + swapInterval = 1; + + eglSwapInterval(display, swapOnVSync ? swapInterval : 0); +} #endif // USE_EGL diff --git a/core/wsi/egl.h b/core/wsi/egl.h index a775770a2..d593914ff 100644 --- a/core/wsi/egl.h +++ b/core/wsi/egl.h @@ -43,6 +43,7 @@ public: private: bool makeCurrent(); + void setSwapInterval(); EGLDisplay display = EGL_NO_DISPLAY; EGLSurface surface = EGL_NO_SURFACE; diff --git a/core/wsi/gl_context.cpp b/core/wsi/gl_context.cpp index 9af69a24f..031518f62 100644 --- a/core/wsi/gl_context.cpp +++ b/core/wsi/gl_context.cpp @@ -21,7 +21,6 @@ #include "gl_context.h" #include "rend/gles/opengl_driver.h" -#include "rend/gui.h" void GLGraphicsContext::findGLVersion() { @@ -44,17 +43,13 @@ void GLGraphicsContext::postInit() { instance = this; findGLVersion(); -#ifndef LIBRETRO - gui_init(); - imguiDriver = std::unique_ptr(new OpenGLDriver()); -#endif + resetUIDriver(); } void GLGraphicsContext::preTerm() { #ifndef LIBRETRO imguiDriver.reset(); - gui_term(); #endif instance = nullptr; } @@ -66,3 +61,10 @@ std::string GLGraphicsContext::getDriverName() { std::string GLGraphicsContext::getDriverVersion() { return (const char *)glGetString(GL_VERSION); } + +void GLGraphicsContext::resetUIDriver() +{ +#ifndef LIBRETRO + imguiDriver = std::unique_ptr(new OpenGLDriver()); +#endif +} diff --git a/core/wsi/gl_context.h b/core/wsi/gl_context.h index 9681cf779..9fe46e771 100644 --- a/core/wsi/gl_context.h +++ b/core/wsi/gl_context.h @@ -42,6 +42,7 @@ public: } std::string getDriverName() override; std::string getDriverVersion() override; + void resetUIDriver(); bool hasPerPixel() override { diff --git a/core/wsi/sdl.cpp b/core/wsi/sdl.cpp index 338f14c92..316292dbf 100644 --- a/core/wsi/sdl.cpp +++ b/core/wsi/sdl.cpp @@ -83,7 +83,7 @@ bool SDLGLGraphicsContext::init() float hdpi, vdpi; if (!SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(sdlWindow), nullptr, &hdpi, &vdpi)) - screen_dpi = (int)roundf(std::max(hdpi, vdpi)); + settings.display.dpi = roundf(std::max(hdpi, vdpi)); INFO_LOG(RENDERER, "Created SDL Window and GL Context successfully"); @@ -135,13 +135,12 @@ void SDLGLGraphicsContext::swap() // Check if drawable has been resized SDL_GL_GetDrawableSize((SDL_Window *)window, &settings.display.width, &settings.display.height); #ifdef __SWITCH__ - float newScaling = settings.display.height == 720 ? 1.5f : 1.0f; - if (newScaling != scaling) + float newScaling = settings.display.height == 720 ? 1.5f : 1.4f; + if (newScaling != settings.display.uiScale) { // Restart the UI to take the new scaling factor into account - scaling = newScaling; - gui_term(); - gui_init(); + settings.display.uiScale = newScaling; + resetUIDriver(); } #endif } diff --git a/core/wsi/switcher.cpp b/core/wsi/switcher.cpp index b3e9984c7..13c024c28 100644 --- a/core/wsi/switcher.cpp +++ b/core/wsi/switcher.cpp @@ -20,7 +20,6 @@ */ #ifndef LIBRETRO #include "context.h" -#include "rend/gui.h" #include "cfg/option.h" #include "gl_context.h" diff --git a/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/JNIdc.java b/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/JNIdc.java index 461894885..5b66bfc7d 100644 --- a/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/JNIdc.java +++ b/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/JNIdc.java @@ -25,7 +25,7 @@ public final class JNIdc public static native void setupMic(SipEmulator sip); public static native int getVirtualGamepadVibration(); - public static native void screenDpi(int screenDpi); + public static native void screenCharacteristics(float screenDpi, float refreshRate); public static native void guiOpenSettings(); public static native boolean guiIsOpen(); public static native boolean guiIsContentBrowser(); diff --git a/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/NativeGLView.java b/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/NativeGLView.java index 85d593a69..756a63479 100644 --- a/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/NativeGLView.java +++ b/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/NativeGLView.java @@ -57,10 +57,6 @@ public class NativeGLView extends SurfaceView implements SurfaceHolder.Callback SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - DisplayMetrics dm = context.getResources().getDisplayMetrics(); - Log.i("flycast", "Display density: " + dm.xdpi + " x " + dm.ydpi + " dpi"); - JNIdc.screenDpi((int)Math.max(dm.xdpi, dm.ydpi)); - this.setLayerType(LAYER_TYPE_HARDWARE, null); } @@ -69,6 +65,9 @@ public class NativeGLView extends SurfaceView implements SurfaceHolder.Callback { super.onLayout(changed, left, top, right, bottom); vjoyDelegate.layout(getWidth(), getHeight()); + DisplayMetrics dm = getContext().getResources().getDisplayMetrics(); + Log.i("flycast", "Display density: " + dm.xdpi + " x " + dm.ydpi + " dpi. Refresh rate: " + getDisplay().getRefreshRate()); + JNIdc.screenCharacteristics(Math.max(dm.xdpi, dm.ydpi), getDisplay().getRefreshRate()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { // Get the display cutouts if any WindowInsets insets = getRootWindowInsets(); diff --git a/shell/android-studio/flycast/src/main/jni/src/Android.cpp b/shell/android-studio/flycast/src/main/jni/src/Android.cpp index 0bc44173b..783c1f700 100644 --- a/shell/android-studio/flycast/src/main/jni/src/Android.cpp +++ b/shell/android-studio/flycast/src/main/jni/src/Android.cpp @@ -81,9 +81,10 @@ extern "C" JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_getVirtual return (jint)config::VirtualGamepadVibration; } -extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_screenDpi(JNIEnv *env, jobject obj, jint screenDpi) +extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_screenCharacteristics(JNIEnv *env, jobject obj, jfloat screenDpi, jfloat refreshRate) { - screen_dpi = screenDpi; + settings.display.dpi = screenDpi; + settings.display.refreshRate = refreshRate; } std::shared_ptr mouse; @@ -214,11 +215,7 @@ extern "C" JNIEXPORT jstring JNICALL Java_com_reicast_emulator_emu_JNIdc_initEnv EventManager::listen(Event::Resume, emuEventCallback); jstring msg = NULL; int rc = flycast_init(0, NULL); - if (rc == -4) - msg = env->NewStringUTF("Cannot find configuration"); - else if (rc == 69) - msg = env->NewStringUTF("Invalid command line"); - else if (rc == -1) + if (rc == -1) msg = env->NewStringUTF("Memory initialization failed"); return msg; } diff --git a/shell/apple/emulator-ios/emulator/FlycastViewController.mm b/shell/apple/emulator-ios/emulator/FlycastViewController.mm index edf0c3dc3..5e79e2156 100644 --- a/shell/apple/emulator-ios/emulator/FlycastViewController.mm +++ b/shell/apple/emulator-ios/emulator/FlycastViewController.mm @@ -164,8 +164,6 @@ static void updateAudioSession(Event event, void *) @end -extern int screen_dpi; - @implementation FlycastViewController { UITextField *textField; BOOL showingKeyboard; @@ -312,7 +310,7 @@ extern int screen_dpi; if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { scale = [[UIScreen mainScreen] scale]; } - screen_dpi = roundf(160 * scale); + settings.display.dpi = 160.f * scale; initRenderApi(); mainui_init(); diff --git a/shell/apple/emulator-osx/emulator-osx/osx-main.mm b/shell/apple/emulator-osx/emulator-osx/osx-main.mm index 68e211946..485e1336b 100644 --- a/shell/apple/emulator-osx/emulator-osx/osx-main.mm +++ b/shell/apple/emulator-osx/emulator-osx/osx-main.mm @@ -14,7 +14,6 @@ #include "types.h" #include "log/LogManager.h" -#include "rend/gui.h" #if defined(USE_SDL) #include "sdl/sdl.h" #endif @@ -126,9 +125,9 @@ extern "C" int SDL_main(int argc, char *argv[]) mainui_loop(); + sdl_window_destroy(); emu_flycast_term(); os_UninstallFaultHandler(); - sdl_window_destroy(); return 0; } diff --git a/shell/libretro/libretro.cpp b/shell/libretro/libretro.cpp index 5bee06671..67a2aa94b 100644 --- a/shell/libretro/libretro.cpp +++ b/shell/libretro/libretro.cpp @@ -3161,9 +3161,3 @@ void gui_display_notification(const char *msg, int duration) retromsg.frames = duration / 17; environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &retromsg); } - -void gui_init() { -} - -void gui_term() { -} diff --git a/shell/libretro/libretro_core_options.h b/shell/libretro/libretro_core_options.h index 56642ac1e..67d29c50f 100644 --- a/shell/libretro/libretro_core_options.h +++ b/shell/libretro/libretro_core_options.h @@ -82,7 +82,7 @@ struct retro_core_option_v2_category option_cats_us[] = { { "performance", "Performance", - "Configure threaded rendering, integer division optimisations and frame skip settings." + "Configure threaded rendering and frame skip settings." }, { "hacks",