diff --git a/src/Cafe/Account/Account.cpp b/src/Cafe/Account/Account.cpp index f1ce0be8..26767049 100644 --- a/src/Cafe/Account/Account.cpp +++ b/src/Cafe/Account/Account.cpp @@ -1,8 +1,6 @@ #include "Account.h" #include "util/helpers/helpers.h" -#include "gui/CemuApp.h" #include "util/helpers/SystemException.h" - #include "config/ActiveSettings.h" #include "Cafe/IOSU/legacy/iosu_crypto.h" #include "Common/FileStream.h" @@ -175,7 +173,7 @@ std::error_code Account::Load() std::error_code Account::Save() { - fs::path path = CemuApp::GetMLCPath(fmt::format(L"usr/save/system/act/{:08x}", m_persistent_id)).ToStdWstring(); + fs::path path = ActiveSettings::GetMlcPath(fmt::format(L"usr/save/system/act/{:08x}", m_persistent_id)); if (!fs::exists(path)) { std::error_code ec; @@ -184,7 +182,7 @@ std::error_code Account::Save() return ec; } - path /= L"account.dat"; + path /= "account.dat"; try { @@ -302,7 +300,7 @@ void Account::SetMiiName(std::wstring_view name) const std::vector& Account::RefreshAccounts() { std::vector result; - const fs::path path = CemuApp::GetMLCPath(L"usr/save/system/act").ToStdWstring(); + const fs::path path = ActiveSettings::GetMlcPath("usr/save/system/act"); if (fs::exists(path)) { for (const auto& it : fs::directory_iterator(path)) @@ -417,7 +415,7 @@ fs::path Account::GetFileName(uint32 persistent_id) if (persistent_id < kMinPersistendId) throw std::invalid_argument(fmt::format("persistent id {:#x} is invalid", persistent_id)); - return CemuApp::GetMLCPath(fmt::format(L"usr/save/system/act/{:08x}/account.dat", persistent_id)).ToStdWstring(); + return ActiveSettings::GetMlcPath(fmt::format("usr/save/system/act/{:08x}/account.dat", persistent_id)); } OnlineValidator Account::ValidateOnlineFiles() const diff --git a/src/Cafe/CMakeLists.txt b/src/Cafe/CMakeLists.txt index 9c671b1e..3c49b60d 100644 --- a/src/Cafe/CMakeLists.txt +++ b/src/Cafe/CMakeLists.txt @@ -454,8 +454,6 @@ add_library(CemuCafe TitleList/BaseInfo.cpp TitleList/BaseInfo.h TitleList/GameInfo.h - TitleList/MetaInfo.cpp - TitleList/MetaInfo.h TitleList/ParsedMetaXml.h TitleList/SaveInfo.cpp TitleList/SaveInfo.h diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index cb58284d..ef3e2806 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -337,7 +337,7 @@ uint32 loadSharedData() // advance write offset and pad to 16 byte alignment dataWritePtr += ((fileSize + 15) & ~15); } - forceLog_printfW(L"COS: System fonts found. Generated shareddata (%dKB)", (uint32)(dataWritePtr - (uint8*)shareddataTable) / 1024); + cemuLog_log(LogType::Force, "COS: System fonts found. Generated shareddata ({}KB)", (uint32)(dataWritePtr - (uint8*)shareddataTable) / 1024); return memory_getVirtualOffsetFromPointer(dataWritePtr); } // alternative method: load RAM dump diff --git a/src/Cafe/GamePatch.cpp b/src/Cafe/GamePatch.cpp index bd4630fe..4134287e 100644 --- a/src/Cafe/GamePatch.cpp +++ b/src/Cafe/GamePatch.cpp @@ -139,7 +139,7 @@ void hle_scan(uint8* data, sint32 dataLength, char* hleFunctionName) uint32 offset = (uint32)(scanCurrent - scanStart) + 0x01000000; debug_printf("HLE signature for '%s' found at 0x%08x\n", hleFunctionName, offset); uint32 opcode = (1<<26)|(functionIndex+0x1000); // opcode for HLE: 0x1000 + FunctionIndex - memory_writeU32Direct(offset, opcode); + memory_write(offset, opcode); break; } scanCurrent += 4; @@ -330,7 +330,7 @@ void GamePatch_scan() #endif sint32 functionIndex = hleIndex_h000000001; uint32 opcode = (1 << 26) | (functionIndex); // opcode for HLE: 0x1000 + FunctionIndex - memory_writeU32Direct(hleAddr - 4, opcode); + memory_write(hleAddr - 4, opcode); } hleIndex_h000000002 = osLib_getFunctionIndex("hle", "h000000002"); hleAddr = hle_locate(botw_busyLoopSignature2, botw_busyLoopMask2, sizeof(botw_busyLoopSignature2)); @@ -341,7 +341,7 @@ void GamePatch_scan() #endif sint32 functionIndex = hleIndex_h000000002; uint32 opcode = (1 << 26) | (functionIndex); // opcode for HLE: 0x1000 + FunctionIndex - memory_writeU32Direct(hleAddr - 4, opcode); + memory_write(hleAddr - 4, opcode); } // FFL library float array endian conversion @@ -353,7 +353,7 @@ void GamePatch_scan() forceLogDebug_printf("HLE: Hook FFL float array endian swap function at 0x%08x", hleAddr); sint32 functionIndex = hleIndex_h000000003; uint32 opcode = (1 << 26) | (functionIndex); // opcode for HLE: 0x1000 + FunctionIndex - memory_writeU32Direct(hleAddr, opcode); + memory_write(hleAddr, opcode); } // XCX freeze workaround diff --git a/src/Cafe/GraphicPack/GraphicPack2.cpp b/src/Cafe/GraphicPack/GraphicPack2.cpp index 0aa9e785..a0045f13 100644 --- a/src/Cafe/GraphicPack/GraphicPack2.cpp +++ b/src/Cafe/GraphicPack/GraphicPack2.cpp @@ -500,6 +500,14 @@ GraphicPack2::GraphicPack2(std::wstring filename, IniParser& rules) } } +// returns true if enabling, disabling (changeEnableState) or changing presets (changePreset) for the graphic pack requires restarting if the game is already running +bool GraphicPack2::RequiresRestart(bool changeEnableState, bool changePreset) +{ + if (!GetTextureRules().empty()) + return true; + return false; +} + bool GraphicPack2::Reload() { Deactivate(); diff --git a/src/Cafe/GraphicPack/GraphicPack2.h b/src/Cafe/GraphicPack/GraphicPack2.h index 4c18b5c6..a087f757 100644 --- a/src/Cafe/GraphicPack/GraphicPack2.h +++ b/src/Cafe/GraphicPack/GraphicPack2.h @@ -105,6 +105,7 @@ public: sint32 GetVersion() const { return m_version; } const std::wstring& GetFilename() const { return m_filename; } const fs::path GetFilename2() const { return fs::path(m_filename); } + bool RequiresRestart(bool changeEnableState, bool changePreset); bool Reload(); bool HasName() const { return !m_name.empty(); } @@ -172,6 +173,7 @@ public: static void ActivateForCurrentTitle(); static void Reset(); + private: bool Activate(); bool Deactivate(); diff --git a/src/Cafe/GraphicPack/GraphicPack2Patches.cpp b/src/Cafe/GraphicPack/GraphicPack2Patches.cpp index 3910000a..ffd36074 100644 --- a/src/Cafe/GraphicPack/GraphicPack2Patches.cpp +++ b/src/Cafe/GraphicPack/GraphicPack2Patches.cpp @@ -102,14 +102,14 @@ bool GraphicPack2::LoadCemuPatches() // load Cemu style patch file if (!ParseCemuPatchesTxtInternal(patchesStream)) { - forceLog_printfW(L"Error while processing \"%s\". No patches for this graphic pack will be applied.", path.c_str()); + cemuLog_log(LogType::Force, "Error while processing \"{}\". No patches for this graphic pack will be applied.", _pathToUtf8(path)); cemu_assert_debug(list_patchGroups.empty()); return true; // return true since a .asm patch was found even if we could not parse it } } else { - forceLog_printfW(L"Unable to load patch file \"%s\"", path.c_str()); + cemuLog_log(LogType::Force, "Unable to load patch file \"{}\"", _pathToUtf8(path)); } foundPatches = true; } diff --git a/src/Cafe/HW/Latte/Core/LatteCommandProcessor.cpp b/src/Cafe/HW/Latte/Core/LatteCommandProcessor.cpp index 95d9bab3..fffa9df5 100644 --- a/src/Cafe/HW/Latte/Core/LatteCommandProcessor.cpp +++ b/src/Cafe/HW/Latte/Core/LatteCommandProcessor.cpp @@ -559,19 +559,19 @@ LatteCMDPtr LatteCP_itLoadReg(LatteCMDPtr cmd, uint32 nWords, uint32 regBase) MPTR physAddressRegArea = LatteReadCMD(); uint32 waitForIdle = LatteReadCMD(); uint32 loadEntries = (nWords - 2) / 2; - uint32 regIndex = 0; + uint32 regShadowMemAddr = physAddressRegArea; for (uint32 i = 0; i < loadEntries; i++) { uint32 regOffset = LatteReadCMD(); uint32 regCount = LatteReadCMD(); cemu_assert_debug(regCount != 0); + uint32 regAddr = regBase + regOffset; for (uint32 f = 0; f < regCount; f++) { - uint32 regAddr = regBase + regOffset + f; - uint32 regShadowMemAddr = physAddressRegArea + regIndex * 4; LatteGPUState.contextRegisterShadowAddr[regAddr] = regShadowMemAddr; - LatteGPUState.contextRegister[regAddr] = memory_readU32Direct(regShadowMemAddr); - regIndex++; + LatteGPUState.contextRegister[regAddr] = memory_read(regShadowMemAddr); + regAddr++; + regShadowMemAddr += 4; } } return cmd; @@ -716,7 +716,7 @@ LatteCMDPtr LatteCP_itHLESampleTimer(LatteCMDPtr cmd, uint32 nWords) { cemu_assert_debug(nWords == 1); MPTR timerMPTR = (MPTR)LatteReadCMD(); - memory_writeU64Slow(timerMPTR, coreinit::coreinit_getTimerTick()); + memory_writeU64(timerMPTR, coreinit::coreinit_getTimerTick()); return cmd; } diff --git a/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp b/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp index 048df102..936378b9 100644 --- a/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp +++ b/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp @@ -219,7 +219,7 @@ void LatteShaderCache_load() if(!fc_shaderCacheGeneric) { // no shader cache available yet - forceLog_printfW(L"Unable to open or create shader cache file \"%s\"", pathGeneric.c_str()); + cemuLog_log(LogType::Force, "Unable to open or create shader cache file \"{}\"", _pathToUtf8(pathGeneric)); LatteShaderCache_finish(); return; } diff --git a/src/Cafe/HW/Latte/Core/LatteTextureLoader.cpp b/src/Cafe/HW/Latte/Core/LatteTextureLoader.cpp index c873bbb8..7782e3d6 100644 --- a/src/Cafe/HW/Latte/Core/LatteTextureLoader.cpp +++ b/src/Cafe/HW/Latte/Core/LatteTextureLoader.cpp @@ -695,7 +695,7 @@ void LatteTextureLoader_UpdateTextureSliceData(LatteTexture* tex, sint32 texture if (textureLoader.dump) { wchar_t path[1024]; - swprintf(path, 1024, L"dump\\textures\\%08x_fmt%04x_slice%d_mip%02d_%dx%d_tm%02d.tga", physImagePtr, (uint32)tex->format, sliceIndex, mipIndex, tex->width, tex->height, tileMode); + swprintf(path, 1024, L"dump/textures/%08x_fmt%04x_slice%d_mip%02d_%dx%d_tm%02d.tga", physImagePtr, (uint32)tex->format, sliceIndex, mipIndex, tex->width, tex->height, tileMode); tga_write_rgba(path, textureLoader.width, textureLoader.height, textureLoader.dumpRGBA); free(textureLoader.dumpRGBA); } diff --git a/src/Cafe/HW/MMU/MMU.cpp b/src/Cafe/HW/MMU/MMU.cpp index 9e22d907..00de8312 100644 --- a/src/Cafe/HW/MMU/MMU.cpp +++ b/src/Cafe/HW/MMU/MMU.cpp @@ -293,11 +293,6 @@ uint8* memory_getPointerFromVirtualOffsetAllowNull(uint32 virtualOffset) return memory_getPointerFromVirtualOffset(virtualOffset); } -void memory_writeU32Direct(uint32 address, uint32 v) -{ - *(uint32*)(memory_getPointerFromVirtualOffset(address)) = CPU_swapEndianU32(v); -} - // write access void memory_writeDouble(uint32 address, double vf) { @@ -320,12 +315,6 @@ void memory_writeU32(uint32 address, uint32 v) *(uint32*)(memory_getPointerFromVirtualOffset(address)) = CPU_swapEndianU32(v); } -void memory_writeU64Slow(uint32 address, uint64 v) -{ - memory_writeU32(address+0, (v>>32)&0xFFFFFFFF); - memory_writeU32(address+4, (v)&0xFFFFFFFF); -} - void memory_writeU64(uint32 address, uint64 v) { *(uint64*)(memory_getPointerFromVirtualOffset(address)) = CPU_swapEndianU64(v); @@ -372,12 +361,6 @@ uint32 memory_readU32(uint32 address) return CPU_swapEndianU32(v); } -uint32 memory_readU32Direct(uint32 address) -{ - uint32 v = *(uint32*)(memory_getPointerFromVirtualOffset(address)); - return CPU_swapEndianU32(v); -} - uint16 memory_readU16(uint32 address) { uint16 v = *(uint16*)(memory_getPointerFromVirtualOffset(address)); diff --git a/src/Cafe/HW/MMU/MMU.h b/src/Cafe/HW/MMU/MMU.h index 63272440..03238aaa 100644 --- a/src/Cafe/HW/MMU/MMU.h +++ b/src/Cafe/HW/MMU/MMU.h @@ -15,7 +15,7 @@ uint8* memory_getPointerFromPhysicalOffset(uint32 physicalOffset); uint32 memory_virtualToPhysical(uint32 virtualOffset); uint32 memory_physicalToVirtual(uint32 physicalOffset); -extern uint8* memory_base; // points to 0x00000000 +extern uint8* memory_base; // points to base of PowerPC address space enum class MMU_MEM_AREA_ID { @@ -171,33 +171,26 @@ bool memory_isAddressRangeAccessible(MPTR virtualAddress, uint32 size); #define MEMORY_SHAREDDATA_AREA_ADDR (0xF8000000) #define MEMORY_SHAREDDATA_AREA_SIZE (0x02000000) // 32MB -static uint16 CPU_swapEndianU16(uint16 v) -{ - return (v>>8)|(v<<8); -} - #if BOOST_OS_WINDOWS #define CPU_swapEndianU64(_v) _byteswap_uint64((uint64)(_v)) #define CPU_swapEndianU32(_v) _byteswap_ulong((uint32)(_v)) +#define CPU_swapEndianU16(_v) _byteswap_ushort((uint16)(_v)) #elif BOOST_OS_LINUX #define CPU_swapEndianU64(_v) bswap_64((uint64)(_v)) #define CPU_swapEndianU32(_v) bswap_32((uint32)(_v)) +#define CPU_swapEndianU16(_v) bswap_16((uint16)(_v)) #elif BOOST_OS_MACOS #define CPU_swapEndianU64(_v) OSSwapInt64((uint64)(_v)) #define CPU_swapEndianU32(_v) OSSwapInt32((uint32)(_v)) +#define CPU_swapEndianU16(_v) OSSwapInt16((uint16)(_v)) #endif -// direct memory access (no hardware interface access) -void memory_writeU32Direct(uint32 address, uint32 v); -uint32 memory_readU32Direct(uint32 address); - -// memory access (includes hardware interface, slower) +// C-style memory access, deprecated. Use memory_read<> and memory_write<> templates instead void memory_writeDouble(uint32 address, double vf); void memory_writeFloat(uint32 address, float vf); void memory_writeU32(uint32 address, uint32 v); void memory_writeU16(uint32 address, uint16 v); void memory_writeU8(uint32 address, uint8 v); -void memory_writeU64Slow(uint32 address, uint64 v); void memory_writeU64(uint32 address, uint64 v); double memory_readDouble(uint32 address); @@ -210,43 +203,24 @@ uint8 memory_readU8(uint32 address); void memory_createDump(); template -void memory_readBytes(uint32 address, std::array& buffer) +void memory_readBytes(VAddr address, std::array& buffer) { memcpy(buffer.data(), memory_getPointerFromVirtualOffset(address), count); } -template T memory_read(uint32 address) +template inline T memory_read(VAddr address) { - if constexpr(std::is_floating_point::value) - { - if constexpr(sizeof(T) == sizeof(float)) - return memory_readFloat(address); - else - return memory_readDouble(address); - } - else if(std::is_integral::value) - { - if constexpr (sizeof(T) == sizeof(uint8)) - return (T)memory_readU8(address); - else if constexpr (sizeof(T) == sizeof(uint16)) - return (T)memory_readU16(address); - else if constexpr (sizeof(T) == sizeof(uint32)) - return (T)memory_readU32(address); - else if constexpr (sizeof(T) == sizeof(uint64)) - return (T)memory_readU64(address); - } + return *(betype*)(memory_base + address); +} - debugBreakpoint(); - return {}; +template inline void memory_write(VAddr address, T value) +{ + *(betype*)(memory_base + address) = value; } // LLE implementation void memory_initPhysicalLayout(); -// updated code -using EAddr = uint32; // effective address -using PAddr = uint32; // physical address - namespace MMU { using MMIOFuncWrite32 = void (*)(PAddr addr, uint32 value); diff --git a/src/Cafe/OS/RPL/rpl.cpp b/src/Cafe/OS/RPL/rpl.cpp index 43e39d5b..ab127354 100644 --- a/src/Cafe/OS/RPL/rpl.cpp +++ b/src/Cafe/OS/RPL/rpl.cpp @@ -734,7 +734,7 @@ uint32 RPLLoader_MakePPCCallable(void(*ppcCallableExport)(PPCInterpreter_t* hCPU sint32 functionIndex = PPCInterpreter_registerHLECall(ppcCallableExport); MPTR codeAddr = memory_getVirtualOffsetFromPointer(RPLLoader_AllocateTrampolineCodeSpace(4)); uint32 opcode = (1 << 26) | functionIndex; - memory_writeU32Direct(codeAddr, opcode); + memory_write(codeAddr, opcode); g_map_callableExports[ppcCallableExport] = codeAddr; return codeAddr; } @@ -772,7 +772,7 @@ uint32 rpl_mapHLEImport(RPLModule* rplLoaderContext, const char* rplName, const { MPTR codeAddr = memory_getVirtualOffsetFromPointer(RPLLoader_AllocateTrampolineCodeSpace(4)); uint32 opcode = (1 << 26) | functionIndex; - memory_writeU32Direct(codeAddr, opcode); + memory_write(codeAddr, opcode); // register mapped import mappedFunctionImport_t newImport; newImport.hash1 = mappedImportHash1; @@ -792,8 +792,8 @@ uint32 rpl_mapHLEImport(RPLModule* rplLoaderContext, const char* rplName, const uint32 codeStart = memory_getVirtualOffsetFromPointer(RPLLoader_AllocateTrampolineCodeSpace(256)); uint32 currentAddress = codeStart; uint32 opcode = (1 << 26) | (0xFFD0); // opcode for HLE: Unsupported import - memory_writeU32Direct(codeStart + 0, opcode); - memory_writeU32Direct(codeStart + 4, 0x4E800020); + memory_write(codeStart + 0, opcode); + memory_write(codeStart + 4, 0x4E800020); currentAddress += 8; // write name of lib/function sint32 libNameLength = std::min(128, (sint32)strlen(libName)); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp index 25c142cc..74087a7e 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp @@ -176,12 +176,11 @@ namespace coreinit alarm->setMagic(); } - void coreinitExport_OSCreateAlarmEx(PPCInterpreter_t* hCPU) + void OSCreateAlarmEx(OSAlarm_t* alarm, const char* alarmName) { - OSAlarm_t* OSAlarm = (OSAlarm_t*)memory_getPointerFromVirtualOffset(hCPU->gpr[3]); - OSCreateAlarm(OSAlarm); - OSAlarm->name = _swapEndianU32(hCPU->gpr[4]); - osLib_returnFromFunction(hCPU, 0); + memset(alarm, 0, sizeof(OSAlarm_t)); + alarm->setMagic(); + alarm->name = alarmName; } std::unordered_map g_activeAlarms; @@ -274,14 +273,12 @@ namespace coreinit void OSSetAlarmUserData(OSAlarm_t* alarm, uint32 userData) { - alarm->userData = _swapEndianU32(userData); + alarm->userData = userData; } - void coreinitExport_OSGetAlarmUserData(PPCInterpreter_t* hCPU) + uint32 OSGetAlarmUserData(OSAlarm_t* alarm) { - OSAlarm_t* OSAlarmBE = (OSAlarm_t*)memory_getPointerFromVirtualOffset(hCPU->gpr[3]); - MPTR userData = _swapEndianU32(OSAlarmBE->userData); - osLib_returnFromFunction(hCPU, userData); + return alarm->userData; } void OSAlarm_resetAll() @@ -337,15 +334,13 @@ namespace coreinit void InitializeAlarm() { - cafeExportRegister("coreinit", OSCreateAlarm, LogType::Placeholder); - cafeExportRegister("coreinit", OSCancelAlarm, LogType::Placeholder); - cafeExportRegister("coreinit", OSSetAlarm, LogType::Placeholder); - cafeExportRegister("coreinit", OSSetPeriodicAlarm, LogType::Placeholder); - - cafeExportRegister("coreinit", OSSetAlarmUserData, LogType::Placeholder); - - osLib_addFunction("coreinit", "OSCreateAlarmEx", coreinitExport_OSCreateAlarmEx); - osLib_addFunction("coreinit", "OSGetAlarmUserData", coreinitExport_OSGetAlarmUserData); + cafeExportRegister("coreinit", OSCreateAlarm, LogType::CoreinitAlarm); + cafeExportRegister("coreinit", OSCreateAlarmEx, LogType::CoreinitAlarm); + cafeExportRegister("coreinit", OSCancelAlarm, LogType::CoreinitAlarm); + cafeExportRegister("coreinit", OSSetAlarm, LogType::CoreinitAlarm); + cafeExportRegister("coreinit", OSSetPeriodicAlarm, LogType::CoreinitAlarm); + cafeExportRegister("coreinit", OSSetAlarmUserData, LogType::CoreinitAlarm); + cafeExportRegister("coreinit", OSGetAlarmUserData, LogType::CoreinitAlarm); // init event OSInitEvent(g_alarmEvent.GetPtr(), OSEvent::EVENT_STATE::STATE_NOT_SIGNALED, OSEvent::EVENT_MODE::MODE_AUTO); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h index 717ecc90..a67beca7 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h @@ -3,7 +3,6 @@ namespace coreinit { - class OSHostAlarm; OSHostAlarm* OSHostAlarmCreate(uint64 nextFire, uint64 period, void(*callbackFunc)(uint64 currentTick, void* context), void* context); void OSHostAlarmDestroy(OSHostAlarm* hostAlarm); @@ -11,7 +10,7 @@ namespace coreinit struct OSAlarm_t { /* +0x00 */ betype magic; - /* +0x04 */ MPTR_UINT8 name; + /* +0x04 */ MEMPTR name; /* +0x08 */ uint32 ukn08; /* +0x0C */ MPTR handler; /* +0x10 */ uint32 ukn10; @@ -21,7 +20,7 @@ namespace coreinit /* +0x24 */ MPTR next; // pointer to OSAlarm /* +0x28 */ uint64 period; // period (zero for non-periodic timer) /* +0x30 */ uint64 startTime; // period start - /* +0x38 */ MPTR userData; + /* +0x38 */ uint32be userData; /* +0x3C */ uint32 ukn3C; /* +0x40 */ OSThreadQueue uknThreadQueue; /* +0x50 */ MPTR alarmQueue; diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h index 615e51d9..bb0aca91 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h @@ -428,8 +428,8 @@ struct OSThread_t /* +0x38C */ coreinit::OSThreadLink activeThreadChain; // queue of active threads (g_activeThreadQueue) - /* +0x394 */ MPTR_UINT8 stackBase; // upper limit of stack - /* +0x398 */ MPTR_UINT32 stackEnd; // lower limit of stack + /* +0x394 */ MPTR stackBase; // upper limit of stack + /* +0x398 */ MPTR stackEnd; // lower limit of stack /* +0x39C */ MPTR entrypoint; /* +0x3A0 */ crt_t crt; @@ -443,8 +443,7 @@ struct OSThread_t /* +0x5C8 */ uint32 userStackPointer; /* +0x5CC */ MEMPTR cleanupCallback2; - /* +0x5D0 */ //MPTR deallocator; - MEMPTR deallocatorFunc; + /* +0x5D0 */ MEMPTR deallocatorFunc; /* +0x5D4 */ uint32 stateFlags; // 0x5D4 | various flags? Controls if canceling/suspension is allowed (at cancel points) or not? If 1 -> Cancel/Suspension not allowed, if 0 -> Cancel/Suspension allowed /* +0x5D8 */ betype requestFlags; diff --git a/src/Cafe/OS/libs/gx2/GX2_Misc.cpp b/src/Cafe/OS/libs/gx2/GX2_Misc.cpp index ae079dc1..1f20cac5 100644 --- a/src/Cafe/OS/libs/gx2/GX2_Misc.cpp +++ b/src/Cafe/OS/libs/gx2/GX2_Misc.cpp @@ -37,8 +37,8 @@ void gx2Export_GX2GetSwapStatus(PPCInterpreter_t* hCPU) { memory_writeU32(hCPU->gpr[3], _swapEndianU32(LatteGPUState.sharedArea->flipRequestCountBE)); memory_writeU32(hCPU->gpr[4], _swapEndianU32(LatteGPUState.sharedArea->flipExecuteCountBE)); - memory_writeU64Slow(hCPU->gpr[5], lastSwapTime); - memory_writeU64Slow(hCPU->gpr[6], lastSwapTime); + memory_writeU64(hCPU->gpr[5], lastSwapTime); + memory_writeU64(hCPU->gpr[6], lastSwapTime); osLib_returnFromFunction(hCPU, 0); } @@ -54,14 +54,14 @@ void gx2Export_GX2GetGPUTimeout(PPCInterpreter_t* hCPU) void gx2Export_GX2SampleTopGPUCycle(PPCInterpreter_t* hCPU) { gx2Log_printf("GX2SampleTopGPUCycle(0x%08x)\n", hCPU->gpr[3]); - memory_writeU64Slow(hCPU->gpr[3], coreinit::coreinit_getTimerTick()); + memory_writeU64(hCPU->gpr[3], coreinit::coreinit_getTimerTick()); osLib_returnFromFunction(hCPU, 0); } void gx2Export_GX2SampleBottomGPUCycle(PPCInterpreter_t* hCPU) { gx2Log_printf("GX2SampleBottomGPUCycle(0x%08x)\n", hCPU->gpr[3]); - memory_writeU64Slow(hCPU->gpr[3], GX2_INVALID_COUNTER_VALUE_U64); + memory_writeU64(hCPU->gpr[3], GX2_INVALID_COUNTER_VALUE_U64); osLib_returnFromFunction(hCPU, 0); return; diff --git a/src/Cafe/OS/libs/nn_temp/nn_temp.cpp b/src/Cafe/OS/libs/nn_temp/nn_temp.cpp index 7ed619ad..2e0030ca 100644 --- a/src/Cafe/OS/libs/nn_temp/nn_temp.cpp +++ b/src/Cafe/OS/libs/nn_temp/nn_temp.cpp @@ -9,7 +9,7 @@ namespace nn::temp forceLogDebug_printf("TEMPCreateAndInitTempDir(...) - placeholder"); // create random temp id - memory_writeU64Slow(hCPU->gpr[5], tempIdGenerator); + memory_writeU64(hCPU->gpr[5], tempIdGenerator); tempIdGenerator = (tempIdGenerator << 3) | (tempIdGenerator >> 61); tempIdGenerator += 0x56e28bd5f4ULL; diff --git a/src/Cafe/OS/libs/nsyshid/nsyshid.cpp b/src/Cafe/OS/libs/nsyshid/nsyshid.cpp index 8c390c0a..e6ae8815 100644 --- a/src/Cafe/OS/libs/nsyshid/nsyshid.cpp +++ b/src/Cafe/OS/libs/nsyshid/nsyshid.cpp @@ -118,7 +118,7 @@ namespace nsyshid deviceItr->hFile = openDevice(deviceItr->devicePath); if (deviceItr->hFile == INVALID_HANDLE_VALUE) { - forceLog_printfW(L"HID: Failed to open device \"%s\"", deviceItr->devicePath); + cemuLog_log(LogType::Force, "HID: Failed to open device \"{}\"", boost::nowide::narrow(std::wstring(deviceItr->devicePath))); return nullptr; } HidD_SetNumInputBuffers(deviceItr->hFile, 2); // dont cache too many reports diff --git a/src/Cafe/TitleList/GameInfo.h b/src/Cafe/TitleList/GameInfo.h index 3a2e6121..c8809a16 100644 --- a/src/Cafe/TitleList/GameInfo.h +++ b/src/Cafe/TitleList/GameInfo.h @@ -1,7 +1,6 @@ #pragma once #include "config/CemuConfig.h" -#include "MetaInfo.h" #include "TitleInfo.h" #include "config/ActiveSettings.h" diff --git a/src/Cafe/TitleList/MetaInfo.cpp b/src/Cafe/TitleList/MetaInfo.cpp deleted file mode 100644 index b08c4fc2..00000000 --- a/src/Cafe/TitleList/MetaInfo.cpp +++ /dev/null @@ -1,179 +0,0 @@ -#include "MetaInfo.h" -#include "Cafe/Filesystem/fsc.h" - -#include "pugixml.hpp" -#include "Cafe/Filesystem/FST/FST.h" - -MetaInfo::MetaInfo() -{ - m_type = GameType::FSC; - - uint32 meta_size; - const auto meta_data = ReadFSCFile("vol/meta/meta.xml", meta_size); - if (meta_size == 0 || !meta_data) - throw std::runtime_error("meta.xml missing"); - - pugi::xml_document meta_doc; - ParseMetaFile(meta_doc, meta_doc.load_buffer_inplace(meta_data.get(), meta_size)); -} - -MetaInfo::MetaInfo(const fs::path& filename) -{ - if (!fs::exists(filename)) - throw std::invalid_argument("filename doesn't exist"); - - if (fs::is_directory(filename)) - { - MetaInfo::ParseDirectory(filename); - m_type = GameType::Directory; - m_type_path = filename; - } - else - MetaInfo::ParseFile(filename); -} - -std::string MetaInfo::GetName(CafeConsoleLanguage language) const -{ - std::string long_name{ GetLongName(language) }; - const auto nl = long_name.find(L'\n'); - if (nl != std::string::npos) - long_name.replace(nl, 1, " - "); - - return long_name; -} - -const std::string& MetaInfo::GetLongName(CafeConsoleLanguage language) const -{ - return m_long_name[(int)language].empty() ? m_long_name[(int)CafeConsoleLanguage::EN] : m_long_name[(int)language]; -} - -const std::string& MetaInfo::GetShortName(CafeConsoleLanguage language) const -{ - return m_short_name[(int)language].empty() ? m_short_name[(int)CafeConsoleLanguage::EN] : m_short_name[(int)language]; -} - -const std::string& MetaInfo::GetPublisher(CafeConsoleLanguage language) const -{ - return m_publisher[(int)language].empty() ? m_publisher[(int)CafeConsoleLanguage::EN] : m_publisher[(int)language]; -} - -void MetaInfo::ParseDirectory(const fs::path& filename) -{ - const auto meta_dir = fs::path(filename).append(L"meta"); - if (!fs::exists(meta_dir) || !fs::is_directory(meta_dir)) - throw std::invalid_argument("meta directory missing"); - - const auto meta_file = meta_dir / L"meta.xml"; - if (!fs::exists(meta_file) || !fs::is_regular_file(meta_file)) - throw std::invalid_argument("meta.xml missing"); - - ParseMetaFile(meta_file.wstring()); -} - -bool MetaInfo::ParseFile(const fs::path& filename) -{ - if (filename.filename() != "meta.xml") - return false; - - const auto base_dir = filename.parent_path().parent_path(); - - ParseMetaFile(filename); - m_type = GameType::Directory; - m_type_path = base_dir; - return true; -} - -void MetaInfo::ParseMetaFile(const fs::path& meta_file) -{ - pugi::xml_document doc; - const auto result = doc.load_file(meta_file.wstring().c_str()); - ParseMetaFile(doc, result); -} - -void MetaInfo::ParseMetaFile(const pugi::xml_document& doc, const pugi::xml_parse_result& result) -{ - if (!result) - throw std::invalid_argument(fmt::format("error when parsing the meta.xml: {}", result.description())); - - const auto root = doc.child("menu"); - if (!root) - throw std::invalid_argument("meta.xml invalid"); - - for (const auto& child : root.children()) - { - std::string_view name = child.name(); - if (name == "title_version") - m_version = child.text().as_uint(); - else if (name == "product_code") - m_product_code = child.text().as_string(); - else if (name == "company_code") - m_company_code = child.text().as_string(); - else if (name == "content_platform") - m_content_platform = child.text().as_string(); - else if (name == "title_id") - m_title_id = std::stoull(child.text().as_string(), nullptr, 16); - else if (name == "region") - m_region = (CafeConsoleRegion)child.text().as_uint(); - else if (boost::starts_with(name, "longname_")) - { - const sint32 index = GetLanguageIndex(name.substr(std::size("longname_") - 1)); - if (index != -1) - m_long_name[index] = child.text().as_string(); - } - else if (boost::starts_with(name, L"shortname_")) - { - const sint32 index = GetLanguageIndex(name.substr(std::size("shortname_") - 1)); - if (index != -1) - m_short_name[index] = child.text().as_string(); - } - else if (boost::starts_with(name, L"publisher_")) - { - const sint32 index = GetLanguageIndex(name.substr(std::size("publisher_") - 1)); - if (index != -1) - m_publisher[index] = child.text().as_string(); - } - } -} - -std::unique_ptr MetaInfo::GetIcon(uint32& size) const -{ - size = 0; - switch (m_type) - { - case GameType::FSC: - return ReadFSCFile("vol/meta/iconTex.tga", size); - case GameType::Directory: - { - cemu_assert_debug(!m_type_path.empty()); - const auto icon = fs::path(m_type_path).append(L"meta").append(L"iconTex.tga"); - std::ifstream file(icon, std::ios::binary | std::ios::ate); - if (file.is_open()) - { - size = file.tellg(); - if (size > 0) - { - file.seekg(0, std::ios::beg); - auto result = std::make_unique(size); - file.read((char*)result.get(), size); - return result; - } - } - return nullptr; - } - case GameType::Image: - { - cemu_assert_debug(!m_type_path.empty()); - FSTVolume* volume = FSTVolume::OpenFromDiscImage(m_type_path); - if (volume) - { - auto result = ReadVirtualFile(volume, "meta/iconTex.tga", size); - delete volume; - return result; - } - return nullptr; - } - default: - UNREACHABLE; - } - return nullptr; -} diff --git a/src/Cafe/TitleList/MetaInfo.h b/src/Cafe/TitleList/MetaInfo.h deleted file mode 100644 index bcd511c3..00000000 --- a/src/Cafe/TitleList/MetaInfo.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include "BaseInfo.h" -#include "config/CemuConfig.h" - -class MetaInfo : public BaseInfo -{ -public: - MetaInfo(); - MetaInfo(const fs::path& filename); - - // returns long name with replaces newlines to ' - ' - [[nodiscard]] std::string GetName(CafeConsoleLanguage language = CafeConsoleLanguage::EN) const; - - [[nodiscard]] uint64 GetTitleId() const { return m_title_id; } - [[nodiscard]] uint32 GetTitleIdHigh() const { return (uint32)(GetTitleId() >> 32); } - [[nodiscard]] uint32 GetTitleIdLow() const { return (uint32)(GetTitleId() & 0xFFFFFFFF); } - - [[nodiscard]] uint64 GetBaseTitleId() const { return m_title_id & ~0xF00000000ULL; } - [[nodiscard]] uint32 GetBaseTitleIdHigh() const { return (uint32)(GetBaseTitleId() >> 32); } - [[nodiscard]] uint32 GetBaseTitleIdLow() const { return (uint32)(GetBaseTitleId() & 0xFFFFFFFF); } - - [[nodiscard]] uint64 GetUpdateTitleId() const { return GetBaseTitleId() | 0xE00000000ULL; } - [[nodiscard]] uint32 GetUpdateTitleIdHigh() const { return (uint32)(GetUpdateTitleId() >> 32); } - [[nodiscard]] uint32 GetUpdateTitleIdLow() const { return (uint32)(GetUpdateTitleId() & 0xFFFFFFFF); } - - [[nodiscard]] uint64 GetDLCTitleId() const { return GetBaseTitleId() | 0xC00000000ULL; } - [[nodiscard]] uint32 GetDLCTitleIdHigh() const { return (uint32)(GetDLCTitleId() >> 32); } - [[nodiscard]] uint32 GetDLCTitleIdLow() const { return (uint32)(GetDLCTitleId() & 0xFFFFFFFF); } - - [[nodiscard]] const std::string& GetLongName(CafeConsoleLanguage language) const; - [[nodiscard]] const std::string& GetShortName(CafeConsoleLanguage language) const; - [[nodiscard]] const std::string& GetPublisher(CafeConsoleLanguage language) const; - [[nodiscard]] const std::string& GetProductCode() const { return m_product_code; } - [[nodiscard]] const std::string& GetCompanyCode() const { return m_company_code; } - [[nodiscard]] const std::string& GetContentPlatform() const { return m_content_platform; } - [[nodiscard]] uint32 GetVersion() const { return m_version; } - [[nodiscard]] CafeConsoleRegion GetRegion() const { return m_region; } - - [[nodiscard]] std::unique_ptr GetIcon(uint32& size) const; - -protected: - // meta.xml - uint32 m_version; - std::string m_product_code; - std::string m_company_code; - std::string m_content_platform; - uint64 m_title_id; - CafeConsoleRegion m_region; - - std::array m_long_name; - std::array m_short_name; - std::array m_publisher; - - void ParseDirectory(const fs::path& filename) override; - bool ParseFile(const fs::path& filename) override; - - void ParseMetaFile(const fs::path& meta_file); - void ParseMetaFile(const pugi::xml_document& doc, const pugi::xml_parse_result& result); -}; - diff --git a/src/Cemu/FileCache/FileCache.cpp b/src/Cemu/FileCache/FileCache.cpp index 105ee860..dd7c6d4f 100644 --- a/src/Cemu/FileCache/FileCache.cpp +++ b/src/Cemu/FileCache/FileCache.cpp @@ -87,12 +87,12 @@ private: #define FILECACHE_FILETABLE_NAME2 0xFEFEFEFEFEFEFEFEULL #define FILECACHE_FILETABLE_FREE_NAME 0ULL -FileCache* FileCache::Create(wzstring_view path, uint32 extraVersion) +FileCache* FileCache::Create(const fs::path& path, uint32 extraVersion) { - FileStream* fs = FileStream::createFile(std::wstring(path).c_str()); + FileStream* fs = FileStream::createFile2(path); if (!fs) { - forceLog_printf("Failed to create cache file \"%ls\"", path); + cemuLog_log(LogType::Force, "Failed to create cache file \"{}\"", _pathToUtf8(path)); return nullptr; } // init file cache @@ -124,9 +124,9 @@ FileCache* FileCache::Create(wzstring_view path, uint32 extraVersion) return fileCache; } -FileCache* FileCache::_OpenExisting(wzstring_view path, bool compareExtraVersion, uint32 extraVersion) +FileCache* FileCache::_OpenExisting(const fs::path& path, bool compareExtraVersion, uint32 extraVersion) { - FileStream* fs = FileStream::openFile2(path.data(), true); + FileStream* fs = FileStream::openFile2(path, true); if (!fs) return nullptr; // read header @@ -165,7 +165,7 @@ FileCache* FileCache::_OpenExisting(wzstring_view path, bool compareExtraVersion fs->readU64(headerFileTableOffset); if (!fs->readU32(headerFileTableSize)) { - forceLog_printf("\"%ls\" is corrupted", path); + cemuLog_log(LogType::Force, "\"{}\" is corrupted", _pathToUtf8(path)); delete fs; return nullptr; } @@ -176,7 +176,7 @@ FileCache* FileCache::_OpenExisting(wzstring_view path, bool compareExtraVersion invalidFileTableSize = (headerFileTableSize % sizeof(FileTableEntry)) != 0; if (invalidFileTableSize) { - forceLog_printf("\"%ls\" is corrupted", path); + cemuLog_log(LogType::Force, "\"{}\" is corrupted", _pathToUtf8(path)); delete fs; return nullptr; } @@ -212,14 +212,14 @@ FileCache* FileCache::_OpenExisting(wzstring_view path, bool compareExtraVersion } if (incompleteFileTable) { - forceLog_printf("\"%ls\" is corrupted (incomplete file table)", path); + cemuLog_log(LogType::Force, "\"{}\" is corrupted (incomplete file table)", _pathToUtf8(path)); delete fileCache; return nullptr; } return fileCache; } -FileCache* FileCache::Open(wzstring_view path, bool allowCreate, uint32 extraVersion) +FileCache* FileCache::Open(const fs::path& path, bool allowCreate, uint32 extraVersion) { FileCache* fileCache = _OpenExisting(path, true, extraVersion); if (fileCache) @@ -229,7 +229,7 @@ FileCache* FileCache::Open(wzstring_view path, bool allowCreate, uint32 extraVer return Create(path, extraVersion); } -FileCache* FileCache::Open(wzstring_view path) +FileCache* FileCache::Open(const fs::path& path) { return _OpenExisting(path, false, 0); } @@ -614,7 +614,7 @@ sint32 FileCache::GetFileCount() void fileCache_test() { - FileCache* fc = FileCache::Create(L"testCache.bin", 0); + FileCache* fc = FileCache::Create("testCache.bin", 0); uint32 time1 = GetTickCount(); char* testString1 = (char*)malloc(1024 * 1024 * 8); @@ -637,7 +637,7 @@ void fileCache_test() debug_printf("Writing took %dms\n", time2-time1); delete fc; // verify if all entries are still valid - FileCache* fcRead = FileCache::Open(L"testCache.bin", 0); + FileCache* fcRead = FileCache::Open("testCache.bin", 0); uint32 time3 = GetTickCount(); for(sint32 i=0; i<2200; i++) { diff --git a/src/Cemu/FileCache/FileCache.h b/src/Cemu/FileCache/FileCache.h index 52972fbd..de1996c5 100644 --- a/src/Cemu/FileCache/FileCache.h +++ b/src/Cemu/FileCache/FileCache.h @@ -1,6 +1,5 @@ #pragma once -#include "Common/zstring_view.h" #include class FileCache @@ -36,9 +35,9 @@ public: ~FileCache(); - static FileCache* Create(wzstring_view path, uint32 extraVersion = 0); - static FileCache* Open(wzstring_view path, bool allowCreate, uint32 extraVersion = 0); - static FileCache* Open(wzstring_view path); // open without extraVersion check + static FileCache* Create(const fs::path& path, uint32 extraVersion = 0); + static FileCache* Open(const fs::path& path, bool allowCreate, uint32 extraVersion = 0); + static FileCache* Open(const fs::path& path); // open without extraVersion check void UseCompression(bool enable) { enableCompression = enable; }; @@ -75,7 +74,7 @@ private: FileCache() {}; - static FileCache* _OpenExisting(wzstring_view path, bool compareExtraVersion, uint32 extraVersion = 0); + static FileCache* _OpenExisting(const fs::path& path, bool compareExtraVersion, uint32 extraVersion = 0); void fileCache_updateFiletable(sint32 extraEntriesToAllocate); void _addFileInternal(uint64 name1, uint64 name2, const uint8* fileData, sint32 fileSize, bool noCompression); diff --git a/src/Cemu/Logging/CemuLogging.h b/src/Cemu/Logging/CemuLogging.h index 72d10ad3..c9718f07 100644 --- a/src/Cemu/Logging/CemuLogging.h +++ b/src/Cemu/Logging/CemuLogging.h @@ -25,6 +25,7 @@ enum class LogType : sint32 CoreinitThread = 17, CoreinitLogging = 18, // OSReport, OSConsoleWrite etc. CoreinitMemoryMapping = 19, // OSGetAvailPhysAddrRange, OSAllocVirtAddr, OSMapMemory etc. + CoreinitAlarm = 23, PPC_IPC = 20, NN_AOC = 21, @@ -93,7 +94,7 @@ bool cemuLog_log(LogType type, const T* format, TArgs&&... args) return cemuLog_log(type, format_str, std::forward(args)...); } -// same as cemuLog_log, but only outputs in debug/release mode +// same as cemuLog_log, but only outputs in debug mode template bool cemuLog_logDebug(LogType type, TFmt format, TArgs&&... args) { @@ -161,7 +162,6 @@ void cemuLog_force(TFmt format, TArgs&&... args) // these are deprecated. Superseded by cemuLog_log(type, ...) #define forceLog_printf(...) cafeLog_log(LOG_TYPE_FORCE, __VA_ARGS__); -#define forceLog_printfW(...) cafeLog_logW(LOG_TYPE_FORCE, __VA_ARGS__); #define gx2Log_printf(...) if( cafeLog_isLoggingFlagEnabled(LOG_TYPE_GX2) ) cafeLog_log(LOG_TYPE_GX2, __VA_ARGS__); #define coreinitMemLog_printf(...) if( cafeLog_isLoggingFlagEnabled(LOG_TYPE_COREINIT_MEM) ) cafeLog_log(LOG_TYPE_COREINIT_MEM, __VA_ARGS__); #define sndApiLog_printf(...) if( cafeLog_isLoggingFlagEnabled(LOG_TYPE_SNDAPI) ) cafeLog_log(LOG_TYPE_SNDAPI, __VA_ARGS__); @@ -172,11 +172,9 @@ void cemuLog_force(TFmt format, TArgs&&... args) #ifdef CEMU_DEBUG_ASSERT #define forceLogDebug_printf(...) cafeLog_log(LOG_TYPE_FORCE, __VA_ARGS__); -#define forceLogDebug_printfW(...) cafeLog_logW(LOG_TYPE_FORCE, __VA_ARGS__); // use this for temporary debug logging. Will trigger compilation error in release builds #define forceLogRemoveMe_printf(...) cafeLog_log(LOG_TYPE_FORCE, __VA_ARGS__); #else #define forceLogDebug_printf(...) ; -#define forceLogDebug_printfW(...) ; #endif diff --git a/src/Common/CMakeLists.txt b/src/Common/CMakeLists.txt index f07150c5..ea132087 100644 --- a/src/Common/CMakeLists.txt +++ b/src/Common/CMakeLists.txt @@ -20,7 +20,6 @@ add_library(CemuCommon SysAllocator.cpp SysAllocator.h version.h - zstring_view.h ) set_property(TARGET CemuCommon PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") diff --git a/src/Common/MemPtr.h b/src/Common/MemPtr.h index 7ad5b76f..7fa0ff18 100644 --- a/src/Common/MemPtr.h +++ b/src/Common/MemPtr.h @@ -2,6 +2,13 @@ #include #include "betype.h" +using MPTR = uint32; // generic address in PowerPC memory space + +#define MPTR_NULL (0) + +using VAddr = uint32; // virtual address +using PAddr = uint32; // physical address + extern uint8* memory_base; extern uint8* PPCInterpreterGetStackPointer(); extern uint8* PPCInterpreterGetAndModifyStackPointer(sint32 offset); diff --git a/src/Common/precompiled.h b/src/Common/precompiled.h index 641eabb4..6183b852 100644 --- a/src/Common/precompiled.h +++ b/src/Common/precompiled.h @@ -85,7 +85,6 @@ namespace fs = std::filesystem; #include "enumFlags.h" -#include "zstring_view.h" // base types using uint64 = uint64_t; @@ -98,11 +97,6 @@ using sint32 = int32_t; using sint16 = int16_t; using sint8 = int8_t; -using MPTR = uint32; -using MPTR_UINT8 = uint32; -using MPTR_UINT16 = uint32; -using MPTR_UINT32 = uint32; - // types with explicit big endian order #include "betype.h" @@ -289,8 +283,6 @@ inline unsigned char _addcarry_u64(unsigned char carry, unsigned long long a, un // MEMPTR #include "Common/MemPtr.h" -#define MPTR_NULL (0) - template constexpr bool HAS_FLAG(T1 flags, T2 test_flag) { return (flags & (T1)test_flag) == (T1)test_flag; } template diff --git a/src/Common/zstring_view.h b/src/Common/zstring_view.h deleted file mode 100644 index 2afd605c..00000000 --- a/src/Common/zstring_view.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef ASZ_ZSTRING_VIEW_HPP -#define ASZ_ZSTRING_VIEW_HPP - -// https://github.com/Aszarsha/zstring_view/blob/master/zstring_view.hpp - -#include - -// Copy interface from cppreference's std::basic_string_view page -// http://en.cppreference.com/w/cpp/string/basic_string_view -// and add conversion from zstring_view to basic_string_view and CharT const* - -template< class CharT - , class Traits = std::char_traits< CharT > -> -class basic_zstring_view - : private std::basic_string_view< CharT, Traits > { -private: - using string_view_base = std::basic_string_view< CharT, Traits >; - -public: /// Types /// - using typename string_view_base::traits_type; - using typename string_view_base::value_type; - using typename string_view_base::pointer; - using typename string_view_base::const_pointer; - using typename string_view_base::reference; - using typename string_view_base::const_reference; - using typename string_view_base::iterator; - using typename string_view_base::const_iterator; - using typename string_view_base::reverse_iterator; - using typename string_view_base::const_reverse_iterator; - using typename string_view_base::size_type; - using typename string_view_base::difference_type; - -public: /// Static members /// - using string_view_base::npos; - -public: /// Special member functions /// - constexpr basic_zstring_view() noexcept = default; - - constexpr basic_zstring_view(basic_zstring_view const&) noexcept = default; - constexpr basic_zstring_view& operator=(basic_zstring_view const&) noexcept = default; - - constexpr basic_zstring_view(basic_zstring_view&&) noexcept = default; - constexpr basic_zstring_view& operator=(basic_zstring_view&&) noexcept = default; - - basic_zstring_view(CharT const* s) : string_view_base{ s } { } - basic_zstring_view(CharT const* s, size_type sz) : string_view_base{ s, sz } { } - - // Explicitly no convertion from string_view, since null-termination is not guaranteed - basic_zstring_view(std::basic_string, std::allocator> const& s) : string_view_base{ s } { } - -public: /// Member functions /// - //== Iterators ==// - using string_view_base::begin; - using string_view_base::cbegin; - - using string_view_base::end; - using string_view_base::cend; - - using string_view_base::rbegin; - using string_view_base::crbegin; - - using string_view_base::rend; - using string_view_base::crend; - - //== Element access ==// - using string_view_base::operator[]; - - using string_view_base::at; - - using string_view_base::front; - - using string_view_base::back; - - using string_view_base::data; - - //== Capacity ==// - using string_view_base::size; - using string_view_base::length; - - using string_view_base::max_size; - - using string_view_base::empty; - - //== Modifiers ==// - using string_view_base::remove_prefix; - - //Explicitly NOT - //using string_view_base::remove_suffix; - - using string_view_base::swap; - - //== Operations ==// - using string_view_base::copy; - - //Explicitly NOT - //using::string_view_base::substr; - - using string_view_base::compare; - - // C++20 - //using string_view_base::starts_with; - - // C++20 - //using string_view_base::ends_with; - - using string_view_base::find; - - using string_view_base::rfind; - - using string_view_base::find_first_of; - - using string_view_base::find_last_of; - - using string_view_base::find_first_not_of; - - using string_view_base::find_last_not_of; - -public: /// Convertions /// - constexpr operator const_pointer() const noexcept { - return data(); - } - - // Ideally operator string_view_base() - // but by language definition (C++17) will never be used: - // From [class.conv.fct]: A conversion function is never used to convert a (possibly cv-qualified) object to the (possibly cv-qualified) same object type (or a reference to it), to a (possibly cv-qualified) base class of that type (or a reference to it), or to (possibly cv-qualified) void. - constexpr string_view_base to_string_view() const noexcept { - return { data(), size() }; - } - -public: /// Misc /// - friend inline std::ostream& operator<<(std::ostream& o, basic_zstring_view v) { - o << v.data(); - return o; - } -}; - -using zstring_view = basic_zstring_view< char >; -using wzstring_view = basic_zstring_view< wchar_t >; -using u16zstring_view = basic_zstring_view< char16_t >; -using u32zstring_view = basic_zstring_view< char32_t >; - -#endif \ No newline at end of file diff --git a/src/config/ActiveSettings.cpp b/src/config/ActiveSettings.cpp index f469c5e3..af5cdb2f 100644 --- a/src/config/ActiveSettings.cpp +++ b/src/config/ActiveSettings.cpp @@ -241,7 +241,7 @@ fs::path ActiveSettings::GetMlcPath() return launch_mlc.value(); if(const auto config_mlc = GetConfig().mlc_path.GetValue(); !config_mlc.empty()) - return config_mlc; + return _utf8ToPath(config_mlc); return GetDefaultMLCPath(); } diff --git a/src/config/CemuConfig.cpp b/src/config/CemuConfig.cpp index feb3ac14..1feb641b 100644 --- a/src/config/CemuConfig.cpp +++ b/src/config/CemuConfig.cpp @@ -10,19 +10,19 @@ XMLCemuConfig_t g_config(L"settings.xml"); -void CemuConfig::SetMLCPath(std::wstring_view path, bool save) +void CemuConfig::SetMLCPath(fs::path path, bool save) { - mlc_path.SetValue(path); + mlc_path.SetValue(_pathToUtf8(path)); if(save) g_config.Save(); // if custom mlc path has been selected, store it in permanent config - if (!boost::starts_with(path, ActiveSettings::GetDefaultMLCPath().generic_wstring())) + if (path != ActiveSettings::GetDefaultMLCPath()) { try { auto pconfig = PermanentConfig::Load(); - pconfig.custom_mlc_path = boost::nowide::narrow(path.data(), path.size()); + pconfig.custom_mlc_path = _pathToUtf8(path); pconfig.Store(); } catch (const PSDisabledException&) {} @@ -46,14 +46,7 @@ void CemuConfig::Load(XMLConfigParser& parser) advanced_ppc_logging = parser.get("advanced_ppc_logging", advanced_ppc_logging.GetInitValue()); const char* mlc = parser.get("mlc_path", ""); - try - { - mlc_path = boost::nowide::widen(mlc); - } - catch (const std::exception&) - { - forceLog_printf("config load error: can't load mlc path: %s", mlc); - } + mlc_path = mlc; permanent_storage = parser.get("permanent_storage", permanent_storage); @@ -357,7 +350,7 @@ void CemuConfig::Save(XMLConfigParser& parser) // general settings config.set("logflag", log_flag.GetValue()); config.set("advanced_ppc_logging", advanced_ppc_logging.GetValue()); - config.set("mlc_path", boost::nowide::narrow(mlc_path.GetValue()).c_str()); + config.set("mlc_path", mlc_path.GetValue().c_str()); config.set("permanent_storage", permanent_storage); config.set("language", language); config.set("use_discord_presence", use_discord_presence); diff --git a/src/config/CemuConfig.h b/src/config/CemuConfig.h index f3469374..f8a30a82 100644 --- a/src/config/CemuConfig.h +++ b/src/config/CemuConfig.h @@ -356,7 +356,7 @@ struct CemuConfig // // sets mlc path, updates permanent config value, saves config - void SetMLCPath(std::wstring_view path, bool save = true); + void SetMLCPath(fs::path path, bool save = true); ConfigValue log_flag{ 0 }; ConfigValue advanced_ppc_logging{ false }; @@ -365,7 +365,7 @@ struct CemuConfig ConfigValue language{ wxLANGUAGE_DEFAULT }; ConfigValue use_discord_presence{ true }; - ConfigValue mlc_path {}; + ConfigValue mlc_path {}; ConfigValue fullscreen_menubar{ false }; ConfigValue fullscreen{ false }; ConfigValue proxy_server{}; diff --git a/src/config/XMLConfig.h b/src/config/XMLConfig.h index c2cba527..3932e2f0 100644 --- a/src/config/XMLConfig.h +++ b/src/config/XMLConfig.h @@ -344,10 +344,9 @@ public: if (L == nullptr) return false; FileStream* fs = FileStream::openFile(filename.c_str()); - - if (fs == nullptr) + if (!fs) { - forceLogDebug_printfW(L"XMLConfig::Load > failed \"%s\" with error %d", filename.c_str(), errno); + cemuLog_logDebug(LogType::Force, "XMLConfig::Load > failed \"{}\" with error {}", boost::nowide::narrow(filename), errno); return false; } std::vector xmlData; @@ -360,7 +359,7 @@ public: const bool success = error == tinyxml2::XML_SUCCESS; if (error != 0) { - forceLogDebug_printf("XMLConfig::Load > LoadFile %d", error); + cemuLog_logDebug(LogType::Force, "XMLConfig::Load > LoadFile {}", error); } if (success) { @@ -401,9 +400,9 @@ public: #else file = fopen(boost::nowide::narrow(tmp_name).c_str(), "wb"); #endif - if (file == nullptr) + if (!file) { - forceLogDebug_printfW(L"XMLConfig::Save > failed \"%s\" with error %d", filename.c_str(), errno); + cemuLog_logDebug(LogType::Force, "XMLConfig::Save > failed \"{}\" with error {}", boost::nowide::narrow(filename), errno); return false; } @@ -417,7 +416,7 @@ public: const tinyxml2::XMLError error = doc.SaveFile(file); const bool success = error == tinyxml2::XML_SUCCESS; if(error != 0) - forceLogDebug_printfW(L"XMLConfig::Save > SaveFile %d", error); + cemuLog_logDebug(LogType::Force, "XMLConfig::Save > SaveFile {}", error); fflush(file); fclose(file); @@ -425,7 +424,7 @@ public: fs::rename(tmp_name, filename, err); if(err) { - forceLog_printf("can't save settings to file: %s", err.message().c_str()); + cemuLog_log(LogType::Force, "Unable to save settings to file: {}", err.message().c_str()); fs::remove(tmp_name, err); } diff --git a/src/gui/CemuApp.cpp b/src/gui/CemuApp.cpp index 4a5974e5..a19981b0 100644 --- a/src/gui/CemuApp.cpp +++ b/src/gui/CemuApp.cpp @@ -15,6 +15,7 @@ #include #include #include +#include "wxHelper.h" #include "Cafe/TitleList/TitleList.h" #include "Cafe/TitleList/SaveList.h" @@ -276,12 +277,12 @@ std::vector CemuApp::GetAvailableLanguages() void CemuApp::CreateDefaultFiles(bool first_start) { - std::wstring mlc = GetMLCPath().ToStdWstring(); + fs::path mlc = ActiveSettings::GetMlcPath(); // check for mlc01 folder missing if custom path has been set if (!fs::exists(mlc) && !first_start) { - const std::wstring message = fmt::format(fmt::runtime(_(L"Your mlc01 folder seems to be missing.\n\nThis is where Cemu stores save files, game updates and other Wii U files.\n\nThe expected path is:\n{}\n\nDo you want to create the folder at the expected path?").ToStdWstring()), mlc); + const std::wstring message = fmt::format(fmt::runtime(_(L"Your mlc01 folder seems to be missing.\n\nThis is where Cemu stores save files, game updates and other Wii U files.\n\nThe expected path is:\n{}\n\nDo you want to create the folder at the expected path?").ToStdWstring()), mlc.wstring()); wxMessageDialog dialog(nullptr, message, "Error", wxCENTRE | wxYES_NO | wxCANCEL| wxICON_WARNING); dialog.SetYesNoCancelLabels(_("Yes"), _("No"), _("Select a custom path")); @@ -292,12 +293,11 @@ void CemuApp::CreateDefaultFiles(bool first_start) { if (!SelectMLCPath()) return; - - mlc = GetMLCPath(); + mlc = ActiveSettings::GetMlcPath(); } else { - GetConfig().mlc_path = L""; + GetConfig().mlc_path = ""; g_config.Save(); } } @@ -305,22 +305,22 @@ void CemuApp::CreateDefaultFiles(bool first_start) // create sys/usr folder in mlc01 try { - const auto sysFolder = fs::path(mlc).append(L"sys"); + const auto sysFolder = fs::path(mlc).append("sys"); fs::create_directories(sysFolder); - const auto usrFolder = fs::path(mlc).append(L"usr"); + const auto usrFolder = fs::path(mlc).append("usr"); fs::create_directories(usrFolder); fs::create_directories(fs::path(usrFolder).append("title/00050000")); // base fs::create_directories(fs::path(usrFolder).append("title/0005000c")); // dlc fs::create_directories(fs::path(usrFolder).append("title/0005000e")); // update // Mii Maker save folders {0x500101004A000, 0x500101004A100, 0x500101004A200}, - fs::create_directories(fs::path(mlc).append(L"usr/save/00050010/1004a000/user/common/db")); - fs::create_directories(fs::path(mlc).append(L"usr/save/00050010/1004a100/user/common/db")); - fs::create_directories(fs::path(mlc).append(L"usr/save/00050010/1004a200/user/common/db")); + fs::create_directories(fs::path(mlc).append("usr/save/00050010/1004a000/user/common/db")); + fs::create_directories(fs::path(mlc).append("usr/save/00050010/1004a100/user/common/db")); + fs::create_directories(fs::path(mlc).append("usr/save/00050010/1004a200/user/common/db")); // lang files - auto langDir = fs::path(mlc).append(L"sys/title/0005001b/1005c000/content"); + const auto langDir = fs::path(mlc).append("sys/title/0005001b/1005c000/content"); fs::create_directories(langDir); auto langFile = fs::path(langDir).append("language.txt"); @@ -357,7 +357,7 @@ void CemuApp::CreateDefaultFiles(bool first_start) catch (const std::exception& ex) { std::stringstream errorMsg; - errorMsg << fmt::format(fmt::runtime(_("Couldn't create a required mlc01 subfolder or file!\n\nError: {0}\nTarget path:\n{1}").ToStdString()), ex.what(), boost::nowide::narrow(mlc)); + errorMsg << fmt::format(fmt::runtime(_("Couldn't create a required mlc01 subfolder or file!\n\nError: {0}\nTarget path:\n{1}").ToStdString()), ex.what(), _pathToUtf8(mlc)); #if BOOST_OS_WINDOWS const DWORD lastError = GetLastError(); @@ -372,11 +372,11 @@ void CemuApp::CreateDefaultFiles(bool first_start) // cemu directories try { - const auto controllerProfileFolder = GetConfigPath(L"controllerProfiles").ToStdWstring(); + const auto controllerProfileFolder = ActiveSettings::GetConfigPath("controllerProfiles"); if (!fs::exists(controllerProfileFolder)) fs::create_directories(controllerProfileFolder); - const auto memorySearcherFolder = GetUserDataPath(L"memorySearcher").ToStdWstring(); + const auto memorySearcherFolder = ActiveSettings::GetUserDataPath("memorySearcher"); if (!fs::exists(memorySearcherFolder)) fs::create_directories(memorySearcherFolder); } @@ -398,12 +398,12 @@ void CemuApp::CreateDefaultFiles(bool first_start) } -bool CemuApp::TrySelectMLCPath(std::wstring path) +bool CemuApp::TrySelectMLCPath(fs::path path) { if (path.empty()) - path = ActiveSettings::GetDefaultMLCPath().wstring(); + path = ActiveSettings::GetDefaultMLCPath(); - if (!TestWriteAccess(fs::path{ path })) + if (!TestWriteAccess(path)) return false; GetConfig().SetMLCPath(path); @@ -421,14 +421,14 @@ bool CemuApp::SelectMLCPath(wxWindow* parent) { auto& config = GetConfig(); - std::wstring default_path; - if (fs::exists(config.mlc_path.GetValue())) - default_path = config.mlc_path.GetValue(); + fs::path default_path; + if (fs::exists(_utf8ToPath(config.mlc_path.GetValue()))) + default_path = _utf8ToPath(config.mlc_path.GetValue()); // try until users selects a valid path or aborts while(true) { - wxDirDialog path_dialog(parent, _("Select a mlc directory"), default_path, wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST); + wxDirDialog path_dialog(parent, _("Select a mlc directory"), wxHelper::FromPath(default_path), wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST); if (path_dialog.ShowModal() != wxID_OK || path_dialog.GetPath().empty()) return false; @@ -449,37 +449,6 @@ bool CemuApp::SelectMLCPath(wxWindow* parent) return false; } - -wxString CemuApp::GetMLCPath() -{ - return ActiveSettings::GetMlcPath().generic_wstring(); -} - -wxString CemuApp::GetMLCPath(const wxString& cat) -{ - return ActiveSettings::GetMlcPath(cat.ToStdString()).generic_wstring(); -} - -wxString CemuApp::GetConfigPath() -{ - return ActiveSettings::GetConfigPath().generic_wstring(); -}; - -wxString CemuApp::GetConfigPath(const wxString& cat) -{ - return ActiveSettings::GetConfigPath(cat.ToStdString()).generic_wstring(); -}; - -wxString CemuApp::GetUserDataPath() -{ - return ActiveSettings::GetUserDataPath().generic_wstring(); -}; - -wxString CemuApp::GetUserDataPath(const wxString& cat) -{ - return ActiveSettings::GetUserDataPath(cat.ToStdString()).generic_wstring(); -}; - void CemuApp::ActivateApp(wxActivateEvent& event) { g_window_info.app_active = event.GetActive(); diff --git a/src/gui/CemuApp.h b/src/gui/CemuApp.h index f462ec39..1dac29f1 100644 --- a/src/gui/CemuApp.h +++ b/src/gui/CemuApp.h @@ -17,17 +17,9 @@ public: static std::vector GetAvailableLanguages(); static void CreateDefaultFiles(bool first_start = false); - static bool TrySelectMLCPath(std::wstring path); + static bool TrySelectMLCPath(fs::path path); static bool SelectMLCPath(wxWindow* parent = nullptr); - static wxString GetConfigPath(); - static wxString GetConfigPath(const wxString& cat); - - static wxString GetUserDataPath(); - static wxString GetUserDataPath(const wxString& cat); - - static wxString GetMLCPath(); - static wxString GetMLCPath(const wxString& cat); private: void ActivateApp(wxActivateEvent& event); diff --git a/src/gui/GeneralSettings2.cpp b/src/gui/GeneralSettings2.cpp index 08d020f9..ac1d3f3b 100644 --- a/src/gui/GeneralSettings2.cpp +++ b/src/gui/GeneralSettings2.cpp @@ -868,7 +868,7 @@ void GeneralSettings2::StoreConfig() } if (!LaunchSettings::GetMLCPath().has_value()) - config.SetMLCPath(m_mlc_path->GetValue().ToStdWstring(), false); + config.SetMLCPath(wxHelper::MakeFSPath(m_mlc_path->GetValue()), false); // -1 is default wx widget value -> set to dummy 0 so mainwindow and padwindow will update it config.window_position = m_save_window_position_size->IsChecked() ? Vector2i{ 0,0 } : Vector2i{-1,-1}; @@ -1464,9 +1464,9 @@ void GeneralSettings2::ApplyConfig() auto& config = GetConfig(); if (LaunchSettings::GetMLCPath().has_value()) - m_mlc_path->SetValue(wxString{ LaunchSettings::GetMLCPath().value().generic_wstring() }); + m_mlc_path->SetValue(wxHelper::FromPath(LaunchSettings::GetMLCPath().value())); else - m_mlc_path->SetValue(config.mlc_path.GetValue()); + m_mlc_path->SetValue(wxHelper::FromUtf8(config.mlc_path.GetValue())); m_save_window_position_size->SetValue(config.window_position != Vector2i{-1,-1}); m_save_padwindow_position_size->SetValue(config.pad_position != Vector2i{-1,-1}); @@ -1910,7 +1910,7 @@ void GeneralSettings2::OnMLCPathSelect(wxCommandEvent& event) if (!CemuApp::SelectMLCPath(this)) return; - m_mlc_path->SetValue(ActiveSettings::GetMlcPath().generic_string()); + m_mlc_path->SetValue(wxHelper::FromPath(ActiveSettings::GetMlcPath())); m_reload_gamelist = true; m_mlc_modified = true; } @@ -1922,16 +1922,16 @@ void GeneralSettings2::OnMLCPathChar(wxKeyEvent& event) if(event.GetKeyCode() == WXK_DELETE || event.GetKeyCode() == WXK_BACK) { - std::wstring newPath = L""; + fs::path newPath = ""; if(!CemuApp::TrySelectMLCPath(newPath)) { const auto res = wxMessageBox(_("The default MLC path is inaccessible.\nDo you want to select a different path?"), _("Error"), wxYES_NO | wxCENTRE | wxICON_ERROR); if (res == wxYES && CemuApp::SelectMLCPath(this)) - newPath = ActiveSettings::GetMlcPath().wstring(); + newPath = ActiveSettings::GetMlcPath(); else return; } - m_mlc_path->SetValue(newPath); + m_mlc_path->SetValue(wxHelper::FromPath(newPath)); m_reload_gamelist = true; m_mlc_modified = true; } diff --git a/src/gui/GettingStartedDialog.cpp b/src/gui/GettingStartedDialog.cpp index 30e5e557..c84582b8 100644 --- a/src/gui/GettingStartedDialog.cpp +++ b/src/gui/GettingStartedDialog.cpp @@ -234,7 +234,7 @@ void GettingStartedDialog::OnClose(wxCloseEvent& event) const fs::path mlcPath = wxHelper::MakeFSPath(m_mlc_folder->GetPath()); if(config.mlc_path.GetValue() != mlcPath && (mlcPath.empty() || fs::exists(mlcPath))) { - config.SetMLCPath(mlcPath.generic_wstring(), false); + config.SetMLCPath(mlcPath, false); m_mlc_changed = true; } diff --git a/src/gui/GraphicPacksWindow2.cpp b/src/gui/GraphicPacksWindow2.cpp index e718605a..0dbb85fd 100644 --- a/src/gui/GraphicPacksWindow2.cpp +++ b/src/gui/GraphicPacksWindow2.cpp @@ -495,15 +495,14 @@ void GraphicPacksWindow2::OnTreeChoiceChanged(wxTreeEvent& event) auto& graphic_pack = data->GetGraphicPack(); graphic_pack->SetEnabled(state); - bool has_texture_rules = false; - if (CafeSystem::IsTitleRunning() && graphic_pack->ContainsTitleId(CafeSystem::GetForegroundTitleId())) + bool requiresRestart = graphic_pack->RequiresRestart(true, false); + bool isRunning = CafeSystem::IsTitleRunning() && graphic_pack->ContainsTitleId(CafeSystem::GetForegroundTitleId()); + if (isRunning) { if (state) { GraphicPack2::ActivateGraphicPack(graphic_pack); - has_texture_rules = !graphic_pack->GetTextureRules().empty(); - - if (!has_texture_rules) + if (!requiresRestart) { ReloadPack(graphic_pack); m_graphic_pack_tree->SetItemTextColour(item, 0x009900); @@ -511,19 +510,16 @@ void GraphicPacksWindow2::OnTreeChoiceChanged(wxTreeEvent& event) } else { - has_texture_rules = !graphic_pack->GetTextureRules().empty(); - - if (!has_texture_rules) + if (!requiresRestart) { DeleteShadersFromRuntimeCache(graphic_pack); m_graphic_pack_tree->SetItemTextColour(item, *wxBLACK); } - GraphicPack2::DeactivateGraphicPack(graphic_pack); } } - if (!m_info_bar->IsShown() && has_texture_rules) + if (!m_info_bar->IsShown() && (isRunning && requiresRestart)) m_info_bar->ShowMessage(_("Restart of Cemu required for changes to take effect")); // also change selection to activated gp @@ -583,7 +579,7 @@ void GraphicPacksWindow2::OnActivePresetChanged(wxCommandEvent& event) m_right_panel->Layout(); } - if (m_shown_graphic_pack->GetTextureRules().empty()) + if (!m_shown_graphic_pack->RequiresRestart(false, true)) ReloadPack(m_shown_graphic_pack); else if (!m_info_bar->IsShown()) m_info_bar->ShowMessage(_("Restart of Cemu required for changes to take effect")); diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index e95b0e68..4e82ad5d 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -624,7 +624,7 @@ void MainWindow::OnFileMenu(wxCommandEvent& event) void MainWindow::OnOpenCemuFolder(wxCommandEvent& event) { - wxLaunchDefaultApplication(ActiveSettings::GetUserDataPath().wstring()); + wxLaunchDefaultApplication(wxHelper::FromPath(ActiveSettings::GetUserDataPath())); } void MainWindow::OnInstallUpdate(wxCommandEvent& event) @@ -1004,7 +1004,7 @@ void MainWindow::OnDebugSetting(wxCommandEvent& event) { try { - const fs::path path(CemuApp::GetUserDataPath().ToStdString()); + const fs::path path(ActiveSettings::GetUserDataPath()); fs::create_directories(path / "dump" / "curl"); } catch (const std::exception& ex) @@ -1061,7 +1061,7 @@ void MainWindow::OnDebugDumpUsedTextures(wxCommandEvent& event) try { // create directory - const fs::path path(CemuApp::GetUserDataPath().ToStdString()); + const fs::path path(ActiveSettings::GetUserDataPath()); fs::create_directories(path / "dump" / "textures"); } catch (const std::exception& ex) @@ -1082,7 +1082,7 @@ void MainWindow::OnDebugDumpUsedShaders(wxCommandEvent& event) try { // create directory - const fs::path path(CemuApp::GetUserDataPath().ToStdString()); + const fs::path path(ActiveSettings::GetUserDataPath()); fs::create_directories(path / "dump" / "shaders"); } catch (const std::exception & ex) diff --git a/src/gui/wxHelper.h b/src/gui/wxHelper.h index 41b13f5d..ac959755 100644 --- a/src/gui/wxHelper.h +++ b/src/gui/wxHelper.h @@ -17,10 +17,16 @@ namespace wxHelper return fs::path(sv); } - inline wxString FromUtf8(std::string_view str) - { - return wxString::FromUTF8(str.data(), str.size()); - } + inline wxString FromUtf8(std::string_view str) + { + return wxString::FromUTF8(str.data(), str.size()); + } + + inline wxString FromPath(const fs::path& path) + { + std::string str = _pathToUtf8(path); + return wxString::FromUTF8(str.data(), str.size()); + } inline wxColour CalculateAccentColour(const wxColour& bgColour) { diff --git a/src/main.cpp b/src/main.cpp index 80e30855..33b1b0a3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -112,7 +112,7 @@ void infoLog_cemuStartup() { cemuLog_force("------- Init {} -------", BUILD_VERSION_WITH_NAME_STRING); cemuLog_force("Init Wii U memory space (base: 0x{:016x})", (size_t)memory_base); - cemuLog_force(u8"mlc01 path: {}", ActiveSettings::GetMlcPath().generic_u8string()); + cemuLog_force("mlc01 path: {}", _pathToUtf8(ActiveSettings::GetMlcPath())); // check for wine version checkForWine(); // CPU and RAM info