mirror of
https://github.com/izzy2lost/WeeU.git
synced 2026-07-06 00:19:59 -07:00
UI+build: Isolate wxWidgets code from non-GUI code (#1633)
This commit is contained in:
@@ -31,6 +31,7 @@ jobs:
|
||||
find src -name *.cpp -o -name *.hpp -o -name *.h |
|
||||
xargs xgettext --from-code=utf-8 -w 100
|
||||
--keyword="_" --keyword="wxTRANSLATE" --keyword="wxPLURAL:1,2"
|
||||
--keyword="_tr" --keyword="TR_NOOP"
|
||||
--check=space-ellipsis --omit-header
|
||||
-o cemu.pot
|
||||
|
||||
|
||||
@@ -150,7 +150,3 @@ if(UNIX AND NOT APPLE)
|
||||
# most likely not helpful in debugging problems with cemu code
|
||||
target_link_options(CemuBin PRIVATE "$<$<CONFIG:Release>:-Xlinker;--strip-debug>")
|
||||
endif()
|
||||
|
||||
if (ENABLE_WXWIDGETS)
|
||||
target_link_libraries(CemuBin PRIVATE wx::base wx::core)
|
||||
endif()
|
||||
|
||||
@@ -597,10 +597,6 @@ else ()
|
||||
target_link_libraries(CemuCafe PRIVATE libusb::libusb)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_WXWIDGETS)
|
||||
target_link_libraries(CemuCafe PRIVATE wx::base wx::core)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(CemuCafe PRIVATE iphlpapi)
|
||||
endif()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "Cafe/OS/common/OSCommon.h"
|
||||
#include "gui/wxgui.h"
|
||||
#include "WindowSystem.h"
|
||||
#include "Cafe/OS/libs/gx2/GX2.h"
|
||||
#include "Cafe/GameProfile/GameProfile.h"
|
||||
#include "Cafe/HW/Espresso/Interpreter/PPCInterpreterInternal.h"
|
||||
@@ -65,9 +65,6 @@
|
||||
// HW interfaces
|
||||
#include "Cafe/HW/SI/si.h"
|
||||
|
||||
// dependency to be removed
|
||||
#include "gui/guiWrapper.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#if BOOST_OS_LINUX
|
||||
@@ -172,7 +169,7 @@ void LoadMainExecutable()
|
||||
applicationRPX = RPLLoader_LoadFromMemory(rpxData, rpxSize, (char*)_pathToExecutable.c_str());
|
||||
if (!applicationRPX)
|
||||
{
|
||||
wxMessageBox(_("Failed to run this title because the executable is damaged"));
|
||||
WindowSystem::ShowErrorDialog(_tr("Failed to run this title because the executable is damaged"));
|
||||
cemuLog_createLogFile(false);
|
||||
cemuLog_waitForFlush();
|
||||
exit(0);
|
||||
@@ -357,7 +354,7 @@ uint32 LoadSharedData()
|
||||
|
||||
void cemu_initForGame()
|
||||
{
|
||||
gui_updateWindowTitles(false, true, 0.0);
|
||||
WindowSystem::UpdateWindowTitles(false, true, 0.0);
|
||||
// input manager apply game profile
|
||||
InputManager::instance().apply_game_profile();
|
||||
// log info for launched title
|
||||
@@ -855,7 +852,7 @@ namespace CafeSystem
|
||||
PPCTimer_waitForInit();
|
||||
// start system
|
||||
sSystemRunning = true;
|
||||
gui_notifyGameLoaded();
|
||||
WindowSystem::NotifyGameLoaded();
|
||||
std::thread t(_LaunchTitleThread);
|
||||
t.detach();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <wx/msgdlg.h>
|
||||
#include <mutex>
|
||||
#include <gui/helpers/wxHelpers.h>
|
||||
|
||||
#include "Cemu/Logging/CemuLogging.h"
|
||||
#include "WindowSystem.h"
|
||||
#include "config/ActiveSettings.h"
|
||||
#include "util/crypto/aes128.h"
|
||||
#include "Common/FileStream.h"
|
||||
@@ -75,7 +75,7 @@ void KeyCache_Prepare()
|
||||
}
|
||||
else
|
||||
{
|
||||
wxMessageBox(_("Unable to create file keys.txt\nThis can happen if Cemu does not have write permission to its own directory, the disk is full or if anti-virus software is blocking Cemu."), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
|
||||
WindowSystem::ShowErrorDialog(_tr("Unable to create file keys.txt\nThis can happen if Cemu does not have write permission to its own directory, the disk is full or if anti-virus software is blocking Cemu."), _tr("Error"), WindowSystem::ErrorCategory::KEYS_TXT_CREATION);
|
||||
}
|
||||
mtxKeyCache.unlock();
|
||||
return;
|
||||
@@ -108,8 +108,8 @@ void KeyCache_Prepare()
|
||||
continue;
|
||||
if( strishex(line) == false )
|
||||
{
|
||||
auto errorMsg = formatWxString(_("Error in keys.txt at line {}"), lineNumber);
|
||||
wxMessageBox(errorMsg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
|
||||
auto errorMsg = _tr("Error in keys.txt at line {}", lineNumber);
|
||||
WindowSystem::ShowErrorDialog(errorMsg, WindowSystem::ErrorCategory::KEYS_TXT_CREATION);
|
||||
continue;
|
||||
}
|
||||
if(line.size() == 32 )
|
||||
|
||||
@@ -85,7 +85,7 @@ bool GraphicPack2::LoadGraphicPack(const fs::path& rulesPath, IniParser& rules)
|
||||
auto gp = std::make_shared<GraphicPack2>(rulesPath, rules);
|
||||
|
||||
// check if enabled and preset set
|
||||
const auto& config_entries = g_config.data().graphic_pack_entries;
|
||||
const auto& config_entries = GetConfigHandle().data().graphic_pack_entries;
|
||||
|
||||
// legacy absolute path checking for not breaking compatibility
|
||||
auto file = gp->GetRulesPath();
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
#include "Cafe/GraphicPack/GraphicPack2.h"
|
||||
#include "Cemu/Logging/CemuLogging.h"
|
||||
#include "Common/FileStream.h"
|
||||
#include "WindowSystem.h"
|
||||
#include "util/helpers/StringParser.h"
|
||||
#include "Cemu/PPCAssembler/ppcAssembler.h"
|
||||
#include "Cafe/OS/RPL/rpl_structs.h"
|
||||
#include "boost/algorithm/string.hpp"
|
||||
|
||||
#include "gui/wxgui.h" // for wxMessageBox
|
||||
#include "gui/helpers/wxHelpers.h"
|
||||
|
||||
// error handler
|
||||
void PatchErrorHandler::printError(class PatchGroup* patchGroup, sint32 lineNumber, std::string_view errorMsg)
|
||||
{
|
||||
@@ -40,13 +39,13 @@ void PatchErrorHandler::printError(class PatchGroup* patchGroup, sint32 lineNumb
|
||||
|
||||
void PatchErrorHandler::showStageErrorMessageBox()
|
||||
{
|
||||
wxString errorMsg;
|
||||
std::string errorMsg;
|
||||
if (m_gp)
|
||||
{
|
||||
if (m_stage == STAGE::PARSER)
|
||||
errorMsg.assign(formatWxString(_("Failed to load patches for graphic pack \'{}\'"), m_gp->GetName()));
|
||||
errorMsg.assign(_tr("Failed to load patches for graphic pack \'{}\'", m_gp->GetName()));
|
||||
else
|
||||
errorMsg.assign(formatWxString(_("Failed to apply patches for graphic pack \'{}\'"), m_gp->GetName()));
|
||||
errorMsg.assign(_tr("Failed to apply patches for graphic pack \'{}\'", m_gp->GetName()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -55,7 +54,7 @@ void PatchErrorHandler::showStageErrorMessageBox()
|
||||
if (cemuLog_isLoggingEnabled(LogType::Patches))
|
||||
{
|
||||
errorMsg.append("\n \n")
|
||||
.append(_("Details:"))
|
||||
.append(_tr("Details:"))
|
||||
.append("\n");
|
||||
for (auto& itr : errorMessages)
|
||||
{
|
||||
@@ -64,7 +63,7 @@ void PatchErrorHandler::showStageErrorMessageBox()
|
||||
}
|
||||
}
|
||||
|
||||
wxMessageBox(errorMsg, _("Graphic pack error"));
|
||||
WindowSystem::ShowErrorDialog(errorMsg, _tr("Graphic pack error"), WindowSystem::ErrorCategory::GRAPHIC_PACKS);
|
||||
}
|
||||
|
||||
// loads Cemu-style patches (patch_<anything>.asm)
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
#include "gui/guiWrapper.h"
|
||||
#include "Common/precompiled.h"
|
||||
#include "Debugger.h"
|
||||
#include "Cafe/OS/RPL/rpl_structs.h"
|
||||
#include "Cemu/PPCAssembler/ppcAssembler.h"
|
||||
#include "Cafe/HW/Espresso/Recompiler/PPCRecompiler.h"
|
||||
#include "Cemu/ExpressionParser/ExpressionParser.h"
|
||||
|
||||
#include "gui/debugger/DebuggerWindow2.h"
|
||||
|
||||
#include "Cafe/OS/libs/coreinit/coreinit.h"
|
||||
#include "OS/RPL/rpl.h"
|
||||
#include "util/helpers/helpers.h"
|
||||
|
||||
#if BOOST_OS_WINDOWS
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
DebuggerDispatcher g_debuggerDispatcher;
|
||||
|
||||
debuggerState_t debuggerState{ };
|
||||
|
||||
DebuggerBreakpoint* debugger_getFirstBP(uint32 address)
|
||||
@@ -337,7 +338,7 @@ void debugger_toggleBreakpoint(uint32 address, bool state, DebuggerBreakpoint* b
|
||||
{
|
||||
bp->enabled = state;
|
||||
debugger_updateExecutionBreakpoint(address);
|
||||
debuggerWindow_updateViewThreadsafe2();
|
||||
g_debuggerDispatcher.UpdateViewThreadsafe();
|
||||
}
|
||||
else if (bpItr->isMemBP())
|
||||
{
|
||||
@@ -359,7 +360,7 @@ void debugger_toggleBreakpoint(uint32 address, bool state, DebuggerBreakpoint* b
|
||||
debugger_updateMemoryBreakpoint(bpItr);
|
||||
else
|
||||
debugger_updateMemoryBreakpoint(nullptr);
|
||||
debuggerWindow_updateViewThreadsafe2();
|
||||
g_debuggerDispatcher.UpdateViewThreadsafe();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -496,7 +497,7 @@ void debugger_stepInto(PPCInterpreter_t* hCPU, bool updateDebuggerWindow = true)
|
||||
debugger_updateExecutionBreakpoint(initialIP);
|
||||
debuggerState.debugSession.instructionPointer = hCPU->instructionPointer;
|
||||
if(updateDebuggerWindow)
|
||||
debuggerWindow_moveIP();
|
||||
g_debuggerDispatcher.MoveIP();
|
||||
ppcRecompilerEnabled = isRecEnabled;
|
||||
}
|
||||
|
||||
@@ -515,7 +516,7 @@ bool debugger_stepOver(PPCInterpreter_t* hCPU)
|
||||
// nothing to skip, use step-into
|
||||
debugger_stepInto(hCPU);
|
||||
debugger_updateExecutionBreakpoint(initialIP);
|
||||
debuggerWindow_moveIP();
|
||||
g_debuggerDispatcher.MoveIP();
|
||||
ppcRecompilerEnabled = isRecEnabled;
|
||||
return false;
|
||||
}
|
||||
@@ -523,7 +524,7 @@ bool debugger_stepOver(PPCInterpreter_t* hCPU)
|
||||
debugger_createCodeBreakpoint(initialIP + 4, DEBUGGER_BP_T_ONE_SHOT);
|
||||
// step over current instruction (to avoid breakpoint)
|
||||
debugger_stepInto(hCPU);
|
||||
debuggerWindow_moveIP();
|
||||
g_debuggerDispatcher.MoveIP();
|
||||
// restore breakpoints
|
||||
debugger_updateExecutionBreakpoint(initialIP);
|
||||
// run
|
||||
@@ -621,8 +622,8 @@ void debugger_enterTW(PPCInterpreter_t* hCPU)
|
||||
DebuggerBreakpoint* singleshotBP = debugger_getFirstBP(debuggerState.debugSession.instructionPointer, DEBUGGER_BP_T_ONE_SHOT);
|
||||
if (singleshotBP)
|
||||
debugger_deleteBreakpoint(singleshotBP);
|
||||
debuggerWindow_notifyDebugBreakpointHit2();
|
||||
debuggerWindow_updateViewThreadsafe2();
|
||||
g_debuggerDispatcher.NotifyDebugBreakpointHit();
|
||||
g_debuggerDispatcher.UpdateViewThreadsafe();
|
||||
// reset step control
|
||||
debuggerState.debugSession.stepInto = false;
|
||||
debuggerState.debugSession.stepOver = false;
|
||||
@@ -639,14 +640,14 @@ void debugger_enterTW(PPCInterpreter_t* hCPU)
|
||||
break; // if true is returned, continue with execution
|
||||
}
|
||||
debugger_createPPCStateSnapshot(hCPU);
|
||||
debuggerWindow_updateViewThreadsafe2();
|
||||
g_debuggerDispatcher.UpdateViewThreadsafe();
|
||||
debuggerState.debugSession.stepOver = false;
|
||||
}
|
||||
if (debuggerState.debugSession.stepInto)
|
||||
{
|
||||
debugger_stepInto(hCPU);
|
||||
debugger_createPPCStateSnapshot(hCPU);
|
||||
debuggerWindow_updateViewThreadsafe2();
|
||||
g_debuggerDispatcher.UpdateViewThreadsafe();
|
||||
debuggerState.debugSession.stepInto = false;
|
||||
continue;
|
||||
}
|
||||
@@ -663,8 +664,8 @@ void debugger_enterTW(PPCInterpreter_t* hCPU)
|
||||
|
||||
debuggerState.debugSession.isTrapped = false;
|
||||
debuggerState.debugSession.hCPU = nullptr;
|
||||
debuggerWindow_updateViewThreadsafe2();
|
||||
debuggerWindow_notifyRun();
|
||||
g_debuggerDispatcher.UpdateViewThreadsafe();
|
||||
g_debuggerDispatcher.NotifyRun();
|
||||
}
|
||||
|
||||
void debugger_shouldBreak(PPCInterpreter_t* hCPU)
|
||||
|
||||
@@ -15,6 +15,69 @@
|
||||
#define DEBUGGER_BP_T_GDBSTUB_TW 0x7C010008
|
||||
#define DEBUGGER_BP_T_DEBUGGER_TW 0x7C020008
|
||||
|
||||
class DebuggerCallbacks
|
||||
{
|
||||
public:
|
||||
virtual void UpdateViewThreadsafe() {}
|
||||
virtual void NotifyDebugBreakpointHit() {}
|
||||
virtual void NotifyRun() {}
|
||||
virtual void MoveIP() {}
|
||||
virtual void NotifyModuleLoaded(void* module) {}
|
||||
virtual void NotifyModuleUnloaded(void* module) {}
|
||||
virtual ~DebuggerCallbacks() = default;
|
||||
};
|
||||
|
||||
class DebuggerDispatcher
|
||||
{
|
||||
private:
|
||||
static inline class DefaultDebuggerCallbacks : public DebuggerCallbacks
|
||||
{
|
||||
} s_defaultDebuggerCallbacks;
|
||||
DebuggerCallbacks* m_callbacks = &s_defaultDebuggerCallbacks;
|
||||
|
||||
public:
|
||||
void SetDebuggerCallbacks(DebuggerCallbacks* debuggerCallbacks)
|
||||
{
|
||||
cemu_assert_debug(m_callbacks == &s_defaultDebuggerCallbacks);
|
||||
m_callbacks = debuggerCallbacks;
|
||||
}
|
||||
|
||||
void ClearDebuggerCallbacks()
|
||||
{
|
||||
cemu_assert_debug(m_callbacks != &s_defaultDebuggerCallbacks);
|
||||
m_callbacks = &s_defaultDebuggerCallbacks;
|
||||
}
|
||||
|
||||
void UpdateViewThreadsafe()
|
||||
{
|
||||
m_callbacks->UpdateViewThreadsafe();
|
||||
}
|
||||
|
||||
void NotifyDebugBreakpointHit()
|
||||
{
|
||||
m_callbacks->NotifyDebugBreakpointHit();
|
||||
}
|
||||
|
||||
void NotifyRun()
|
||||
{
|
||||
m_callbacks->NotifyRun();
|
||||
}
|
||||
|
||||
void MoveIP()
|
||||
{
|
||||
m_callbacks->MoveIP();
|
||||
}
|
||||
|
||||
void NotifyModuleLoaded(void* module)
|
||||
{
|
||||
m_callbacks->NotifyModuleLoaded(module);
|
||||
}
|
||||
|
||||
void NotifyModuleUnloaded(void* module)
|
||||
{
|
||||
m_callbacks->NotifyModuleUnloaded(module);
|
||||
}
|
||||
} extern g_debuggerDispatcher;
|
||||
|
||||
struct DebuggerBreakpoint
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "Cafe/HW/Latte/Core/LatteOverlay.h"
|
||||
#include "Cafe/HW/Latte/Core/LattePerformanceMonitor.h"
|
||||
#include "gui/guiWrapper.h"
|
||||
#include "WindowSystem.h"
|
||||
|
||||
#include "config/CemuConfig.h"
|
||||
|
||||
@@ -519,17 +519,17 @@ void LatteOverlay_render(bool pad_view)
|
||||
return;
|
||||
|
||||
sint32 w = 0, h = 0;
|
||||
if (pad_view && gui_isPadWindowOpen())
|
||||
gui_getPadWindowPhysSize(w, h);
|
||||
if (pad_view && WindowSystem::IsPadWindowOpen())
|
||||
WindowSystem::GetPadWindowPhysSize(w, h);
|
||||
else
|
||||
gui_getWindowPhysSize(w, h);
|
||||
WindowSystem::GetWindowPhysSize(w, h);
|
||||
|
||||
if (w == 0 || h == 0)
|
||||
return;
|
||||
|
||||
const Vector2f window_size{ (float)w,(float)h };
|
||||
|
||||
float fontDPIScale = !pad_view ? gui_getWindowDPIScale() : gui_getPadDPIScale();
|
||||
float fontDPIScale = !pad_view ? WindowSystem::GetWindowDPIScale() : WindowSystem::GetPadDPIScale();
|
||||
|
||||
float overlayFontSize = 14.0f * (float)config.overlay.text_scale / 100.0f * fontDPIScale;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "Cafe/HW/Latte/Core/LattePerformanceMonitor.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteOverlay.h"
|
||||
#include "gui/guiWrapper.h"
|
||||
#include "WindowSystem.h"
|
||||
|
||||
performanceMonitor_t performanceMonitor{};
|
||||
|
||||
@@ -106,12 +106,12 @@ void LattePerformanceMonitor_frameEnd()
|
||||
if (isFirstUpdate)
|
||||
{
|
||||
LatteOverlay_updateStats(0.0, 0, 0);
|
||||
gui_updateWindowTitles(false, false, 0.0);
|
||||
WindowSystem::UpdateWindowTitles(false, false, 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
LatteOverlay_updateStats(fps, drawCallCounter / elapsedFrames, fastDrawCallCounter / elapsedFrames);
|
||||
gui_updateWindowTitles(false, false, fps);
|
||||
WindowSystem::UpdateWindowTitles(false, false, fps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "Cafe/HW/Latte/Core/LattePerformanceMonitor.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack2.h"
|
||||
#include "config/ActiveSettings.h"
|
||||
#include "gui/guiWrapper.h"
|
||||
#include "WindowSystem.h"
|
||||
#include "Cafe/OS/libs/erreula/erreula.h"
|
||||
#include "input/InputManager.h"
|
||||
#include "Cafe/OS/libs/swkbd/swkbd.h"
|
||||
@@ -838,10 +838,10 @@ sint32 _currentOutputImageHeight = 0;
|
||||
void LatteRenderTarget_getScreenImageArea(sint32* x, sint32* y, sint32* width, sint32* height, sint32* fullWidth, sint32* fullHeight, bool padView)
|
||||
{
|
||||
int w, h;
|
||||
if(padView && gui_isPadWindowOpen())
|
||||
gui_getPadWindowPhysSize(w, h);
|
||||
if(padView && WindowSystem::IsPadWindowOpen())
|
||||
WindowSystem::GetPadWindowPhysSize(w, h);
|
||||
else
|
||||
gui_getWindowPhysSize(w, h);
|
||||
WindowSystem::GetWindowPhysSize(w, h);
|
||||
|
||||
sint32 scaledOutputX;
|
||||
sint32 scaledOutputY;
|
||||
@@ -999,8 +999,8 @@ void LatteRenderTarget_itHLECopyColorBufferToScanBuffer(MPTR colorBufferPtr, uin
|
||||
return {pressed && !toggle, pressed && toggle};
|
||||
};
|
||||
|
||||
const bool tabPressed = gui_isKeyDown(PlatformKeyCodes::TAB);
|
||||
const bool ctrlPressed = gui_isKeyDown(PlatformKeyCodes::LCONTROL);
|
||||
const bool tabPressed = WindowSystem::IsKeyDown(WindowSystem::PlatformKeyCodes::TAB);
|
||||
const bool ctrlPressed = WindowSystem::IsKeyDown(WindowSystem::PlatformKeyCodes::LCONTROL);
|
||||
const auto [vpad0Active, vpad0Toggle] = getVPADScreenActive(0);
|
||||
const auto [vpad1Active, vpad1Toggle] = getVPADScreenActive(1);
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "Cafe/HW/Latte/Core/FetchShader.h"
|
||||
#include "Cemu/FileCache/FileCache.h"
|
||||
#include "Cafe/GameProfile/GameProfile.h"
|
||||
#include "gui/guiWrapper.h"
|
||||
#include "WindowSystem.h"
|
||||
|
||||
#include "Cafe/HW/Latte/Renderer/Renderer.h"
|
||||
#include "Cafe/HW/Latte/Renderer/OpenGL/RendererShaderGL.h"
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "Cafe/HW/Latte/Common/ShaderSerializer.h"
|
||||
#include "util/helpers/Serializer.h"
|
||||
|
||||
#include <wx/msgdlg.h>
|
||||
#include <audio/IAudioAPI.h>
|
||||
#include <util/bootSound/BootSoundReader.h>
|
||||
#include <thread>
|
||||
@@ -69,8 +68,6 @@ void LatteShaderCache_LoadVulkanPipelineCache(uint64 cacheTitleId);
|
||||
bool LatteShaderCache_updatePipelineLoadingProgress();
|
||||
void LatteShaderCache_ShowProgress(const std::function <bool(void)>& loadUpdateFunc, bool isPipelines);
|
||||
|
||||
void LatteShaderCache_handleDeprecatedCacheFiles(fs::path pathGeneric, fs::path pathGenericPre1_25_0, fs::path pathGenericPre1_16_0);
|
||||
|
||||
struct
|
||||
{
|
||||
struct
|
||||
@@ -360,10 +357,7 @@ void LatteShaderCache_Load()
|
||||
RendererShaderGL::ShaderCacheLoading_begin(cacheTitleId);
|
||||
// get cache file name
|
||||
const auto pathGeneric = ActiveSettings::GetCachePath("shaderCache/transferable/{:016x}_shaders.bin", cacheTitleId);
|
||||
const auto pathGenericPre1_25_0 = ActiveSettings::GetCachePath("shaderCache/transferable/{:016x}.bin", cacheTitleId); // before 1.25.0
|
||||
const auto pathGenericPre1_16_0 = ActiveSettings::GetCachePath("shaderCache/transferable/{:08x}.bin", CafeSystem::GetRPXHashBase()); // before 1.16.0
|
||||
|
||||
LatteShaderCache_handleDeprecatedCacheFiles(pathGeneric, pathGenericPre1_25_0, pathGenericPre1_16_0);
|
||||
// calculate extraVersion for transferable and precompiled shader cache
|
||||
uint32 transferableExtraVersion = SHADER_CACHE_GENERIC_EXTRA_VERSION;
|
||||
s_shaderCacheGeneric = FileCache::Open(pathGeneric, false, transferableExtraVersion); // legacy extra version (1.25.0 - 1.25.1b)
|
||||
@@ -511,7 +505,7 @@ void LatteShaderCache_ShowProgress(const std::function <bool(void)>& loadUpdateF
|
||||
continue;
|
||||
|
||||
int w, h;
|
||||
gui_getWindowPhysSize(w, h);
|
||||
WindowSystem::GetWindowPhysSize(w, h);
|
||||
const Vector2f window_size{ (float)w,(float)h };
|
||||
|
||||
ImGui_GetFont(window_size.y / 32.0f); // = 24 by default
|
||||
@@ -900,30 +894,3 @@ void LatteShaderCache_Close()
|
||||
if (g_renderer->GetType() == RendererAPI::Vulkan)
|
||||
VulkanPipelineStableCache::GetInstance().Close();
|
||||
}
|
||||
|
||||
#include <wx/msgdlg.h>
|
||||
|
||||
void LatteShaderCache_handleDeprecatedCacheFiles(fs::path pathGeneric, fs::path pathGenericPre1_25_0, fs::path pathGenericPre1_16_0)
|
||||
{
|
||||
std::error_code ec;
|
||||
|
||||
bool hasOldCacheFiles = fs::exists(pathGenericPre1_25_0, ec) || fs::exists(pathGenericPre1_16_0, ec);
|
||||
bool hasNewCacheFiles = fs::exists(pathGeneric, ec);
|
||||
|
||||
if (hasOldCacheFiles && !hasNewCacheFiles)
|
||||
{
|
||||
// ask user if they want to delete or keep the old cache file
|
||||
auto infoMsg = _("Cemu detected that the shader cache for this game is outdated.\nOnly shader caches generated with Cemu 1.25.0 or above are supported.\n\nWe recommend deleting the outdated cache file as it will no longer be used by Cemu.");
|
||||
|
||||
wxMessageDialog dialog(nullptr, infoMsg, _("Outdated shader cache"),
|
||||
wxYES_NO | wxCENTRE | wxICON_EXCLAMATION);
|
||||
|
||||
dialog.SetYesNoLabels(_("Delete outdated cache file [recommended]"), _("Keep outdated cache file"));
|
||||
const auto result = dialog.ShowModal();
|
||||
if (result == wxID_YES)
|
||||
{
|
||||
fs::remove(pathGenericPre1_16_0, ec);
|
||||
fs::remove(pathGenericPre1_25_0, ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "Cafe/HW/Latte/Core/LatteAsyncCommands.h"
|
||||
#include "Cafe/GameProfile/GameProfile.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack2.h"
|
||||
#include "gui/guiWrapper.h"
|
||||
#include "WindowSystem.h"
|
||||
|
||||
#include "Cafe/HW/Latte/Core/LatteBufferCache.h"
|
||||
|
||||
@@ -115,7 +115,7 @@ int Latte_ThreadEntry()
|
||||
{
|
||||
SetThreadName("LatteThread");
|
||||
sint32 w,h;
|
||||
gui_getWindowPhysSize(w,h);
|
||||
WindowSystem::GetWindowPhysSize(w,h);
|
||||
|
||||
// renderer
|
||||
g_renderer->Initialize();
|
||||
@@ -166,8 +166,7 @@ int Latte_ThreadEntry()
|
||||
|
||||
g_renderer->DrawEmptyFrame(true);
|
||||
g_renderer->DrawEmptyFrame(false);
|
||||
|
||||
gui_hasScreenshotRequest(); // keep the screenshot request queue empty
|
||||
g_renderer->CancelScreenshotRequest(); // keep the screenshot request queue empty
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000/60));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.h"
|
||||
#include "gui/guiWrapper.h"
|
||||
#include "WindowSystem.h"
|
||||
|
||||
#include "Cafe/HW/Latte/Core/LatteRingBuffer.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteDraw.h"
|
||||
@@ -19,7 +19,38 @@
|
||||
#include "Cafe/HW/Latte/ISA/RegDefines.h"
|
||||
#include "Cafe/OS/libs/gx2/GX2.h"
|
||||
|
||||
#include "gui/canvas/OpenGLCanvas.h"
|
||||
class DefaultOpenGLCanvasCallbacks : public OpenGLCanvasCallbacks
|
||||
{
|
||||
} g_defaultOpenGLCanvasCallbacks;
|
||||
|
||||
OpenGLCanvasCallbacks* g_openGLCanvasCallbacks = &g_defaultOpenGLCanvasCallbacks;
|
||||
|
||||
void SetOpenGLCanvasCallbacks(OpenGLCanvasCallbacks* callbacks)
|
||||
{
|
||||
cemu_assert_debug(g_openGLCanvasCallbacks == &g_defaultOpenGLCanvasCallbacks);
|
||||
g_openGLCanvasCallbacks = callbacks;
|
||||
}
|
||||
|
||||
void ClearOpenGLCanvasCallbacks()
|
||||
{
|
||||
cemu_assert_debug(g_openGLCanvasCallbacks != &g_defaultOpenGLCanvasCallbacks);
|
||||
g_openGLCanvasCallbacks = &g_defaultOpenGLCanvasCallbacks;
|
||||
}
|
||||
|
||||
bool GLCanvas_HasPadViewOpen()
|
||||
{
|
||||
return g_openGLCanvasCallbacks->HasPadViewOpen();
|
||||
}
|
||||
|
||||
bool GLCanvas_MakeCurrent(bool padView)
|
||||
{
|
||||
return g_openGLCanvasCallbacks->MakeCurrent(padView);
|
||||
}
|
||||
|
||||
void GLCanvas_SwapBuffers(bool swapTV, bool swapDRC)
|
||||
{
|
||||
g_openGLCanvasCallbacks->SwapBuffers(swapTV, swapDRC);
|
||||
}
|
||||
|
||||
#define STRINGIFY2(X) #X
|
||||
#define STRINGIFY(X) STRINGIFY2(X)
|
||||
@@ -479,8 +510,7 @@ void OpenGLRenderer::ClearColorbuffer(bool padView)
|
||||
|
||||
void OpenGLRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool padView)
|
||||
{
|
||||
const bool hasScreenshotRequest = gui_hasScreenshotRequest();
|
||||
if(!hasScreenshotRequest && m_screenshot_state == ScreenshotState::None)
|
||||
if(!m_screenshot_requested && m_screenshot_state == ScreenshotState::None)
|
||||
return;
|
||||
|
||||
if (IsPadWindowActive())
|
||||
@@ -563,9 +593,9 @@ void OpenGLRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
|
||||
{
|
||||
int windowWidth, windowHeight;
|
||||
if (padView)
|
||||
gui_getPadWindowPhysSize(windowWidth, windowHeight);
|
||||
WindowSystem::GetPadWindowPhysSize(windowWidth, windowHeight);
|
||||
else
|
||||
gui_getWindowPhysSize(windowWidth, windowHeight);
|
||||
WindowSystem::GetWindowPhysSize(windowWidth, windowHeight);
|
||||
g_renderer->renderTarget_setViewport(0, 0, windowWidth, windowHeight, 0.0f, 1.0f);
|
||||
g_renderer->ClearColorbuffer(padView);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,28 @@
|
||||
|
||||
#define GPU_GL_MAX_NUM_ATTRIBUTE (16) // Wii U GPU supports more than 16 but not all desktop GPUs do. Have to keep this at 16 until we find a better solution
|
||||
|
||||
class OpenGLCanvasCallbacks
|
||||
{
|
||||
public:
|
||||
virtual bool HasPadViewOpen() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool MakeCurrent(bool padView)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual void SwapBuffers(bool swapTV, bool swapDRC) {}
|
||||
virtual ~OpenGLCanvasCallbacks() = default;
|
||||
};
|
||||
|
||||
void SetOpenGLCanvasCallbacks(OpenGLCanvasCallbacks* callbacks);
|
||||
void ClearOpenGLCanvasCallbacks();
|
||||
|
||||
bool GLCanvas_HasPadViewOpen();
|
||||
bool GLCanvas_MakeCurrent(bool padView);
|
||||
void GLCanvas_SwapBuffers(bool swapTV, bool swapDRC);
|
||||
|
||||
class OpenGLRenderer : public Renderer
|
||||
{
|
||||
friend class OpenGLCanvas;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "Cafe/HW/Latte/Renderer/Renderer.h"
|
||||
#include "gui/guiWrapper.h"
|
||||
#include "WindowSystem.h"
|
||||
|
||||
#include "config/CemuConfig.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteOverlay.h"
|
||||
@@ -10,11 +10,6 @@
|
||||
|
||||
#include "config/ActiveSettings.h"
|
||||
|
||||
#include <wx/image.h>
|
||||
#include <wx/dataobj.h>
|
||||
#include <wx/clipbrd.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
std::unique_ptr<Renderer> g_renderer;
|
||||
|
||||
bool Renderer::GetVRAMInfo(int& usageInMB, int& totalInMB) const
|
||||
@@ -69,10 +64,10 @@ void Renderer::Shutdown()
|
||||
bool Renderer::ImguiBegin(bool mainWindow)
|
||||
{
|
||||
sint32 w = 0, h = 0;
|
||||
if(mainWindow)
|
||||
gui_getWindowPhysSize(w, h);
|
||||
else if(gui_isPadWindowOpen())
|
||||
gui_getPadWindowPhysSize(w, h);
|
||||
if (mainWindow)
|
||||
WindowSystem::GetWindowPhysSize(w, h);
|
||||
else if (WindowSystem::IsPadWindowOpen())
|
||||
WindowSystem::GetPadWindowPhysSize(w, h);
|
||||
else
|
||||
return false;
|
||||
|
||||
@@ -82,9 +77,9 @@ bool Renderer::ImguiBegin(bool mainWindow)
|
||||
// select the right context
|
||||
ImGui::SetCurrentContext(mainWindow ? imguiTVContext : imguiPadContext);
|
||||
|
||||
const Vector2f window_size{ (float)w,(float)h };
|
||||
const Vector2f window_size{(float)w, (float)h};
|
||||
auto& io = ImGui::GetIO();
|
||||
io.DisplaySize = { window_size.x, window_size.y }; // should be only updated in the renderer and only when needed
|
||||
io.DisplaySize = {window_size.x, window_size.y}; // should be only updated in the renderer and only when needed
|
||||
|
||||
ImGui_PrecacheFonts();
|
||||
return true;
|
||||
@@ -114,107 +109,29 @@ uint8 Renderer::RGBComponentToSRGB(uint8 cli)
|
||||
return (uint8)(cs * 255.0f);
|
||||
}
|
||||
|
||||
static std::optional<fs::path> GenerateScreenshotFilename(bool isDRC)
|
||||
void Renderer::RequestScreenshot(ScreenshotSaveFunction onSaveScreenshot)
|
||||
{
|
||||
fs::path screendir = ActiveSettings::GetUserDataPath("screenshots");
|
||||
// build screenshot name with format Screenshot_YYYY-MM-DD_HH-MM-SS[_GamePad].png
|
||||
// if the file already exists add a suffix counter (_2.png, _3.png etc)
|
||||
std::time_t time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
std::tm* tm = std::localtime(&time_t);
|
||||
|
||||
std::string screenshotFileName = fmt::format("Screenshot_{:04}-{:02}-{:02}_{:02}-{:02}-{:02}", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
if (isDRC)
|
||||
screenshotFileName.append("_GamePad");
|
||||
|
||||
fs::path screenshotPath;
|
||||
for(sint32 i=0; i<999; i++)
|
||||
{
|
||||
screenshotPath = screendir;
|
||||
if (i == 0)
|
||||
screenshotPath.append(fmt::format("{}.png", screenshotFileName));
|
||||
else
|
||||
screenshotPath.append(fmt::format("{}_{}.png", screenshotFileName, i + 1));
|
||||
|
||||
std::error_code ec;
|
||||
bool exists = fs::exists(screenshotPath, ec);
|
||||
|
||||
if (!ec && !exists)
|
||||
return screenshotPath;
|
||||
}
|
||||
return std::nullopt;
|
||||
m_screenshot_requested = true;
|
||||
m_on_save_screenshot = onSaveScreenshot;
|
||||
}
|
||||
|
||||
std::mutex s_clipboardMutex;
|
||||
|
||||
static bool SaveScreenshotToClipboard(const wxImage &image)
|
||||
void Renderer::CancelScreenshotRequest()
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
s_clipboardMutex.lock();
|
||||
if (wxTheClipboard->Open())
|
||||
{
|
||||
wxTheClipboard->SetData(new wxImageDataObject(image));
|
||||
wxTheClipboard->Close();
|
||||
success = true;
|
||||
}
|
||||
s_clipboardMutex.unlock();
|
||||
|
||||
return success;
|
||||
m_screenshot_requested = false;
|
||||
m_on_save_screenshot = {};
|
||||
}
|
||||
|
||||
static bool SaveScreenshotToFile(const wxImage &image, bool mainWindow)
|
||||
|
||||
void Renderer::SaveScreenshot(const std::vector<uint8>& rgb_data, int width, int height, bool mainWindow)
|
||||
{
|
||||
auto path = GenerateScreenshotFilename(!mainWindow);
|
||||
if (!path) return false;
|
||||
|
||||
std::error_code ec;
|
||||
fs::create_directories(path->parent_path(), ec);
|
||||
if (ec) return false;
|
||||
|
||||
// suspend wxWidgets logging for the lifetime this object, to prevent a message box if wxImage::SaveFile fails
|
||||
wxLogNull _logNo;
|
||||
return image.SaveFile(path->wstring());
|
||||
}
|
||||
|
||||
static void ScreenshotThread(std::vector<uint8> data, bool save_screenshot, int width, int height, bool mainWindow)
|
||||
{
|
||||
#if BOOST_OS_WINDOWS
|
||||
// on Windows wxWidgets uses OLE API for the clipboard
|
||||
// to make this work we need to call OleInitialize() on the same thread
|
||||
OleInitialize(nullptr);
|
||||
#endif
|
||||
|
||||
wxImage image(width, height, data.data(), true);
|
||||
|
||||
if (mainWindow)
|
||||
{
|
||||
if(SaveScreenshotToClipboard(image))
|
||||
{
|
||||
if (!save_screenshot)
|
||||
LatteOverlay_pushNotification("Screenshot saved to clipboard", 2500);
|
||||
}
|
||||
else
|
||||
{
|
||||
LatteOverlay_pushNotification("Failed to open clipboard", 2500);
|
||||
}
|
||||
}
|
||||
|
||||
if (save_screenshot)
|
||||
{
|
||||
if (SaveScreenshotToFile(image, mainWindow))
|
||||
{
|
||||
if (mainWindow)
|
||||
LatteOverlay_pushNotification("Screenshot saved", 2500);
|
||||
}
|
||||
else
|
||||
{
|
||||
LatteOverlay_pushNotification("Failed to save screenshot to file", 2500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::SaveScreenshot(const std::vector<uint8>& rgb_data, int width, int height, bool mainWindow) const
|
||||
{
|
||||
const bool save_screenshot = GetConfig().save_screenshot;
|
||||
std::thread(ScreenshotThread, rgb_data, save_screenshot, width, height, mainWindow).detach();
|
||||
std::thread(
|
||||
[=, screenshotRequested = std::exchange(m_screenshot_requested, false), onSaveScreenshot = std::exchange(m_on_save_screenshot, {})]() {
|
||||
if (screenshotRequested && onSaveScreenshot)
|
||||
{
|
||||
auto notificationMessage = onSaveScreenshot(rgb_data, width, height, mainWindow);
|
||||
if (notificationMessage.has_value())
|
||||
LatteOverlay_pushNotification(notificationMessage.value(), 2500);
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
@@ -65,6 +65,10 @@ public:
|
||||
virtual void DrawEmptyFrame(bool mainWindow) = 0;
|
||||
virtual void SwapBuffers(bool swapTV, bool swapDRC) = 0;
|
||||
|
||||
using ScreenshotSaveFunction = std::function<std::optional<std::string>(const std::vector<uint8>&, int, int, bool)>;
|
||||
void RequestScreenshot(ScreenshotSaveFunction onSaveScreenshot);
|
||||
void CancelScreenshotRequest();
|
||||
|
||||
virtual void HandleScreenshotRequest(LatteTextureView* texView, bool padView){}
|
||||
|
||||
virtual void DrawBackbufferQuad(LatteTextureView* texView, RendererOutputShader* shader, bool useLinearTexFilter,
|
||||
@@ -168,7 +172,10 @@ protected:
|
||||
Pad,
|
||||
};
|
||||
ScreenshotState m_screenshot_state = ScreenshotState::None;
|
||||
void SaveScreenshot(const std::vector<uint8>& rgb_data, int width, int height, bool mainWindow) const;
|
||||
bool m_screenshot_requested = false;
|
||||
ScreenshotSaveFunction m_on_save_screenshot;
|
||||
|
||||
void SaveScreenshot(const std::vector<uint8>& rgb_data, int width, int height, bool mainWindow);
|
||||
|
||||
|
||||
ImFontAtlas* imguiFontAtlas{};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "SwapchainInfoVk.h"
|
||||
|
||||
#include "config/CemuConfig.h"
|
||||
#include "gui/guiWrapper.h"
|
||||
#include "WindowSystem.h"
|
||||
#include "Cafe/HW/Latte/Core/Latte.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteTiming.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h"
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
SwapchainInfoVk::SwapchainInfoVk(bool mainWindow, Vector2i size) : mainWindow(mainWindow), m_desiredExtent(size)
|
||||
{
|
||||
auto& windowHandleInfo = mainWindow ? gui_getWindowInfo().canvas_main : gui_getWindowInfo().canvas_pad;
|
||||
auto& windowHandleInfo = mainWindow ? WindowSystem::GetWindowInfo().canvas_main : WindowSystem::GetWindowInfo().canvas_pad;
|
||||
auto renderer = VulkanRenderer::GetInstance();
|
||||
m_instance = renderer->GetVkInstance();
|
||||
m_logicalDevice = renderer->GetLogicalDevice();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "gui/MainWindow.h"
|
||||
|
||||
#if BOOST_OS_WINDOWS
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#include "WindowSystem.h"
|
||||
|
||||
typedef LONG NTSTATUS;
|
||||
|
||||
typedef UINT32 D3DKMT_HANDLE;
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
private:
|
||||
bool HasMonitorChanged()
|
||||
{
|
||||
HWND hWnd = (HWND)g_mainFrame->GetRenderCanvasHWND();
|
||||
HWND hWnd = (HWND)WindowSystem::GetWindowInfo().canvas_main.surface;
|
||||
if (hWnd == 0)
|
||||
return true;
|
||||
HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
|
||||
@@ -71,9 +71,7 @@ private:
|
||||
|
||||
HRESULT GetAdapterHandleFromHwnd(D3DKMT_HANDLE* phAdapter, UINT* pOutput)
|
||||
{
|
||||
if (!g_mainFrame)
|
||||
return E_FAIL;
|
||||
HWND hWnd = (HWND)g_mainFrame->GetRenderCanvasHWND();
|
||||
HWND hWnd = (HWND)WindowSystem::GetWindowInfo().canvas_main.surface;
|
||||
if (hWnd == 0)
|
||||
return E_FAIL;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user