mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-03 21:41:19 +12:00
GCC build
This commit is contained in:
parent
be0f062de8
commit
c8c9fad128
48 changed files with 327 additions and 273 deletions
4
build.sh
Executable file
4
build.sh
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=release -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++
|
||||||
|
cd ..
|
|
@ -21,8 +21,9 @@ if(MSVC)
|
||||||
# _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
|
# _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
|
||||||
elseif(UNIX)
|
elseif(UNIX)
|
||||||
add_definitions(-fms-extensions)
|
add_definitions(-fms-extensions)
|
||||||
add_definitions(-fms-compatibility-version=19.14)
|
# add_definitions(-fms-compatibility-version=19.14)
|
||||||
add_definitions(-fdelayed-template-parsing)
|
# add_definitions(-fdelayed-template-parsing)
|
||||||
|
add_definitions(-fpermissive)
|
||||||
add_definitions(-DVK_USE_PLATFORM_XLIB_KHR) # legacy. Do we need to support XLIB surfaces?
|
add_definitions(-DVK_USE_PLATFORM_XLIB_KHR) # legacy. Do we need to support XLIB surfaces?
|
||||||
add_definitions(-DVK_USE_PLATFORM_XCB_KHR)
|
add_definitions(-DVK_USE_PLATFORM_XCB_KHR)
|
||||||
add_definitions(-maes)
|
add_definitions(-maes)
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
project(CemuCafe)
|
project(CemuCafe)
|
||||||
|
|
||||||
include_directories(".")
|
include_directories(".")
|
||||||
|
|
||||||
|
if((CMAKE_C_COMPILER_ID MATCHES "GNU") OR (CMAKE_C_COMPILER_ID MATCHES "Clang"))
|
||||||
|
add_compile_options(-mssse3 -mavx2)
|
||||||
|
endif()
|
||||||
|
|
||||||
file(GLOB_RECURSE CPP_FILES *.cpp)
|
file(GLOB_RECURSE CPP_FILES *.cpp)
|
||||||
file(GLOB_RECURSE H_FILES *.h)
|
file(GLOB_RECURSE H_FILES *.h)
|
||||||
add_library(CemuCafe ${CPP_FILES} ${H_FILES})
|
add_library(CemuCafe ${CPP_FILES} ${H_FILES})
|
||||||
|
|
||||||
|
|
||||||
set_property(TARGET CemuCafe PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
set_property(TARGET CemuCafe PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||||
|
|
||||||
target_precompile_headers(CemuCafe PRIVATE ../Common/precompiled.h)
|
target_precompile_headers(CemuCafe PRIVATE ../Common/precompiled.h)
|
||||||
|
@ -23,7 +29,6 @@ target_link_libraries(CemuCafe glslang SPIRV)
|
||||||
target_link_libraries(CemuCafe ih264d zarchive)
|
target_link_libraries(CemuCafe ih264d zarchive)
|
||||||
#target_link_libraries(CemuCafe zstd::libzstd_static)
|
#target_link_libraries(CemuCafe zstd::libzstd_static)
|
||||||
|
|
||||||
|
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
target_link_libraries(CemuCafe iphlpapi)
|
target_link_libraries(CemuCafe iphlpapi)
|
||||||
ENDIF()
|
ENDIF()
|
|
@ -282,7 +282,7 @@ struct
|
||||||
|
|
||||||
static_assert(sizeof(SharedDataEntry) == 0x1C);
|
static_assert(sizeof(SharedDataEntry) == 0x1C);
|
||||||
|
|
||||||
__declspec(dllexport) uint32 loadSharedData()
|
DLLEXPORT uint32 loadSharedData()
|
||||||
{
|
{
|
||||||
// check if font files are dumped
|
// check if font files are dumped
|
||||||
bool hasAllShareddataFiles = true;
|
bool hasAllShareddataFiles = true;
|
||||||
|
|
|
@ -22,7 +22,7 @@ struct gameProfileBooleanOption_t
|
||||||
* If the option exists, true is returned.
|
* If the option exists, true is returned.
|
||||||
* The boolean is stored in *optionValue
|
* The boolean is stored in *optionValue
|
||||||
*/
|
*/
|
||||||
__declspec(dllexport) bool gameProfile_loadBooleanOption(IniParser* iniParser, char* optionName, gameProfileBooleanOption_t* option)
|
DLLEXPORT bool gameProfile_loadBooleanOption(IniParser* iniParser, char* optionName, gameProfileBooleanOption_t* option)
|
||||||
{
|
{
|
||||||
auto option_value = iniParser->FindOption(optionName);
|
auto option_value = iniParser->FindOption(optionName);
|
||||||
option->isPresent = false;
|
option->isPresent = false;
|
||||||
|
@ -81,7 +81,7 @@ bool gameProfile_loadBooleanOption2(IniParser& iniParser, const char* optionName
|
||||||
* Attempts to load a integer option
|
* Attempts to load a integer option
|
||||||
* Allows to specify min and max value (error is logged if out of range and default value is picked)
|
* Allows to specify min and max value (error is logged if out of range and default value is picked)
|
||||||
*/
|
*/
|
||||||
__declspec(dllexport) bool gameProfile_loadIntegerOption(IniParser* iniParser, const char* optionName, gameProfileIntegerOption_t* option, sint32 defaultValue, sint32 minVal, sint32 maxVal)
|
DLLEXPORT bool gameProfile_loadIntegerOption(IniParser* iniParser, const char* optionName, gameProfileIntegerOption_t* option, sint32 defaultValue, sint32 minVal, sint32 maxVal)
|
||||||
{
|
{
|
||||||
auto option_value = iniParser->FindOption(optionName);
|
auto option_value = iniParser->FindOption(optionName);
|
||||||
option->isPresent = false;
|
option->isPresent = false;
|
||||||
|
@ -167,7 +167,7 @@ bool gameProfile_loadEnumOption(IniParser& iniParser, const char* optionName, st
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma optimize( "", off )
|
#pragma optimize( "", off )
|
||||||
__declspec(dllexport) __declspec(noinline) void gameProfile_categoryBegin(IniParser* iniParser)
|
DLLEXPORT NOINLINE void gameProfile_categoryBegin(IniParser* iniParser)
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -381,11 +381,11 @@ void GameProfile::Reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
// legacy code for Cemuhook
|
// legacy code for Cemuhook
|
||||||
__declspec(dllexport) char* gameProfile_loadStringOption(IniParser* iniParser, char* optionName)
|
DLLEXPORT char* gameProfile_loadStringOption(IniParser* iniParser, char* optionName)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
__declspec(dllexport) char* gameProfile_getCurrentCategoryName(IniParser* iniParser)
|
DLLEXPORT char* gameProfile_getCurrentCategoryName(IniParser* iniParser)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -396,7 +396,7 @@ struct gpNamedOptionEntry_t
|
||||||
sint32 value;
|
sint32 value;
|
||||||
};
|
};
|
||||||
|
|
||||||
__declspec(dllexport) bool gameProfile_loadIntegerNamedOption(IniParser* iniParser, char* optionName, gameProfileIntegerOption_t* option, sint32 defaultValue, const gpNamedOptionEntry_t* nameValues, sint32 numNameValues)
|
DLLEXPORT bool gameProfile_loadIntegerNamedOption(IniParser* iniParser, char* optionName, gameProfileIntegerOption_t* option, sint32 defaultValue, const gpNamedOptionEntry_t* nameValues, sint32 numNameValues)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
|
@ -65,4 +65,4 @@ private:
|
||||||
};
|
};
|
||||||
extern std::unique_ptr<GameProfile> g_current_game_profile;
|
extern std::unique_ptr<GameProfile> g_current_game_profile;
|
||||||
|
|
||||||
__declspec(dllexport) void gameProfile_load();
|
DLLEXPORT void gameProfile_load();
|
||||||
|
|
|
@ -10,7 +10,7 @@ typedef struct
|
||||||
}graphicPack_t;
|
}graphicPack_t;
|
||||||
|
|
||||||
// scans the graphic pack directory for shaders
|
// scans the graphic pack directory for shaders
|
||||||
__declspec(dllexport) void graphicPack_loadGraphicPackShaders(graphicPack_t* gp, wchar_t* graphicPackPath)
|
DLLEXPORT void graphicPack_loadGraphicPackShaders(graphicPack_t* gp, wchar_t* graphicPackPath)
|
||||||
{
|
{
|
||||||
// this function is part of the deprecated/removed v1 graphic pack code
|
// this function is part of the deprecated/removed v1 graphic pack code
|
||||||
// as of Cemuhook 0.5.7.3 this function must exist with a minimum length for detour
|
// as of Cemuhook 0.5.7.3 this function must exist with a minimum length for detour
|
||||||
|
@ -21,7 +21,7 @@ __declspec(dllexport) void graphicPack_loadGraphicPackShaders(graphicPack_t* gp,
|
||||||
}
|
}
|
||||||
|
|
||||||
// for cemuhook compatibility only
|
// for cemuhook compatibility only
|
||||||
__declspec(dllexport) bool config_isGraphicPackEnabled(uint64 id)
|
DLLEXPORT bool config_isGraphicPackEnabled(uint64 id)
|
||||||
{
|
{
|
||||||
forceLog_printf("STUB4");
|
forceLog_printf("STUB4");
|
||||||
forceLog_printf("STUB5");
|
forceLog_printf("STUB5");
|
||||||
|
|
|
@ -601,13 +601,13 @@ void GraphicPack2::LoadShaders()
|
||||||
|
|
||||||
#pragma optimize( "", off )
|
#pragma optimize( "", off )
|
||||||
|
|
||||||
DLLEXPORT __declspec(noinline) void GraphicPack2_notifyActivate(GraphicPack2* gp, ExpressionParser* ep)
|
DLLEXPORT NOINLINE void GraphicPack2_notifyActivate(GraphicPack2* gp, ExpressionParser* ep)
|
||||||
{
|
{
|
||||||
// for Cemuhook
|
// for Cemuhook
|
||||||
int placeholder = 0xDEADDEAD;
|
int placeholder = 0xDEADDEAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLLEXPORT __declspec(noinline) void GraphicPack2_notifyDeactivate(GraphicPack2* gp)
|
DLLEXPORT NOINLINE void GraphicPack2_notifyDeactivate(GraphicPack2* gp)
|
||||||
{
|
{
|
||||||
// for Cemuhook
|
// for Cemuhook
|
||||||
int placeholder = 0xDEADDEAD;
|
int placeholder = 0xDEADDEAD;
|
||||||
|
|
|
@ -166,8 +166,8 @@ public:
|
||||||
static bool DeactivateGraphicPack(const std::shared_ptr<GraphicPack2>& graphic_pack);
|
static bool DeactivateGraphicPack(const std::shared_ptr<GraphicPack2>& graphic_pack);
|
||||||
static void ClearGraphicPacks();
|
static void ClearGraphicPacks();
|
||||||
private:
|
private:
|
||||||
__declspec(dllexport) bool Activate();
|
DLLEXPORT bool Activate();
|
||||||
__declspec(dllexport) bool Deactivate();
|
DLLEXPORT bool Deactivate();
|
||||||
|
|
||||||
static std::vector<std::shared_ptr<GraphicPack2>> s_graphic_packs;
|
static std::vector<std::shared_ptr<GraphicPack2>> s_graphic_packs;
|
||||||
static std::vector<std::shared_ptr<GraphicPack2>> s_active_graphic_packs;
|
static std::vector<std::shared_ptr<GraphicPack2>> s_active_graphic_packs;
|
||||||
|
|
|
@ -34,7 +34,7 @@ PPCInterpreter_t* PPCInterpreter_getCurrentInstance()
|
||||||
return ppcInterpreterCurrentInstance;
|
return ppcInterpreterCurrentInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(noinline) uint64 PPCInterpreter_getMainCoreCycleCounter()
|
NOINLINE uint64 PPCInterpreter_getMainCoreCycleCounter()
|
||||||
{
|
{
|
||||||
return PPCTimer_getFromRDTSC();
|
return PPCTimer_getFromRDTSC();
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ PPCInterpreter_t* PPCCore_executeCallbackInternal(uint32 functionMPTR)
|
||||||
return hCPU;
|
return hCPU;
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) void PPCCore_executeCallback(uint32 functionMPTR)
|
DLLEXPORT void PPCCore_executeCallback(uint32 functionMPTR)
|
||||||
{
|
{
|
||||||
PPCCore_executeCallbackInternal(functionMPTR);
|
PPCCore_executeCallbackInternal(functionMPTR);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,11 @@
|
||||||
|
|
||||||
#if BOOST_OS_LINUX > 0
|
#if BOOST_OS_LINUX > 0
|
||||||
static __inline__
|
static __inline__
|
||||||
unsigned __int64 _umul128(unsigned __int64,
|
uint64 _umul128(uint64 multiplier, uint64 multiplicand, uint64 *highProduct) {
|
||||||
unsigned __int64,
|
unsigned __int128 x = (unsigned __int128)multiplier * (unsigned __int128)multiplicand;
|
||||||
unsigned __int64*);
|
*highProduct = (x >> 64);
|
||||||
|
return x & 0xFFFFFFFFFFFFFFFF;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint64 _rdtscLastMeasure = 0;
|
uint64 _rdtscLastMeasure = 0;
|
||||||
|
@ -49,7 +51,7 @@ uint64 PPCTimer_estimateRDTSCFrequency()
|
||||||
forceLog_printf("Invariant TSC not supported");
|
forceLog_printf("Invariant TSC not supported");
|
||||||
|
|
||||||
_mm_mfence();
|
_mm_mfence();
|
||||||
unsigned __int64 tscStart = __rdtsc();
|
uint64 tscStart = __rdtsc();
|
||||||
unsigned int startTime = GetTickCount();
|
unsigned int startTime = GetTickCount();
|
||||||
HRTick startTick = HighResolutionTimer::now().getTick();
|
HRTick startTick = HighResolutionTimer::now().getTick();
|
||||||
// wait roughly 3 seconds
|
// wait roughly 3 seconds
|
||||||
|
@ -61,7 +63,7 @@ uint64 PPCTimer_estimateRDTSCFrequency()
|
||||||
}
|
}
|
||||||
_mm_mfence();
|
_mm_mfence();
|
||||||
HRTick stopTick = HighResolutionTimer::now().getTick();
|
HRTick stopTick = HighResolutionTimer::now().getTick();
|
||||||
unsigned __int64 tscEnd = __rdtsc();
|
uint64 tscEnd = __rdtsc();
|
||||||
// derive frequency approximation from measured time difference
|
// derive frequency approximation from measured time difference
|
||||||
uint64 tsc_diff = tscEnd - tscStart;
|
uint64 tsc_diff = tscEnd - tscStart;
|
||||||
uint64 hrtFreq = 0;
|
uint64 hrtFreq = 0;
|
||||||
|
|
|
@ -580,7 +580,7 @@ void PPCRecompiler_init()
|
||||||
__cpuid(cpuInfo, 0x1);
|
__cpuid(cpuInfo, 0x1);
|
||||||
hasMOVBESupport = ((cpuInfo[2] >> 22) & 1) != 0;
|
hasMOVBESupport = ((cpuInfo[2] >> 22) & 1) != 0;
|
||||||
hasAVXSupport = ((cpuInfo[2] >> 28) & 1) != 0;
|
hasAVXSupport = ((cpuInfo[2] >> 28) & 1) != 0;
|
||||||
__cpuidex(cpuInfo, 0x7, 0);
|
__cpuidex1(cpuInfo, 0x7, 0);
|
||||||
hasBMI2Support = ((cpuInfo[1] >> 8) & 1) != 0;
|
hasBMI2Support = ((cpuInfo[1] >> 8) & 1) != 0;
|
||||||
|
|
||||||
forceLog_printf("Recompiler initialized. CPU extensions: %s%s%s", hasLZCNTSupport ? "LZCNT " : "", hasMOVBESupport ? "MOVBE " : "", hasAVXSupport ? "AVX " : "");
|
forceLog_printf("Recompiler initialized. CPU extensions: %s%s%s", hasLZCNTSupport ? "LZCNT " : "", hasMOVBESupport ? "MOVBE " : "", hasAVXSupport ? "AVX " : "");
|
||||||
|
|
|
@ -345,20 +345,20 @@ typedef struct
|
||||||
PPCRecFunction_t* ppcRecompilerFuncTable[PPC_REC_ALIGN_TO_4MB(PPC_REC_CODE_AREA_SIZE/4)]; // one virtual-function pointer for each potential ppc instruction
|
PPCRecFunction_t* ppcRecompilerFuncTable[PPC_REC_ALIGN_TO_4MB(PPC_REC_CODE_AREA_SIZE/4)]; // one virtual-function pointer for each potential ppc instruction
|
||||||
PPCREC_JUMP_ENTRY ppcRecompilerDirectJumpTable[PPC_REC_ALIGN_TO_4MB(PPC_REC_CODE_AREA_SIZE/4)]; // lookup table for ppc offset to native code function
|
PPCREC_JUMP_ENTRY ppcRecompilerDirectJumpTable[PPC_REC_ALIGN_TO_4MB(PPC_REC_CODE_AREA_SIZE/4)]; // lookup table for ppc offset to native code function
|
||||||
// x64 data
|
// x64 data
|
||||||
uint64 __declspec(align(16)) _x64XMM_xorNegateMaskBottom[2];
|
uint64 ALIGN(16) _x64XMM_xorNegateMaskBottom[2];
|
||||||
uint64 __declspec(align(16)) _x64XMM_xorNegateMaskPair[2];
|
uint64 ALIGN(16) _x64XMM_xorNegateMaskPair[2];
|
||||||
uint64 __declspec(align(16)) _x64XMM_xorNOTMask[2];
|
uint64 ALIGN(16) _x64XMM_xorNOTMask[2];
|
||||||
uint64 __declspec(align(16)) _x64XMM_andAbsMaskBottom[2];
|
uint64 ALIGN(16) _x64XMM_andAbsMaskBottom[2];
|
||||||
uint64 __declspec(align(16)) _x64XMM_andAbsMaskPair[2];
|
uint64 ALIGN(16) _x64XMM_andAbsMaskPair[2];
|
||||||
uint32 __declspec(align(16)) _x64XMM_andFloatAbsMaskBottom[4];
|
uint32 ALIGN(16) _x64XMM_andFloatAbsMaskBottom[4];
|
||||||
uint64 __declspec(align(16)) _x64XMM_singleWordMask[2];
|
uint64 ALIGN(16) _x64XMM_singleWordMask[2];
|
||||||
double __declspec(align(16)) _x64XMM_constDouble1_1[2];
|
double ALIGN(16) _x64XMM_constDouble1_1[2];
|
||||||
double __declspec(align(16)) _x64XMM_constDouble0_0[2];
|
double ALIGN(16) _x64XMM_constDouble0_0[2];
|
||||||
float __declspec(align(16)) _x64XMM_constFloat0_0[2];
|
float ALIGN(16) _x64XMM_constFloat0_0[2];
|
||||||
float __declspec(align(16)) _x64XMM_constFloat1_1[2];
|
float ALIGN(16) _x64XMM_constFloat1_1[2];
|
||||||
float __declspec(align(16)) _x64XMM_constFloatMin[2];
|
float ALIGN(16) _x64XMM_constFloatMin[2];
|
||||||
uint32 __declspec(align(16)) _x64XMM_flushDenormalMask1[4];
|
uint32 ALIGN(16) _x64XMM_flushDenormalMask1[4];
|
||||||
uint32 __declspec(align(16)) _x64XMM_flushDenormalMaskResetSignBits[4];
|
uint32 ALIGN(16) _x64XMM_flushDenormalMaskResetSignBits[4];
|
||||||
// PSQ load/store scale tables
|
// PSQ load/store scale tables
|
||||||
double _psq_ld_scale_ps0_ps1[64 * 2];
|
double _psq_ld_scale_ps0_ps1[64 * 2];
|
||||||
double _psq_ld_scale_ps0_1[64 * 2];
|
double _psq_ld_scale_ps0_1[64 * 2];
|
||||||
|
@ -369,10 +369,10 @@ typedef struct
|
||||||
uint32 _x64XMM_mxCsr_ftzOff;
|
uint32 _x64XMM_mxCsr_ftzOff;
|
||||||
}PPCRecompilerInstanceData_t;
|
}PPCRecompilerInstanceData_t;
|
||||||
|
|
||||||
extern __declspec(dllexport) PPCRecompilerInstanceData_t* ppcRecompilerInstanceData;
|
extern DLLEXPORT PPCRecompilerInstanceData_t* ppcRecompilerInstanceData;
|
||||||
extern bool ppcRecompilerEnabled;
|
extern bool ppcRecompilerEnabled;
|
||||||
|
|
||||||
__declspec(dllexport) void PPCRecompiler_init();
|
DLLEXPORT void PPCRecompiler_init();
|
||||||
|
|
||||||
void PPCRecompiler_allocateRange(uint32 startAddress, uint32 size);
|
void PPCRecompiler_allocateRange(uint32 startAddress, uint32 size);
|
||||||
|
|
||||||
|
@ -385,10 +385,10 @@ extern void ATTR_MS_ABI (*PPCRecompiler_leaveRecompilerCode_unvisited)();
|
||||||
#define PPC_REC_INVALID_FUNCTION ((PPCRecFunction_t*)-1)
|
#define PPC_REC_INVALID_FUNCTION ((PPCRecFunction_t*)-1)
|
||||||
|
|
||||||
// CPUID
|
// CPUID
|
||||||
extern __declspec(dllexport) bool hasLZCNTSupport;
|
extern DLLEXPORT bool hasLZCNTSupport;
|
||||||
extern __declspec(dllexport) bool hasMOVBESupport;
|
extern DLLEXPORT bool hasMOVBESupport;
|
||||||
extern __declspec(dllexport) bool hasBMI2Support;
|
extern DLLEXPORT bool hasBMI2Support;
|
||||||
extern __declspec(dllexport) bool hasAVXSupport;
|
extern DLLEXPORT bool hasAVXSupport;
|
||||||
|
|
||||||
// todo - move some of the stuff above into PPCRecompilerInternal.h
|
// todo - move some of the stuff above into PPCRecompilerInternal.h
|
||||||
|
|
||||||
|
|
|
@ -2221,7 +2221,10 @@ void PPCRecompilerX64Gen_imlInstruction_r_name(PPCRecFunction_t* PPCRecFunction,
|
||||||
else if (sprIndex == SPR_XER)
|
else if (sprIndex == SPR_XER)
|
||||||
x64Emit_mov_reg64_mem32(x64GenContext, tempToRealRegister(imlInstruction->op_r_name.registerIndex), REG_RSP, offsetof(PPCInterpreter_t, spr.XER));
|
x64Emit_mov_reg64_mem32(x64GenContext, tempToRealRegister(imlInstruction->op_r_name.registerIndex), REG_RSP, offsetof(PPCInterpreter_t, spr.XER));
|
||||||
else if (sprIndex >= SPR_UGQR0 && sprIndex <= SPR_UGQR7)
|
else if (sprIndex >= SPR_UGQR0 && sprIndex <= SPR_UGQR7)
|
||||||
x64Emit_mov_reg64_mem32(x64GenContext, tempToRealRegister(imlInstruction->op_r_name.registerIndex), REG_RSP, offsetof(PPCInterpreter_t, spr.UGQR[sprIndex - SPR_UGQR0]));
|
{
|
||||||
|
sint32 memOffset = offsetof(PPCInterpreter_t, spr.UGQR) + sizeof(PPCInterpreter_t::spr.UGQR[0]) * (sprIndex - SPR_UGQR0);
|
||||||
|
x64Emit_mov_reg64_mem32(x64GenContext, tempToRealRegister(imlInstruction->op_r_name.registerIndex), REG_RSP, memOffset);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
assert_dbg();
|
assert_dbg();
|
||||||
//x64Emit_mov_reg64_mem32(x64GenContext, tempToRealRegister(imlInstruction->op_r_name.registerIndex), REG_RSP, offsetof(PPCInterpreter_t, spr)+sizeof(uint32)*(name-PPCREC_NAME_SPR0));
|
//x64Emit_mov_reg64_mem32(x64GenContext, tempToRealRegister(imlInstruction->op_r_name.registerIndex), REG_RSP, offsetof(PPCInterpreter_t, spr)+sizeof(uint32)*(name-PPCREC_NAME_SPR0));
|
||||||
|
@ -2239,7 +2242,7 @@ void PPCRecompilerX64Gen_imlInstruction_name_r(PPCRecFunction_t* PPCRecFunction,
|
||||||
}
|
}
|
||||||
else if( name >= PPCREC_NAME_SPR0 && name < PPCREC_NAME_SPR0+999 )
|
else if( name >= PPCREC_NAME_SPR0 && name < PPCREC_NAME_SPR0+999 )
|
||||||
{
|
{
|
||||||
uint32 sprIndex = (name - PPCREC_NAME_SPR0);
|
const uint32 sprIndex = (name - PPCREC_NAME_SPR0);
|
||||||
if (sprIndex == SPR_LR)
|
if (sprIndex == SPR_LR)
|
||||||
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, spr.LR), tempToRealRegister(imlInstruction->op_r_name.registerIndex));
|
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, spr.LR), tempToRealRegister(imlInstruction->op_r_name.registerIndex));
|
||||||
else if (sprIndex == SPR_CTR)
|
else if (sprIndex == SPR_CTR)
|
||||||
|
@ -2247,7 +2250,10 @@ void PPCRecompilerX64Gen_imlInstruction_name_r(PPCRecFunction_t* PPCRecFunction,
|
||||||
else if (sprIndex == SPR_XER)
|
else if (sprIndex == SPR_XER)
|
||||||
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, spr.XER), tempToRealRegister(imlInstruction->op_r_name.registerIndex));
|
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, spr.XER), tempToRealRegister(imlInstruction->op_r_name.registerIndex));
|
||||||
else if (sprIndex >= SPR_UGQR0 && sprIndex <= SPR_UGQR7)
|
else if (sprIndex >= SPR_UGQR0 && sprIndex <= SPR_UGQR7)
|
||||||
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, spr.UGQR[sprIndex-SPR_UGQR0]), tempToRealRegister(imlInstruction->op_r_name.registerIndex));
|
{
|
||||||
|
sint32 memOffset = offsetof(PPCInterpreter_t, spr.UGQR) + sizeof(PPCInterpreter_t::spr.UGQR[0]) * (sprIndex - SPR_UGQR0);
|
||||||
|
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, memOffset, tempToRealRegister(imlInstruction->op_r_name.registerIndex));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
assert_dbg();
|
assert_dbg();
|
||||||
}
|
}
|
||||||
|
|
|
@ -516,7 +516,7 @@ void LatteOverlay_translateScreenPosition(ScreenPosition pos, const Vector2f& wi
|
||||||
direction = -1;
|
direction = -1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
__assume(false);
|
ASSUME(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -430,7 +430,7 @@ void LatteTC_UnloadAllTextures()
|
||||||
/*
|
/*
|
||||||
* Asynchronous way to invalidate textures
|
* Asynchronous way to invalidate textures
|
||||||
*/
|
*/
|
||||||
__declspec(dllexport) void gpu7Texture_forceInvalidateByImagePtr(MPTR imagePtr)
|
DLLEXPORT void gpu7Texture_forceInvalidateByImagePtr(MPTR imagePtr)
|
||||||
{
|
{
|
||||||
// deprecated. Texture cache heuristics are now good enough to detect moving frames
|
// deprecated. Texture cache heuristics are now good enough to detect moving frames
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,7 @@ struct LatteDecompilerCFInstruction
|
||||||
LatteDecompilerCFInstruction(LatteDecompilerCFInstruction&& mE) = default;
|
LatteDecompilerCFInstruction(LatteDecompilerCFInstruction&& mE) = default;
|
||||||
#else
|
#else
|
||||||
LatteDecompilerCFInstruction(const LatteDecompilerCFInstruction& mE) = default;
|
LatteDecompilerCFInstruction(const LatteDecompilerCFInstruction& mE) = default;
|
||||||
LatteDecompilerCFInstruction(const LatteDecompilerCFInstruction&& mE) = default;
|
constexpr LatteDecompilerCFInstruction(LatteDecompilerCFInstruction&& mE) = default;
|
||||||
#endif
|
#endif
|
||||||
LatteDecompilerCFInstruction& operator=(LatteDecompilerCFInstruction&& mE) = default;
|
LatteDecompilerCFInstruction& operator=(LatteDecompilerCFInstruction&& mE) = default;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1458,7 +1458,7 @@ void OpenGLRenderer::shader_bind(RendererShader* shader)
|
||||||
prevGeometryShaderProgram = program;
|
prevGeometryShaderProgram = program;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
__assume(false);
|
ASSUME(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
catchOpenGLError();
|
catchOpenGLError();
|
||||||
|
@ -1489,7 +1489,7 @@ void OpenGLRenderer::shader_unbind(RendererShader::ShaderType shaderType)
|
||||||
prevGeometryShaderProgram = -1;
|
prevGeometryShaderProgram = -1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
__assume(false);
|
ASSUME(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -270,7 +270,7 @@ void RendererShaderGL::ShaderCacheLoading_begin(uint64 cacheTitleId)
|
||||||
usePrecompiled = false;
|
usePrecompiled = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
__assume(false);
|
ASSUME(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
forceLog_printf("Using precompiled shaders: %s", usePrecompiled ? "true" : "false");
|
forceLog_printf("Using precompiled shaders: %s", usePrecompiled ? "true" : "false");
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Cafe/HW/Latte/Renderer/RendererShader.h"
|
#include "Cafe/HW/Latte/Renderer/RendererShader.h"
|
||||||
#include "Common\GLInclude\GLInclude.h"
|
#include "Common/GLInclude/GLInclude.h"
|
||||||
|
|
||||||
class RendererShaderGL : public RendererShader
|
class RendererShaderGL : public RendererShader
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <glslang/Public/ShaderLang.h>
|
#include <glslang/Public/ShaderLang.h>
|
||||||
#if GLSLANG_VERSION_LESS_OR_EQUAL_TO(11, 0, 0)
|
#if 1 //GLSLANG_VERSION_LESS_OR_EQUAL_TO(11, 0, 0)
|
||||||
#include <glslang/SPIRV/GlslangToSpv.h>
|
#include <glslang/SPIRV/GlslangToSpv.h>
|
||||||
#else
|
#else
|
||||||
#include <SPIRV/Logger.h>
|
#include <SPIRV/Logger.h>
|
||||||
|
@ -131,7 +131,7 @@ const TBuiltInResource DefaultTBuiltInResource = {
|
||||||
/* .maxDualSourceDrawBuffersEXT = */ 1,
|
/* .maxDualSourceDrawBuffersEXT = */ 1,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* .limits = */ {
|
/* .limits = */
|
||||||
/* .nonInductiveForLoops = */ 1,
|
/* .nonInductiveForLoops = */ 1,
|
||||||
/* .whileLoops = */ 1,
|
/* .whileLoops = */ 1,
|
||||||
/* .doWhileLoops = */ 1,
|
/* .doWhileLoops = */ 1,
|
||||||
|
@ -141,7 +141,6 @@ const TBuiltInResource DefaultTBuiltInResource = {
|
||||||
/* .generalSamplerIndexing = */ 1,
|
/* .generalSamplerIndexing = */ 1,
|
||||||
/* .generalVariableIndexing = */ 1,
|
/* .generalVariableIndexing = */ 1,
|
||||||
/* .generalConstantMatrixVectorIndexing = */ 1,
|
/* .generalConstantMatrixVectorIndexing = */ 1,
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class _ShaderVkThreadPool
|
class _ShaderVkThreadPool
|
||||||
|
|
|
@ -3409,7 +3409,7 @@ VkDescriptorSetInfo::~VkDescriptorSetInfo()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
__assume(false);
|
ASSUME(false);
|
||||||
}
|
}
|
||||||
// update global stats
|
// update global stats
|
||||||
performanceMonitor.vk.numDescriptorSamplerTextures.decrement(statsNumSamplerTextures);
|
performanceMonitor.vk.numDescriptorSamplerTextures.decrement(statsNumSamplerTextures);
|
||||||
|
|
|
@ -528,7 +528,7 @@ uint64 VulkanRenderer::GetDescriptorSetStateHash(LatteDecompilerShader* shader)
|
||||||
texUnitRegIndex += Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_GS;
|
texUnitRegIndex += Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_GS;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
__assume(false);
|
ASSUME(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto texture = m_state.boundTexture[hostTextureUnit];
|
auto texture = m_state.boundTexture[hostTextureUnit];
|
||||||
|
@ -590,7 +590,7 @@ VkDescriptorSetInfo* VulkanRenderer::draw_getOrCreateDescriptorSet(PipelineInfo*
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
__assume(false);
|
ASSUME(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create new descriptor set
|
// create new descriptor set
|
||||||
|
@ -646,7 +646,7 @@ VkDescriptorSetInfo* VulkanRenderer::draw_getOrCreateDescriptorSet(PipelineInfo*
|
||||||
texUnitRegIndex += Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_GS;
|
texUnitRegIndex += Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_GS;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
__assume(false);
|
ASSUME(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto textureView = m_state.boundTexture[hostTextureUnit];
|
auto textureView = m_state.boundTexture[hostTextureUnit];
|
||||||
|
@ -996,7 +996,7 @@ VkDescriptorSetInfo* VulkanRenderer::draw_getOrCreateDescriptorSet(PipelineInfo*
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
__assume(false);
|
ASSUME(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dsInfo;
|
return dsInfo;
|
||||||
|
|
|
@ -389,7 +389,7 @@ uint8 memory_readU8(uint32 address)
|
||||||
return *(uint8*)(memory_getPointerFromVirtualOffset(address));
|
return *(uint8*)(memory_getPointerFromVirtualOffset(address));
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) void* memory_getBase()
|
DLLEXPORT void* memory_getBase()
|
||||||
{
|
{
|
||||||
return memory_base;
|
return memory_base;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,8 @@ ChunkedFlatAllocator<64 * 1024> g_heapTrampolineArea;
|
||||||
|
|
||||||
std::vector<rplDependency_t*> rplDependencyList = std::vector<rplDependency_t*>();
|
std::vector<rplDependency_t*> rplDependencyList = std::vector<rplDependency_t*>();
|
||||||
|
|
||||||
__declspec(dllexport) RPLModule* rplModuleList[256];
|
DLLEXPORT RPLModule* rplModuleList[256];
|
||||||
__declspec(dllexport) sint32 rplModuleCount = 0;
|
DLLEXPORT sint32 rplModuleCount = 0;
|
||||||
|
|
||||||
uint32 _currentTLSModuleIndex = 1; // value 0 is reserved
|
uint32 _currentTLSModuleIndex = 1; // value 0 is reserved
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ MPTR RPLLoader_AllocateCodeSpace(uint32 size, uint32 alignment);
|
||||||
uint32 RPLLoader_GetMaxCodeOffset();
|
uint32 RPLLoader_GetMaxCodeOffset();
|
||||||
uint32 RPLLoader_GetDataAllocatorAddr();
|
uint32 RPLLoader_GetDataAllocatorAddr();
|
||||||
|
|
||||||
__declspec(dllexport) RPLModule* rpl_loadFromMem(uint8* rplData, sint32 size, char* name);
|
DLLEXPORT RPLModule* rpl_loadFromMem(uint8* rplData, sint32 size, char* name);
|
||||||
uint32 rpl_mapHLEImport(RPLModule* rplLoaderContext, const char* rplName, const char* funcName, bool functionMustExist);
|
uint32 rpl_mapHLEImport(RPLModule* rplLoaderContext, const char* rplName, const char* funcName, bool functionMustExist);
|
||||||
void RPLLoader_Link();
|
void RPLLoader_Link();
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ void osLib_addFunctionInternal(const char* libraryName, const char* functionName
|
||||||
s_osFunctionTable->emplace_back(libHashA, libHashB, funcHashA, funcHashB, fmt::format("{}.{}", libraryName, functionName), PPCInterpreter_registerHLECall(osFunction));
|
s_osFunctionTable->emplace_back(libHashA, libHashB, funcHashA, funcHashB, fmt::format("{}.{}", libraryName, functionName), PPCInterpreter_registerHLECall(osFunction));
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) void osLib_registerHLEFunction(const char* libraryName, const char* functionName, void(*osFunction)(PPCInterpreter_t* hCPU))
|
DLLEXPORT void osLib_registerHLEFunction(const char* libraryName, const char* functionName, void(*osFunction)(PPCInterpreter_t* hCPU))
|
||||||
{
|
{
|
||||||
osLib_addFunctionInternal(libraryName, functionName, osFunction);
|
osLib_addFunctionInternal(libraryName, functionName, osFunction);
|
||||||
}
|
}
|
||||||
|
|
|
@ -398,7 +398,7 @@ namespace coreinit
|
||||||
else
|
else
|
||||||
track = (MEMBlockHeapTrackDEPR*)memory_getPointerFromVirtualOffsetAllowNull(_swapEndianU32(blockHeapHead->headBlock));
|
track = (MEMBlockHeapTrackDEPR*)memory_getPointerFromVirtualOffsetAllowNull(_swapEndianU32(blockHeapHead->headBlock));
|
||||||
|
|
||||||
cemu_assert_debug(__popcnt(alignment) == 1); // not a supported alignment value
|
cemu_assert_debug(POPCNT(alignment) == 1); // not a supported alignment value
|
||||||
while (track)
|
while (track)
|
||||||
{
|
{
|
||||||
if (track->isFree != _swapEndianU32(0))
|
if (track->isFree != _swapEndianU32(0))
|
||||||
|
|
|
@ -45,8 +45,8 @@ namespace coreinit
|
||||||
|
|
||||||
bool g_isMulticoreMode;
|
bool g_isMulticoreMode;
|
||||||
|
|
||||||
__declspec(thread) uint32 t_assignedCoreIndex;
|
THREAD_LOCAL uint32 t_assignedCoreIndex;
|
||||||
__declspec(thread) Fiber* t_schedulerFiber;
|
THREAD_LOCAL Fiber* t_schedulerFiber;
|
||||||
|
|
||||||
struct OSHostThread
|
struct OSHostThread
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace coreinit
|
||||||
osLib_returnFromFunction64(hCPU, osTime);
|
osLib_returnFromFunction64(hCPU, osTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(noinline) uint64 coreinit_getTimeBase_dummy()
|
NOINLINE uint64 coreinit_getTimeBase_dummy()
|
||||||
{
|
{
|
||||||
return __rdtsc();
|
return __rdtsc();
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,8 +201,8 @@ static_assert(sizeof(CURLMsg_t) <= 0xC, "sizeof(CURLMsg_t)");
|
||||||
|
|
||||||
size_t header_callback(char* buffer, size_t size, size_t nitems, void* userdata);
|
size_t header_callback(char* buffer, size_t size, size_t nitems, void* userdata);
|
||||||
|
|
||||||
__declspec(thread) PPCConcurrentQueue<QueueMsg_t>* g_callerQueue;
|
THREAD_LOCAL PPCConcurrentQueue<QueueMsg_t>* g_callerQueue;
|
||||||
__declspec(thread) ConcurrentQueue<QueueMsg_t>* g_threadQueue;
|
THREAD_LOCAL ConcurrentQueue<QueueMsg_t>* g_threadQueue;
|
||||||
void CurlWorkerThread(CURL_t* curl, PPCConcurrentQueue<QueueMsg_t>* callerQueue, ConcurrentQueue<QueueMsg_t>* threadQueue)
|
void CurlWorkerThread(CURL_t* curl, PPCConcurrentQueue<QueueMsg_t>* callerQueue, ConcurrentQueue<QueueMsg_t>* threadQueue)
|
||||||
{
|
{
|
||||||
g_callerQueue = callerQueue;
|
g_callerQueue = callerQueue;
|
||||||
|
|
|
@ -174,7 +174,7 @@ std::unique_ptr<uint8[]> MetaInfo::GetIcon(uint32& size) const
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
__assume(false);
|
ASSUME(false);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,7 +243,7 @@ void cafeLog_logW(uint32 type, const wchar_t* format, ...)
|
||||||
LoggingWindow::Log(it->second, logTempStr);
|
LoggingWindow::Log(it->second, logTempStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) void cemuLog_log()
|
DLLEXPORT void cemuLog_log()
|
||||||
{
|
{
|
||||||
typedef void(*VoidFunc)();
|
typedef void(*VoidFunc)();
|
||||||
const VoidFunc func = (VoidFunc)cafeLog_log;
|
const VoidFunc func = (VoidFunc)cafeLog_log;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
uint32 coreinit_allocFromSysArea(uint32 size, uint32 alignment);
|
uint32 coreinit_allocFromSysArea(uint32 size, uint32 alignment);
|
||||||
class SysAllocatorBase;
|
class SysAllocatorBase;
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ void (__cpuid)(int __cpuVal[4], unsigned int __leaf)
|
||||||
}
|
}
|
||||||
#undef __cpuid
|
#undef __cpuid
|
||||||
|
|
||||||
void __cpuidex (int __cpuid_info[4], int __leaf, int __subleaf)
|
void __cpuidex1(int __cpuid_info[4], int __leaf, int __subleaf)
|
||||||
{
|
{
|
||||||
__cpuid_count (__leaf, __subleaf, __cpuid_info[0], __cpuid_info[1],
|
__cpuid_count (__leaf, __subleaf, __cpuid_info[0], __cpuid_info[1],
|
||||||
__cpuid_info[2], __cpuid_info[3]);
|
__cpuid_info[2], __cpuid_info[3]);
|
||||||
|
|
|
@ -45,7 +45,7 @@ inline uint32_t GetExceptionError()
|
||||||
|
|
||||||
// cpu id (somewhat hacky, reorganize later)
|
// cpu id (somewhat hacky, reorganize later)
|
||||||
void (__cpuid)(int __cpuVal[4], unsigned int __leaf);
|
void (__cpuid)(int __cpuVal[4], unsigned int __leaf);
|
||||||
void __cpuidex (int __cpuid_info[4], int __leaf, int __subleaf);
|
void __cpuidex1 (int __cpuid_info[4], int __leaf, int __subleaf);
|
||||||
|
|
||||||
// placeholder
|
// placeholder
|
||||||
uint32_t GetTickCount();
|
uint32_t GetTickCount();
|
||||||
|
|
|
@ -166,6 +166,16 @@ inline sint16 _swapEndianS16(sint16 v)
|
||||||
return (sint16)(((uint16)v >> 8) | ((uint16)v << 8));
|
return (sint16)(((uint16)v >> 8) | ((uint16)v << 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint64 _rotl64 (uint64 x, sint8 r)
|
||||||
|
{
|
||||||
|
return (x << r) | (x >> (64 - r));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint64 _rotr64 (uint64 x, sint8 r)
|
||||||
|
{
|
||||||
|
return (x >> r) | (x << (64 - r));
|
||||||
|
}
|
||||||
|
|
||||||
typedef uint8_t BYTE;
|
typedef uint8_t BYTE;
|
||||||
typedef uint32_t DWORD;
|
typedef uint32_t DWORD;
|
||||||
typedef int32_t LONG;
|
typedef int32_t LONG;
|
||||||
|
@ -201,10 +211,25 @@ typedef union _LARGE_INTEGER {
|
||||||
// macros
|
// macros
|
||||||
#if BOOST_OS_WINDOWS
|
#if BOOST_OS_WINDOWS
|
||||||
#define DLLEXPORT __declspec(dllexport)
|
#define DLLEXPORT __declspec(dllexport)
|
||||||
|
#define DLLIMPORT __declspec(dllimport)
|
||||||
|
#define DEBUG_BREAK __debugbreak()
|
||||||
|
#define ALIGN(N) __declspec(align(N))
|
||||||
|
#define NOINLINE __declspec(noinline)
|
||||||
|
#define ASSUME(X) __assume((X)
|
||||||
|
#define THREAD_LOCAL __declspec(thread)
|
||||||
|
#define POPCNT(X) __popcnt((X))
|
||||||
#else
|
#else
|
||||||
#define DLLEXPORT __declspec(dllexport)
|
#define DLLEXPORT
|
||||||
|
#define DLLIMPORT
|
||||||
|
#define DEBUG_BREAK
|
||||||
|
#define ALIGN(N) __attribute__((aligned (N)))
|
||||||
|
#define NOINLINE __attribute__((noinline))
|
||||||
|
#define ASSUME(X)
|
||||||
|
#define THREAD_LOCAL __thread
|
||||||
|
#define POPCNT(X) __builtin_popcount((X))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
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>
|
||||||
|
@ -286,7 +311,7 @@ inline void cemu_assert(bool _condition)
|
||||||
{
|
{
|
||||||
if ((_condition) == false)
|
if ((_condition) == false)
|
||||||
{
|
{
|
||||||
__debugbreak();
|
DEBUG_BREAK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,32 +332,32 @@ inline void cemu_assert_suspicious()
|
||||||
|
|
||||||
inline void cemu_assert_error()
|
inline void cemu_assert_error()
|
||||||
{
|
{
|
||||||
__debugbreak();
|
DEBUG_BREAK;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
inline void cemu_assert_debug(bool _condition)
|
inline void cemu_assert_debug(bool _condition)
|
||||||
{
|
{
|
||||||
if ((_condition) == false)
|
if ((_condition) == false)
|
||||||
__debugbreak();
|
DEBUG_BREAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void cemu_assert_unimplemented()
|
inline void cemu_assert_unimplemented()
|
||||||
{
|
{
|
||||||
__debugbreak();
|
DEBUG_BREAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void cemu_assert_suspicious()
|
inline void cemu_assert_suspicious()
|
||||||
{
|
{
|
||||||
__debugbreak();
|
DEBUG_BREAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void cemu_assert_error()
|
inline void cemu_assert_error()
|
||||||
{
|
{
|
||||||
__debugbreak();
|
DEBUG_BREAK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define assert_dbg() __debugbreak() // old style unconditional generic assert
|
#define assert_dbg() DEBUG_BREAK // old style unconditional generic assert
|
||||||
|
|
||||||
// Some string conversion helpers because C++20 std::u8string is too cumbersome to use in practice
|
// Some string conversion helpers because C++20 std::u8string is too cumbersome to use in practice
|
||||||
// mixing string types generally causes loads of issues and many of the libraries we use dont expose interfaces for u8string
|
// mixing string types generally causes loads of issues and many of the libraries we use dont expose interfaces for u8string
|
||||||
|
@ -383,7 +408,7 @@ public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool future_is_ready(std::future<T>& f)
|
bool future_is_ready(std::future<T>& f)
|
||||||
{
|
{
|
||||||
#ifdef __clang__
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
return f.wait_for(std::chrono::nanoseconds(0)) == std::future_status::ready;
|
return f.wait_for(std::chrono::nanoseconds(0)) == std::future_status::ready;
|
||||||
#else
|
#else
|
||||||
return f._Is_ready();
|
return f._Is_ready();
|
||||||
|
@ -399,7 +424,7 @@ std::atomic<T>* _rawPtrToAtomic(T* ptr)
|
||||||
return reinterpret_cast<std::atomic<T>*>(ptr);
|
return reinterpret_cast<std::atomic<T>*>(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __clang__
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
#define ATTR_MS_ABI __attribute__((ms_abi))
|
#define ATTR_MS_ABI __attribute__((ms_abi))
|
||||||
#else
|
#else
|
||||||
#define ATTR_MS_ABI
|
#define ATTR_MS_ABI
|
||||||
|
@ -420,7 +445,7 @@ inline uint32 GetTitleIdLow(uint64 titleId)
|
||||||
return titleId & 0xFFFFFFFF;
|
return titleId & 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __clang__
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
#define memcpy_dwords(__dest, __src, __numDwords) memcpy((__dest), (__src), (__numDwords) * sizeof(uint32))
|
#define memcpy_dwords(__dest, __src, __numDwords) memcpy((__dest), (__src), (__numDwords) * sizeof(uint32))
|
||||||
#define memcpy_qwords(__dest, __src, __numQwords) memcpy((__dest), (__src), (__numQwords) * sizeof(uint64))
|
#define memcpy_qwords(__dest, __src, __numQwords) memcpy((__dest), (__src), (__numQwords) * sizeof(uint64))
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -31,28 +31,28 @@
|
||||||
#define CHECK_FOR_WX_EVT_STRING(strVar, strConst) if (strcmp(strVar, #strConst) == 0){ return static_cast<int>(strConst); }
|
#define CHECK_FOR_WX_EVT_STRING(strVar, strConst) if (strcmp(strVar, #strConst) == 0){ return static_cast<int>(strConst); }
|
||||||
|
|
||||||
|
|
||||||
__declspec(dllexport) wxEvtHandler* wxEvtHandler_Initialize(uint8_t* allocMemory)
|
DLLEXPORT wxEvtHandler* wxEvtHandler_Initialize(uint8_t* allocMemory)
|
||||||
{
|
{
|
||||||
wxEvtHandler* handler = new (allocMemory) wxEvtHandler();
|
wxEvtHandler* handler = new (allocMemory) wxEvtHandler();
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) void wxEvtHandler_Connect(wxEvtHandler* eventSource, int id, int lastId, int eventType, wxObjectEventFunction func, wxObject* userData, wxEvtHandler* eventSink)
|
DLLEXPORT void wxEvtHandler_Connect(wxEvtHandler* eventSource, int id, int lastId, int eventType, wxObjectEventFunction func, wxObject* userData, wxEvtHandler* eventSink)
|
||||||
{
|
{
|
||||||
eventSource->Connect(id, lastId, eventType, func, userData, eventSink);
|
eventSource->Connect(id, lastId, eventType, func, userData, eventSink);
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) void wxEvtHandler_Disconnect(wxEvtHandler* eventSource, int id, int lastId, int eventType, wxObjectEventFunction func, wxObject* userData, wxEvtHandler* eventSink)
|
DLLEXPORT void wxEvtHandler_Disconnect(wxEvtHandler* eventSource, int id, int lastId, int eventType, wxObjectEventFunction func, wxObject* userData, wxEvtHandler* eventSink)
|
||||||
{
|
{
|
||||||
eventSource->Disconnect(id, lastId, eventType, func, userData, eventSink);
|
eventSource->Disconnect(id, lastId, eventType, func, userData, eventSink);
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) const wchar_t* GetTranslationWChar(const wchar_t* text)
|
DLLEXPORT const wchar_t* GetTranslationWChar(const wchar_t* text)
|
||||||
{
|
{
|
||||||
return wxGetTranslation(text).wc_str();
|
return wxGetTranslation(text).wc_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) int wxGetEventByName(const char* eventName)
|
DLLEXPORT int wxGetEventByName(const char* eventName)
|
||||||
{
|
{
|
||||||
#define PROCESS_OWN_WXEVT(EventVarName,EventHookId) if (!strcmp(eventName,#EventVarName)){ return static_cast<int>(EventVarName); }
|
#define PROCESS_OWN_WXEVT(EventVarName,EventHookId) if (!strcmp(eventName,#EventVarName)){ return static_cast<int>(EventVarName); }
|
||||||
#include "wxEvtHook.inl"
|
#include "wxEvtHook.inl"
|
||||||
|
@ -95,7 +95,7 @@ void FixupWxEvtIdsToMatchCemuHook()
|
||||||
|
|
||||||
// these I added on my own since they might be useful
|
// these I added on my own since they might be useful
|
||||||
|
|
||||||
__declspec(dllexport) void coreinitAPI_OSYieldThread()
|
DLLEXPORT void coreinitAPI_OSYieldThread()
|
||||||
{
|
{
|
||||||
PPCCore_switchToScheduler();
|
PPCCore_switchToScheduler();
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,49 +148,41 @@ public:
|
||||||
return default_value;
|
return default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
bool value(bool default_value)
|
bool value(bool default_value)
|
||||||
{
|
{
|
||||||
return m_current_element ? m_current_element->BoolText(default_value) : default_value;
|
return m_current_element ? m_current_element->BoolText(default_value) : default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
float value(float default_value)
|
float value(float default_value)
|
||||||
{
|
{
|
||||||
return m_current_element ? m_current_element->FloatText(default_value) : default_value;
|
return m_current_element ? m_current_element->FloatText(default_value) : default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
double value(double default_value)
|
double value(double default_value)
|
||||||
{
|
{
|
||||||
return m_current_element ? m_current_element->DoubleText(default_value) : default_value;
|
return m_current_element ? m_current_element->DoubleText(default_value) : default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
uint32 value(uint32 default_value)
|
uint32 value(uint32 default_value)
|
||||||
{
|
{
|
||||||
return m_current_element ? m_current_element->UnsignedText(default_value) : default_value;
|
return m_current_element ? m_current_element->UnsignedText(default_value) : default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
sint32 value(sint32 default_value)
|
sint32 value(sint32 default_value)
|
||||||
{
|
{
|
||||||
return m_current_element ? m_current_element->IntText(default_value) : default_value;
|
return m_current_element ? m_current_element->IntText(default_value) : default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
uint64 value(uint64 default_value)
|
uint64 value(uint64 default_value)
|
||||||
{
|
{
|
||||||
return m_current_element ? (uint64)m_current_element->Int64Text(default_value) : default_value;
|
return m_current_element ? (uint64)m_current_element->Int64Text(default_value) : default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
sint64 value(sint64 default_value)
|
sint64 value(sint64 default_value)
|
||||||
{
|
{
|
||||||
return m_current_element ? m_current_element->Int64Text(default_value) : default_value;
|
return m_current_element ? m_current_element->Int64Text(default_value) : default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
const char* value(const char* default_value)
|
const char* value(const char* default_value)
|
||||||
{
|
{
|
||||||
if (m_current_element)
|
if (m_current_element)
|
||||||
|
@ -243,7 +235,6 @@ public:
|
||||||
set(name, value.load());
|
set(name, value.load());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
void set(const char* name, uint64 value)
|
void set(const char* name, uint64 value)
|
||||||
{
|
{
|
||||||
set(name, (sint64)value);
|
set(name, (sint64)value);
|
||||||
|
@ -300,7 +291,6 @@ public:
|
||||||
return set_attribute(name, value.GetValue());
|
return set_attribute(name, value.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
XMLConfigParser& set_attribute(const char* name, const std::string& value)
|
XMLConfigParser& set_attribute(const char* name, const std::string& value)
|
||||||
{
|
{
|
||||||
return set_attribute(name, value.c_str());
|
return set_attribute(name, value.c_str());
|
||||||
|
|
|
@ -70,7 +70,7 @@ void unused_translation_dummy()
|
||||||
|
|
||||||
|
|
||||||
#pragma optimize( "", off )
|
#pragma optimize( "", off )
|
||||||
DLLEXPORT _declspec(noinline) wxTopLevelWindow* wxMainWindowCreated(wxTopLevelWindow* wndPtr, uint32 magicConstant, CemuApp* appPointer)
|
DLLEXPORT NOINLINE wxTopLevelWindow* wxMainWindowCreated(wxTopLevelWindow* wndPtr, uint32 magicConstant, CemuApp* appPointer)
|
||||||
{
|
{
|
||||||
return wndPtr;
|
return wndPtr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,9 +72,6 @@ private:
|
||||||
return iss && iss.eof();
|
return iss && iss.eof();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
bool ConvertStringToType(const char* inValue, sint8& outValue) const;
|
|
||||||
|
|
||||||
using ListType_t = std::vector<MEMPTR<void>>;
|
using ListType_t = std::vector<MEMPTR<void>>;
|
||||||
ListType_t SearchValues(SearchDataType type, void* ptr, uint32 size)
|
ListType_t SearchValues(SearchDataType type, void* ptr, uint32 size)
|
||||||
{
|
{
|
||||||
|
@ -197,6 +194,10 @@ wxDECLARE_EVENT_TABLE();
|
||||||
bool m_clear_state = false;
|
bool m_clear_state = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
bool MemorySearcherTool::ConvertStringToType(const char* inValue, sint8& outValue) const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -941,7 +941,7 @@ wxString wxTitleManagerList::GetTitleEntryText(const TitleEntry& entry, ItemColu
|
||||||
//return wxStringFormat2("{}", entry.format);
|
//return wxStringFormat2("{}", entry.format);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
__assume(false);
|
ASSUME(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxEmptyString;
|
return wxEmptyString;
|
||||||
|
|
15
src/main.cpp
15
src/main.cpp
|
@ -39,11 +39,14 @@
|
||||||
#define _putenv(__s) putenv((char*)(__s))
|
#define _putenv(__s) putenv((char*)(__s))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if BOOST_OS_WINDOWS > 0
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
DLLEXPORT int AmdPowerXpressRequestHighPerformance = 1;
|
||||||
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
DLLEXPORT DWORD NvOptimusEnablement = 0x00000001;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
bool _cpuExtension_SSSE3 = false;
|
bool _cpuExtension_SSSE3 = false;
|
||||||
bool _cpuExtension_SSE4_1 = false;
|
bool _cpuExtension_SSE4_1 = false;
|
||||||
|
@ -51,7 +54,9 @@ bool _cpuExtension_AVX2 = false;
|
||||||
|
|
||||||
std::atomic_bool g_isGPUInitFinished = false;
|
std::atomic_bool g_isGPUInitFinished = false;
|
||||||
|
|
||||||
|
#if BOOST_OS_WINDOWS > 0
|
||||||
std::wstring executablePath;
|
std::wstring executablePath;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool g_cemuhook_loaded = false;
|
bool g_cemuhook_loaded = false;
|
||||||
bool IsCemuhookLoaded()
|
bool IsCemuhookLoaded()
|
||||||
|
@ -236,7 +241,7 @@ void mainEmulatorCommonInit()
|
||||||
_cpuExtension_SSSE3 = ((cpuInfo[2] >> 9) & 1) != 0;
|
_cpuExtension_SSSE3 = ((cpuInfo[2] >> 9) & 1) != 0;
|
||||||
_cpuExtension_SSE4_1 = ((cpuInfo[2] >> 19) & 1) != 0;
|
_cpuExtension_SSE4_1 = ((cpuInfo[2] >> 19) & 1) != 0;
|
||||||
|
|
||||||
__cpuidex(cpuInfo, 0x7, 0);
|
__cpuidex1(cpuInfo, 0x7, 0);
|
||||||
_cpuExtension_AVX2 = ((cpuInfo[1] >> 5) & 1) != 0;
|
_cpuExtension_AVX2 = ((cpuInfo[1] >> 5) & 1) != 0;
|
||||||
|
|
||||||
#if BOOST_OS_WINDOWS > 0
|
#if BOOST_OS_WINDOWS > 0
|
||||||
|
@ -426,7 +431,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
#pragma optimize("",off)
|
#pragma optimize("",off)
|
||||||
|
|
||||||
__declspec(dllexport) void gameMeta_loadForCurrent()
|
DLLEXPORT void gameMeta_loadForCurrent()
|
||||||
{
|
{
|
||||||
int placeholderA = 0x11223344;
|
int placeholderA = 0x11223344;
|
||||||
int placeholderB = 0x55667788;
|
int placeholderB = 0x55667788;
|
||||||
|
@ -434,7 +439,7 @@ __declspec(dllexport) void gameMeta_loadForCurrent()
|
||||||
|
|
||||||
#pragma optimize("",on)
|
#pragma optimize("",on)
|
||||||
|
|
||||||
__declspec(dllexport) uint64 gameMeta_getTitleId()
|
DLLEXPORT uint64 gameMeta_getTitleId()
|
||||||
{
|
{
|
||||||
return CafeSystem::GetForegroundTitleId();
|
return CafeSystem::GetForegroundTitleId();
|
||||||
}
|
}
|
||||||
|
|
|
@ -759,7 +759,7 @@ void AESNI128_CBC_decryptWithExpandedKey(const unsigned char *in,
|
||||||
|
|
||||||
void __aesni__AES128_CBC_decrypt(uint8* output, uint8* input, uint32 length, const uint8* key, const uint8* iv)
|
void __aesni__AES128_CBC_decrypt(uint8* output, uint8* input, uint32 length, const uint8* key, const uint8* iv)
|
||||||
{
|
{
|
||||||
__declspec(align(16)) uint8 expandedKey[11 * 16];
|
ALIGN(16) uint8 expandedKey[11 * 16];
|
||||||
AESNI128_KeyExpansionDecrypt(key, expandedKey);
|
AESNI128_KeyExpansionDecrypt(key, expandedKey);
|
||||||
if (iv)
|
if (iv)
|
||||||
{
|
{
|
||||||
|
@ -774,7 +774,7 @@ void __aesni__AES128_CBC_decrypt(uint8* output, uint8* input, uint32 length, con
|
||||||
|
|
||||||
void __aesni__AES128_ECB_encrypt(uint8* input, const uint8* key, uint8* output)
|
void __aesni__AES128_ECB_encrypt(uint8* input, const uint8* key, uint8* output)
|
||||||
{
|
{
|
||||||
__declspec(align(16)) uint8 expandedKey[11 * 16];
|
ALIGN(16) uint8 expandedKey[11 * 16];
|
||||||
AESNI128_KeyExpansionEncrypt(key, expandedKey);
|
AESNI128_KeyExpansionEncrypt(key, expandedKey);
|
||||||
// encrypt single ECB block
|
// encrypt single ECB block
|
||||||
__m128i feedback;
|
__m128i feedback;
|
||||||
|
|
162
src/util/helpers/Serializer.cpp
Normal file
162
src/util/helpers/Serializer.cpp
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
#include "Serializer.h"
|
||||||
|
|
||||||
|
template<>
|
||||||
|
uint8 MemStreamReader::readBE()
|
||||||
|
{
|
||||||
|
if (!reserveReadLength(sizeof(uint8)))
|
||||||
|
return 0;
|
||||||
|
uint8 v = m_data[m_cursorPos];
|
||||||
|
m_cursorPos += sizeof(uint8);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
uint16 MemStreamReader::readBE()
|
||||||
|
{
|
||||||
|
if (!reserveReadLength(sizeof(uint16)))
|
||||||
|
return 0;
|
||||||
|
const uint8* p = m_data + m_cursorPos;
|
||||||
|
uint16 v;
|
||||||
|
std::memcpy(&v, p, sizeof(v));
|
||||||
|
v = _BE(v);
|
||||||
|
m_cursorPos += sizeof(uint16);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
uint32 MemStreamReader::readBE()
|
||||||
|
{
|
||||||
|
if (!reserveReadLength(sizeof(uint32)))
|
||||||
|
return 0;
|
||||||
|
const uint8* p = m_data + m_cursorPos;
|
||||||
|
uint32 v;
|
||||||
|
std::memcpy(&v, p, sizeof(v));
|
||||||
|
v = _BE(v);
|
||||||
|
m_cursorPos += sizeof(uint32);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
uint64 MemStreamReader::readBE()
|
||||||
|
{
|
||||||
|
if (!reserveReadLength(sizeof(uint64)))
|
||||||
|
return 0;
|
||||||
|
const uint8* p = m_data + m_cursorPos;
|
||||||
|
uint64 v;
|
||||||
|
std::memcpy(&v, p, sizeof(v));
|
||||||
|
v = _BE(v);
|
||||||
|
m_cursorPos += sizeof(uint64);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
std::string MemStreamReader::readBE()
|
||||||
|
{
|
||||||
|
std::string s;
|
||||||
|
uint32 stringSize = readBE<uint32>();
|
||||||
|
if (hasError())
|
||||||
|
return s;
|
||||||
|
if (stringSize >= (32 * 1024 * 1024))
|
||||||
|
{
|
||||||
|
// out of bounds read or suspiciously large string
|
||||||
|
m_hasError = true;
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
s.resize(stringSize);
|
||||||
|
readData(s.data(), stringSize);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
uint8 MemStreamReader::readLE()
|
||||||
|
{
|
||||||
|
return readBE<uint8>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
uint32 MemStreamReader::readLE()
|
||||||
|
{
|
||||||
|
if (!reserveReadLength(sizeof(uint32)))
|
||||||
|
return 0;
|
||||||
|
const uint8* p = m_data + m_cursorPos;
|
||||||
|
uint32 v;
|
||||||
|
std::memcpy(&v, p, sizeof(v));
|
||||||
|
v = _LE(v);
|
||||||
|
m_cursorPos += sizeof(uint32);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
uint64 MemStreamReader::readLE()
|
||||||
|
{
|
||||||
|
if (!reserveReadLength(sizeof(uint64)))
|
||||||
|
return 0;
|
||||||
|
const uint8* p = m_data + m_cursorPos;
|
||||||
|
uint64 v;
|
||||||
|
std::memcpy(&v, p, sizeof(v));
|
||||||
|
v = _LE(v);
|
||||||
|
m_cursorPos += sizeof(uint64);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void MemStreamWriter::writeBE<uint64>(const uint64& v)
|
||||||
|
{
|
||||||
|
m_buffer.resize(m_buffer.size() + 8);
|
||||||
|
uint8* p = m_buffer.data() + m_buffer.size() - 8;
|
||||||
|
uint64 tmp = _BE(v);
|
||||||
|
std::memcpy(p, &tmp, sizeof(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void MemStreamWriter::writeBE<uint32>(const uint32& v)
|
||||||
|
{
|
||||||
|
m_buffer.resize(m_buffer.size() + 4);
|
||||||
|
uint8* p = m_buffer.data() + m_buffer.size() - 4;
|
||||||
|
uint32 tmp = _BE(v);
|
||||||
|
std::memcpy(p, &tmp, sizeof(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void MemStreamWriter::writeBE<uint16>(const uint16& v)
|
||||||
|
{
|
||||||
|
m_buffer.resize(m_buffer.size() + 2);
|
||||||
|
uint8* p = m_buffer.data() + m_buffer.size() - 2;
|
||||||
|
uint16 tmp = _BE(v);
|
||||||
|
std::memcpy(p, &tmp, sizeof(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void MemStreamWriter::writeBE<uint8>(const uint8& v)
|
||||||
|
{
|
||||||
|
m_buffer.emplace_back(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void MemStreamWriter::writeBE<std::string>(const std::string& v)
|
||||||
|
{
|
||||||
|
writeBE<uint32>((uint32)v.size());
|
||||||
|
writeData(v.data(), v.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void MemStreamWriter::writeLE<uint64>(const uint64& v)
|
||||||
|
{
|
||||||
|
m_buffer.resize(m_buffer.size() + 8);
|
||||||
|
uint8* p = m_buffer.data() + m_buffer.size() - 8;
|
||||||
|
uint64 tmp = _LE(v);
|
||||||
|
std::memcpy(p, &tmp, sizeof(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void MemStreamWriter::writeLE<uint32>(const uint32& v)
|
||||||
|
{
|
||||||
|
m_buffer.resize(m_buffer.size() + 4);
|
||||||
|
uint8* p = m_buffer.data() + m_buffer.size() - 4;
|
||||||
|
uint32 tmp = _LE(v);
|
||||||
|
std::memcpy(p, &tmp, sizeof(tmp));
|
||||||
|
}
|
|
@ -11,97 +11,6 @@ public:
|
||||||
template<typename T> T readBE();
|
template<typename T> T readBE();
|
||||||
template<typename T> T readLE();
|
template<typename T> T readLE();
|
||||||
|
|
||||||
template<> uint8 readBE()
|
|
||||||
{
|
|
||||||
if (!reserveReadLength(sizeof(uint8)))
|
|
||||||
return 0;
|
|
||||||
uint8 v = m_data[m_cursorPos];
|
|
||||||
m_cursorPos += sizeof(uint8);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> uint16 readBE()
|
|
||||||
{
|
|
||||||
if (!reserveReadLength(sizeof(uint16)))
|
|
||||||
return 0;
|
|
||||||
const uint8* p = m_data + m_cursorPos;
|
|
||||||
uint16 v;
|
|
||||||
std::memcpy(&v, p, sizeof(v));
|
|
||||||
v = _BE(v);
|
|
||||||
m_cursorPos += sizeof(uint16);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> uint32 readBE()
|
|
||||||
{
|
|
||||||
if (!reserveReadLength(sizeof(uint32)))
|
|
||||||
return 0;
|
|
||||||
const uint8* p = m_data + m_cursorPos;
|
|
||||||
uint32 v;
|
|
||||||
std::memcpy(&v, p, sizeof(v));
|
|
||||||
v = _BE(v);
|
|
||||||
m_cursorPos += sizeof(uint32);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> uint64 readBE()
|
|
||||||
{
|
|
||||||
if (!reserveReadLength(sizeof(uint64)))
|
|
||||||
return 0;
|
|
||||||
const uint8* p = m_data + m_cursorPos;
|
|
||||||
uint64 v;
|
|
||||||
std::memcpy(&v, p, sizeof(v));
|
|
||||||
v = _BE(v);
|
|
||||||
m_cursorPos += sizeof(uint64);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> std::string readBE()
|
|
||||||
{
|
|
||||||
std::string s;
|
|
||||||
uint32 stringSize = readBE<uint32>();
|
|
||||||
if (hasError())
|
|
||||||
return s;
|
|
||||||
if (stringSize >= (32 * 1024 * 1024))
|
|
||||||
{
|
|
||||||
// out of bounds read or suspiciously large string
|
|
||||||
m_hasError = true;
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
s.resize(stringSize);
|
|
||||||
readData(s.data(), stringSize);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> uint8 readLE()
|
|
||||||
{
|
|
||||||
return readBE<uint8>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> uint32 readLE()
|
|
||||||
{
|
|
||||||
if (!reserveReadLength(sizeof(uint32)))
|
|
||||||
return 0;
|
|
||||||
const uint8* p = m_data + m_cursorPos;
|
|
||||||
uint32 v;
|
|
||||||
std::memcpy(&v, p, sizeof(v));
|
|
||||||
v = _LE(v);
|
|
||||||
m_cursorPos += sizeof(uint32);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> uint64 readLE()
|
|
||||||
{
|
|
||||||
if (!reserveReadLength(sizeof(uint64)))
|
|
||||||
return 0;
|
|
||||||
const uint8* p = m_data + m_cursorPos;
|
|
||||||
uint64 v;
|
|
||||||
std::memcpy(&v, p, sizeof(v));
|
|
||||||
v = _LE(v);
|
|
||||||
m_cursorPos += sizeof(uint64);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::vector<T> readPODVector()
|
std::vector<T> readPODVector()
|
||||||
{
|
{
|
||||||
|
@ -224,6 +133,7 @@ private:
|
||||||
bool m_hasError{ false };
|
bool m_hasError{ false };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class MemStreamWriter
|
class MemStreamWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -243,67 +153,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> void writeBE(const T& v);
|
template<typename T> void writeBE(const T& v);
|
||||||
|
|
||||||
template<>
|
|
||||||
void writeBE<uint64>(const uint64& v)
|
|
||||||
{
|
|
||||||
m_buffer.resize(m_buffer.size() + 8);
|
|
||||||
uint8* p = m_buffer.data() + m_buffer.size() - 8;
|
|
||||||
uint64 tmp = _BE(v);
|
|
||||||
std::memcpy(p, &tmp, sizeof(tmp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
void writeBE<uint32>(const uint32& v)
|
|
||||||
{
|
|
||||||
m_buffer.resize(m_buffer.size() + 4);
|
|
||||||
uint8* p = m_buffer.data() + m_buffer.size() - 4;
|
|
||||||
uint32 tmp = _BE(v);
|
|
||||||
std::memcpy(p, &tmp, sizeof(tmp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
void writeBE<uint16>(const uint16& v)
|
|
||||||
{
|
|
||||||
m_buffer.resize(m_buffer.size() + 2);
|
|
||||||
uint8* p = m_buffer.data() + m_buffer.size() - 2;
|
|
||||||
uint16 tmp = _BE(v);
|
|
||||||
std::memcpy(p, &tmp, sizeof(tmp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
void writeBE<uint8>(const uint8& v)
|
|
||||||
{
|
|
||||||
m_buffer.emplace_back(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
void writeBE<std::string>(const std::string& v)
|
|
||||||
{
|
|
||||||
writeBE<uint32>((uint32)v.size());
|
|
||||||
writeData(v.data(), v.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T> void writeLE(const T& v);
|
template<typename T> void writeLE(const T& v);
|
||||||
|
|
||||||
template<>
|
|
||||||
void writeLE<uint64>(const uint64& v)
|
|
||||||
{
|
|
||||||
m_buffer.resize(m_buffer.size() + 8);
|
|
||||||
uint8* p = m_buffer.data() + m_buffer.size() - 8;
|
|
||||||
uint64 tmp = _LE(v);
|
|
||||||
std::memcpy(p, &tmp, sizeof(tmp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
void writeLE<uint32>(const uint32& v)
|
|
||||||
{
|
|
||||||
m_buffer.resize(m_buffer.size() + 4);
|
|
||||||
uint8* p = m_buffer.data() + m_buffer.size() - 4;
|
|
||||||
uint32 tmp = _LE(v);
|
|
||||||
std::memcpy(p, &tmp, sizeof(tmp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void writePODVector(const std::vector<T>& v)
|
void writePODVector(const std::vector<T>& v)
|
||||||
{
|
{
|
||||||
|
@ -328,6 +179,7 @@ private:
|
||||||
std::vector<uint8> m_buffer;
|
std::vector<uint8> m_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class SerializerHelper
|
class SerializerHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -6,7 +6,8 @@ template<typename T, uint32 elements, typename P = uint32>
|
||||||
class RingBuffer
|
class RingBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RingBuffer<T, elements, P>();
|
//RingBuffer<T, elements, P>();
|
||||||
|
RingBuffer();
|
||||||
|
|
||||||
bool Push(const T& v);
|
bool Push(const T& v);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue