mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-25 21:50:15 +00:00
Use enums instead of string for type. Fix possible issue when reading file.
This commit is contained in:
parent
c1e9f1fd8d
commit
68c5f4c492
@ -3,7 +3,6 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "common/common_paths.h"
|
||||
#include "common/file_util.h"
|
||||
#include "core/cheat_core.h"
|
||||
@ -67,32 +66,34 @@ std::vector<std::shared_ptr<CheatBase>> 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<GatewayCheat>(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<GatewayCheat>(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<GatewayCheat>(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<GatewayCheat>(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<u16>(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<u8>(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<u16>(reg));
|
||||
offset += 2;
|
||||
break;
|
||||
}
|
||||
case 0x08: {
|
||||
addr = line.value + offset;
|
||||
Memory::Write8(addr, static_cast<u8>(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<u16>(reg));
|
||||
offset += 2;
|
||||
break;
|
||||
}
|
||||
case CheatType::IncrementiveWrite8: {
|
||||
addr = line.value + offset;
|
||||
Memory::Write8(addr, static_cast<u8>(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].
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#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<CheatType>(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;
|
||||
|
Loading…
Reference in New Issue
Block a user