From f88b3921f96a10b33a9ff63face6758b1f2d896c Mon Sep 17 00:00:00 2001 From: Souryo Date: Sun, 5 Jul 2015 19:06:06 -0400 Subject: [PATCH] Added missing cheat-related files --- Core/CheatManager.cpp | 157 +++++++++++++++++++++++++ GUI.NET/Forms/Cheats/frmCheatList.resx | 123 +++++++++++++++++++ 2 files changed, 280 insertions(+) create mode 100644 Core/CheatManager.cpp create mode 100644 GUI.NET/Forms/Cheats/frmCheatList.resx diff --git a/Core/CheatManager.cpp b/Core/CheatManager.cpp new file mode 100644 index 00000000..82d9e8a9 --- /dev/null +++ b/Core/CheatManager.cpp @@ -0,0 +1,157 @@ +#include "stdafx.h" + +#include "CheatManager.h" +#include "Console.h" +#include "MessageManager.h" + +CheatManager* CheatManager::Instance = new CheatManager(); + +CheatManager::CheatManager() +{ + for(int i = 0; i <= 0xFFFF; i++) { + _relativeCheatCodes.push_back(nullptr); + } +} + +uint32_t CheatManager::DecodeValue(uint32_t code, uint32_t* bitIndexes, uint32_t bitCount) +{ + uint32_t result = 0; + for(uint32_t i = 0; i < bitCount; i++) { + result <<= 1; + result |= (code >> bitIndexes[i]) & 0x01; + } + return result; +} + +CodeInfo CheatManager::GetGGCodeInfo(string ggCode) +{ + string ggLetters = "APZLGITYEOXUKSVN"; + + uint32_t rawCode = 0; + for(int i = 0, len = ggCode.size(); i < len; i++) { + rawCode |= ggLetters.find(ggCode[i]) << (i * 4); + } + + CodeInfo code = { 0 }; + code.IsRelativeAddress = true; + code.CompareValue = -1; + uint32_t addressBits[15] = { 14, 13, 12, 19, 22, 21, 20, 7, 10, 9, 8, 15, 18, 17, 16 }; + uint32_t valueBits[8] = { 3, 6, 5, 4, 23, 2, 1, 0 }; + if(ggCode.size() == 8) { + //Bit 5 of the value is stored in a different location for 8-character codes + valueBits[5] = 31; + + uint32_t compareValueBits[8] = { 27, 30, 29, 28, 23, 26, 25, 24 }; + code.CompareValue = DecodeValue(rawCode, compareValueBits, 8); + } + code.Address = DecodeValue(rawCode, addressBits, 15) + 0x8000; + code.Value = DecodeValue(rawCode, valueBits, 8); + + return code; +} + +CodeInfo CheatManager::GetPARCodeInfo(uint32_t parCode) +{ + uint32_t shiftValues[31] = { + 3, 13, 14, 1, 6, 9, 5, 0, 12, 7, 2, 8, 10, 11, 4, //address + 19, 21, 23, 22, 20, 17, 16, 18, //compare + 29, 31, 24, 26, 25, 30, 27, 28 //value + }; + uint32_t key = 0x7E5EE93A; + uint32_t xorValue = 0x5C184B91; + + //Throw away bit 0, not used. + parCode >>= 1; + + uint32_t result = 0; + for(int32_t i = 30; i >= 0; i--) { + if(((key ^ parCode) >> 30) & 0x01) { + result |= 0x01 << shiftValues[i]; + key ^= xorValue; + } + parCode <<= 1; + key <<= 1; + } + + CodeInfo code = { 0 }; + code.IsRelativeAddress = true; + code.Address = (result & 0x7fff) + 0x8000; + code.Value = (result >> 24) & 0xFF; + code.CompareValue = (result >> 16) & 0xFF; + + return code; +} + +void CheatManager::AddCode(CodeInfo &code) +{ + if(code.IsRelativeAddress) { + if(_relativeCheatCodes[code.Address] == nullptr) { + _relativeCheatCodes[code.Address].reset(new vector()); + } + _relativeCheatCodes[code.Address]->push_back(code); + } else { + _absoluteCheatCodes.push_back(code); + MessageManager::SendNotification(ConsoleNotificationType::CheatAdded); + } +} + +void CheatManager::AddGameGenieCode(string code) +{ + Instance->AddCode(Instance->GetGGCodeInfo(code)); +} + +void CheatManager::AddProActionRockyCode(uint32_t code) +{ + Instance->AddCode(Instance->GetPARCodeInfo(code)); +} + +void CheatManager::AddCustomCode(uint32_t address, uint8_t value, int32_t compareValue, bool isRelativeAddress) +{ + CodeInfo code; + code.Address = address; + code.Value = value; + code.CompareValue = compareValue; + code.IsRelativeAddress = isRelativeAddress; + + Instance->AddCode(code); +} + +void CheatManager::ClearCodes() +{ + for(int i = 0; i <= 0xFFFF; i++) { + Instance->_relativeCheatCodes[i] = nullptr; + } + + bool sendNotification = Instance->_absoluteCheatCodes.size() > 0; + Instance->_absoluteCheatCodes.clear(); + if(sendNotification) { + MessageManager::SendNotification(ConsoleNotificationType::CheatRemoved); + } +} + +void CheatManager::ApplyRamCodes(uint16_t addr, uint8_t &value) +{ + if(Instance->_relativeCheatCodes[addr] != nullptr) { + for(uint32_t i = 0, len = i < Instance->_relativeCheatCodes[addr]->size(); i < len; i++) { + CodeInfo code = Instance->_relativeCheatCodes[addr]->at(i); + if(code.CompareValue == -1 || code.CompareValue == value) { + value = code.Value; + return; + } + } + } +} + +void CheatManager::ApplyPrgCodes(uint8_t *prgRam, uint32_t prgSize) +{ + Console::Pause(); + for(uint32_t i = 0, len = i < Instance->_absoluteCheatCodes.size(); i < len; i++) { + CodeInfo code = Instance->_absoluteCheatCodes[i]; + if(code.Address < prgSize) { + if(code.CompareValue == -1 || code.CompareValue == prgRam[code.Address]) { + prgRam[code.Address] = code.Value; + } + } + } + Console::Resume(); +} \ No newline at end of file diff --git a/GUI.NET/Forms/Cheats/frmCheatList.resx b/GUI.NET/Forms/Cheats/frmCheatList.resx new file mode 100644 index 00000000..5211f46c --- /dev/null +++ b/GUI.NET/Forms/Cheats/frmCheatList.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file