mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-26 11:04:18 +01:00
Code clean up + replace some wstring instances with utf8 (#640)
This commit is contained in:
parent
ca79a6aa0d
commit
f3ff919be2
@ -1,8 +1,6 @@
|
|||||||
#include "Account.h"
|
#include "Account.h"
|
||||||
#include "util/helpers/helpers.h"
|
#include "util/helpers/helpers.h"
|
||||||
#include "gui/CemuApp.h"
|
|
||||||
#include "util/helpers/SystemException.h"
|
#include "util/helpers/SystemException.h"
|
||||||
|
|
||||||
#include "config/ActiveSettings.h"
|
#include "config/ActiveSettings.h"
|
||||||
#include "Cafe/IOSU/legacy/iosu_crypto.h"
|
#include "Cafe/IOSU/legacy/iosu_crypto.h"
|
||||||
#include "Common/FileStream.h"
|
#include "Common/FileStream.h"
|
||||||
@ -175,7 +173,7 @@ std::error_code Account::Load()
|
|||||||
|
|
||||||
std::error_code Account::Save()
|
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))
|
if (!fs::exists(path))
|
||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
@ -184,7 +182,7 @@ std::error_code Account::Save()
|
|||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
path /= L"account.dat";
|
path /= "account.dat";
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -302,7 +300,7 @@ void Account::SetMiiName(std::wstring_view name)
|
|||||||
const std::vector<Account>& Account::RefreshAccounts()
|
const std::vector<Account>& Account::RefreshAccounts()
|
||||||
{
|
{
|
||||||
std::vector<Account> result;
|
std::vector<Account> 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))
|
if (fs::exists(path))
|
||||||
{
|
{
|
||||||
for (const auto& it : fs::directory_iterator(path))
|
for (const auto& it : fs::directory_iterator(path))
|
||||||
@ -417,7 +415,7 @@ fs::path Account::GetFileName(uint32 persistent_id)
|
|||||||
if (persistent_id < kMinPersistendId)
|
if (persistent_id < kMinPersistendId)
|
||||||
throw std::invalid_argument(fmt::format("persistent id {:#x} is invalid", persistent_id));
|
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
|
OnlineValidator Account::ValidateOnlineFiles() const
|
||||||
|
@ -454,8 +454,6 @@ add_library(CemuCafe
|
|||||||
TitleList/BaseInfo.cpp
|
TitleList/BaseInfo.cpp
|
||||||
TitleList/BaseInfo.h
|
TitleList/BaseInfo.h
|
||||||
TitleList/GameInfo.h
|
TitleList/GameInfo.h
|
||||||
TitleList/MetaInfo.cpp
|
|
||||||
TitleList/MetaInfo.h
|
|
||||||
TitleList/ParsedMetaXml.h
|
TitleList/ParsedMetaXml.h
|
||||||
TitleList/SaveInfo.cpp
|
TitleList/SaveInfo.cpp
|
||||||
TitleList/SaveInfo.h
|
TitleList/SaveInfo.h
|
||||||
|
@ -337,7 +337,7 @@ uint32 loadSharedData()
|
|||||||
// advance write offset and pad to 16 byte alignment
|
// advance write offset and pad to 16 byte alignment
|
||||||
dataWritePtr += ((fileSize + 15) & ~15);
|
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);
|
return memory_getVirtualOffsetFromPointer(dataWritePtr);
|
||||||
}
|
}
|
||||||
// alternative method: load RAM dump
|
// alternative method: load RAM dump
|
||||||
|
@ -139,7 +139,7 @@ void hle_scan(uint8* data, sint32 dataLength, char* hleFunctionName)
|
|||||||
uint32 offset = (uint32)(scanCurrent - scanStart) + 0x01000000;
|
uint32 offset = (uint32)(scanCurrent - scanStart) + 0x01000000;
|
||||||
debug_printf("HLE signature for '%s' found at 0x%08x\n", hleFunctionName, offset);
|
debug_printf("HLE signature for '%s' found at 0x%08x\n", hleFunctionName, offset);
|
||||||
uint32 opcode = (1<<26)|(functionIndex+0x1000); // opcode for HLE: 0x1000 + FunctionIndex
|
uint32 opcode = (1<<26)|(functionIndex+0x1000); // opcode for HLE: 0x1000 + FunctionIndex
|
||||||
memory_writeU32Direct(offset, opcode);
|
memory_write<uint32>(offset, opcode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
scanCurrent += 4;
|
scanCurrent += 4;
|
||||||
@ -330,7 +330,7 @@ void GamePatch_scan()
|
|||||||
#endif
|
#endif
|
||||||
sint32 functionIndex = hleIndex_h000000001;
|
sint32 functionIndex = hleIndex_h000000001;
|
||||||
uint32 opcode = (1 << 26) | (functionIndex); // opcode for HLE: 0x1000 + FunctionIndex
|
uint32 opcode = (1 << 26) | (functionIndex); // opcode for HLE: 0x1000 + FunctionIndex
|
||||||
memory_writeU32Direct(hleAddr - 4, opcode);
|
memory_write<uint32>(hleAddr - 4, opcode);
|
||||||
}
|
}
|
||||||
hleIndex_h000000002 = osLib_getFunctionIndex("hle", "h000000002");
|
hleIndex_h000000002 = osLib_getFunctionIndex("hle", "h000000002");
|
||||||
hleAddr = hle_locate(botw_busyLoopSignature2, botw_busyLoopMask2, sizeof(botw_busyLoopSignature2));
|
hleAddr = hle_locate(botw_busyLoopSignature2, botw_busyLoopMask2, sizeof(botw_busyLoopSignature2));
|
||||||
@ -341,7 +341,7 @@ void GamePatch_scan()
|
|||||||
#endif
|
#endif
|
||||||
sint32 functionIndex = hleIndex_h000000002;
|
sint32 functionIndex = hleIndex_h000000002;
|
||||||
uint32 opcode = (1 << 26) | (functionIndex); // opcode for HLE: 0x1000 + FunctionIndex
|
uint32 opcode = (1 << 26) | (functionIndex); // opcode for HLE: 0x1000 + FunctionIndex
|
||||||
memory_writeU32Direct(hleAddr - 4, opcode);
|
memory_write<uint32>(hleAddr - 4, opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FFL library float array endian conversion
|
// 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);
|
forceLogDebug_printf("HLE: Hook FFL float array endian swap function at 0x%08x", hleAddr);
|
||||||
sint32 functionIndex = hleIndex_h000000003;
|
sint32 functionIndex = hleIndex_h000000003;
|
||||||
uint32 opcode = (1 << 26) | (functionIndex); // opcode for HLE: 0x1000 + FunctionIndex
|
uint32 opcode = (1 << 26) | (functionIndex); // opcode for HLE: 0x1000 + FunctionIndex
|
||||||
memory_writeU32Direct(hleAddr, opcode);
|
memory_write<uint32>(hleAddr, opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// XCX freeze workaround
|
// XCX freeze workaround
|
||||||
|
@ -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()
|
bool GraphicPack2::Reload()
|
||||||
{
|
{
|
||||||
Deactivate();
|
Deactivate();
|
||||||
|
@ -105,6 +105,7 @@ public:
|
|||||||
sint32 GetVersion() const { return m_version; }
|
sint32 GetVersion() const { return m_version; }
|
||||||
const std::wstring& GetFilename() const { return m_filename; }
|
const std::wstring& GetFilename() const { return m_filename; }
|
||||||
const fs::path GetFilename2() const { return fs::path(m_filename); }
|
const fs::path GetFilename2() const { return fs::path(m_filename); }
|
||||||
|
bool RequiresRestart(bool changeEnableState, bool changePreset);
|
||||||
bool Reload();
|
bool Reload();
|
||||||
|
|
||||||
bool HasName() const { return !m_name.empty(); }
|
bool HasName() const { return !m_name.empty(); }
|
||||||
@ -172,6 +173,7 @@ public:
|
|||||||
|
|
||||||
static void ActivateForCurrentTitle();
|
static void ActivateForCurrentTitle();
|
||||||
static void Reset();
|
static void Reset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool Activate();
|
bool Activate();
|
||||||
bool Deactivate();
|
bool Deactivate();
|
||||||
|
@ -102,14 +102,14 @@ bool GraphicPack2::LoadCemuPatches()
|
|||||||
// load Cemu style patch file
|
// load Cemu style patch file
|
||||||
if (!ParseCemuPatchesTxtInternal(patchesStream))
|
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());
|
cemu_assert_debug(list_patchGroups.empty());
|
||||||
return true; // return true since a .asm patch was found even if we could not parse it
|
return true; // return true since a .asm patch was found even if we could not parse it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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;
|
foundPatches = true;
|
||||||
}
|
}
|
||||||
|
@ -559,19 +559,19 @@ LatteCMDPtr LatteCP_itLoadReg(LatteCMDPtr cmd, uint32 nWords, uint32 regBase)
|
|||||||
MPTR physAddressRegArea = LatteReadCMD();
|
MPTR physAddressRegArea = LatteReadCMD();
|
||||||
uint32 waitForIdle = LatteReadCMD();
|
uint32 waitForIdle = LatteReadCMD();
|
||||||
uint32 loadEntries = (nWords - 2) / 2;
|
uint32 loadEntries = (nWords - 2) / 2;
|
||||||
uint32 regIndex = 0;
|
uint32 regShadowMemAddr = physAddressRegArea;
|
||||||
for (uint32 i = 0; i < loadEntries; i++)
|
for (uint32 i = 0; i < loadEntries; i++)
|
||||||
{
|
{
|
||||||
uint32 regOffset = LatteReadCMD();
|
uint32 regOffset = LatteReadCMD();
|
||||||
uint32 regCount = LatteReadCMD();
|
uint32 regCount = LatteReadCMD();
|
||||||
cemu_assert_debug(regCount != 0);
|
cemu_assert_debug(regCount != 0);
|
||||||
|
uint32 regAddr = regBase + regOffset;
|
||||||
for (uint32 f = 0; f < regCount; f++)
|
for (uint32 f = 0; f < regCount; f++)
|
||||||
{
|
{
|
||||||
uint32 regAddr = regBase + regOffset + f;
|
|
||||||
uint32 regShadowMemAddr = physAddressRegArea + regIndex * 4;
|
|
||||||
LatteGPUState.contextRegisterShadowAddr[regAddr] = regShadowMemAddr;
|
LatteGPUState.contextRegisterShadowAddr[regAddr] = regShadowMemAddr;
|
||||||
LatteGPUState.contextRegister[regAddr] = memory_readU32Direct(regShadowMemAddr);
|
LatteGPUState.contextRegister[regAddr] = memory_read<uint32>(regShadowMemAddr);
|
||||||
regIndex++;
|
regAddr++;
|
||||||
|
regShadowMemAddr += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cmd;
|
return cmd;
|
||||||
@ -716,7 +716,7 @@ LatteCMDPtr LatteCP_itHLESampleTimer(LatteCMDPtr cmd, uint32 nWords)
|
|||||||
{
|
{
|
||||||
cemu_assert_debug(nWords == 1);
|
cemu_assert_debug(nWords == 1);
|
||||||
MPTR timerMPTR = (MPTR)LatteReadCMD();
|
MPTR timerMPTR = (MPTR)LatteReadCMD();
|
||||||
memory_writeU64Slow(timerMPTR, coreinit::coreinit_getTimerTick());
|
memory_writeU64(timerMPTR, coreinit::coreinit_getTimerTick());
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ void LatteShaderCache_load()
|
|||||||
if(!fc_shaderCacheGeneric)
|
if(!fc_shaderCacheGeneric)
|
||||||
{
|
{
|
||||||
// no shader cache available yet
|
// 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();
|
LatteShaderCache_finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -695,7 +695,7 @@ void LatteTextureLoader_UpdateTextureSliceData(LatteTexture* tex, sint32 texture
|
|||||||
if (textureLoader.dump)
|
if (textureLoader.dump)
|
||||||
{
|
{
|
||||||
wchar_t path[1024];
|
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);
|
tga_write_rgba(path, textureLoader.width, textureLoader.height, textureLoader.dumpRGBA);
|
||||||
free(textureLoader.dumpRGBA);
|
free(textureLoader.dumpRGBA);
|
||||||
}
|
}
|
||||||
|
@ -293,11 +293,6 @@ uint8* memory_getPointerFromVirtualOffsetAllowNull(uint32 virtualOffset)
|
|||||||
return memory_getPointerFromVirtualOffset(virtualOffset);
|
return memory_getPointerFromVirtualOffset(virtualOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_writeU32Direct(uint32 address, uint32 v)
|
|
||||||
{
|
|
||||||
*(uint32*)(memory_getPointerFromVirtualOffset(address)) = CPU_swapEndianU32(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
// write access
|
// write access
|
||||||
void memory_writeDouble(uint32 address, double vf)
|
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);
|
*(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)
|
void memory_writeU64(uint32 address, uint64 v)
|
||||||
{
|
{
|
||||||
*(uint64*)(memory_getPointerFromVirtualOffset(address)) = CPU_swapEndianU64(v);
|
*(uint64*)(memory_getPointerFromVirtualOffset(address)) = CPU_swapEndianU64(v);
|
||||||
@ -372,12 +361,6 @@ uint32 memory_readU32(uint32 address)
|
|||||||
return CPU_swapEndianU32(v);
|
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 memory_readU16(uint32 address)
|
||||||
{
|
{
|
||||||
uint16 v = *(uint16*)(memory_getPointerFromVirtualOffset(address));
|
uint16 v = *(uint16*)(memory_getPointerFromVirtualOffset(address));
|
||||||
|
@ -15,7 +15,7 @@ uint8* memory_getPointerFromPhysicalOffset(uint32 physicalOffset);
|
|||||||
uint32 memory_virtualToPhysical(uint32 virtualOffset);
|
uint32 memory_virtualToPhysical(uint32 virtualOffset);
|
||||||
uint32 memory_physicalToVirtual(uint32 physicalOffset);
|
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
|
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_ADDR (0xF8000000)
|
||||||
#define MEMORY_SHAREDDATA_AREA_SIZE (0x02000000) // 32MB
|
#define MEMORY_SHAREDDATA_AREA_SIZE (0x02000000) // 32MB
|
||||||
|
|
||||||
static uint16 CPU_swapEndianU16(uint16 v)
|
|
||||||
{
|
|
||||||
return (v>>8)|(v<<8);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if BOOST_OS_WINDOWS
|
#if BOOST_OS_WINDOWS
|
||||||
#define CPU_swapEndianU64(_v) _byteswap_uint64((uint64)(_v))
|
#define CPU_swapEndianU64(_v) _byteswap_uint64((uint64)(_v))
|
||||||
#define CPU_swapEndianU32(_v) _byteswap_ulong((uint32)(_v))
|
#define CPU_swapEndianU32(_v) _byteswap_ulong((uint32)(_v))
|
||||||
|
#define CPU_swapEndianU16(_v) _byteswap_ushort((uint16)(_v))
|
||||||
#elif BOOST_OS_LINUX
|
#elif BOOST_OS_LINUX
|
||||||
#define CPU_swapEndianU64(_v) bswap_64((uint64)(_v))
|
#define CPU_swapEndianU64(_v) bswap_64((uint64)(_v))
|
||||||
#define CPU_swapEndianU32(_v) bswap_32((uint32)(_v))
|
#define CPU_swapEndianU32(_v) bswap_32((uint32)(_v))
|
||||||
|
#define CPU_swapEndianU16(_v) bswap_16((uint16)(_v))
|
||||||
#elif BOOST_OS_MACOS
|
#elif BOOST_OS_MACOS
|
||||||
#define CPU_swapEndianU64(_v) OSSwapInt64((uint64)(_v))
|
#define CPU_swapEndianU64(_v) OSSwapInt64((uint64)(_v))
|
||||||
#define CPU_swapEndianU32(_v) OSSwapInt32((uint32)(_v))
|
#define CPU_swapEndianU32(_v) OSSwapInt32((uint32)(_v))
|
||||||
|
#define CPU_swapEndianU16(_v) OSSwapInt16((uint16)(_v))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// direct memory access (no hardware interface access)
|
// C-style memory access, deprecated. Use memory_read<> and memory_write<> templates instead
|
||||||
void memory_writeU32Direct(uint32 address, uint32 v);
|
|
||||||
uint32 memory_readU32Direct(uint32 address);
|
|
||||||
|
|
||||||
// memory access (includes hardware interface, slower)
|
|
||||||
void memory_writeDouble(uint32 address, double vf);
|
void memory_writeDouble(uint32 address, double vf);
|
||||||
void memory_writeFloat(uint32 address, float vf);
|
void memory_writeFloat(uint32 address, float vf);
|
||||||
void memory_writeU32(uint32 address, uint32 v);
|
void memory_writeU32(uint32 address, uint32 v);
|
||||||
void memory_writeU16(uint32 address, uint16 v);
|
void memory_writeU16(uint32 address, uint16 v);
|
||||||
void memory_writeU8(uint32 address, uint8 v);
|
void memory_writeU8(uint32 address, uint8 v);
|
||||||
void memory_writeU64Slow(uint32 address, uint64 v);
|
|
||||||
void memory_writeU64(uint32 address, uint64 v);
|
void memory_writeU64(uint32 address, uint64 v);
|
||||||
|
|
||||||
double memory_readDouble(uint32 address);
|
double memory_readDouble(uint32 address);
|
||||||
@ -210,43 +203,24 @@ uint8 memory_readU8(uint32 address);
|
|||||||
void memory_createDump();
|
void memory_createDump();
|
||||||
|
|
||||||
template<size_t count>
|
template<size_t count>
|
||||||
void memory_readBytes(uint32 address, std::array<uint8, count>& buffer)
|
void memory_readBytes(VAddr address, std::array<uint8, count>& buffer)
|
||||||
{
|
{
|
||||||
memcpy(buffer.data(), memory_getPointerFromVirtualOffset(address), count);
|
memcpy(buffer.data(), memory_getPointerFromVirtualOffset(address), count);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> T memory_read(uint32 address)
|
template <typename T> inline T memory_read(VAddr address)
|
||||||
{
|
{
|
||||||
if constexpr(std::is_floating_point<T>::value)
|
return *(betype<T>*)(memory_base + address);
|
||||||
{
|
}
|
||||||
if constexpr(sizeof(T) == sizeof(float))
|
|
||||||
return memory_readFloat(address);
|
|
||||||
else
|
|
||||||
return memory_readDouble(address);
|
|
||||||
}
|
|
||||||
else if(std::is_integral<T>::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);
|
|
||||||
}
|
|
||||||
|
|
||||||
debugBreakpoint();
|
template <typename T> inline void memory_write(VAddr address, T value)
|
||||||
return {};
|
{
|
||||||
|
*(betype<T>*)(memory_base + address) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LLE implementation
|
// LLE implementation
|
||||||
void memory_initPhysicalLayout();
|
void memory_initPhysicalLayout();
|
||||||
|
|
||||||
// updated code
|
|
||||||
using EAddr = uint32; // effective address
|
|
||||||
using PAddr = uint32; // physical address
|
|
||||||
|
|
||||||
namespace MMU
|
namespace MMU
|
||||||
{
|
{
|
||||||
using MMIOFuncWrite32 = void (*)(PAddr addr, uint32 value);
|
using MMIOFuncWrite32 = void (*)(PAddr addr, uint32 value);
|
||||||
|
@ -734,7 +734,7 @@ uint32 RPLLoader_MakePPCCallable(void(*ppcCallableExport)(PPCInterpreter_t* hCPU
|
|||||||
sint32 functionIndex = PPCInterpreter_registerHLECall(ppcCallableExport);
|
sint32 functionIndex = PPCInterpreter_registerHLECall(ppcCallableExport);
|
||||||
MPTR codeAddr = memory_getVirtualOffsetFromPointer(RPLLoader_AllocateTrampolineCodeSpace(4));
|
MPTR codeAddr = memory_getVirtualOffsetFromPointer(RPLLoader_AllocateTrampolineCodeSpace(4));
|
||||||
uint32 opcode = (1 << 26) | functionIndex;
|
uint32 opcode = (1 << 26) | functionIndex;
|
||||||
memory_writeU32Direct(codeAddr, opcode);
|
memory_write<uint32>(codeAddr, opcode);
|
||||||
g_map_callableExports[ppcCallableExport] = codeAddr;
|
g_map_callableExports[ppcCallableExport] = codeAddr;
|
||||||
return codeAddr;
|
return codeAddr;
|
||||||
}
|
}
|
||||||
@ -772,7 +772,7 @@ uint32 rpl_mapHLEImport(RPLModule* rplLoaderContext, const char* rplName, const
|
|||||||
{
|
{
|
||||||
MPTR codeAddr = memory_getVirtualOffsetFromPointer(RPLLoader_AllocateTrampolineCodeSpace(4));
|
MPTR codeAddr = memory_getVirtualOffsetFromPointer(RPLLoader_AllocateTrampolineCodeSpace(4));
|
||||||
uint32 opcode = (1 << 26) | functionIndex;
|
uint32 opcode = (1 << 26) | functionIndex;
|
||||||
memory_writeU32Direct(codeAddr, opcode);
|
memory_write<uint32>(codeAddr, opcode);
|
||||||
// register mapped import
|
// register mapped import
|
||||||
mappedFunctionImport_t newImport;
|
mappedFunctionImport_t newImport;
|
||||||
newImport.hash1 = mappedImportHash1;
|
newImport.hash1 = mappedImportHash1;
|
||||||
@ -792,8 +792,8 @@ uint32 rpl_mapHLEImport(RPLModule* rplLoaderContext, const char* rplName, const
|
|||||||
uint32 codeStart = memory_getVirtualOffsetFromPointer(RPLLoader_AllocateTrampolineCodeSpace(256));
|
uint32 codeStart = memory_getVirtualOffsetFromPointer(RPLLoader_AllocateTrampolineCodeSpace(256));
|
||||||
uint32 currentAddress = codeStart;
|
uint32 currentAddress = codeStart;
|
||||||
uint32 opcode = (1 << 26) | (0xFFD0); // opcode for HLE: Unsupported import
|
uint32 opcode = (1 << 26) | (0xFFD0); // opcode for HLE: Unsupported import
|
||||||
memory_writeU32Direct(codeStart + 0, opcode);
|
memory_write<uint32>(codeStart + 0, opcode);
|
||||||
memory_writeU32Direct(codeStart + 4, 0x4E800020);
|
memory_write<uint32>(codeStart + 4, 0x4E800020);
|
||||||
currentAddress += 8;
|
currentAddress += 8;
|
||||||
// write name of lib/function
|
// write name of lib/function
|
||||||
sint32 libNameLength = std::min(128, (sint32)strlen(libName));
|
sint32 libNameLength = std::min(128, (sint32)strlen(libName));
|
||||||
|
@ -176,12 +176,11 @@ namespace coreinit
|
|||||||
alarm->setMagic();
|
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]);
|
memset(alarm, 0, sizeof(OSAlarm_t));
|
||||||
OSCreateAlarm(OSAlarm);
|
alarm->setMagic();
|
||||||
OSAlarm->name = _swapEndianU32(hCPU->gpr[4]);
|
alarm->name = alarmName;
|
||||||
osLib_returnFromFunction(hCPU, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<OSAlarm_t*, OSHostAlarm*> g_activeAlarms;
|
std::unordered_map<OSAlarm_t*, OSHostAlarm*> g_activeAlarms;
|
||||||
@ -274,14 +273,12 @@ namespace coreinit
|
|||||||
|
|
||||||
void OSSetAlarmUserData(OSAlarm_t* alarm, uint32 userData)
|
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]);
|
return alarm->userData;
|
||||||
MPTR userData = _swapEndianU32(OSAlarmBE->userData);
|
|
||||||
osLib_returnFromFunction(hCPU, userData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSAlarm_resetAll()
|
void OSAlarm_resetAll()
|
||||||
@ -337,15 +334,13 @@ namespace coreinit
|
|||||||
|
|
||||||
void InitializeAlarm()
|
void InitializeAlarm()
|
||||||
{
|
{
|
||||||
cafeExportRegister("coreinit", OSCreateAlarm, LogType::Placeholder);
|
cafeExportRegister("coreinit", OSCreateAlarm, LogType::CoreinitAlarm);
|
||||||
cafeExportRegister("coreinit", OSCancelAlarm, LogType::Placeholder);
|
cafeExportRegister("coreinit", OSCreateAlarmEx, LogType::CoreinitAlarm);
|
||||||
cafeExportRegister("coreinit", OSSetAlarm, LogType::Placeholder);
|
cafeExportRegister("coreinit", OSCancelAlarm, LogType::CoreinitAlarm);
|
||||||
cafeExportRegister("coreinit", OSSetPeriodicAlarm, LogType::Placeholder);
|
cafeExportRegister("coreinit", OSSetAlarm, LogType::CoreinitAlarm);
|
||||||
|
cafeExportRegister("coreinit", OSSetPeriodicAlarm, LogType::CoreinitAlarm);
|
||||||
cafeExportRegister("coreinit", OSSetAlarmUserData, LogType::Placeholder);
|
cafeExportRegister("coreinit", OSSetAlarmUserData, LogType::CoreinitAlarm);
|
||||||
|
cafeExportRegister("coreinit", OSGetAlarmUserData, LogType::CoreinitAlarm);
|
||||||
osLib_addFunction("coreinit", "OSCreateAlarmEx", coreinitExport_OSCreateAlarmEx);
|
|
||||||
osLib_addFunction("coreinit", "OSGetAlarmUserData", coreinitExport_OSGetAlarmUserData);
|
|
||||||
|
|
||||||
// init event
|
// init event
|
||||||
OSInitEvent(g_alarmEvent.GetPtr(), OSEvent::EVENT_STATE::STATE_NOT_SIGNALED, OSEvent::EVENT_MODE::MODE_AUTO);
|
OSInitEvent(g_alarmEvent.GetPtr(), OSEvent::EVENT_STATE::STATE_NOT_SIGNALED, OSEvent::EVENT_MODE::MODE_AUTO);
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
namespace coreinit
|
namespace coreinit
|
||||||
{
|
{
|
||||||
|
|
||||||
class OSHostAlarm;
|
class OSHostAlarm;
|
||||||
OSHostAlarm* OSHostAlarmCreate(uint64 nextFire, uint64 period, void(*callbackFunc)(uint64 currentTick, void* context), void* context);
|
OSHostAlarm* OSHostAlarmCreate(uint64 nextFire, uint64 period, void(*callbackFunc)(uint64 currentTick, void* context), void* context);
|
||||||
void OSHostAlarmDestroy(OSHostAlarm* hostAlarm);
|
void OSHostAlarmDestroy(OSHostAlarm* hostAlarm);
|
||||||
@ -11,7 +10,7 @@ namespace coreinit
|
|||||||
struct OSAlarm_t
|
struct OSAlarm_t
|
||||||
{
|
{
|
||||||
/* +0x00 */ betype<uint32> magic;
|
/* +0x00 */ betype<uint32> magic;
|
||||||
/* +0x04 */ MPTR_UINT8 name;
|
/* +0x04 */ MEMPTR<const char> name;
|
||||||
/* +0x08 */ uint32 ukn08;
|
/* +0x08 */ uint32 ukn08;
|
||||||
/* +0x0C */ MPTR handler;
|
/* +0x0C */ MPTR handler;
|
||||||
/* +0x10 */ uint32 ukn10;
|
/* +0x10 */ uint32 ukn10;
|
||||||
@ -21,7 +20,7 @@ namespace coreinit
|
|||||||
/* +0x24 */ MPTR next; // pointer to OSAlarm
|
/* +0x24 */ MPTR next; // pointer to OSAlarm
|
||||||
/* +0x28 */ uint64 period; // period (zero for non-periodic timer)
|
/* +0x28 */ uint64 period; // period (zero for non-periodic timer)
|
||||||
/* +0x30 */ uint64 startTime; // period start
|
/* +0x30 */ uint64 startTime; // period start
|
||||||
/* +0x38 */ MPTR userData;
|
/* +0x38 */ uint32be userData;
|
||||||
/* +0x3C */ uint32 ukn3C;
|
/* +0x3C */ uint32 ukn3C;
|
||||||
/* +0x40 */ OSThreadQueue uknThreadQueue;
|
/* +0x40 */ OSThreadQueue uknThreadQueue;
|
||||||
/* +0x50 */ MPTR alarmQueue;
|
/* +0x50 */ MPTR alarmQueue;
|
||||||
|
@ -428,8 +428,8 @@ struct OSThread_t
|
|||||||
|
|
||||||
/* +0x38C */ coreinit::OSThreadLink activeThreadChain; // queue of active threads (g_activeThreadQueue)
|
/* +0x38C */ coreinit::OSThreadLink activeThreadChain; // queue of active threads (g_activeThreadQueue)
|
||||||
|
|
||||||
/* +0x394 */ MPTR_UINT8 stackBase; // upper limit of stack
|
/* +0x394 */ MPTR stackBase; // upper limit of stack
|
||||||
/* +0x398 */ MPTR_UINT32 stackEnd; // lower limit of stack
|
/* +0x398 */ MPTR stackEnd; // lower limit of stack
|
||||||
|
|
||||||
/* +0x39C */ MPTR entrypoint;
|
/* +0x39C */ MPTR entrypoint;
|
||||||
/* +0x3A0 */ crt_t crt;
|
/* +0x3A0 */ crt_t crt;
|
||||||
@ -443,8 +443,7 @@ struct OSThread_t
|
|||||||
/* +0x5C8 */ uint32 userStackPointer;
|
/* +0x5C8 */ uint32 userStackPointer;
|
||||||
|
|
||||||
/* +0x5CC */ MEMPTR<void> cleanupCallback2;
|
/* +0x5CC */ MEMPTR<void> cleanupCallback2;
|
||||||
/* +0x5D0 */ //MPTR deallocator;
|
/* +0x5D0 */ MEMPTR<void> deallocatorFunc;
|
||||||
MEMPTR<void> 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
|
/* +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<REQUEST_FLAG_BIT> requestFlags;
|
/* +0x5D8 */ betype<REQUEST_FLAG_BIT> requestFlags;
|
||||||
|
@ -37,8 +37,8 @@ void gx2Export_GX2GetSwapStatus(PPCInterpreter_t* hCPU)
|
|||||||
{
|
{
|
||||||
memory_writeU32(hCPU->gpr[3], _swapEndianU32(LatteGPUState.sharedArea->flipRequestCountBE));
|
memory_writeU32(hCPU->gpr[3], _swapEndianU32(LatteGPUState.sharedArea->flipRequestCountBE));
|
||||||
memory_writeU32(hCPU->gpr[4], _swapEndianU32(LatteGPUState.sharedArea->flipExecuteCountBE));
|
memory_writeU32(hCPU->gpr[4], _swapEndianU32(LatteGPUState.sharedArea->flipExecuteCountBE));
|
||||||
memory_writeU64Slow(hCPU->gpr[5], lastSwapTime);
|
memory_writeU64(hCPU->gpr[5], lastSwapTime);
|
||||||
memory_writeU64Slow(hCPU->gpr[6], lastSwapTime);
|
memory_writeU64(hCPU->gpr[6], lastSwapTime);
|
||||||
|
|
||||||
osLib_returnFromFunction(hCPU, 0);
|
osLib_returnFromFunction(hCPU, 0);
|
||||||
}
|
}
|
||||||
@ -54,14 +54,14 @@ void gx2Export_GX2GetGPUTimeout(PPCInterpreter_t* hCPU)
|
|||||||
void gx2Export_GX2SampleTopGPUCycle(PPCInterpreter_t* hCPU)
|
void gx2Export_GX2SampleTopGPUCycle(PPCInterpreter_t* hCPU)
|
||||||
{
|
{
|
||||||
gx2Log_printf("GX2SampleTopGPUCycle(0x%08x)\n", hCPU->gpr[3]);
|
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);
|
osLib_returnFromFunction(hCPU, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gx2Export_GX2SampleBottomGPUCycle(PPCInterpreter_t* hCPU)
|
void gx2Export_GX2SampleBottomGPUCycle(PPCInterpreter_t* hCPU)
|
||||||
{
|
{
|
||||||
gx2Log_printf("GX2SampleBottomGPUCycle(0x%08x)\n", hCPU->gpr[3]);
|
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);
|
osLib_returnFromFunction(hCPU, 0);
|
||||||
return;
|
return;
|
||||||
|
@ -9,7 +9,7 @@ namespace nn::temp
|
|||||||
forceLogDebug_printf("TEMPCreateAndInitTempDir(...) - placeholder");
|
forceLogDebug_printf("TEMPCreateAndInitTempDir(...) - placeholder");
|
||||||
|
|
||||||
// create random temp id
|
// create random temp id
|
||||||
memory_writeU64Slow(hCPU->gpr[5], tempIdGenerator);
|
memory_writeU64(hCPU->gpr[5], tempIdGenerator);
|
||||||
tempIdGenerator = (tempIdGenerator << 3) | (tempIdGenerator >> 61);
|
tempIdGenerator = (tempIdGenerator << 3) | (tempIdGenerator >> 61);
|
||||||
tempIdGenerator += 0x56e28bd5f4ULL;
|
tempIdGenerator += 0x56e28bd5f4ULL;
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ namespace nsyshid
|
|||||||
deviceItr->hFile = openDevice(deviceItr->devicePath);
|
deviceItr->hFile = openDevice(deviceItr->devicePath);
|
||||||
if (deviceItr->hFile == INVALID_HANDLE_VALUE)
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
HidD_SetNumInputBuffers(deviceItr->hFile, 2); // dont cache too many reports
|
HidD_SetNumInputBuffers(deviceItr->hFile, 2); // dont cache too many reports
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "config/CemuConfig.h"
|
#include "config/CemuConfig.h"
|
||||||
#include "MetaInfo.h"
|
|
||||||
#include "TitleInfo.h"
|
#include "TitleInfo.h"
|
||||||
#include "config/ActiveSettings.h"
|
#include "config/ActiveSettings.h"
|
||||||
|
|
||||||
|
@ -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<uint8[]> 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<uint8[]>(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;
|
|
||||||
}
|
|
@ -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<uint8[]> 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<std::string, 12> m_long_name;
|
|
||||||
std::array<std::string, 12> m_short_name;
|
|
||||||
std::array<std::string, 12> 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);
|
|
||||||
};
|
|
||||||
|
|
@ -87,12 +87,12 @@ private:
|
|||||||
#define FILECACHE_FILETABLE_NAME2 0xFEFEFEFEFEFEFEFEULL
|
#define FILECACHE_FILETABLE_NAME2 0xFEFEFEFEFEFEFEFEULL
|
||||||
#define FILECACHE_FILETABLE_FREE_NAME 0ULL
|
#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)
|
if (!fs)
|
||||||
{
|
{
|
||||||
forceLog_printf("Failed to create cache file \"%ls\"", path);
|
cemuLog_log(LogType::Force, "Failed to create cache file \"{}\"", _pathToUtf8(path));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
// init file cache
|
// init file cache
|
||||||
@ -124,9 +124,9 @@ FileCache* FileCache::Create(wzstring_view path, uint32 extraVersion)
|
|||||||
return fileCache;
|
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)
|
if (!fs)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
// read header
|
// read header
|
||||||
@ -165,7 +165,7 @@ FileCache* FileCache::_OpenExisting(wzstring_view path, bool compareExtraVersion
|
|||||||
fs->readU64(headerFileTableOffset);
|
fs->readU64(headerFileTableOffset);
|
||||||
if (!fs->readU32(headerFileTableSize))
|
if (!fs->readU32(headerFileTableSize))
|
||||||
{
|
{
|
||||||
forceLog_printf("\"%ls\" is corrupted", path);
|
cemuLog_log(LogType::Force, "\"{}\" is corrupted", _pathToUtf8(path));
|
||||||
delete fs;
|
delete fs;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -176,7 +176,7 @@ FileCache* FileCache::_OpenExisting(wzstring_view path, bool compareExtraVersion
|
|||||||
invalidFileTableSize = (headerFileTableSize % sizeof(FileTableEntry)) != 0;
|
invalidFileTableSize = (headerFileTableSize % sizeof(FileTableEntry)) != 0;
|
||||||
if (invalidFileTableSize)
|
if (invalidFileTableSize)
|
||||||
{
|
{
|
||||||
forceLog_printf("\"%ls\" is corrupted", path);
|
cemuLog_log(LogType::Force, "\"{}\" is corrupted", _pathToUtf8(path));
|
||||||
delete fs;
|
delete fs;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -212,14 +212,14 @@ FileCache* FileCache::_OpenExisting(wzstring_view path, bool compareExtraVersion
|
|||||||
}
|
}
|
||||||
if (incompleteFileTable)
|
if (incompleteFileTable)
|
||||||
{
|
{
|
||||||
forceLog_printf("\"%ls\" is corrupted (incomplete file table)", path);
|
cemuLog_log(LogType::Force, "\"{}\" is corrupted (incomplete file table)", _pathToUtf8(path));
|
||||||
delete fileCache;
|
delete fileCache;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return fileCache;
|
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);
|
FileCache* fileCache = _OpenExisting(path, true, extraVersion);
|
||||||
if (fileCache)
|
if (fileCache)
|
||||||
@ -229,7 +229,7 @@ FileCache* FileCache::Open(wzstring_view path, bool allowCreate, uint32 extraVer
|
|||||||
return Create(path, extraVersion);
|
return Create(path, extraVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileCache* FileCache::Open(wzstring_view path)
|
FileCache* FileCache::Open(const fs::path& path)
|
||||||
{
|
{
|
||||||
return _OpenExisting(path, false, 0);
|
return _OpenExisting(path, false, 0);
|
||||||
}
|
}
|
||||||
@ -614,7 +614,7 @@ sint32 FileCache::GetFileCount()
|
|||||||
|
|
||||||
void fileCache_test()
|
void fileCache_test()
|
||||||
{
|
{
|
||||||
FileCache* fc = FileCache::Create(L"testCache.bin", 0);
|
FileCache* fc = FileCache::Create("testCache.bin", 0);
|
||||||
uint32 time1 = GetTickCount();
|
uint32 time1 = GetTickCount();
|
||||||
|
|
||||||
char* testString1 = (char*)malloc(1024 * 1024 * 8);
|
char* testString1 = (char*)malloc(1024 * 1024 * 8);
|
||||||
@ -637,7 +637,7 @@ void fileCache_test()
|
|||||||
debug_printf("Writing took %dms\n", time2-time1);
|
debug_printf("Writing took %dms\n", time2-time1);
|
||||||
delete fc;
|
delete fc;
|
||||||
// verify if all entries are still valid
|
// 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();
|
uint32 time3 = GetTickCount();
|
||||||
for(sint32 i=0; i<2200; i++)
|
for(sint32 i=0; i<2200; i++)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common/zstring_view.h"
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
class FileCache
|
class FileCache
|
||||||
@ -36,9 +35,9 @@ public:
|
|||||||
|
|
||||||
~FileCache();
|
~FileCache();
|
||||||
|
|
||||||
static FileCache* Create(wzstring_view path, uint32 extraVersion = 0);
|
static FileCache* Create(const fs::path& path, uint32 extraVersion = 0);
|
||||||
static FileCache* Open(wzstring_view path, bool allowCreate, uint32 extraVersion = 0);
|
static FileCache* Open(const fs::path& path, bool allowCreate, uint32 extraVersion = 0);
|
||||||
static FileCache* Open(wzstring_view path); // open without extraVersion check
|
static FileCache* Open(const fs::path& path); // open without extraVersion check
|
||||||
|
|
||||||
void UseCompression(bool enable) { enableCompression = enable; };
|
void UseCompression(bool enable) { enableCompression = enable; };
|
||||||
|
|
||||||
@ -75,7 +74,7 @@ private:
|
|||||||
|
|
||||||
FileCache() {};
|
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 fileCache_updateFiletable(sint32 extraEntriesToAllocate);
|
||||||
void _addFileInternal(uint64 name1, uint64 name2, const uint8* fileData, sint32 fileSize, bool noCompression);
|
void _addFileInternal(uint64 name1, uint64 name2, const uint8* fileData, sint32 fileSize, bool noCompression);
|
||||||
|
@ -25,6 +25,7 @@ enum class LogType : sint32
|
|||||||
CoreinitThread = 17,
|
CoreinitThread = 17,
|
||||||
CoreinitLogging = 18, // OSReport, OSConsoleWrite etc.
|
CoreinitLogging = 18, // OSReport, OSConsoleWrite etc.
|
||||||
CoreinitMemoryMapping = 19, // OSGetAvailPhysAddrRange, OSAllocVirtAddr, OSMapMemory etc.
|
CoreinitMemoryMapping = 19, // OSGetAvailPhysAddrRange, OSAllocVirtAddr, OSMapMemory etc.
|
||||||
|
CoreinitAlarm = 23,
|
||||||
|
|
||||||
PPC_IPC = 20,
|
PPC_IPC = 20,
|
||||||
NN_AOC = 21,
|
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<TArgs>(args)...);
|
return cemuLog_log(type, format_str, std::forward<TArgs>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
// same as cemuLog_log, but only outputs in debug/release mode
|
// same as cemuLog_log, but only outputs in debug mode
|
||||||
template<typename TFmt, typename ... TArgs>
|
template<typename TFmt, typename ... TArgs>
|
||||||
bool cemuLog_logDebug(LogType type, TFmt format, TArgs&&... args)
|
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, ...)
|
// these are deprecated. Superseded by cemuLog_log(type, ...)
|
||||||
#define forceLog_printf(...) cafeLog_log(LOG_TYPE_FORCE, __VA_ARGS__);
|
#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 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 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__);
|
#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
|
#ifdef CEMU_DEBUG_ASSERT
|
||||||
#define forceLogDebug_printf(...) cafeLog_log(LOG_TYPE_FORCE, __VA_ARGS__);
|
#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
|
// use this for temporary debug logging. Will trigger compilation error in release builds
|
||||||
#define forceLogRemoveMe_printf(...) cafeLog_log(LOG_TYPE_FORCE, __VA_ARGS__);
|
#define forceLogRemoveMe_printf(...) cafeLog_log(LOG_TYPE_FORCE, __VA_ARGS__);
|
||||||
#else
|
#else
|
||||||
#define forceLogDebug_printf(...) ;
|
#define forceLogDebug_printf(...) ;
|
||||||
#define forceLogDebug_printfW(...) ;
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,7 +20,6 @@ add_library(CemuCommon
|
|||||||
SysAllocator.cpp
|
SysAllocator.cpp
|
||||||
SysAllocator.h
|
SysAllocator.h
|
||||||
version.h
|
version.h
|
||||||
zstring_view.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set_property(TARGET CemuCommon PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
set_property(TARGET CemuCommon PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||||
|
@ -2,6 +2,13 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include "betype.h"
|
#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* memory_base;
|
||||||
extern uint8* PPCInterpreterGetStackPointer();
|
extern uint8* PPCInterpreterGetStackPointer();
|
||||||
extern uint8* PPCInterpreterGetAndModifyStackPointer(sint32 offset);
|
extern uint8* PPCInterpreterGetAndModifyStackPointer(sint32 offset);
|
||||||
|
@ -85,7 +85,6 @@
|
|||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
#include "enumFlags.h"
|
#include "enumFlags.h"
|
||||||
#include "zstring_view.h"
|
|
||||||
|
|
||||||
// base types
|
// base types
|
||||||
using uint64 = uint64_t;
|
using uint64 = uint64_t;
|
||||||
@ -98,11 +97,6 @@ using sint32 = int32_t;
|
|||||||
using sint16 = int16_t;
|
using sint16 = int16_t;
|
||||||
using sint8 = int8_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
|
// types with explicit big endian order
|
||||||
#include "betype.h"
|
#include "betype.h"
|
||||||
|
|
||||||
@ -289,8 +283,6 @@ inline unsigned char _addcarry_u64(unsigned char carry, unsigned long long a, un
|
|||||||
// MEMPTR
|
// MEMPTR
|
||||||
#include "Common/MemPtr.h"
|
#include "Common/MemPtr.h"
|
||||||
|
|
||||||
#define MPTR_NULL (0)
|
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
constexpr bool HAS_FLAG(T1 flags, T2 test_flag) { return (flags & (T1)test_flag) == (T1)test_flag; }
|
constexpr bool HAS_FLAG(T1 flags, T2 test_flag) { return (flags & (T1)test_flag) == (T1)test_flag; }
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
|
@ -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 <string_view>
|
|
||||||
|
|
||||||
// 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<CharT, std::char_traits<CharT>, std::allocator<CharT>> 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
|
|
@ -241,7 +241,7 @@ fs::path ActiveSettings::GetMlcPath()
|
|||||||
return launch_mlc.value();
|
return launch_mlc.value();
|
||||||
|
|
||||||
if(const auto config_mlc = GetConfig().mlc_path.GetValue(); !config_mlc.empty())
|
if(const auto config_mlc = GetConfig().mlc_path.GetValue(); !config_mlc.empty())
|
||||||
return config_mlc;
|
return _utf8ToPath(config_mlc);
|
||||||
|
|
||||||
return GetDefaultMLCPath();
|
return GetDefaultMLCPath();
|
||||||
}
|
}
|
||||||
|
@ -10,19 +10,19 @@
|
|||||||
|
|
||||||
XMLCemuConfig_t g_config(L"settings.xml");
|
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)
|
if(save)
|
||||||
g_config.Save();
|
g_config.Save();
|
||||||
|
|
||||||
// if custom mlc path has been selected, store it in permanent config
|
// 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
|
try
|
||||||
{
|
{
|
||||||
auto pconfig = PermanentConfig::Load();
|
auto pconfig = PermanentConfig::Load();
|
||||||
pconfig.custom_mlc_path = boost::nowide::narrow(path.data(), path.size());
|
pconfig.custom_mlc_path = _pathToUtf8(path);
|
||||||
pconfig.Store();
|
pconfig.Store();
|
||||||
}
|
}
|
||||||
catch (const PSDisabledException&) {}
|
catch (const PSDisabledException&) {}
|
||||||
@ -46,14 +46,7 @@ void CemuConfig::Load(XMLConfigParser& parser)
|
|||||||
advanced_ppc_logging = parser.get("advanced_ppc_logging", advanced_ppc_logging.GetInitValue());
|
advanced_ppc_logging = parser.get("advanced_ppc_logging", advanced_ppc_logging.GetInitValue());
|
||||||
|
|
||||||
const char* mlc = parser.get("mlc_path", "");
|
const char* mlc = parser.get("mlc_path", "");
|
||||||
try
|
mlc_path = mlc;
|
||||||
{
|
|
||||||
mlc_path = boost::nowide::widen(mlc);
|
|
||||||
}
|
|
||||||
catch (const std::exception&)
|
|
||||||
{
|
|
||||||
forceLog_printf("config load error: can't load mlc path: %s", mlc);
|
|
||||||
}
|
|
||||||
|
|
||||||
permanent_storage = parser.get("permanent_storage", permanent_storage);
|
permanent_storage = parser.get("permanent_storage", permanent_storage);
|
||||||
|
|
||||||
@ -357,7 +350,7 @@ void CemuConfig::Save(XMLConfigParser& parser)
|
|||||||
// general settings
|
// general settings
|
||||||
config.set("logflag", log_flag.GetValue());
|
config.set("logflag", log_flag.GetValue());
|
||||||
config.set("advanced_ppc_logging", advanced_ppc_logging.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<bool>("permanent_storage", permanent_storage);
|
config.set<bool>("permanent_storage", permanent_storage);
|
||||||
config.set<sint32>("language", language);
|
config.set<sint32>("language", language);
|
||||||
config.set<bool>("use_discord_presence", use_discord_presence);
|
config.set<bool>("use_discord_presence", use_discord_presence);
|
||||||
|
@ -356,7 +356,7 @@ struct CemuConfig
|
|||||||
//
|
//
|
||||||
|
|
||||||
// sets mlc path, updates permanent config value, saves config
|
// 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<uint64> log_flag{ 0 };
|
ConfigValue<uint64> log_flag{ 0 };
|
||||||
ConfigValue<bool> advanced_ppc_logging{ false };
|
ConfigValue<bool> advanced_ppc_logging{ false };
|
||||||
@ -365,7 +365,7 @@ struct CemuConfig
|
|||||||
|
|
||||||
ConfigValue<sint32> language{ wxLANGUAGE_DEFAULT };
|
ConfigValue<sint32> language{ wxLANGUAGE_DEFAULT };
|
||||||
ConfigValue<bool> use_discord_presence{ true };
|
ConfigValue<bool> use_discord_presence{ true };
|
||||||
ConfigValue<std::wstring> mlc_path {};
|
ConfigValue<std::string> mlc_path {};
|
||||||
ConfigValue<bool> fullscreen_menubar{ false };
|
ConfigValue<bool> fullscreen_menubar{ false };
|
||||||
ConfigValue<bool> fullscreen{ false };
|
ConfigValue<bool> fullscreen{ false };
|
||||||
ConfigValue<std::string> proxy_server{};
|
ConfigValue<std::string> proxy_server{};
|
||||||
|
@ -344,10 +344,9 @@ public:
|
|||||||
if (L == nullptr)
|
if (L == nullptr)
|
||||||
return false;
|
return false;
|
||||||
FileStream* fs = FileStream::openFile(filename.c_str());
|
FileStream* fs = FileStream::openFile(filename.c_str());
|
||||||
|
if (!fs)
|
||||||
if (fs == nullptr)
|
|
||||||
{
|
{
|
||||||
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;
|
return false;
|
||||||
}
|
}
|
||||||
std::vector<uint8> xmlData;
|
std::vector<uint8> xmlData;
|
||||||
@ -360,7 +359,7 @@ public:
|
|||||||
const bool success = error == tinyxml2::XML_SUCCESS;
|
const bool success = error == tinyxml2::XML_SUCCESS;
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
forceLogDebug_printf("XMLConfig::Load > LoadFile %d", error);
|
cemuLog_logDebug(LogType::Force, "XMLConfig::Load > LoadFile {}", error);
|
||||||
}
|
}
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
@ -401,9 +400,9 @@ public:
|
|||||||
#else
|
#else
|
||||||
file = fopen(boost::nowide::narrow(tmp_name).c_str(), "wb");
|
file = fopen(boost::nowide::narrow(tmp_name).c_str(), "wb");
|
||||||
#endif
|
#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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,7 +416,7 @@ public:
|
|||||||
const tinyxml2::XMLError error = doc.SaveFile(file);
|
const tinyxml2::XMLError error = doc.SaveFile(file);
|
||||||
const bool success = error == tinyxml2::XML_SUCCESS;
|
const bool success = error == tinyxml2::XML_SUCCESS;
|
||||||
if(error != 0)
|
if(error != 0)
|
||||||
forceLogDebug_printfW(L"XMLConfig::Save > SaveFile %d", error);
|
cemuLog_logDebug(LogType::Force, "XMLConfig::Save > SaveFile {}", error);
|
||||||
|
|
||||||
fflush(file);
|
fflush(file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
@ -425,7 +424,7 @@ public:
|
|||||||
fs::rename(tmp_name, filename, err);
|
fs::rename(tmp_name, filename, err);
|
||||||
if(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);
|
fs::remove(tmp_name, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <wx/image.h>
|
#include <wx/image.h>
|
||||||
#include <wx/filename.h>
|
#include <wx/filename.h>
|
||||||
#include <wx/stdpaths.h>
|
#include <wx/stdpaths.h>
|
||||||
|
#include "wxHelper.h"
|
||||||
|
|
||||||
#include "Cafe/TitleList/TitleList.h"
|
#include "Cafe/TitleList/TitleList.h"
|
||||||
#include "Cafe/TitleList/SaveList.h"
|
#include "Cafe/TitleList/SaveList.h"
|
||||||
@ -276,12 +277,12 @@ std::vector<const wxLanguageInfo*> CemuApp::GetAvailableLanguages()
|
|||||||
|
|
||||||
void CemuApp::CreateDefaultFiles(bool first_start)
|
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
|
// check for mlc01 folder missing if custom path has been set
|
||||||
if (!fs::exists(mlc) && !first_start)
|
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);
|
wxMessageDialog dialog(nullptr, message, "Error", wxCENTRE | wxYES_NO | wxCANCEL| wxICON_WARNING);
|
||||||
dialog.SetYesNoCancelLabels(_("Yes"), _("No"), _("Select a custom path"));
|
dialog.SetYesNoCancelLabels(_("Yes"), _("No"), _("Select a custom path"));
|
||||||
@ -292,12 +293,11 @@ void CemuApp::CreateDefaultFiles(bool first_start)
|
|||||||
{
|
{
|
||||||
if (!SelectMLCPath())
|
if (!SelectMLCPath())
|
||||||
return;
|
return;
|
||||||
|
mlc = ActiveSettings::GetMlcPath();
|
||||||
mlc = GetMLCPath();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GetConfig().mlc_path = L"";
|
GetConfig().mlc_path = "";
|
||||||
g_config.Save();
|
g_config.Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -305,22 +305,22 @@ void CemuApp::CreateDefaultFiles(bool first_start)
|
|||||||
// create sys/usr folder in mlc01
|
// create sys/usr folder in mlc01
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const auto sysFolder = fs::path(mlc).append(L"sys");
|
const auto sysFolder = fs::path(mlc).append("sys");
|
||||||
fs::create_directories(sysFolder);
|
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(usrFolder);
|
||||||
fs::create_directories(fs::path(usrFolder).append("title/00050000")); // base
|
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/0005000c")); // dlc
|
||||||
fs::create_directories(fs::path(usrFolder).append("title/0005000e")); // update
|
fs::create_directories(fs::path(usrFolder).append("title/0005000e")); // update
|
||||||
|
|
||||||
// Mii Maker save folders {0x500101004A000, 0x500101004A100, 0x500101004A200},
|
// 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("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("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/1004a200/user/common/db"));
|
||||||
|
|
||||||
// lang files
|
// 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);
|
fs::create_directories(langDir);
|
||||||
|
|
||||||
auto langFile = fs::path(langDir).append("language.txt");
|
auto langFile = fs::path(langDir).append("language.txt");
|
||||||
@ -357,7 +357,7 @@ void CemuApp::CreateDefaultFiles(bool first_start)
|
|||||||
catch (const std::exception& ex)
|
catch (const std::exception& ex)
|
||||||
{
|
{
|
||||||
std::stringstream errorMsg;
|
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
|
#if BOOST_OS_WINDOWS
|
||||||
const DWORD lastError = GetLastError();
|
const DWORD lastError = GetLastError();
|
||||||
@ -372,11 +372,11 @@ void CemuApp::CreateDefaultFiles(bool first_start)
|
|||||||
// cemu directories
|
// cemu directories
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const auto controllerProfileFolder = GetConfigPath(L"controllerProfiles").ToStdWstring();
|
const auto controllerProfileFolder = ActiveSettings::GetConfigPath("controllerProfiles");
|
||||||
if (!fs::exists(controllerProfileFolder))
|
if (!fs::exists(controllerProfileFolder))
|
||||||
fs::create_directories(controllerProfileFolder);
|
fs::create_directories(controllerProfileFolder);
|
||||||
|
|
||||||
const auto memorySearcherFolder = GetUserDataPath(L"memorySearcher").ToStdWstring();
|
const auto memorySearcherFolder = ActiveSettings::GetUserDataPath("memorySearcher");
|
||||||
if (!fs::exists(memorySearcherFolder))
|
if (!fs::exists(memorySearcherFolder))
|
||||||
fs::create_directories(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())
|
if (path.empty())
|
||||||
path = ActiveSettings::GetDefaultMLCPath().wstring();
|
path = ActiveSettings::GetDefaultMLCPath();
|
||||||
|
|
||||||
if (!TestWriteAccess(fs::path{ path }))
|
if (!TestWriteAccess(path))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
GetConfig().SetMLCPath(path);
|
GetConfig().SetMLCPath(path);
|
||||||
@ -421,14 +421,14 @@ bool CemuApp::SelectMLCPath(wxWindow* parent)
|
|||||||
{
|
{
|
||||||
auto& config = GetConfig();
|
auto& config = GetConfig();
|
||||||
|
|
||||||
std::wstring default_path;
|
fs::path default_path;
|
||||||
if (fs::exists(config.mlc_path.GetValue()))
|
if (fs::exists(_utf8ToPath(config.mlc_path.GetValue())))
|
||||||
default_path = config.mlc_path.GetValue();
|
default_path = _utf8ToPath(config.mlc_path.GetValue());
|
||||||
|
|
||||||
// try until users selects a valid path or aborts
|
// try until users selects a valid path or aborts
|
||||||
while(true)
|
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())
|
if (path_dialog.ShowModal() != wxID_OK || path_dialog.GetPath().empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -449,37 +449,6 @@ bool CemuApp::SelectMLCPath(wxWindow* parent)
|
|||||||
return false;
|
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)
|
void CemuApp::ActivateApp(wxActivateEvent& event)
|
||||||
{
|
{
|
||||||
g_window_info.app_active = event.GetActive();
|
g_window_info.app_active = event.GetActive();
|
||||||
|
@ -17,17 +17,9 @@ public:
|
|||||||
static std::vector<const wxLanguageInfo*> GetAvailableLanguages();
|
static std::vector<const wxLanguageInfo*> GetAvailableLanguages();
|
||||||
|
|
||||||
static void CreateDefaultFiles(bool first_start = false);
|
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 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:
|
private:
|
||||||
void ActivateApp(wxActivateEvent& event);
|
void ActivateApp(wxActivateEvent& event);
|
||||||
|
|
||||||
|
@ -868,7 +868,7 @@ void GeneralSettings2::StoreConfig()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!LaunchSettings::GetMLCPath().has_value())
|
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
|
// -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};
|
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();
|
auto& config = GetConfig();
|
||||||
|
|
||||||
if (LaunchSettings::GetMLCPath().has_value())
|
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
|
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_window_position_size->SetValue(config.window_position != Vector2i{-1,-1});
|
||||||
m_save_padwindow_position_size->SetValue(config.pad_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))
|
if (!CemuApp::SelectMLCPath(this))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_mlc_path->SetValue(ActiveSettings::GetMlcPath().generic_string());
|
m_mlc_path->SetValue(wxHelper::FromPath(ActiveSettings::GetMlcPath()));
|
||||||
m_reload_gamelist = true;
|
m_reload_gamelist = true;
|
||||||
m_mlc_modified = true;
|
m_mlc_modified = true;
|
||||||
}
|
}
|
||||||
@ -1922,16 +1922,16 @@ void GeneralSettings2::OnMLCPathChar(wxKeyEvent& event)
|
|||||||
|
|
||||||
if(event.GetKeyCode() == WXK_DELETE || event.GetKeyCode() == WXK_BACK)
|
if(event.GetKeyCode() == WXK_DELETE || event.GetKeyCode() == WXK_BACK)
|
||||||
{
|
{
|
||||||
std::wstring newPath = L"";
|
fs::path newPath = "";
|
||||||
if(!CemuApp::TrySelectMLCPath(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);
|
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))
|
if (res == wxYES && CemuApp::SelectMLCPath(this))
|
||||||
newPath = ActiveSettings::GetMlcPath().wstring();
|
newPath = ActiveSettings::GetMlcPath();
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_mlc_path->SetValue(newPath);
|
m_mlc_path->SetValue(wxHelper::FromPath(newPath));
|
||||||
m_reload_gamelist = true;
|
m_reload_gamelist = true;
|
||||||
m_mlc_modified = true;
|
m_mlc_modified = true;
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ void GettingStartedDialog::OnClose(wxCloseEvent& event)
|
|||||||
const fs::path mlcPath = wxHelper::MakeFSPath(m_mlc_folder->GetPath());
|
const fs::path mlcPath = wxHelper::MakeFSPath(m_mlc_folder->GetPath());
|
||||||
if(config.mlc_path.GetValue() != mlcPath && (mlcPath.empty() || fs::exists(mlcPath)))
|
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;
|
m_mlc_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,15 +495,14 @@ void GraphicPacksWindow2::OnTreeChoiceChanged(wxTreeEvent& event)
|
|||||||
auto& graphic_pack = data->GetGraphicPack();
|
auto& graphic_pack = data->GetGraphicPack();
|
||||||
graphic_pack->SetEnabled(state);
|
graphic_pack->SetEnabled(state);
|
||||||
|
|
||||||
bool has_texture_rules = false;
|
bool requiresRestart = graphic_pack->RequiresRestart(true, false);
|
||||||
if (CafeSystem::IsTitleRunning() && graphic_pack->ContainsTitleId(CafeSystem::GetForegroundTitleId()))
|
bool isRunning = CafeSystem::IsTitleRunning() && graphic_pack->ContainsTitleId(CafeSystem::GetForegroundTitleId());
|
||||||
|
if (isRunning)
|
||||||
{
|
{
|
||||||
if (state)
|
if (state)
|
||||||
{
|
{
|
||||||
GraphicPack2::ActivateGraphicPack(graphic_pack);
|
GraphicPack2::ActivateGraphicPack(graphic_pack);
|
||||||
has_texture_rules = !graphic_pack->GetTextureRules().empty();
|
if (!requiresRestart)
|
||||||
|
|
||||||
if (!has_texture_rules)
|
|
||||||
{
|
{
|
||||||
ReloadPack(graphic_pack);
|
ReloadPack(graphic_pack);
|
||||||
m_graphic_pack_tree->SetItemTextColour(item, 0x009900);
|
m_graphic_pack_tree->SetItemTextColour(item, 0x009900);
|
||||||
@ -511,19 +510,16 @@ void GraphicPacksWindow2::OnTreeChoiceChanged(wxTreeEvent& event)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
has_texture_rules = !graphic_pack->GetTextureRules().empty();
|
if (!requiresRestart)
|
||||||
|
|
||||||
if (!has_texture_rules)
|
|
||||||
{
|
{
|
||||||
DeleteShadersFromRuntimeCache(graphic_pack);
|
DeleteShadersFromRuntimeCache(graphic_pack);
|
||||||
m_graphic_pack_tree->SetItemTextColour(item, *wxBLACK);
|
m_graphic_pack_tree->SetItemTextColour(item, *wxBLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicPack2::DeactivateGraphicPack(graphic_pack);
|
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"));
|
m_info_bar->ShowMessage(_("Restart of Cemu required for changes to take effect"));
|
||||||
|
|
||||||
// also change selection to activated gp
|
// also change selection to activated gp
|
||||||
@ -583,7 +579,7 @@ void GraphicPacksWindow2::OnActivePresetChanged(wxCommandEvent& event)
|
|||||||
m_right_panel->Layout();
|
m_right_panel->Layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_shown_graphic_pack->GetTextureRules().empty())
|
if (!m_shown_graphic_pack->RequiresRestart(false, true))
|
||||||
ReloadPack(m_shown_graphic_pack);
|
ReloadPack(m_shown_graphic_pack);
|
||||||
else if (!m_info_bar->IsShown())
|
else if (!m_info_bar->IsShown())
|
||||||
m_info_bar->ShowMessage(_("Restart of Cemu required for changes to take effect"));
|
m_info_bar->ShowMessage(_("Restart of Cemu required for changes to take effect"));
|
||||||
|
@ -624,7 +624,7 @@ void MainWindow::OnFileMenu(wxCommandEvent& event)
|
|||||||
|
|
||||||
void MainWindow::OnOpenCemuFolder(wxCommandEvent& event)
|
void MainWindow::OnOpenCemuFolder(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
wxLaunchDefaultApplication(ActiveSettings::GetUserDataPath().wstring());
|
wxLaunchDefaultApplication(wxHelper::FromPath(ActiveSettings::GetUserDataPath()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::OnInstallUpdate(wxCommandEvent& event)
|
void MainWindow::OnInstallUpdate(wxCommandEvent& event)
|
||||||
@ -1004,7 +1004,7 @@ void MainWindow::OnDebugSetting(wxCommandEvent& event)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const fs::path path(CemuApp::GetUserDataPath().ToStdString());
|
const fs::path path(ActiveSettings::GetUserDataPath());
|
||||||
fs::create_directories(path / "dump" / "curl");
|
fs::create_directories(path / "dump" / "curl");
|
||||||
}
|
}
|
||||||
catch (const std::exception& ex)
|
catch (const std::exception& ex)
|
||||||
@ -1061,7 +1061,7 @@ void MainWindow::OnDebugDumpUsedTextures(wxCommandEvent& event)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// create directory
|
// create directory
|
||||||
const fs::path path(CemuApp::GetUserDataPath().ToStdString());
|
const fs::path path(ActiveSettings::GetUserDataPath());
|
||||||
fs::create_directories(path / "dump" / "textures");
|
fs::create_directories(path / "dump" / "textures");
|
||||||
}
|
}
|
||||||
catch (const std::exception& ex)
|
catch (const std::exception& ex)
|
||||||
@ -1082,7 +1082,7 @@ void MainWindow::OnDebugDumpUsedShaders(wxCommandEvent& event)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// create directory
|
// create directory
|
||||||
const fs::path path(CemuApp::GetUserDataPath().ToStdString());
|
const fs::path path(ActiveSettings::GetUserDataPath());
|
||||||
fs::create_directories(path / "dump" / "shaders");
|
fs::create_directories(path / "dump" / "shaders");
|
||||||
}
|
}
|
||||||
catch (const std::exception & ex)
|
catch (const std::exception & ex)
|
||||||
|
@ -22,6 +22,12 @@ namespace wxHelper
|
|||||||
return wxString::FromUTF8(str.data(), str.size());
|
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)
|
inline wxColour CalculateAccentColour(const wxColour& bgColour)
|
||||||
{
|
{
|
||||||
wxColour bgColourSecondary;
|
wxColour bgColourSecondary;
|
||||||
|
@ -112,7 +112,7 @@ void infoLog_cemuStartup()
|
|||||||
{
|
{
|
||||||
cemuLog_force("------- Init {} -------", BUILD_VERSION_WITH_NAME_STRING);
|
cemuLog_force("------- Init {} -------", BUILD_VERSION_WITH_NAME_STRING);
|
||||||
cemuLog_force("Init Wii U memory space (base: 0x{:016x})", (size_t)memory_base);
|
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
|
// check for wine version
|
||||||
checkForWine();
|
checkForWine();
|
||||||
// CPU and RAM info
|
// CPU and RAM info
|
||||||
|
Loading…
Reference in New Issue
Block a user