mirror of
https://github.com/SourMesen/Mesen.git
synced 2025-04-02 10:52:48 -04:00
Added missing cheat-related files
This commit is contained in:
parent
c895d1252e
commit
f88b3921f9
2 changed files with 280 additions and 0 deletions
157
Core/CheatManager.cpp
Normal file
157
Core/CheatManager.cpp
Normal file
|
@ -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<CodeInfo>());
|
||||
}
|
||||
_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();
|
||||
}
|
123
GUI.NET/Forms/Cheats/frmCheatList.resx
Normal file
123
GUI.NET/Forms/Cheats/frmCheatList.resx
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="contextMenuCheats.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
Loading…
Add table
Reference in a new issue