diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 75fd9ac8cd..af3e6d053d 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -109,6 +109,7 @@ Fast USE_FFMPEG;_MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS Speed + MultiThreadedDLL true @@ -157,6 +158,7 @@ + @@ -330,6 +332,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 1d7eafeb18..fb483ba538 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -417,6 +417,9 @@ FileSystems + + Core + @@ -769,6 +772,9 @@ HLE\Libraries + + Core + diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 8749e8f96c..a6ee85f621 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -1,10 +1,471 @@ #include "CwCheat.h" -#include "Config.h" -#include "UI\MenuScreens.cpp" +#include "../Core/CoreTiming.h" +#include "../Core/CoreParameter.h" using namespace std; -void runCheats() { +static int CheatEvent = -1; +CheatsGUI member; + +void hleCheat(u64 userdata, int cyclesLate); + + +void __CheatInit() { + + CheatEvent = CoreTiming::RegisterEvent("CheatEvent", &hleCheat); + CoreTiming::ScheduleEvent(msToCycles(66), CheatEvent, 0); +} +void __CheatShutdown() { + member.Exit(); +} + +void hleCheat(u64 userdata, int cyclesLate) { + CoreTiming::ScheduleEvent(msToCycles(66), CheatEvent, 0); + member.Run(); +} +CheatsGUI::CheatsGUI() { } +void CheatsGUI::Exit() { + exit2 = true; +} + +string CheatsGUI::GetNextCode() { + string code; + string modifier = "_L"; + while (true) { + if (currentCode >= codes.size()) { + code.clear(); + break; + } + + code = codes[currentCode++]; + trim2(code); + + if (code.substr(0,2) == modifier) { + code = code.substr(3,21); + } + else if (code[0] == '0') { + break; + } + } + return code; +} + +void CheatsGUI::skipCodes(int count) { + for (int i = 0; i < count; i ++) { + if (GetNextCode() == "") { + break; + } + } +} + +void CheatsGUI::skipAllCodes() { + currentCode = codes.size(); +} + +int CheatsGUI::getAddress(int value) { + // The User space base address has to be added to given value + return (value + 0x08800000) & 0x3FFFFFFF; +} + + + + +void CheatsGUI::AddCheatLine(string& line) { + //Need GUI text area here + string cheatCodes; + if (cheatCodes.length() <= 0) { + cheatCodes = line; + } else { + cheatCodes += "/n" + line; + } + } + + +inline static long parseHexLong(string s) { + long value = 0; + + if (s.substr(0,2) == "0x") { + s = s.substr(2); + } + value = strtol(s.c_str(),NULL, 16); + return value; + } +inline static long parseLong(string s) { + long value = 0; + if (s.substr(0,2) == "0x") { + s = s.substr(2); + value = strtol(s.c_str(),NULL, 16); + } else { + value = strtol(s.c_str(),NULL, 10); + } + return value; + } + + +inline void trim2(string& str) +{ + string::size_type pos = str.find_last_not_of(' '); + if(pos != string::npos) { + str.erase(pos + 1); + pos = str.find_first_not_of(' '); + if(pos != string::npos) str.erase(0, pos); + } + else str.erase(str.begin(), str.end()); +} + +inline vector makeCodeParts(string l) { + vector parts; + char split_char = '/n'; + char empty = ' '; + + for (int i=0; i < l.length(); i++) { + if (l[i] == empty) { + l[i] = '\n'; + } + } + trim2(l); + istringstream iss (l); + for (std::string each; std::getline(iss, each, split_char);parts.push_back(each)) + {} + return parts; +} + +vector CheatsGUI::GetCodesList() { + string text = "0x203BFA00 0x05F5E0FF"; + vector codeslist; + codeslist = makeCodeParts(text); + trim2(codeslist[0]); + trim2(codeslist[1]); + return codeslist; +} + +void CheatsGUI::OnCheatsThreadEnded() { + cheatsThread = false; + } +void CheatsGUI::Dispose() { +} + +void CheatsGUI::Run() { + CheatsGUI cheats; + while (!exit2) { + codes = cheats.GetCodesList(); //UI Member + currentCode = 0; + + while (true) { + string code = GetNextCode(); + vectorparts = makeCodeParts(code); + int value; + trim2(parts[0]); + trim2(parts[1]); + int comm = (int)parseHexLong(parts[0]); + int arg = (int)parseHexLong(parts[1]); + int addr = getAddress(comm & 0x0FFFFFFF); + + switch (comm >> 28) { + case 0: // 8-bit write. + if (Memory::IsValidAddress(addr)){ + Memory::Write_U8((u8) arg, addr); + } + break; + case 0x1: // 16-bit write + if (Memory::IsValidAddress(addr)){ + Memory::Write_U16((u16) arg, addr); + } + break; + case 0x2: // 32-bit write + if (Memory::IsValidAddress(addr)){ + Memory::Write_U32((u32) arg, addr); + } + break; + case 0x3: // Increment/Decrement + { + addr = getAddress(arg); + value = 0; + int increment = 0; + // Read value from memory + switch ((comm >> 20) & 0xF) { + case 1: + case 2: // 8-bit + value = Memory::Read_U8(addr); + increment = comm & 0xFF; + break; + case 3: + case 4: // 16-bit + value = Memory::Read_U16(addr); + increment = comm & 0xFFFF; + break; + case 5: + case 6: // 32-bit + value = Memory::Read_U32(addr); + code = GetNextCode(); + parts = makeCodeParts(code); + trim2(parts[0]); + if ( parts[0] != "") { + increment = (int) parseHexLong(parts[0]); + } + break; + } + // Increment/Decrement value + switch ((comm >> 20) & 0xF) { + case 1: + case 3: + case 5: // increment + value += increment; + break; + case 2: + case 4: + case 6: // Decrement + value -= increment; + break; + } + // Write value back to memory + switch ((comm >> 20) & 0xF) { + case 1: + case 2: // 8-bit + Memory::Write_U8((u8) value, addr); + break; + case 3: + case 4: // 16-bit + Memory::Write_U16((u16) value, addr); + break; + case 5: + case 6: // 32-bit + Memory::Write_U32((u32) value, addr); + break; + } + break; } + case 0x4: // 32-bit patch code + code = GetNextCode(); + parts = makeCodeParts(code); + trim2(parts[0]); + trim2(parts[1]); + if (parts[0] != "") { + int data = (int) parseHexLong(parts[0]); + int dataAdd = (int) parseHexLong(parts[1]); + + int maxAddr = (arg >> 16) & 0xFFFF; + int stepAddr = (arg & 0xFFFF) * 4; + for (int a = 0; a < maxAddr; a++) { + if (Memory::IsValidAddress(addr)) { + Memory::Write_U32((u32) data, addr); + } + addr += stepAddr; + data += dataAdd; + } + } + break; + case 0x5: // Memcpy command + code = GetNextCode(); + parts = makeCodeParts(code); + trim2(parts[0]); + trim2(parts[1]); + if (parts[0] != "") { + int destAddr = (int) parseHexLong(parts[0]); + if (Memory::IsValidAddress(addr) && Memory::IsValidAddress(destAddr)) { + Memory::Memcpy(destAddr, Memory::GetPointer(addr), arg); + } + } + break; + case 0x6: // Pointer commands + code = GetNextCode(); + parts = makeCodeParts(code); + trim2(parts[0]); + trim2(parts[1]); + if (parts[0] != "") { + int arg2 = (int) parseHexLong(parts[0]); + int offset = (int) parseHexLong(parts[1]); + int baseOffset = (arg2 >> 20) * 4; + int base = Memory::Read_U32(addr + baseOffset); + int count = arg2 & 0xFFFF; + int type = (arg2 >> 16) & 0xF; + for (int i = 1; i < count; i ++ ) { + if (i+1 < count) { + code = GetNextCode(); + parts = makeCodeParts(code); + trim2(parts[0]); + trim2(parts[1]); + int arg3 = (int) parseHexLong(parts[0]); + int arg4 = (int) parseHexLong(parts[1]); + int comm3 = arg3 >> 28; + switch (comm3) { + case 0x1: // type copy byte + { + int srcAddr = Memory::Read_U32(addr) + offset; + int dstAddr = Memory::Read_U16(addr + baseOffset) + (arg3 & 0x0FFFFFFF); + Memory::Memcpy(dstAddr, Memory::GetPointer(srcAddr), arg); + type = -1; //Done + break; } + case 0x2: + case 0x3: // type pointer walk + { + int walkOffset = arg3 & 0x0FFFFFFF; + if (comm3 == 0x3) { + walkOffset = -walkOffset; + } + base = Memory::Read_U32(base + walkOffset); + int comm4 = arg4 >> 28; + switch (comm4) { + case 0x2: + case 0x3: // type pointer walk + walkOffset = arg4 & 0x0FFFFFFF; + if (comm4 == 0x3) { + walkOffset = -walkOffset; + } + base = Memory::Read_U32(base + walkOffset); + break; + } + break; } + case 0x9: // type multi address write + base += arg3 & 0x0FFFFFFF; + arg += arg4; + break; + } + } + } + + switch (type) { + case 0: // 8 bit write + Memory::Write_U8((u8) arg, base + offset); + break; + case 1: // 16-bit write + Memory::Write_U16((u16) arg, base + offset); + break; + case 2: // 32-bit write + Memory::Write_U32((u32) arg, base + offset); + break; + case 3: // 8 bit inverse write + Memory::Write_U8((u8) arg, base - offset); + break; + case 4: // 16-bit inverse write + Memory::Write_U16((u16) arg, base - offset); + break; + case 5: // 32-bit inverse write + Memory::Write_U32((u32) arg, base - offset); + break; + case -1: // Operation already performed, nothing to do + break; + } + } + break; + case 0x7: // Boolean commands. + switch (arg >> 16) { + case 0x0000: // 8-bit OR. + if (Memory::IsValidAddress(addr)) { + int val1 = (int) (arg & 0xFF); + int val2 = (int) Memory::Read_U8(addr); + Memory::Write_U8((u8) (val1 | val2), addr); + } + break; + case 0x0002: // 8-bit AND. + if (Memory::IsValidAddress(addr)) { + int val1 = (int) (arg & 0xFF); + int val2 = (int) Memory::Read_U8(addr); + Memory::Write_U8((u8) (val1 & val2), addr); + } + break; + case 0x0004: // 8-bit XOR. + if (Memory::IsValidAddress(addr)) { + int val1 = (int) (arg & 0xFF); + int val2 = (int) Memory::Read_U8(addr); + Memory::Write_U8((u8) (val1 ^ val2), addr); + } + break; + case 0x0001: // 16-bit OR. + if (Memory::IsValidAddress(addr)) { + short val1 = (short) (arg & 0xFFFF); + short val2 = (short) Memory::Read_U16(addr); + Memory::Write_U16((u16) (val1 | val2), addr); + } + break; + case 0x0003: // 16-bit AND. + if (Memory::IsValidAddress(addr)) { + short val1 = (short) (arg & 0xFFFF); + short val2 = (short) Memory::Read_U16(addr); + Memory::Write_U16((u16) (val1 & val2), addr); + } + break; + case 0x0005: // 16-bit OR. + if (Memory::IsValidAddress(addr)) { + short val1 = (short) (arg & 0xFFFF); + short val2 = (short) Memory::Read_U16(addr); + Memory::Write_U16((u16) (val1 ^ val2), addr); + } + break; + } + break; + case 0x8: // 8-bit and 16-bit patch code + code = GetNextCode(); + parts = makeCodeParts(code); + trim2(parts[0]); + trim2(parts[1]); + if (parts[0] != "") { + int data = (int) parseHexLong(parts[0]); + int dataAdd = (int) parseHexLong(parts[1]); + + bool is8Bit = (data >> 16) == 0x0000; + int maxAddr = (arg >> 16) & 0xFFFF; + int stepAddr = (arg & 0xFFFF) * (is8Bit ? 1 : 2); + for (int a = 0; a < maxAddr; a++) { + if (Memory::IsValidAddress(addr)) { + if (is8Bit) { + Memory::Write_U8((u8) (data & 0xFF), addr); + } + else { + Memory::Write_U16((u16) (data & 0xFFFF), addr); + } + } + addr += stepAddr; + data += dataAdd; + } + } + break; + case 0xB: // Time command (not sure what to do?) + break; + case 0xC: // Code stopper + if (Memory::IsValidAddress(addr)) { + value = Memory::Read_U32(addr); + if (value != arg) { + skipAllCodes(); + } + } + break; + case 0xD: // Test commands & Jocker codes ( Someone will have to help me with these) + break; + case 0xE: // Test commands, multiple skip + bool is8Bit = (comm >> 24) == 0x1; + addr = getAddress(arg & 0x0FFFFFFF); + if (Memory::IsValidAddress(addr)) { + int memoryValue = is8Bit ? Memory::Read_U8(addr) : Memory::Read_U16(addr); + int testValue = comm & (is8Bit ? 0xFF : 0xFFFF); + bool executeNextLines = false; + switch ( arg >> 28) { + case 0x0: // Equal + executeNextLines = memoryValue == testValue; + break; + case 0x1: // Not Equal + executeNextLines = memoryValue != testValue; + break; + case 0x2: // Less Than + executeNextLines = memoryValue < testValue; + break; + case 0x3: // Greater Than + executeNextLines = memoryValue > testValue; + break; + } + if (!executeNextLines) { + int skip = (comm >> 16) & (is8Bit ? 0xFF : 0xFFF); + skipCodes(skip); + } + } + break; + } + } + } + // exiting... + cheats.OnCheatsThreadEnded(); + } + + diff --git a/Core/CwCheat.h b/Core/CwCheat.h index e04945da71..8ab46fbb86 100644 --- a/Core/CwCheat.h +++ b/Core/CwCheat.h @@ -1,15 +1,17 @@ #include #include -#include #include #include - #include "Core\MemMap.h" +void __CheatInit(); +void __CheatShutdown(); +//void Register_CwCheat(); using namespace std; -class CheatsThread; -class CheatsGUI; + + + vector makeCodeParts(string l); void trim2(string& str); static long parseLong(string s); @@ -18,477 +20,30 @@ static long parseHexLong(string s); class CheatsGUI { private: - static long const serialVersionUID = 6791588139795694296L; static long const int cheatsThreadSleepMillis = 5; bool cheatsOn; - CheatsThread cheatsThread; + std::vector codes; + int currentCode; + bool exit2; + void skipCodes(int count); + void skipAllCodes(); + int getAddress(int value); + bool cheatsThread; + public: CheatsGUI(); string String(); - void addCheatLine(string& line); - void onCheatsThreadEnded(); - void dispose(); - vector getCodesList(); -}; -class CheatsThread { - private: - std::vector codes; - int currentCode; - CheatsGUI cheats; - bool exit2; - void skipCodes(int count); - void skipAllCodes(); - int getAddress(int value); + void AddCheatLine(string& line); + void OnCheatsThreadEnded(); + void Dispose(); + vector GetCodesList(); - - public: - CheatsThread(CheatsGUI cheats); - void exit(); - void run(); - string getNextCode(); + void Exit(); + void Run(); + string GetNextCode(); }; -CheatsThread::CheatsThread(CheatsGUI cheats){ - this->cheats = cheats; -} - -void CheatsThread::exit() { - exit2 = true; -} - -string CheatsThread::getNextCode() { - string code; - string modifier = "_L"; - while (true) { - if (currentCode >= codes.size()) { - code.clear(); - break; - } - - code = codes[currentCode++]; - trim2(code); - - if (code.substr(0,2) == modifier) { - code = code.substr(3,21); - } - else if (code[0] == '0') { - break; - } - } - return code; -} - -void CheatsThread::skipCodes(int count) { - for (int i = 0; i < count; i ++) { - if (getNextCode() == "") { - break; - } - } -} - -void CheatsThread::skipAllCodes() { - currentCode = codes.size(); -} - -int CheatsThread::getAddress(int value) { - // The User space base address has to be added to given value - return (value + 0x08800000) & 0x3FFFFFFF; -} - -void CheatsThread::run() { - while (!exit2) { - codes = cheats.getCodesList(); //UI Member - currentCode = 0; - - while (true) { - string code = getNextCode(); - vectorparts = makeCodeParts(code); - int value; - trim2(parts[0]); - trim2(parts[1]); - int comm = (int)parseHexLong(parts[0]); - int arg = (int)parseHexLong(parts[1]); - int addr = getAddress(comm & 0x0FFFFFFF); - - switch (comm >> 28) { - case 0: // 8-bit write. - if (Memory::IsValidAddress(addr)){ - Memory::Write_U8((u8) arg, addr); - } - break; - case 0x1: // 16-bit write - if (Memory::IsValidAddress(addr)){ - Memory::Write_U16((u16) arg, addr); - } - break; - case 0x2: // 32-bit write - if (Memory::IsValidAddress(addr)){ - Memory::Write_U32((u32) arg, addr); - } - break; - case 0x3: // Increment/Decrement - { - addr = getAddress(arg); - value = 0; - int increment = 0; - // Read value from memory - switch ((comm >> 20) & 0xF) { - case 1: - case 2: // 8-bit - value = Memory::Read_U8(addr); - increment = comm & 0xFF; - break; - case 3: - case 4: // 16-bit - value = Memory::Read_U16(addr); - increment = comm & 0xFFFF; - break; - case 5: - case 6: // 32-bit - value = Memory::Read_U32(addr); - code = getNextCode(); - parts = makeCodeParts(code); - trim2(parts[0]); - if ( parts[0] != "") { - increment = (int) parseHexLong(parts[0]); - } - break; - } - // Increment/Decrement value - switch ((comm >> 20) & 0xF) { - case 1: - case 3: - case 5: // increment - value += increment; - break; - case 2: - case 4: - case 6: // Decrement - value -= increment; - break; - } - // Write value back to memory - switch ((comm >> 20) & 0xF) { - case 1: - case 2: // 8-bit - Memory::Write_U8((u8) value, addr); - break; - case 3: - case 4: // 16-bit - Memory::Write_U16((u16) value, addr); - break; - case 5: - case 6: // 32-bit - Memory::Write_U32((u32) value, addr); - break; - } - break; } - case 0x4: // 32-bit patch code - code = getNextCode(); - parts = makeCodeParts(code); - trim2(parts[0]); - trim2(parts[1]); - if (parts[0] != "") { - int data = (int) parseHexLong(parts[0]); - int dataAdd = (int) parseHexLong(parts[1]); - - int maxAddr = (arg >> 16) & 0xFFFF; - int stepAddr = (arg & 0xFFFF) * 4; - for (int a = 0; a < maxAddr; a++) { - if (Memory::IsValidAddress(addr)) { - Memory::Write_U32((u32) data, addr); - } - addr += stepAddr; - data += dataAdd; - } - } - break; - case 0x5: // Memcpy command - code = getNextCode(); - parts = makeCodeParts(code); - trim2(parts[0]); - trim2(parts[1]); - if (parts[0] != "") { - int destAddr = (int) parseHexLong(parts[0]); - if (Memory::IsValidAddress(addr) && Memory::IsValidAddress(destAddr)) { - Memory::Memcpy(destAddr, Memory::GetPointer(addr), arg); - } - } - break; - case 0x6: // Pointer commands - code = getNextCode(); - parts = makeCodeParts(code); - trim2(parts[0]); - trim2(parts[1]); - if (parts[0] != "") { - int arg2 = (int) parseHexLong(parts[0]); - int offset = (int) parseHexLong(parts[1]); - int baseOffset = (arg2 >> 20) * 4; - int base = Memory::Read_U32(addr + baseOffset); - int count = arg2 & 0xFFFF; - int type = (arg2 >> 16) & 0xF; - for (int i = 1; i < count; i ++ ) { - if (i+1 < count) { - code = getNextCode(); - parts = makeCodeParts(code); - trim2(parts[0]); - trim2(parts[1]); - int arg3 = (int) parseHexLong(parts[0]); - int arg4 = (int) parseHexLong(parts[1]); - int comm3 = arg3 >> 28; - switch (comm3) { - case 0x1: // type copy byte - { - int srcAddr = Memory::Read_U32(addr) + offset; - int dstAddr = Memory::Read_U16(addr + baseOffset) + (arg3 & 0x0FFFFFFF); - Memory::Memcpy(dstAddr, Memory::GetPointer(srcAddr), arg); - type = -1; //Done - break; } - case 0x2: - case 0x3: // type pointer walk - { - int walkOffset = arg3 & 0x0FFFFFFF; - if (comm3 == 0x3) { - walkOffset = -walkOffset; - } - base = Memory::Read_U32(base + walkOffset); - int comm4 = arg4 >> 28; - switch (comm4) { - case 0x2: - case 0x3: // type pointer walk - walkOffset = arg4 & 0x0FFFFFFF; - if (comm4 == 0x3) { - walkOffset = -walkOffset; - } - base = Memory::Read_U32(base + walkOffset); - break; - } - break; } - case 0x9: // type multi address write - base += arg3 & 0x0FFFFFFF; - arg += arg4; - break; - } - } - } - - switch (type) { - case 0: // 8 bit write - Memory::Write_U8((u8) arg, base + offset); - break; - case 1: // 16-bit write - Memory::Write_U16((u16) arg, base + offset); - break; - case 2: // 32-bit write - Memory::Write_U32((u32) arg, base + offset); - break; - case 3: // 8 bit inverse write - Memory::Write_U8((u8) arg, base - offset); - break; - case 4: // 16-bit inverse write - Memory::Write_U16((u16) arg, base - offset); - break; - case 5: // 32-bit inverse write - Memory::Write_U32((u32) arg, base - offset); - break; - case -1: // Operation already performed, nothing to do - break; - } - } - break; - case 0x7: // Boolean commands. - switch (arg >> 16) { - case 0x0000: // 8-bit OR. - if (Memory::IsValidAddress(addr)) { - int val1 = (int) (arg & 0xFF); - int val2 = (int) Memory::Read_U8(addr); - Memory::Write_U8((u8) (val1 | val2), addr); - } - break; - case 0x0002: // 8-bit AND. - if (Memory::IsValidAddress(addr)) { - int val1 = (int) (arg & 0xFF); - int val2 = (int) Memory::Read_U8(addr); - Memory::Write_U8((u8) (val1 & val2), addr); - } - break; - case 0x0004: // 8-bit XOR. - if (Memory::IsValidAddress(addr)) { - int val1 = (int) (arg & 0xFF); - int val2 = (int) Memory::Read_U8(addr); - Memory::Write_U8((u8) (val1 ^ val2), addr); - } - break; - case 0x0001: // 16-bit OR. - if (Memory::IsValidAddress(addr)) { - short val1 = (short) (arg & 0xFFFF); - short val2 = (short) Memory::Read_U16(addr); - Memory::Write_U16((u16) (val1 | val2), addr); - } - break; - case 0x0003: // 16-bit AND. - if (Memory::IsValidAddress(addr)) { - short val1 = (short) (arg & 0xFFFF); - short val2 = (short) Memory::Read_U16(addr); - Memory::Write_U16((u16) (val1 & val2), addr); - } - break; - case 0x0005: // 16-bit OR. - if (Memory::IsValidAddress(addr)) { - short val1 = (short) (arg & 0xFFFF); - short val2 = (short) Memory::Read_U16(addr); - Memory::Write_U16((u16) (val1 ^ val2), addr); - } - break; - } - break; - case 0x8: // 8-bit and 16-bit patch code - code = getNextCode(); - parts = makeCodeParts(code); - trim2(parts[0]); - trim2(parts[1]); - if (parts[0] != "") { - int data = (int) parseHexLong(parts[0]); - int dataAdd = (int) parseHexLong(parts[1]); - - bool is8Bit = (data >> 16) == 0x0000; - int maxAddr = (arg >> 16) & 0xFFFF; - int stepAddr = (arg & 0xFFFF) * (is8Bit ? 1 : 2); - for (int a = 0; a < maxAddr; a++) { - if (Memory::IsValidAddress(addr)) { - if (is8Bit) { - Memory::Write_U8((u8) (data & 0xFF), addr); - } - else { - Memory::Write_U16((u16) (data & 0xFFFF), addr); - } - } - addr += stepAddr; - data += dataAdd; - } - } - break; - case 0xB: // Time command (not sure what to do?) - break; - case 0xC: // Code stopper - if (Memory::IsValidAddress(addr)) { - value = Memory::Read_U32(addr); - if (value != arg) { - skipAllCodes(); - } - } - break; - case 0xD: // Test commands & Jocker codes ( Someone will have to help me with these) - break; - case 0xE: // Test commands, multiple skip - bool is8Bit = (comm >> 24) == 0x1; - addr = getAddress(arg & 0x0FFFFFFF); - if (Memory::IsValidAddress(addr)) { - int memoryValue = is8Bit ? Memory::Read_U8(addr) : Memory::Read_U16(addr); - int testValue = comm & (is8Bit ? 0xFF : 0xFFFF); - bool executeNextLines = false; - switch ( arg >> 28) { - case 0x0: // Equal - executeNextLines = memoryValue == testValue; - break; - case 0x1: // Not Equal - executeNextLines = memoryValue != testValue; - break; - case 0x2: // Less Than - executeNextLines = memoryValue < testValue; - break; - case 0x3: // Greater Than - executeNextLines = memoryValue > testValue; - break; - } - if (!executeNextLines) { - int skip = (comm >> 16) & (is8Bit ? 0xFF : 0xFFF); - skipCodes(skip); - } - } - break; - } - } - } - // exiting... - cheats.onCheatsThreadEnded(); - } - -CheatsGUI::CheatsGUI() { -} - -void CheatsGUI::addCheatLine(string& line) { - //Need GUI text area here - string cheatCodes; - if (cheatCodes.length() <= 0) { - cheatCodes = line; - } else { - cheatCodes += "/n" + line; - } - } -static long parseHexLong(string s) { - long value = 0; - - if (s.substr(0,2) == "0x") { - s = s.substr(2); - } - value = strtol(s.c_str(),NULL, 16); - return value; - } -static long parseLong(string s) { - long value = 0; - if (s.substr(0,2) == "0x") { - s = s.substr(2); - value = strtol(s.c_str(),NULL, 16); - } else { - value = strtol(s.c_str(),NULL, 10); - } - return value; - } - - -void trim2(string& str) -{ - string::size_type pos = str.find_last_not_of(' '); - if(pos != string::npos) { - str.erase(pos + 1); - pos = str.find_first_not_of(' '); - if(pos != string::npos) str.erase(0, pos); - } - else str.erase(str.begin(), str.end()); -} - -vector makeCodeParts(string l) { - vector parts; - char split_char = '/n'; - char empty = ' '; - - for (int i=0; i < l.length(); i++) { - if (l[i] == empty) { - l[i] = '\n'; - } - } - trim2(l); - istringstream iss (l); - for (std::string each; std::getline(iss, each, split_char);parts.push_back(each)) - {} - return parts; -} - -vector CheatsGUI::getCodesList() { - string text = "0x203BFA00 0x3B9AC9FF"; - vector codes; - trim2(text); - codes = makeCodeParts(text); - return codes; -} - -void CheatsGUI::onCheatsThreadEnded() { - cheatsThread = NULL; - } -void CheatsGUI::dispose() { -} diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index b29f964133..42741e901c 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Core/Config.h" +#include "Core/Cwcheat.h" #include "Core/HLE/HLE.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPSCodeUtils.h" @@ -115,6 +116,7 @@ void __KernelInit() __UsbInit(); __FontInit(); __NetInit(); + __CheatInit(); SaveState::Init(); // Must be after IO, as it may create a directory @@ -156,6 +158,7 @@ void __KernelShutdown() __KernelThreadingShutdown(); __KernelMemoryShutdown(); __InterruptsShutdown(); + __CheatShutdown(); CoreTiming::ClearPendingEvents(); CoreTiming::UnregisterAllEvents();