Improve performance of applying cheats; Set correct interval for applying cheats (#5305)

This commit is contained in:
Ben 2020-06-20 20:20:31 +02:00 committed by GitHub
parent 902cc1eb49
commit cb44e4408d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 15 deletions

View file

@ -15,7 +15,9 @@
namespace Cheats { 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_) { CheatEngine::CheatEngine(Core::System& system_) : system(system_) {
LoadCheatFile(); LoadCheatFile();

View file

@ -28,14 +28,18 @@ struct State {
bool loop_flag = false; bool loop_flag = false;
}; };
template <typename T, typename WriteFunction> template <typename T, typename ReadFunction, typename WriteFunction>
static inline std::enable_if_t<std::is_integral_v<T>> WriteOp(const GatewayCheat::CheatLine& line, static inline std::enable_if_t<std::is_integral_v<T>> WriteOp(const GatewayCheat::CheatLine& line,
const State& state, const State& state,
ReadFunction read_func,
WriteFunction write_func, WriteFunction write_func,
Core::System& system) { Core::System& system) {
u32 addr = line.address + state.offset; u32 addr = line.address + state.offset;
write_func(addr, static_cast<T>(line.value)); T val = read_func(addr);
system.InvalidateCacheRange(addr, sizeof(T)); if (val != static_cast<T>(line.value)) {
write_func(addr, static_cast<T>(line.value));
system.InvalidateCacheRange(addr, sizeof(T));
}
} }
template <typename T, typename ReadFunction, typename CompareFunc> template <typename T, typename ReadFunction, typename CompareFunc>
@ -99,13 +103,16 @@ static inline void SetValueOp(const GatewayCheat::CheatLine& line, State& state)
state.reg = line.value; state.reg = line.value;
} }
template <typename T, typename WriteFunction> template <typename T, typename ReadFunction, typename WriteFunction>
static inline std::enable_if_t<std::is_integral_v<T>> IncrementiveWriteOp( static inline std::enable_if_t<std::is_integral_v<T>> IncrementiveWriteOp(
const GatewayCheat::CheatLine& line, State& state, WriteFunction write_func, const GatewayCheat::CheatLine& line, State& state, ReadFunction read_func,
Core::System& system) { WriteFunction write_func, Core::System& system) {
u32 addr = line.value + state.offset; u32 addr = line.value + state.offset;
write_func(addr, static_cast<T>(state.reg)); T val = read_func(addr);
system.InvalidateCacheRange(addr, sizeof(T)); if (val != static_cast<T>(state.reg)) {
write_func(addr, static_cast<T>(state.reg));
system.InvalidateCacheRange(addr, sizeof(T));
}
state.offset += sizeof(T); state.offset += sizeof(T);
} }
@ -273,15 +280,15 @@ void GatewayCheat::Execute(Core::System& system) const {
break; break;
case CheatType::Write32: case CheatType::Write32:
// 0XXXXXXX YYYYYYYY - word[XXXXXXX+offset] = YYYYYYYY // 0XXXXXXX YYYYYYYY - word[XXXXXXX+offset] = YYYYYYYY
WriteOp<u32>(line, state, Write32, system); WriteOp<u32>(line, state, Read32, Write32, system);
break; break;
case CheatType::Write16: case CheatType::Write16:
// 1XXXXXXX 0000YYYY - half[XXXXXXX+offset] = YYYY // 1XXXXXXX 0000YYYY - half[XXXXXXX+offset] = YYYY
WriteOp<u16>(line, state, Write16, system); WriteOp<u16>(line, state, Read16, Write16, system);
break; break;
case CheatType::Write8: case CheatType::Write8:
// 2XXXXXXX 000000YY - byte[XXXXXXX+offset] = YY // 2XXXXXXX 000000YY - byte[XXXXXXX+offset] = YY
WriteOp<u8>(line, state, Write8, system); WriteOp<u8>(line, state, Read8, Write8, system);
break; break;
case CheatType::GreaterThan32: case CheatType::GreaterThan32:
// 3XXXXXXX YYYYYYYY - Execute next block IF YYYYYYYY > word[XXXXXXX] ;unsigned // 3XXXXXXX YYYYYYYY - Execute next block IF YYYYYYYY > word[XXXXXXX] ;unsigned
@ -367,17 +374,17 @@ void GatewayCheat::Execute(Core::System& system) const {
} }
case CheatType::IncrementiveWrite32: { case CheatType::IncrementiveWrite32: {
// D6000000 XXXXXXXX (32bit) [XXXXXXXX+offset] = reg ; offset += 4 // D6000000 XXXXXXXX (32bit) [XXXXXXXX+offset] = reg ; offset += 4
IncrementiveWriteOp<u32>(line, state, Write32, system); IncrementiveWriteOp<u32>(line, state, Read32, Write32, system);
break; break;
} }
case CheatType::IncrementiveWrite16: { case CheatType::IncrementiveWrite16: {
// D7000000 XXXXXXXX (16bit) [XXXXXXXX+offset] = reg & 0xffff ; offset += 2 // D7000000 XXXXXXXX (16bit) [XXXXXXXX+offset] = reg & 0xffff ; offset += 2
IncrementiveWriteOp<u16>(line, state, Write16, system); IncrementiveWriteOp<u16>(line, state, Read16, Write16, system);
break; break;
} }
case CheatType::IncrementiveWrite8: { case CheatType::IncrementiveWrite8: {
// D8000000 XXXXXXXX (16bit) [XXXXXXXX+offset] = reg & 0xff ; offset++ // D8000000 XXXXXXXX (16bit) [XXXXXXXX+offset] = reg & 0xff ; offset++
IncrementiveWriteOp<u8>(line, state, Write8, system); IncrementiveWriteOp<u8>(line, state, Read8, Write8, system);
break; break;
} }
case CheatType::Load32: { case CheatType::Load32: {