diff --git a/src/core/cheat_core.cpp b/src/core/cheat_core.cpp index c814c84de..34f9e68b1 100644 --- a/src/core/cheat_core.cpp +++ b/src/core/cheat_core.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include - #include "common/common_paths.h" #include "common/file_util.h" #include "core/cheat_core.h" @@ -67,32 +66,34 @@ std::vector> CheatEngine::ReadFileContents() { for (size_t i = 0; i < lines.size(); i++) { std::string current_line = std::string(lines[i].c_str()); current_line = Common::Trim(current_line); - if (current_line.compare(0, 2, "+[") == 0) { // Enabled code - if (!cheat_lines.empty()) { - if (code_type == "Gateway") - cheats.push_back( - std::make_shared(cheat_lines, notes, enabled, name)); + if (!current_line.empty()) { + if (current_line.compare(0, 2, "+[") == 0) { // Enabled code + if (!cheat_lines.empty()) { + if (code_type == "Gateway") + cheats.push_back( + std::make_shared(cheat_lines, notes, enabled, name)); + } + name = current_line.substr(2, current_line.length() - 3); + cheat_lines.clear(); + notes.clear(); + enabled = true; + continue; + } else if (current_line.front() == '[') { // Disabled code + if (!cheat_lines.empty()) { + if (code_type == "Gateway") + cheats.push_back( + std::make_shared(cheat_lines, notes, enabled, name)); + } + name = current_line.substr(1, current_line.length() - 2); + cheat_lines.clear(); + notes.clear(); + enabled = false; + continue; + } else if (current_line.front() == '*') { // Comment + notes.push_back(std::move(current_line)); + } else { + cheat_lines.emplace_back(std::move(current_line)); } - name = current_line.substr(2, current_line.length() - 3); - cheat_lines.clear(); - notes.clear(); - enabled = true; - continue; - } else if (current_line.front() == '[') { // Disabled code - if (!cheat_lines.empty()) { - if (code_type == "Gateway") - cheats.push_back( - std::make_shared(cheat_lines, notes, enabled, name)); - } - name = current_line.substr(1, current_line.length() - 2); - cheat_lines.clear(); - notes.clear(); - enabled = false; - continue; - } else if (current_line.front() == '*') { // Comment - notes.push_back(std::move(current_line)); - } else if (!current_line.empty()) { - cheat_lines.emplace_back(std::move(current_line)); } if (i == lines.size() - 1) { // End of file if (!cheat_lines.empty()) { @@ -143,16 +144,16 @@ void GatewayCheat::Execute() { bool loop_flag = false; for (size_t i = 0; i < cheat_lines.size(); i++) { auto line = cheat_lines[i]; - if (line.type == -1) + if (line.type == CheatType::Null) continue; addr = line.address; val = line.value; if (if_flag > 0) { - if (line.type == 0x0E) + if (line.type == CheatType::Patch) i += (line.value + 7) / 8; - if ((line.type == 0x0D) && (line.sub_type == 0)) - if_flag--; // ENDIF - if ((line.type == 0x0D) && (line.sub_type == 2)) // NEXT & Flush + if (line.type == CheatType::Terminator) + if_flag--; // ENDIF + if (line.type == CheatType::FullTerminator) // NEXT & Flush { if (loop_flag) i = loopbackline - 1; @@ -169,22 +170,23 @@ void GatewayCheat::Execute() { } switch (line.type) { - case 0x00: { // 0XXXXXXX YYYYYYYY word[XXXXXXX+offset] = YYYYYYYY + case CheatType::Write32: { // 0XXXXXXX YYYYYYYY word[XXXXXXX+offset] = YYYYYYYY addr = line.address + offset; Memory::Write32(addr, val); break; } - case 0x01: { // 1XXXXXXX 0000YYYY half[XXXXXXX+offset] = YYYY + case CheatType::Write16: { // 1XXXXXXX 0000YYYY half[XXXXXXX+offset] = YYYY addr = line.address + offset; Memory::Write16(addr, static_cast(val)); break; } - case 0x02: { // 2XXXXXXX 000000YY byte[XXXXXXX+offset] = YY + case CheatType::Write8: { // 2XXXXXXX 000000YY byte[XXXXXXX+offset] = YY addr = line.address + offset; Memory::Write8(addr, static_cast(val)); break; } - case 0x03: { // 3XXXXXXX YYYYYYYY IF YYYYYYYY > word[XXXXXXX] ;unsigned + case CheatType::GreaterThan32: { // 3XXXXXXX YYYYYYYY IF YYYYYYYY > word[XXXXXXX] + // ;unsigned if (line.address == 0) line.address = offset; val = Memory::Read32(line.address); @@ -196,7 +198,7 @@ void GatewayCheat::Execute() { } break; } - case 0x04: { // 4XXXXXXX YYYYYYYY IF YYYYYYYY < word[XXXXXXX] ;unsigned + case CheatType::LessThan32: { // 4XXXXXXX YYYYYYYY IF YYYYYYYY < word[XXXXXXX] ;unsigned if (line.address == 0) line.address = offset; val = Memory::Read32(line.address); @@ -208,7 +210,7 @@ void GatewayCheat::Execute() { } break; } - case 0x05: { // 5XXXXXXX YYYYYYYY IF YYYYYYYY = word[XXXXXXX] + case CheatType::EqualTo32: { // 5XXXXXXX YYYYYYYY IF YYYYYYYY = word[XXXXXXX] if (line.address == 0) line.address = offset; val = Memory::Read32(line.address); @@ -220,7 +222,7 @@ void GatewayCheat::Execute() { } break; } - case 0x06: { // 6XXXXXXX YYYYYYYY IF YYYYYYYY <> word[XXXXXXX] + case CheatType::NotEqualTo32: { // 6XXXXXXX YYYYYYYY IF YYYYYYYY <> word[XXXXXXX] if (line.address == 0) line.address = offset; val = Memory::Read32(line.address); @@ -232,7 +234,8 @@ void GatewayCheat::Execute() { } break; } - case 0x07: { // 7XXXXXXX ZZZZYYYY IF YYYY > ((not ZZZZ) AND half[XXXXXXX]) + case CheatType::GreaterThan16: { // 7XXXXXXX ZZZZYYYY IF YYYY > ((not ZZZZ) AND + // half[XXXXXXX]) if (line.address == 0) line.address = offset; val = Memory::Read16(line.address); @@ -244,7 +247,8 @@ void GatewayCheat::Execute() { } break; } - case 0x08: { // 8XXXXXXX ZZZZYYYY IF YYYY < ((not ZZZZ) AND half[XXXXXXX]) + case CheatType::LessThan16: { // 8XXXXXXX ZZZZYYYY IF YYYY < ((not ZZZZ) AND + // half[XXXXXXX]) if (line.address == 0) line.address = offset; val = Memory::Read16(line.address); @@ -256,7 +260,7 @@ void GatewayCheat::Execute() { } break; } - case 0x09: { // 9XXXXXXX ZZZZYYYY IF YYYY = ((not ZZZZ) AND half[XXXXXXX]) + case CheatType::EqualTo16: { // 9XXXXXXX ZZZZYYYY IF YYYY = ((not ZZZZ) AND half[XXXXXXX]) if (line.address == 0) line.address = offset; val = Memory::Read16(line.address); @@ -268,7 +272,8 @@ void GatewayCheat::Execute() { } break; } - case 0x0A: { // AXXXXXXX ZZZZYYYY IF YYYY <> ((not ZZZZ) AND half[XXXXXXX]) + case CheatType::NotEqualTo16: { // AXXXXXXX ZZZZYYYY IF YYYY <> ((not ZZZZ) AND + // half[XXXXXXX]) if (line.address == 0) line.address = offset; val = Memory::Read16(line.address); @@ -280,12 +285,12 @@ void GatewayCheat::Execute() { } break; } - case 0x0B: { // BXXXXXXX 00000000 offset = word[XXXXXXX+offset] + case CheatType::LoadOffset: { // BXXXXXXX 00000000 offset = word[XXXXXXX+offset] addr = line.address + offset; offset = Memory::Read32(addr); break; } - case 0x0C: { + case CheatType::Loop: { if (loop_count < (line.value + 1)) loop_flag = 1; else @@ -294,86 +299,83 @@ void GatewayCheat::Execute() { loopbackline = i; break; } - case 0x0D: { - switch (line.sub_type) { - case 0x00: - break; - case 0x01: { - if (loop_flag) - i = loopbackline - 1; - break; - } - case 0x02: { - if (loop_flag) - i = loopbackline - 1; - else { - offset = 0; - reg = 0; - loop_count = 0; - counter = 0; - if_flag = 0; - loop_flag = 0; - } - break; - } - case 0x03: { - offset = line.value; - break; - } - case 0x04: { - reg += line.value; - break; - } - case 0x05: { - reg = line.value; - break; - } - case 0x06: { - addr = line.value + offset; - Memory::Write32(addr, reg); - offset += 4; - break; - } - case 0x07: { - addr = line.value + offset; - Memory::Write16(addr, static_cast(reg)); - offset += 2; - break; - } - case 0x08: { - addr = line.value + offset; - Memory::Write8(addr, static_cast(reg)); - offset += 1; - break; - } - case 0x09: { - addr = line.value + offset; - reg = Memory::Read32(addr); - break; - } - case 0x0A: { - addr = line.value + offset; - reg = Memory::Read16(addr); - break; - } - case 0x0B: { - addr = line.value + offset; - reg = Memory::Read8(addr); - break; - } - case 0x0C: { - offset += line.value; - break; - } - case 0x0D: { - bool pressed = false; // TODO replace after input overhaul - if (!pressed) - if_flag++; - break; - } - } + case CheatType::Terminator: { + break; } - case 0x0E: { + case CheatType::LoopExecuteVariant: { + if (loop_flag) + i = loopbackline - 1; + break; + } + case CheatType::FullTerminator: { + if (loop_flag) + i = loopbackline - 1; + else { + offset = 0; + reg = 0; + loop_count = 0; + counter = 0; + if_flag = 0; + loop_flag = 0; + } + break; + } + case CheatType::SetOffset: { + offset = line.value; + break; + } + case CheatType::AddValue: { + reg += line.value; + break; + } + case CheatType::SetValue: { + reg = line.value; + break; + } + case CheatType::IncrementiveWrite32: { + addr = line.value + offset; + Memory::Write32(addr, reg); + offset += 4; + break; + } + case CheatType::IncrementiveWrite16: { + addr = line.value + offset; + Memory::Write16(addr, static_cast(reg)); + offset += 2; + break; + } + case CheatType::IncrementiveWrite8: { + addr = line.value + offset; + Memory::Write8(addr, static_cast(reg)); + offset += 1; + break; + } + case CheatType::Load32: { + addr = line.value + offset; + reg = Memory::Read32(addr); + break; + } + case CheatType::Load16: { + addr = line.value + offset; + reg = Memory::Read16(addr); + break; + } + case CheatType::Load8: { + addr = line.value + offset; + reg = Memory::Read8(addr); + break; + } + case CheatType::AddOffset: { + offset += line.value; + break; + } + case CheatType::Joker: { + bool pressed = false; // TODO replace after input overhaul + if (!pressed) + if_flag++; + break; + } + case CheatType::Patch: { // Patch Code (Miscellaneous Memory Manipulation Codes) // EXXXXXXX YYYYYYYY // Copies YYYYYYYY bytes from (current code location + 8) to [XXXXXXXX + offset]. diff --git a/src/core/cheat_core.h b/src/core/cheat_core.h index 8e987c009..f32639a34 100644 --- a/src/core/cheat_core.h +++ b/src/core/cheat_core.h @@ -5,7 +5,6 @@ #include #include #include - #include "common/string_util.h" #include "core/core_timing.h" @@ -18,6 +17,38 @@ void Shutdown(); void RefreshCheats(); } namespace CheatEngine { + +enum class CheatType { + Null = -0x1, + Write32 = 0x00, + Write16 = 0x01, + Write8 = 0x02, + GreaterThan32 = 0x03, + LessThan32 = 0x04, + EqualTo32 = 0x05, + NotEqualTo32 = 0x06, + GreaterThan16 = 0x07, + LessThan16 = 0x08, + EqualTo16 = 0x09, + NotEqualTo16 = 0x0A, + LoadOffset = 0x0B, + Loop = 0x0C, + Terminator = 0xD0, + LoopExecuteVariant = 0xD1, + FullTerminator = 0xD2, + SetOffset = 0xD3, + AddValue = 0xD4, + SetValue = 0xD5, + IncrementiveWrite32 = 0xD6, + IncrementiveWrite16 = 0xD7, + IncrementiveWrite8 = 0xD8, + Load32 = 0xD9, + Load16 = 0xDA, + Load8 = 0xDB, + AddOffset = 0xDC, + Joker = 0xDD, + Patch = 0x0E, +}; /* * Represents a single line of a cheat, i.e. 1xxxxxxxx yyyyyyyy */ @@ -27,26 +58,28 @@ struct CheatLine { line = Common::Trim(line); constexpr int cheat_length = 17; if (line.length() != cheat_length) { - type = -1; + type = CheatType::Null; cheat_line = line; return; } try { - type = std::stoi(line.substr(0, 1), 0, 16); + std::string type_temp = line.substr(0, 1); + // 0xD types have extra subtype value, i.e. 0xDA - if (type == 0xD) - sub_type = std::stoi(line.substr(1, 1), 0, 16); + std::string sub_type_temp; + if (type_temp == "D" || type_temp == "d") + sub_type_temp = line.substr(1, 1); + type = static_cast(std::stoi(type_temp + sub_type_temp, 0, 16)); address = std::stoi(line.substr(1, 8), 0, 16); value = std::stoi(line.substr(10, 8), 0, 16); cheat_line = line; } catch (std::exception e) { - type = -1; + type = CheatType::Null; cheat_line = line; return; } } - int type; - int sub_type; + CheatType type; u32 address; u32 value; std::string cheat_line;