mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-07 06:35:40 +12:00
96 lines
No EOL
2.1 KiB
C++
96 lines
No EOL
2.1 KiB
C++
#include "cheats.hpp"
|
|
#include "swap.hpp"
|
|
|
|
Cheats::Cheats(Memory& mem, HIDService& hid) : ar(mem, hid) { reset(); }
|
|
|
|
void Cheats::reset() {
|
|
clear(); // Clear loaded cheats
|
|
ar.reset(); // Reset ActionReplay
|
|
}
|
|
|
|
u32 Cheats::addCheat(const Cheat& cheat) {
|
|
cheatsLoaded = true;
|
|
|
|
// Find an empty slot if a cheat was previously removed
|
|
for (size_t i = 0; i < cheats.size(); i++) {
|
|
if (cheats[i].type == CheatType::None) {
|
|
cheats[i] = cheat;
|
|
return i;
|
|
}
|
|
}
|
|
|
|
// Otherwise, just add a new slot
|
|
cheats.push_back(cheat);
|
|
return cheats.size() - 1;
|
|
}
|
|
|
|
u32 Cheats::addCheat(const u8* data, size_t size) {
|
|
if ((size % 8) != 0) {
|
|
return badCheatHandle;
|
|
}
|
|
|
|
Cheats::Cheat cheat;
|
|
cheat.enabled = true;
|
|
cheat.type = Cheats::CheatType::ActionReplay;
|
|
|
|
for (size_t i = 0; i < size; i += 8) {
|
|
auto read32 = [](const u8* ptr) { return (u32(ptr[3]) << 24) | (u32(ptr[2]) << 16) | (u32(ptr[1]) << 8) | u32(ptr[0]); };
|
|
|
|
// Data is passed to us in big endian so we bswap
|
|
u32 firstWord = Common::swap32(read32(data + i));
|
|
u32 secondWord = Common::swap32(read32(data + i + 4));
|
|
cheat.instructions.insert(cheat.instructions.end(), {firstWord, secondWord});
|
|
}
|
|
|
|
return addCheat(cheat);
|
|
}
|
|
|
|
void Cheats::removeCheat(u32 id) {
|
|
if (id >= cheats.size()) {
|
|
return;
|
|
}
|
|
|
|
// Not using std::erase because we don't want to invalidate cheat IDs
|
|
cheats[id].type = CheatType::None;
|
|
cheats[id].instructions.clear();
|
|
|
|
// Check if no cheats are loaded
|
|
for (const auto& cheat : cheats) {
|
|
if (cheat.type != CheatType::None) return;
|
|
}
|
|
|
|
cheatsLoaded = false;
|
|
}
|
|
|
|
void Cheats::enableCheat(u32 id) {
|
|
if (id < cheats.size()) {
|
|
cheats[id].enabled = true;
|
|
}
|
|
}
|
|
|
|
void Cheats::disableCheat(u32 id) {
|
|
if (id < cheats.size()) {
|
|
cheats[id].enabled = false;
|
|
}
|
|
}
|
|
|
|
void Cheats::clear() {
|
|
cheats.clear();
|
|
cheatsLoaded = false;
|
|
}
|
|
|
|
void Cheats::run() {
|
|
for (const Cheat& cheat : cheats) {
|
|
if (!cheat.enabled) continue;
|
|
|
|
switch (cheat.type) {
|
|
case CheatType::ActionReplay: {
|
|
ar.runCheat(cheat.instructions);
|
|
break;
|
|
}
|
|
|
|
case CheatType::None: break;
|
|
default: Helpers::panic("Unknown cheat device!");
|
|
}
|
|
}
|
|
} |