diff --git a/src/core/cheats/cheats.cpp b/src/core/cheats/cheats.cpp index 75192f584..f4b48fd06 100644 --- a/src/core/cheats/cheats.cpp +++ b/src/core/cheats/cheats.cpp @@ -15,7 +15,9 @@ namespace Cheats { -constexpr u64 run_interval_ticks = GPU::frame_ticks; +// Luma3DS uses this interval for applying cheats, so to keep consistent behavior +// we use the same value +constexpr u64 run_interval_ticks = 50'000'000; CheatEngine::CheatEngine(Core::System& system_) : system(system_) { LoadCheatFile(); diff --git a/src/core/cheats/gateway_cheat.cpp b/src/core/cheats/gateway_cheat.cpp index cba74bb7c..b36309d26 100644 --- a/src/core/cheats/gateway_cheat.cpp +++ b/src/core/cheats/gateway_cheat.cpp @@ -28,14 +28,18 @@ struct State { bool loop_flag = false; }; -template +template static inline std::enable_if_t> WriteOp(const GatewayCheat::CheatLine& line, const State& state, + ReadFunction read_func, WriteFunction write_func, Core::System& system) { u32 addr = line.address + state.offset; - write_func(addr, static_cast(line.value)); - system.InvalidateCacheRange(addr, sizeof(T)); + T val = read_func(addr); + if (val != static_cast(line.value)) { + write_func(addr, static_cast(line.value)); + system.InvalidateCacheRange(addr, sizeof(T)); + } } template @@ -99,13 +103,16 @@ static inline void SetValueOp(const GatewayCheat::CheatLine& line, State& state) state.reg = line.value; } -template +template static inline std::enable_if_t> IncrementiveWriteOp( - const GatewayCheat::CheatLine& line, State& state, WriteFunction write_func, - Core::System& system) { + const GatewayCheat::CheatLine& line, State& state, ReadFunction read_func, + WriteFunction write_func, Core::System& system) { u32 addr = line.value + state.offset; - write_func(addr, static_cast(state.reg)); - system.InvalidateCacheRange(addr, sizeof(T)); + T val = read_func(addr); + if (val != static_cast(state.reg)) { + write_func(addr, static_cast(state.reg)); + system.InvalidateCacheRange(addr, sizeof(T)); + } state.offset += sizeof(T); } @@ -273,15 +280,15 @@ void GatewayCheat::Execute(Core::System& system) const { break; case CheatType::Write32: // 0XXXXXXX YYYYYYYY - word[XXXXXXX+offset] = YYYYYYYY - WriteOp(line, state, Write32, system); + WriteOp(line, state, Read32, Write32, system); break; case CheatType::Write16: // 1XXXXXXX 0000YYYY - half[XXXXXXX+offset] = YYYY - WriteOp(line, state, Write16, system); + WriteOp(line, state, Read16, Write16, system); break; case CheatType::Write8: // 2XXXXXXX 000000YY - byte[XXXXXXX+offset] = YY - WriteOp(line, state, Write8, system); + WriteOp(line, state, Read8, Write8, system); break; case CheatType::GreaterThan32: // 3XXXXXXX YYYYYYYY - Execute next block IF YYYYYYYY > word[XXXXXXX] ;unsigned @@ -367,17 +374,17 @@ void GatewayCheat::Execute(Core::System& system) const { } case CheatType::IncrementiveWrite32: { // D6000000 XXXXXXXX – (32bit) [XXXXXXXX+offset] = reg ; offset += 4 - IncrementiveWriteOp(line, state, Write32, system); + IncrementiveWriteOp(line, state, Read32, Write32, system); break; } case CheatType::IncrementiveWrite16: { // D7000000 XXXXXXXX – (16bit) [XXXXXXXX+offset] = reg & 0xffff ; offset += 2 - IncrementiveWriteOp(line, state, Write16, system); + IncrementiveWriteOp(line, state, Read16, Write16, system); break; } case CheatType::IncrementiveWrite8: { // D8000000 XXXXXXXX – (16bit) [XXXXXXXX+offset] = reg & 0xff ; offset++ - IncrementiveWriteOp(line, state, Write8, system); + IncrementiveWriteOp(line, state, Read8, Write8, system); break; } case CheatType::Load32: {