Added cheat code support - Supports Game Genie, Pro Action Rocky and Custom codes

This commit is contained in:
Souryo 2015-07-05 19:05:33 -04:00
parent 8bff3c7283
commit c895d1252e
20 changed files with 338 additions and 542 deletions

View file

@ -6,14 +6,17 @@
#include "ROMLoader.h"
#include <assert.h>
#include "../Utilities/FolderUtilities.h"
#include "CheatManager.h"
#include "MessageManager.h"
class BaseMapper : public IMemoryHandler, public Snapshotable
class BaseMapper : public IMemoryHandler, public Snapshotable, public INotificationListener
{
protected:
const int ExpansionRAMSize = 0x2000;
const int SRAMSize = 0x2000;
uint8_t* _prgRAM;
uint8_t* _originalPrgRam;
uint8_t* _chrRAM;
uint32_t _prgSize;
uint32_t _chrSize;
@ -110,6 +113,11 @@ class BaseMapper : public IMemoryHandler, public Snapshotable
{
return FolderUtilities::GetSaveFolder() + _romFilename + L".sav";
}
void RestoreOriginalPrgRam()
{
memcpy(_prgRAM, _originalPrgRam, GetPRGSize());
}
protected:
virtual void StreamState(bool saving)
@ -145,8 +153,9 @@ class BaseMapper : public IMemoryHandler, public Snapshotable
void Initialize(ROMLoader &romLoader)
{
_mirroringType = romLoader.GetMirroringType();
_prgRAM = romLoader.GetPRGRam();
_chrRAM = romLoader.GetCHRRam();
romLoader.GetPRGRam(&_prgRAM);
romLoader.GetPRGRam(&_originalPrgRam);
romLoader.GetCHRRam(&_chrRAM);
_prgSize = romLoader.GetPRGSize();
_chrSize = romLoader.GetCHRSize();
_hasBattery = romLoader.HasBattery();
@ -190,6 +199,10 @@ class BaseMapper : public IMemoryHandler, public Snapshotable
_prgPageMask = GetPRGPageSize() - 1;
InitMapper();
MessageManager::RegisterNotificationListener(this);
ApplyCheats();
}
virtual ~BaseMapper()
@ -199,11 +212,30 @@ class BaseMapper : public IMemoryHandler, public Snapshotable
}
delete[] _prgRAM;
delete[] _chrRAM;
delete[] _originalPrgRam;
delete[] _prgSlotPages;
delete[] _chrSlotPages;
delete[] _SRAM;
delete[] _expansionRAM;
MessageManager::UnregisterNotificationListener(this);
}
void ProcessNotification(ConsoleNotificationType type)
{
switch(type) {
case ConsoleNotificationType::CheatAdded:
case ConsoleNotificationType::CheatRemoved:
ApplyCheats();
break;
}
}
void ApplyCheats()
{
RestoreOriginalPrgRam();
CheatManager::ApplyPrgCodes(_prgRAM, GetPRGSize());
}
void GetMemoryRanges(MemoryRanges &ranges)

37
Core/CheatManager.h Normal file
View file

@ -0,0 +1,37 @@
#pragma once
#include "stdafx.h"
#include <unordered_set>
using std::unordered_set;
struct CodeInfo
{
uint32_t Address;
uint8_t Value;
int32_t CompareValue;
bool IsRelativeAddress;
};
class CheatManager
{
private:
static CheatManager* Instance;
vector<unique_ptr<vector<CodeInfo>>> _relativeCheatCodes;
vector<CodeInfo> _absoluteCheatCodes;
uint32_t DecodeValue(uint32_t code, uint32_t* bitIndexes, uint32_t bitCount);
CodeInfo GetGGCodeInfo(string ggCode);
CodeInfo GetPARCodeInfo(uint32_t parCode);
void AddCode(CodeInfo &code);
public:
CheatManager();
static void AddGameGenieCode(string code);
static void AddProActionRockyCode(uint32_t code);
static void AddCustomCode(uint32_t address, uint8_t value, int32_t compareValue = -1, bool isRelativeAddress = true);
static void ClearCodes();
static void ApplyRamCodes(uint16_t addr, uint8_t &value);
static void ApplyPrgCodes(uint8_t *prgRam, uint32_t prgSize);
};

View file

@ -11,8 +11,6 @@
shared_ptr<Console> Console::Instance = nullptr;
uint32_t Console::Flags = 0;
uint32_t Console::CurrentFPS = 0;
SimpleLock Console::PauseLock;
SimpleLock Console::RunningLock;
Console::Console(wstring filename)
{
@ -34,6 +32,7 @@ shared_ptr<Console> Console::GetInstance()
void Console::Initialize(wstring filename)
{
MessageManager::SendNotification(ConsoleNotificationType::GameStopped);
if(Console::Instance == nullptr) {
Console::Instance.reset(this);
}
@ -110,22 +109,22 @@ void Console::Stop()
{
_stop = true;
Console::ClearFlags(EmulationFlags::Paused);
Console::RunningLock.Acquire();
Console::RunningLock.Release();
Console::Instance->_stopLock.Acquire();
Console::Instance->_stopLock.Release();
}
void Console::Pause()
{
Console::PauseLock.Acquire();
Console::Instance->_pauseLock.Acquire();
//Spin wait until emu pauses
Console::RunningLock.Acquire();
Console::Instance->_runLock.Acquire();
}
void Console::Resume()
{
Console::RunningLock.Release();
Console::PauseLock.Release();
Console::Instance->_runLock.Release();
Console::Instance->_pauseLock.Release();
}
void Console::SetFlags(int flags)
@ -156,7 +155,8 @@ void Console::Run()
double elapsedTime = 0;
double targetTime = 16.6666666666666666;
Console::RunningLock.Acquire();
_runLock.Acquire();
_stopLock.Acquire();
while(true) {
bool frameDone = _apu->Exec(_cpu->Exec());
@ -174,19 +174,19 @@ void Console::Run()
}
}
if(!Console::PauseLock.IsFree()) {
if(!_pauseLock.IsFree()) {
//Need to temporarely pause the emu (to save/load a state, etc.)
Console::RunningLock.Release();
_runLock.Release();
//Spin wait until we are allowed to start again
Console::PauseLock.WaitForRelease();
_pauseLock.WaitForRelease();
Console::RunningLock.Acquire();
_runLock.Acquire();
}
if(CheckFlag(EmulationFlags::Paused) && !_stop) {
MessageManager::SendNotification(ConsoleNotificationType::GamePaused);
Console::RunningLock.Release();
_runLock.Release();
//Prevent audio from looping endlessly while game is paused
_apu->StopAudio();
@ -195,7 +195,7 @@ void Console::Run()
//Sleep until emulation is resumed
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(100));
}
Console::RunningLock.Acquire();
_runLock.Acquire();
MessageManager::SendNotification(ConsoleNotificationType::GameResumed);
}
clockTimer.Reset();
@ -217,8 +217,9 @@ void Console::Run()
fpsTimer.Reset();
}
}
Console::RunningLock.Release();
_apu->StopAudio();
_stopLock.Release();
_runLock.Release();
}
void Console::SaveState(ostream &saveStream)
@ -259,64 +260,3 @@ shared_ptr<Debugger> Console::GetDebugger()
{
return shared_ptr<Debugger>(new Debugger(Console::Instance, _cpu, _ppu, _memoryManager, _mapper));
}
bool Console::RunTest(uint8_t *expectedResult)
{
Timer timer;
uint8_t maxWait = 60;
uint8_t* lastFrameBuffer = new uint8_t[256 * 240 * 4];
bool result = false;
Console::RunningLock.Acquire();
while(true) {
if(_apu->Exec(_cpu->Exec())) {
_cpu->EndFrame();
}
if(timer.GetElapsedMS() > 100) {
if(memcmp(_ppu->GetFrameBuffer(), expectedResult, 256 * 240 * 4) == 0) {
result = true;
break;
}
timer.Reset();
if(memcmp(lastFrameBuffer, _ppu->GetFrameBuffer(), 256 * 240 * 4) != 0) {
memcpy(lastFrameBuffer, _ppu->GetFrameBuffer(), 256 * 240 * 4);
maxWait = 60;
}
maxWait--;
if(maxWait == 0) {
result = false;
break;
}
}
}
Console::RunningLock.Release();
delete[] lastFrameBuffer;
return result;
}
void Console::SaveTestResult()
{
wstring filename = _romFilepath + L".trt";
ofstream testResultFile(filename, ios::out | ios::binary);
if(!testResultFile) {
throw std::exception("File could not be opened");
}
uint8_t* buffer = new uint8_t[256 * 240 * 4];
memcpy(buffer, _ppu->GetFrameBuffer(), 256 * 240 * 4);
testResultFile.write((char *)buffer, 256 * 240 * 4);
testResultFile.close();
delete[] buffer;
}

View file

@ -23,8 +23,9 @@ class Console
static shared_ptr<Console> Instance;
static uint32_t Flags;
static uint32_t CurrentFPS;
static SimpleLock PauseLock;
static SimpleLock RunningLock;
SimpleLock _pauseLock;
SimpleLock _runLock;
SimpleLock _stopLock;
shared_ptr<CPU> _cpu;
shared_ptr<PPU> _ppu;
@ -54,9 +55,6 @@ class Console
//Used to resume the emu loop after calling Pause()
static void Resume();
bool RunTest(uint8_t* expectedResult);
void SaveTestResult();
shared_ptr<Debugger> Console::GetDebugger();
static void SaveState(ostream &saveStream);

View file

@ -94,6 +94,7 @@
<ClInclude Include="AXROM.h" />
<ClInclude Include="BaseMapper.h" />
<ClInclude Include="Breakpoint.h" />
<ClInclude Include="CheatManager.h" />
<ClInclude Include="ClientConnectionData.h" />
<ClInclude Include="CNROM.h" />
<ClInclude Include="ColorDreams.h" />
@ -155,6 +156,7 @@
<ItemGroup>
<ClCompile Include="APU.cpp" />
<ClCompile Include="Breakpoint.cpp" />
<ClCompile Include="CheatManager.cpp" />
<ClCompile Include="Console.cpp" />
<ClCompile Include="ControlManager.cpp" />
<ClCompile Include="Debugger.cpp" />

View file

@ -215,6 +215,9 @@
<ClInclude Include="MessageManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CheatManager.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CPU.cpp">
@ -280,5 +283,8 @@
<ClCompile Include="MessageManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CheatManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -10,6 +10,8 @@ enum class ConsoleNotificationType
GameResumed = 4,
GameStopped = 5,
CodeBreak = 6,
CheatAdded = 7,
CheatRemoved = 8
};
class INotificationListener

View file

@ -50,16 +50,12 @@ shared_ptr<BaseMapper> MapperFactory::InitializeFromFile(wstring filename)
if(loader.LoadFile(filename)) {
uint8_t mapperID = loader.GetMapperID();
BaseMapper* mapper = GetMapperFromID(mapperID);
shared_ptr<BaseMapper> mapper(GetMapperFromID(mapperID));
if(mapper) {
mapper->Initialize(loader);
return shared_ptr<BaseMapper>(mapper);
} else {
loader.FreeMemory();
return nullptr;
return mapper;
}
} else {
return nullptr;
}
return nullptr;
}

View file

@ -2,6 +2,7 @@
#include "MemoryManager.h"
#include "BaseMapper.h"
#include "Debugger.h"
#include "CheatManager.h"
MemoryManager::MemoryManager(shared_ptr<BaseMapper> mapper)
{
@ -114,6 +115,7 @@ uint8_t MemoryManager::Read(uint16_t addr, bool forExecution)
value = ReadRegister(addr);
}
CheatManager::ApplyRamCodes(addr, value);
return value;
}

View file

@ -144,6 +144,18 @@ class ROMLoader
{
}
~ROMLoader()
{
if(_prgRAM) {
delete[] _prgRAM;
_prgRAM = nullptr;
}
if(_chrRAM) {
delete[] _chrRAM;
_chrRAM = nullptr;
}
}
bool LoadFile(wstring filename)
{
bool result = false;
@ -169,26 +181,16 @@ class ROMLoader
return result;
}
void FreeMemory()
void GetPRGRam(uint8_t** buffer)
{
if(_prgRAM) {
delete[] _prgRAM;
_prgRAM = nullptr;
}
if(_chrRAM) {
delete[] _chrRAM;
_chrRAM = nullptr;
}
*buffer = new uint8_t[GetPRGSize()];
memcpy(*buffer, _prgRAM, GetPRGSize());
}
uint8_t* GetPRGRam()
void GetCHRRam(uint8_t** buffer)
{
return _prgRAM;
}
uint8_t* GetCHRRam()
{
return _chrRAM;
*buffer = new uint8_t[GetCHRSize()];
memcpy(*buffer, _chrRAM, GetCHRSize());
}
uint32_t GetPRGSize()
@ -227,7 +229,6 @@ class ROMLoader
uint32_t crc = 0;
if(loader.LoadFile(filename)) {
crc = loader._crc32;
loader.FreeMemory();
}
return crc;
}

View file

@ -15,12 +15,13 @@ namespace Mesen.GUI.Config
public class CheatInfo
{
public bool Enabled;
public bool Enabled = true;
public string CheatName;
public string GameName;
public string GameHash;
public CheatType CheatType;
public string Code;
public string GameGenieCode;
public UInt32 ProActionRockyCode;
public UInt32 Address;
public Byte Value;
public Byte CompareValue;
@ -28,10 +29,57 @@ namespace Mesen.GUI.Config
public override string ToString()
{
if(CheatType == CheatType.Custom) {
return !IsRelativeAddress ? "!" : "" + string.Format("{0:X4}:{1:X2}:{2:X2}", Address, Value, CompareValue);
} else {
return Code;
switch(CheatType) {
case CheatType.Custom:
return (!IsRelativeAddress ? "!" : "") + string.Format("{0:X4}:{1:X2}:{2:X2}", Address, Value, CompareValue);
case Config.CheatType.GameGenie:
return "GG: " + GameGenieCode;
case Config.CheatType.ProActionRocky:
return "PRA: " + ProActionRockyCode.ToString("X");
}
return string.Empty;
}
public void ApplyCheat()
{
switch(CheatType) {
case CheatType.Custom:
InteropEmu.CheatAddCustom(Address, Value, CompareValue, IsRelativeAddress);
break;
case Config.CheatType.GameGenie:
InteropEmu.CheatAddGameGenie(GameGenieCode);
break;
case Config.CheatType.ProActionRocky:
InteropEmu.CheatAddProActionRocky(ProActionRockyCode);
break;
}
}
public static void ClearCheats()
{
InteropEmu.CheatClear();
}
public static void ApplyCheats()
{
InteropEmu.CheatClear();
string romPath = InteropEmu.GetROMPath();
string md5Hash = MD5Helper.GetMD5Hash(romPath);
int cheatCount = 0;
foreach(CheatInfo cheat in ConfigManager.Config.Cheats.Where(c => c.GameHash == md5Hash)) {
if(cheat.Enabled) {
cheat.ApplyCheat();
cheatCount++;
}
}
if(cheatCount == 1) {
InteropEmu.DisplayMessage("Cheats", "1 cheat applied.");
} else if(cheatCount > 1) {
InteropEmu.DisplayMessage("Cheats", cheatCount.ToString() + " cheats applied.");
}
}
}

View file

@ -17,6 +17,7 @@ namespace Mesen.GUI.Config
public ServerInfo ServerInfo;
public List<string> RecentFiles;
public List<CheatInfo> Cheats;
public bool ShowOnlyCheatsForCurrentGame;
public Configuration()
{

View file

@ -27,7 +27,6 @@
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmCheat));
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
@ -111,7 +110,6 @@
this.txtCheatName.Name = "txtCheatName";
this.txtCheatName.Size = new System.Drawing.Size(304, 20);
this.txtCheatName.TabIndex = 2;
this.txtCheatName.TextChanged += new System.EventHandler(this.txtBox_TextChanged);
//
// grpCode
//
@ -155,7 +153,6 @@
this.radCustom.TabIndex = 3;
this.radCustom.Text = "Custom:";
this.radCustom.UseVisualStyleBackColor = true;
this.radCustom.CheckedChanged += new System.EventHandler(this.radType_CheckedChanged);
//
// txtProActionRocky
//
@ -164,7 +161,6 @@
this.txtProActionRocky.Name = "txtProActionRocky";
this.txtProActionRocky.Size = new System.Drawing.Size(71, 20);
this.txtProActionRocky.TabIndex = 1;
this.txtProActionRocky.TextChanged += new System.EventHandler(this.txtBox_TextChanged);
this.txtProActionRocky.Enter += new System.EventHandler(this.txtProActionRocky_Enter);
//
// txtGameGenie
@ -174,7 +170,6 @@
this.txtGameGenie.Name = "txtGameGenie";
this.txtGameGenie.Size = new System.Drawing.Size(71, 20);
this.txtGameGenie.TabIndex = 1;
this.txtGameGenie.TextChanged += new System.EventHandler(this.txtBox_TextChanged);
this.txtGameGenie.Enter += new System.EventHandler(this.txtGameGenie_Enter);
//
// radGameGenie
@ -188,7 +183,6 @@
this.radGameGenie.TabStop = true;
this.radGameGenie.Text = "Game Genie:";
this.radGameGenie.UseVisualStyleBackColor = true;
this.radGameGenie.CheckedChanged += new System.EventHandler(this.radType_CheckedChanged);
//
// radProActionRocky
//
@ -199,7 +193,6 @@
this.radProActionRocky.TabIndex = 2;
this.radProActionRocky.Text = "Pro Action Rocky:";
this.radProActionRocky.UseVisualStyleBackColor = true;
this.radProActionRocky.CheckedChanged += new System.EventHandler(this.radType_CheckedChanged);
//
// tlpCustom
//
@ -242,7 +235,6 @@
this.txtAddress.Name = "txtAddress";
this.txtAddress.Size = new System.Drawing.Size(69, 20);
this.txtAddress.TabIndex = 1;
this.txtAddress.TextChanged += new System.EventHandler(this.txtBox_TextChanged);
this.txtAddress.Enter += new System.EventHandler(this.customField_Enter);
//
// lblNewValue
@ -306,7 +298,6 @@
this.txtValue.Name = "txtValue";
this.txtValue.Size = new System.Drawing.Size(30, 20);
this.txtValue.TabIndex = 5;
this.txtValue.TextChanged += new System.EventHandler(this.txtBox_TextChanged);
this.txtValue.Enter += new System.EventHandler(this.customField_Enter);
//
// txtCompare
@ -316,7 +307,6 @@
this.txtCompare.Name = "txtCompare";
this.txtCompare.Size = new System.Drawing.Size(30, 20);
this.txtCompare.TabIndex = 6;
this.txtCompare.TextChanged += new System.EventHandler(this.txtBox_TextChanged);
//
// flowLayoutPanel3
//
@ -328,10 +318,10 @@
this.flowLayoutPanel3.Size = new System.Drawing.Size(310, 26);
this.flowLayoutPanel3.TabIndex = 5;
//
// txtGame
// txtGameName
//
this.txtGameName.Location = new System.Drawing.Point(3, 3);
this.txtGameName.Name = "txtGame";
this.txtGameName.Name = "txtGameName";
this.txtGameName.ReadOnly = true;
this.txtGameName.Size = new System.Drawing.Size(223, 20);
this.txtGameName.TabIndex = 0;
@ -363,7 +353,6 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(385, 294);
this.Controls.Add(this.tableLayoutPanel2);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximumSize = new System.Drawing.Size(401, 332);
this.MinimumSize = new System.Drawing.Size(401, 332);
this.Name = "frmCheat";

View file

@ -21,19 +21,40 @@ namespace Mesen.GUI.Forms.Cheats
private string _gameHash;
CheatInfo _originalCheat;
public frmCheat(CheatInfo cheat)
{
InitializeComponent();
_originalCheat = cheat;
if(cheat != null) {
UpdateUI(cheat);
}
Entity = cheat;
_gameHash = cheat.GameHash;
radGameGenie.Tag = CheatType.GameGenie;
radProActionRocky.Tag = CheatType.ProActionRocky;
radCustom.Tag = CheatType.Custom;
radRelativeAddress.Tag = true;
radAbsoluteAddress.Tag = false;
AddBinding("Enabled", chkEnabled);
AddBinding("CheatName", txtCheatName);
AddBinding("GameName", txtGameName);
AddBinding("CheatType", radGameGenie.Parent);
AddBinding("GameGenieCode", txtGameGenie);
AddBinding("ProActionRockyCode", txtProActionRocky);
AddBinding("Address", txtAddress);
AddBinding("Value", txtValue);
AddBinding("CompareValue", txtCompare);
AddBinding("IsRelativeAddress", radRelativeAddress.Parent);
UpdateUI();
UpdateOKButton();
}
protected override Type BindedType
{
get { return typeof(CheatInfo); }
}
protected override bool ApplyChangesOnOK
{
get { return false; }
@ -41,30 +62,13 @@ namespace Mesen.GUI.Forms.Cheats
protected override void UpdateConfig()
{
if(ConfigManager.Config.Cheats.Contains(_originalCheat)) {
ConfigManager.Config.Cheats.Remove(_originalCheat);
}
ConfigManager.Config.Cheats.Add(GetCheatInfo());
UpdateObject();
((CheatInfo)Entity).GameHash = _gameHash;
}
private void UpdateOKButton()
{
btnOK.Enabled = this.IsValidInput();
}
private string GetMD5Hash(string filename)
{
var md5 = System.Security.Cryptography.MD5.Create();
if(filename.EndsWith(".nes", StringComparison.InvariantCultureIgnoreCase)) {
return BitConverter.ToString(md5.ComputeHash(File.ReadAllBytes(filename))).Replace("-", "");
} else if(filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) {
foreach(var entry in ZipFile.OpenRead(filename).Entries) {
if(entry.Name.EndsWith(".nes", StringComparison.InvariantCultureIgnoreCase)) {
return BitConverter.ToString(md5.ComputeHash(entry.Open())).Replace("-", "");
}
}
}
return null;
btnOK.Enabled = true; //this.IsValidInput();
}
private void btnBrowse_Click(object sender, EventArgs e)
@ -72,7 +76,7 @@ namespace Mesen.GUI.Forms.Cheats
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "All supported formats (*.nes, *.zip)|*.NES;*.ZIP|NES Roms (*.nes)|*.NES|ZIP Archives (*.zip)|*.ZIP";
if(ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
_gameHash = GetMD5Hash(ofd.FileName);
_gameHash = MD5Helper.GetMD5Hash(ofd.FileName);
if(_gameHash != null) {
txtGameName.Text = Path.GetFileNameWithoutExtension(ofd.FileName);
UpdateOKButton();
@ -80,10 +84,39 @@ namespace Mesen.GUI.Forms.Cheats
}
}
public bool IsValidInput()
protected override bool ValidateInput()
{
if(radCustom.Checked) {
UInt32 val;
UInt32 val;
if(_gameHash == null) {
return false;
}
if(string.IsNullOrWhiteSpace(txtGameName.Text)) {
return false;
}
if(string.IsNullOrWhiteSpace(txtCheatName.Text)) {
return false;
}
if(radGameGenie.Checked) {
if(txtGameGenie.Text.Length != frmCheat.GGShortCodeLength && txtGameGenie.Text.Length != frmCheat.GGLongCodeLength) {
return false;
}
if(txtGameGenie.Text.Count(c => !"APZLGITYEOXUKSVN".Contains(c.ToString().ToUpper())) > 0) {
return false;
}
} else if(radProActionRocky.Checked) {
if(txtProActionRocky.Text.Length != frmCheat.PARCodeLength) {
return false;
}
if(!UInt32.TryParse(txtProActionRocky.Text, System.Globalization.NumberStyles.AllowHexSpecifier, null, out val)) {
return false;
}
if(txtProActionRocky.Text.Count(c => !"1234567890ABCDEF".Contains(c.ToString().ToUpper())) > 0) {
return false;
}
} else {
Byte byteVal;
if(!UInt32.TryParse(txtAddress.Text, System.Globalization.NumberStyles.AllowHexSpecifier, null, out val)) {
return false;
@ -98,102 +131,22 @@ namespace Mesen.GUI.Forms.Cheats
}
}
CheatInfo cheat;
try {
cheat = this.GetCheatInfo();
} catch {
return false;
}
if(cheat.GameHash == null) {
return false;
}
if(string.IsNullOrWhiteSpace(cheat.CheatName)) {
return false;
}
if(cheat.CheatType == CheatType.GameGenie) {
if(cheat.Code.Length != frmCheat.GGShortCodeLength && cheat.Code.Length != frmCheat.GGLongCodeLength) {
return false;
}
} else if(cheat.CheatType == CheatType.ProActionRocky) {
if(cheat.Code.Length != frmCheat.PARCodeLength) {
return false;
}
}
return true;
}
public CheatInfo GetCheatInfo()
{
return new CheatInfo() {
Enabled = chkEnabled.Checked,
CheatName = txtCheatName.Text,
GameName = txtGameName.Text,
GameHash = _gameHash,
CheatType = radGameGenie.Checked ? CheatType.GameGenie : radProActionRocky.Checked ? CheatType.ProActionRocky : CheatType.Custom,
Code = (radGameGenie.Checked ? txtGameGenie.Text : txtProActionRocky.Text).ToUpper(),
Address = radCustom.Checked ? UInt32.Parse(txtAddress.Text, System.Globalization.NumberStyles.AllowHexSpecifier) : 0,
Value = radCustom.Checked ? Byte.Parse(txtValue.Text, System.Globalization.NumberStyles.AllowHexSpecifier) : (byte)0,
CompareValue = radCustom.Checked ? Byte.Parse(txtCompare.Text, System.Globalization.NumberStyles.AllowHexSpecifier) : (byte)0,
IsRelativeAddress = radRelativeAddress.Checked
};
}
private void UpdateUI(CheatInfo cheat)
{
chkEnabled.Checked = cheat.Enabled;
txtCheatName.Text = cheat.CheatName;
txtGameName.Text = cheat.GameName;
_gameHash = cheat.GameHash;
switch(cheat.CheatType) {
case CheatType.GameGenie:
radGameGenie.Checked = true;
txtGameGenie.Text = cheat.Code;
break;
case CheatType.ProActionRocky:
radProActionRocky.Checked = true;
txtProActionRocky.Text = cheat.Code;
break;
case CheatType.Custom:
radCustom.Checked = true;
txtAddress.Text = cheat.Address.ToString("X");
txtValue.Text = cheat.Value.ToString("X");
txtCompare.Text = cheat.CompareValue.ToString("X");
radAbsoluteAddress.Checked = !cheat.IsRelativeAddress;
radRelativeAddress.Checked = cheat.IsRelativeAddress;
break;
}
}
private void txtBox_TextChanged(object sender, EventArgs e)
{
UpdateOKButton();
}
private void txtGameGenie_Enter(object sender, EventArgs e)
{
radGameGenie.Checked = true;
UpdateOKButton();
}
private void txtProActionRocky_Enter(object sender, EventArgs e)
{
radProActionRocky.Checked = true;
UpdateOKButton();
}
private void customField_Enter(object sender, EventArgs e)
{
radCustom.Checked = true;
UpdateOKButton();
}
private void radType_CheckedChanged(object sender, EventArgs e)
{
UpdateOKButton();
}
}
}

View file

@ -117,293 +117,4 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAMAEBAAAAAAGABoAwAANgAAACAgAAAAABgAqAwAAJ4DAABAQAAAAAAYACgyAABGEAAAKAAAABAA
AAAgAAAAAQAYAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAANPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT
09PT09PT09PT09PT0/////////////////////////7+/v7+/v///////////////////////9PT09PT
0////////////+np6cHBwaamppubm5qamqWlpb6+vuTk5P///////////9PT09PT0/////j4+Ly8vJqa
mpqamq2trb6+vr6+vq6urpubm5qamrW1tfT09P///9PT09PT0/b29qqqqpqamry8vPDw8Pz8/Ofn5+fn
5/z8/PPz88PDw5ubm6WlpfLy8tPT09PT07a2tpqamtbW1v///+Li4qKiopqampqamqKiouLi4v///9/f
35ubm7Ozs9PT09PT06WlpcPDw/////T09J6enp6enqmpqZqampqamp6envT09P///8XFxaWlpdPT09PT
0/f5/f7+/////9jY2JqamsTExO3t7ZqampqampqamtjY2P////7+//f5/dPT09PT0xxv/22i/////93d
3ZqamsbGxu/v75qampqampqamt3d3f///2mg/xxv/9PT09PT00CG/wRg/67L//v7+6mpqbq6uuHh4Zqa
mpqamqmpqfv7+5e9/wFf/0eL/9PT09PT093q/xtv/wJf/2mg/9ji9b29vaCgoKCgoL29vc/d9FeV/wBe
/yh3/+jw/9PT09PT0////+Pt/0SJ/wBe/wJf/zR//1uX/1qX/zF8/wFf/wBe/1eV/+70/////9PT09PT
0////////////7zU/1yY/x1w/wFf/wFf/x9x/2Kc/8jc/////////////9PT09PT0///////////////
//////////z9//z9/////////////////////////9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT
09PT09PT09PT09PT09PT09PT09PT0///AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABABgAAAAAAAAMAAAAAAAAAAAAAAAA
AAAAAAAA09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT
09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////09PT09PT////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////09PT09PT////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////09PT09PT////////////////////////////////////
/Pz84eHhycnJtra2qqqqpKSkpKSkqqqqtra2x8fH3t7e+fn5////////////////////////////////
////09PT09PT////////////////////////////7u7uwcHBn5+fmpqampqampqampqampqampqampqa
mpqampqampqanJycubm54+Pj////////////////////////////09PT09PT////////////////////
8/Pzvb29m5ubmpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqasLCw6Ojo
////////////////////09PT09PT////////////////2NjYn5+fmpqampqampqampqampqampqapqam
tbW1vb29vb29tbW1p6enmpqampqampqampqampqampqam5ubxcXF/Pz8////////////09PT09PT////
/////f39wcHBmpqampqampqampqampqarKys1NTU8/Pz////////////////////////9vb22tratbW1
mpqampqampqampqampqasLCw9vb2////////09PT09PT/////f39ubm5mpqampqampqampqaqqqq4eHh
////////////////////////////////////////////////7e3tt7e3mpqampqampqampqaq6ur9/f3
////09PT09PT////wcHBmpqampqampqampqayMjI/Pz8////////////7e3txMTEqqqqnZ2dnZ2dqqqq
xMTE7e3t////////////////29vbn5+fmpqampqampqatLS0/v7+09PT09PT3t7empqampqampqanJyc
3Nzc/////////////f39xsbGm5ubmpqampqampqampqampqampqam5ubxsbG/f39////////////7Ozs
o6Ojmpqampqampqa1tbW09PT09PTrKysmpqampqampqa3d3d/////////////v7+u7u7mpqampqampqa
mpqampqampqampqampqampqampqau7u7/v7+////////////6urqnZ2dmpqampqaqqqq09PT09PTnZ2d
mpqampqawcHB////////////////1dXVmpqampqampqampqampqampqampqampqampqampqampqampqa
1dXV////////////////xcXFmpqampqanZ2d09PT09PTz8/Pm5ubqKio8/Pz/////////////v7+pKSk
mpqampqampqavLy819fXpaWlmpqampqampqampqampqampqapaWl/v7+////////////8/PzqKiom5ub
0NDQ09PT09PT/////Pz8/v7+////////////////6+vrmpqampqampqanp6e/f39////19fXmpqampqa
mpqampqampqampqampqa6+vr/////////////////v7+/Pz8////09PT09PT////+Pr//v7/////////
////////3t7empqampqampqaoqKi////////3d3dmpqampqampqampqampqampqampqa3t7e////////
/////////v7/+Pr/////09PT09PTiLP/BWD/JXT/4ez/////////////4uLimpqampqampqaoqKi////
////3d3dmpqampqampqampqampqampqampqa4uLi////////////4ez/JXT/BWD/ibP/09PT09PTCmT/
AF7/AF7/b6P/////////////9vb2m5ubmpqampqaoqKi////////3d3dmpqampqampqampqampqampqa
m5ub9vb2////////////Y5z/AF7/AF7/CmT/09PT09PTKnj/AF7/AF7/B2L/zN7/////////////ubm5
mpqampqaoqKi////////3d3dmpqampqampqampqampqampqauLi4////////////qsj/AV//AF7/AF7/
Lnr/09PT09PTmr7/AF7/AF7/AF7/F2z/0eH/////////8PDwn5+fmpqam5ub8fHx////yMjImpqampqa
mpqampqampqan5+f8PDw////////qMf/BmH/AF7/AF7/AF7/rcv/09PT09PT/f3/Qof/AF7/AF7/AF7/
DWb/pcX/////////5eXloKCgmpqaoaGhsbGxmpqampqampqampqampqaoKCg5eXl////+fv/dqf/AV//
AF7/AF7/AF7/ZJz/////09PT09PT////7PL/Knj/AF7/AF7/AF7/AF7/Soz/0uL/////8fHxurq6m5ub
mpqampqampqampqam5uburq68fHx////tM//KXf/AF7/AF7/AF7/AF7/UI//+vz/////09PT09PT////
////6vH/OIH/AF7/AF7/AF7/AF7/AV//RYn/osP/6vH/9PT02trazs7Ozs7O2tra9PT04uz/k7r/L3v/
AF7/AF7/AF7/AF7/AF7/ZJz/+vz/////////09PT09PT////////////+Pr/bqP/Al//AF7/AF7/AF7/
AF7/AF7/AV7/InP/Ror/WJX/WZX/RYn/HnD/AF7/AF7/AF7/AF7/AF7/AF7/DWb/ncH/////////////
////09PT09PT////////////////////xtr/OIH/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/
AF7/AF7/AF7/AF7/AF7/Al//WZb/4u3/////////////////////09PT09PT////////////////////
////////utP/UJD/BmH/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/DWb/ZZ3/1OP/////////
////////////////////09PT09PT////////////////////////////////////8PX/rMr/cqX/R4r/
Knj/G27/G27/Knj/SYv/d6n/ttD/9vn/////////////////////////////////////09PT09PT////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////09PT09PT////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////09PT09PT////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////09PT09PT09PT09PT09PT09PT09PT
09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT
09PT09PT09PT09PT09PT09PTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAQAAAAIAAAAABABgAAAAAAAAwAAAAAAAAAAAAAAAA
AAAAAAAA09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT
09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT
09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT
09PT09PT09PT09PT09PT09PT09PT////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////09PT09PT////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////09PT09PT////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////09PT09PT////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////09PT09PT////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////09PT09PT////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////09PT09PT////////////////////////////////////
////////////////////////////////////////////////////////////+vr66Ojo2dnZzc3NxMTE
v7+/vLy8vLy8v7+/xcXFzc3N2NjY5ubm+Pj4////////////////////////////////////////////
////////////////////////////////////////////////////09PT09PT////////////////////
////////////////////////////////////////////////////////////+fn53d3dwsLCqqqqmpqa
mpqampqampqampqampqampqampqampqampqampqampqampqampqapaWlvLy81dXV8vLy////////////
////////////////////////////////////////////////////////////////////09PT09PT////
/////////////////////////////////////////////////////////////////Pz83Nzct7e3nJyc
mpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqa
mpqaq6urzc3N8/Pz////////////////////////////////////////////////////////////////
////09PT09PT////////////////////////////////////////////////////////////9fX1ysrK
oqKimpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqa
mpqampqampqampqampqampqampqam5ubtra24uLi////////////////////////////////////////
////////////////////09PT09PT////////////////////////////////////////////////////
9vb2xcXFnZ2dmpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqa
mpqampqampqampqampqampqampqampqampqampqampqampqampqampqara2t4ODg////////////////
////////////////////////////////////09PT09PT////////////////////////////////////
/////////f39z8/Pn5+fmpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqa
mpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqa
sbGx6+vr////////////////////////////////////////////09PT09PT////////////////////
////////////////////6Ojoqqqqmpqampqampqampqampqampqampqampqampqampqampqampqampqa
mpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqa
mpqampqampqampqampqam5ubxsbG+/v7////////////////////////////////////09PT09PT////
/////////////////////////////f39ysrKm5ubmpqampqampqampqampqampqampqampqampqampqa
mpqampqampqampqampqampqaoqKirq6utbW1uLi4uLi4tbW1rq6uo6Ojmpqampqampqampqampqampqa
mpqampqampqampqampqampqampqampqampqampqampqaqKio6urq////////////////////////////
////09PT09PT////////////////////////////9fX1sbGxmpqampqampqampqampqampqampqampqa
mpqampqampqampqampqanJyctLS0z8/P5eXl+fn5////////////////////////////////+/v76enp
1NTUvLy8oaGhmpqampqampqampqampqampqampqampqampqampqampqampqampqanJyc1tbW////////
////////////////////09PT09PT////////////////////////6+vrpKSkmpqampqampqampqampqa
mpqampqampqampqampqampqampqasrKy2NjY+fn5////////////////////////////////////////
/////////////////////////v7+5eXlwsLCn5+fmpqampqampqampqampqampqampqampqampqampqa
mpqampqaxcXF/v7+////////////////////09PT09PT////////////////////5OTkn5+fmpqampqa
mpqampqampqampqampqampqampqampqam5ubvr6+7Ozs////////////////////////////////////
////////////////////////////////////////////////////+vr61NTUpqammpqampqampqampqa
mpqampqampqampqampqampqampqavb29/v7+////////////////09PT09PT////////////////4+Pj
nZ2dmpqampqampqampqampqampqampqampqampqampqauLi47+/v////////////////////////////
/////////////////////////////////////////////////////////////////////////////f39
1dXVoqKimpqampqampqampqampqampqampqampqampqampqavb29/v7+////////////09PT09PT////
////////6OjonZ2dmpqampqampqampqampqampqampqampqampqapaWl4eHh////////////////////
////////////////////////+/v76enp3d3d19fX19fX3d3d6enp+/v7////////////////////////
////////////////////+fn5w8PDmpqampqampqampqampqampqampqampqampqampqaxsbG////////
////09PT09PT////////8vLyoaGhmpqampqampqampqampqampqampqampqampqavr6++fn5////////
////////////////////////////9vb20NDQsLCwm5ubmpqampqampqampqampqampqam5ubsLCw0NDQ
9vb2////////////////////////////////////////5OTkpKSkmpqampqampqampqampqampqampqa
mpqampqa29vb////////09PT09PT/////f39rq6umpqampqampqampqampqampqampqampqanJyc19fX
////////////////////////////////////9/f3xMTEnZ2dmpqampqampqampqampqampqampqampqa
mpqampqampqampqanZ2dxMTE9/f3////////////////////////////////////9vb2sbGxmpqampqa
mpqampqampqampqampqampqan5+f8/Pz////09PT09PT////zMzMmpqampqampqampqampqampqampqa
mpqaoKCg5ubm////////////////////////////////////39/foqKimpqampqampqampqampqampqa
mpqampqampqampqampqampqampqampqampqampqaoqKi39/f////////////////////////////////
/////Pz8urq6mpqampqampqampqampqampqampqampqau7u7////09PT09PT8/PznZ2dmpqampqampqa
mpqampqampqampqaoaGh7Ozs////////////////////////////////////zMzMmpqampqampqampqa
mpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqazMzM////////////
/////////////////////////f39urq6mpqampqampqampqampqampqampqampqa7Ozs09PT09PTx8fH
mpqampqampqampqampqampqampqanp6e6urq////////////////////////////////////ysrKmpqa
mpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqa
mpqaysrK/////////////////////////////////////Pz8sLCwmpqampqampqampqampqampqampqa
w8PD09PT09PTpaWlmpqampqampqampqampqampqampqa3t7e////////////////////////////////
////2dnZmpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqa
mpqampqampqampqampqampqa2dnZ////////////////////////////////////8/Pzn5+fmpqampqa
mpqampqampqampqapaWl09PT09PTm5ubmpqampqampqampqampqampqav7+/////////////////////
////////////////8/Pznp6empqampqampqampqampqampqampqampqampqampqampqampqampqampqa
mpqampqampqampqampqampqampqampqampqampqan5+f8/Pz////////////////////////////////
////zc3Nmpqampqampqampqampqampqam5ub09PT09PTrKysmpqampqampqampqampqam5ub8vLy////
////////////////////////////////vb29mpqampqampqampqampqampqampqampqampqampqampqa
mpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqavb29////////////////
////////////////////8/PzmpqampqampqampqampqampqarKys09PT09PT39/fmpqampqampqampqa
mpqawsLC////////////////////////////////////8fHxmpqampqampqampqampqampqampqampqa
mpqasLCwxcXFrq6umpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqam5ub
8fHx////////////////////////////////////wsLCmpqampqampqampqampqa39/f09PT09PT////
3d3dqKiompqaoKCgysrK/f39////////////////////////////////////zMzMmpqampqampqampqa
mpqampqampqampqazs7O////////////yMjImpqampqampqampqampqampqampqampqampqampqampqa
mpqampqampqampqazMzM/////////////////////////////////////f39ysrKoKCgmpqaqKio3d3d
////09PT09PT////////////+/v7/v7+////////////////////////////////////////////r6+v
mpqampqampqampqampqampqampqaqqqq/////////////////f39paWlmpqampqampqampqampqampqa
mpqampqampqampqampqampqampqampqar6+v////////////////////////////////////////////
/v7++/v7////////////09PT09PT////////////////////////////////////////////////////
/////////f39nJycmpqampqampqampqampqampqampqavb29////////////////////uLi4mpqampqa
mpqampqampqampqampqampqampqampqampqampqampqampqanJyc/v7+////////////////////////
////////////////////////////////////09PT09PT////////////////////////////////////
////////////////////////9PT0mpqampqampqampqampqampqampqampqavr6+////////////////
////ubm5mpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqa9PT0////////
////////////////////////////////////////////////////09PT09PT////////////+vz//f7/
////////////////////////////////////////7+/vmpqampqampqampqampqampqampqampqavr6+
////////////////////ubm5mpqampqampqampqampqampqampqampqampqampqampqampqampqampqa
mpqa7u7u/////////////////////////////////////////f7/+vz/////////////09PT09PT////
rMn/J3X/Al7/FGn/fKr/+/z/////////////////////////////////8/Pzmpqampqampqampqampqa
mpqampqampqavr6+////////////////////ubm5mpqampqampqampqampqampqampqampqampqampqa
mpqampqampqampqampqa8/Pz////////////////////////////////+/z/e6r/FGn/Al7/KHX/rMn/
////09PT09PTsMv/AV7/AF7/AF7/AF7/AF7/aJ7//////////////////////////////////Pz8m5ub
mpqampqampqampqampqampqampqavr6+////////////////////ubm5mpqampqampqampqampqampqa
mpqampqampqampqampqampqampqampqam5ub/f39////////////////////////////////aJ7/AF7/
AF7/AF7/AF7/Al//sMz/09PT09PTMHv/AF7/AF7/AF7/AF7/AF7/A1//4+3/////////////////////
////////////rKysmpqampqampqampqampqampqampqavr6+////////////////////ubm5mpqampqa
mpqampqampqampqampqampqampqampqampqampqampqampqarKys////////////////////////////
////3+r/Al7/AF7/AF7/AF7/AF7/AF7/MHv/09PT09PTBGD/AF7/AF7/AF7/AF7/AF7/AF7/hbD/////
////////////////////////////x8fHmpqampqampqampqampqampqampqavr6+////////////////
////ubm5mpqampqampqampqampqampqampqampqampqampqampqampqampqampqax8fH////////////
////////////////////YZr/AF7/AF7/AF7/AF7/AF7/AF7/BGD/09PT09PTHm//AF7/AF7/AF7/AF7/
AF7/AF7/D2b/4uz/////////////////////////////7Ozsmpqampqampqampqampqampqampqavr6+
////////////////////ubm5mpqampqampqampqampqampqampqampqampqampqampqampqampqampqa
7Ozs////////////////////////////rcr/AV7/AF7/AF7/AF7/AF7/AF7/AF7/HnD/09PT09PTaZ//
AF7/AF7/AF7/AF7/AF7/AF7/AF7/OoH/+Pr/////////////////////////////tbW1mpqampqampqa
mpqampqampqavr6+////////////////////ubm5mpqampqampqampqampqampqampqampqampqampqa
mpqampqampqatbW1////////////////////////////zN7/DGX/AF7/AF7/AF7/AF7/AF7/AF7/AF7/
dKX/09PT09PTz+D/AV7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/VZH//P3/////////////////////////
7e3tm5ubmpqampqampqampqampqauLi4////////////////////srKympqampqampqampqampqampqa
mpqampqampqampqampqampqanJyc7e3t////////////////////////0OD/FGn/AF7/AF7/AF7/AF7/
AF7/AF7/AF7/CWP/4+z/09PT09PT////VJH/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/VZH/+fv/////
////////////////////zs7OmpqampqampqampqampqanZ2d8vLy////////////7e3tm5ubmpqampqa
mpqampqampqampqampqampqampqampqampqampqazs7O////////////////////////wtf/EWj/AF7/
AF7/AF7/AF7/AF7/AF7/AF7/AF7/gK3/////09PT09PT////4ez/Dmb/AF7/AF7/AF7/AF7/AF7/AF7/
AF7/AF7/PYP/6fD//////////////////////v7+vb29mpqampqampqampqampqaqKio4+Pj+fn54ODg
paWlmpqampqampqampqampqampqampqampqampqampqampqampqavLy8/v7+////////////////////
nL//B2L/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/NH3/+vv/////09PT09PT////////pcX/AF7/AF7/
AF7/AF7/AF7/AF7/AF7/AF7/AF7/G27/vtX//////////////////////f39vb29mpqampqampqampqa
mpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqavb29/f39////////
////////8fb/Xpj/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/FWr/3+r/////////09PT09PT////
////////c6T/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/Al//bKD/8fb/////////////////////
0NDQnJycmpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqanJyc0NDQ
////////////////////ttD/H3D/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/CmT/xtr/////////
////09PT09PT/////////////f3/WZX/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/GGz/mL3/
+/z/////////////////7u7utra2mpqampqampqampqampqampqampqampqampqampqampqampqampqa
mpqatra27u7u////////////////2OX/T47/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/CWP/
utL/////////////////09PT09PT////////////////+vz/WZT/AF7/AF7/AF7/AF7/AF7/AF7/AF7/
AF7/AF7/AF7/AF7/InL/lbr/9Pj/////////////////6urqwsLCoqKimpqampqampqampqampqampqa
mpqampqaoqKiwsLC6urq////////////////0+L/XZf/BGD/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/
AF7/AF7/DWX/vdT/////////////////////09PT09PT/////////////////////P3/bqL/AF7/AF7/
AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/EGf/Z53/wdb//P3//////////////v7+7e3t2tra
zs7OyMjIyMjIzs7O2tra7e3t/v7+////////////8PX/oMH/P4T/AV7/AF7/AF7/AF7/AF7/AF7/AF7/
AF7/AF7/AF7/AF7/AF7/HG7/z9//////////////////////////09PT09PT////////////////////
////////mL3/BmH/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/FWr/WJT/lrv/
ytz/9fn/////////////////////////////////8fb/wdb/iLL/RIj/B2L/AF7/AF7/AF7/AF7/AF7/
AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/PYP/5+//////////////////////////////09PT09PT////
////////////////////////////zN7/JnT/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/
AF7/AF7/AF7/AF7/AF7/Al7/Gm3/NH3/Ron/To7/T47/R4n/NH3/GGz/AV3/AF7/AF7/AF7/AF7/AF7/
AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/A1//fKv/+/z/////////////////////////////
////09PT09PT////////////////////////////////////9Pj/cKP/Al//AF7/AF7/AF7/AF7/AF7/
AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/
AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/Knf/x9r/////////////////////
////////////////////09PT09PT////////////////////////////////////////////zd7/PIP/
AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/
AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/Dmb/ibP/+fv/////////
////////////////////////////////////09PT09PT////////////////////////////////////
/////////////v7/sc3/MXz/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/
AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/CWP/cKP/6fH/
////////////////////////////////////////////////////09PT09PT////////////////////
/////////////////////////////////////v//uNH/Sov/Al7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/
AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/FWr/
e6r/5+//////////////////////////////////////////////////////////////09PT09PT////
////////////////////////////////////////////////////////////////4Or/hLD/LXj/AV7/
AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/
BmH/TI3/qcf/9/r/////////////////////////////////////////////////////////////////
////09PT09PT////////////////////////////////////////////////////////////////////
////////////3en/l7z/V5P/HW//AV7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/AF7/
A17/KXb/Zp3/q8n/7/X/////////////////////////////////////////////////////////////
////////////////////09PT09PT////////////////////////////////////////////////////
/////////////////////////////////////////v//7PL/wtf/n8H/g6//bqL/YJn/WZT/WJT/X5n/
bqL/hLD/osP/x9r/8fb/////////////////////////////////////////////////////////////
////////////////////////////////////09PT09PT////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////09PT09PT////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////09PT09PT////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////09PT09PT////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////09PT09PT////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////09PT09PT////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////09PT09PT09PT09PT09PT09PT09PT
09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT
09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT
09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
</value>
</data>
</root>

View file

@ -29,7 +29,6 @@ namespace Mesen.GUI.Forms.Cheats
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmCheatList));
this.tabMain = new System.Windows.Forms.TabControl();
this.tabCheats = new System.Windows.Forms.TabPage();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
@ -99,6 +98,7 @@ namespace Mesen.GUI.Forms.Cheats
this.chkCurrentGameOnly.TabIndex = 0;
this.chkCurrentGameOnly.Text = "Only show cheats for the current game";
this.chkCurrentGameOnly.UseVisualStyleBackColor = true;
this.chkCurrentGameOnly.CheckedChanged += new System.EventHandler(this.chkCurrentGameOnly_CheckedChanged);
//
// lstCheats
//
@ -190,7 +190,6 @@ namespace Mesen.GUI.Forms.Cheats
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(443, 255);
this.Controls.Add(this.tableLayoutPanel2);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "frmCheatList";
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
this.Text = "Cheats";

View file

@ -17,7 +17,11 @@ namespace Mesen.GUI.Forms.Cheats
public frmCheatList()
{
InitializeComponent();
UpdateCheatList();
chkCurrentGameOnly.Checked = ConfigManager.Config.ShowOnlyCheatsForCurrentGame;
if(!chkCurrentGameOnly.Checked) {
UpdateCheatList();
}
}
protected override void OnLoad(EventArgs e)
@ -26,21 +30,31 @@ namespace Mesen.GUI.Forms.Cheats
Location = new Point(Owner.Location.X + (Owner.Width - Width) / 2, Owner.Location.Y + (Owner.Height - Height) / 2);
}
protected override void UpdateConfig()
{
ConfigManager.Config.ShowOnlyCheatsForCurrentGame = chkCurrentGameOnly.Checked;
}
private void UpdateCheatList()
{
string md5hash = MD5Helper.GetMD5Hash(InteropEmu.GetROMPath());
lstCheats.Items.Clear();
foreach(CheatInfo cheat in ConfigManager.Config.Cheats) {
ListViewItem item = lstCheats.Items.Add(cheat.GameName);
item.SubItems.AddRange(new string[] { cheat.CheatName, cheat.ToString() });
item.Tag = cheat;
item.Checked = cheat.Enabled;
if(!chkCurrentGameOnly.Checked || cheat.GameHash == md5hash) {
ListViewItem item = lstCheats.Items.Add(cheat.GameName);
item.SubItems.AddRange(new string[] { cheat.CheatName, cheat.ToString() });
item.Tag = cheat;
item.Checked = cheat.Enabled;
}
}
}
private void mnuAddCheat_Click(object sender, EventArgs e)
{
frmCheat frm = new frmCheat(null);
if(frm.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
CheatInfo newCheat = new CheatInfo();
frmCheat frm = new frmCheat(newCheat);
if(frm.ShowDialog() == DialogResult.OK) {
ConfigManager.Config.Cheats.Add(newCheat);
UpdateCheatList();
}
}
@ -49,7 +63,7 @@ namespace Mesen.GUI.Forms.Cheats
{
if(lstCheats.SelectedItems.Count == 1) {
frmCheat frm = new frmCheat((CheatInfo)lstCheats.SelectedItems[0].Tag);
if(frm.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
if(frm.ShowDialog() == DialogResult.OK) {
UpdateCheatList();
}
}
@ -61,5 +75,10 @@ namespace Mesen.GUI.Forms.Cheats
((CheatInfo)e.Item.Tag).Enabled = e.Item.Checked;
}
}
private void chkCurrentGameOnly_CheckedChanged(object sender, EventArgs e)
{
UpdateCheatList();
}
}
}

View file

@ -4,6 +4,7 @@ using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@ -27,16 +28,19 @@ namespace Mesen.GUI.Forms
Application.ThreadException += Application_ThreadException;
InitializeComponent();
InteropEmu.InitializeEmu(this.Handle, this.dxViewer.Handle);
InteropEmu.SetFlags((int)EmulationFlags.LimitFPS);
_notifListener = new InteropEmu.NotificationListener();
_notifListener.OnNotification += _notifListener_OnNotification;
InteropEmu.InitializeEmu(this.Handle, this.dxViewer.Handle);
InteropEmu.SetFlags((int)EmulationFlags.LimitFPS);
UpdateMenus();
UpdateRecentFiles();
StartRenderThread();
Icon = Properties.Resources.MesenIcon;
if(!DesignMode) {
Icon = Properties.Resources.MesenIcon;
}
}
void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
@ -47,7 +51,10 @@ namespace Mesen.GUI.Forms
void _notifListener_OnNotification(InteropEmu.NotificationEventArgs e)
{
if(e.NotificationType == InteropEmu.ConsoleNotificationType.GameLoaded) {
CheatInfo.ApplyCheats();
this.StartEmuThread();
} else if(e.NotificationType == InteropEmu.ConsoleNotificationType.GameStopped) {
CheatInfo.ClearCheats();
}
UpdateMenus();
}
@ -356,7 +363,12 @@ namespace Mesen.GUI.Forms
private void mnuCheats_Click(object sender, EventArgs e)
{
new frmCheatList().Show(this);
frmCheatList frm = new frmCheatList();
frm.Show(this);
frm.FormClosed += (object a, FormClosedEventArgs b) => {
frm = null;
CheatInfo.ApplyCheats();
};
}
}
}

View file

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
@ -18,6 +20,7 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void Resume();
[DllImport(DLLPath)] public static extern bool IsPaused();
[DllImport(DLLPath)] public static extern void Stop();
[DllImport(DLLPath, EntryPoint="GetROMPath")] private static extern IntPtr GetROMPathWrapper();
[DllImport(DLLPath)] public static extern void Reset();
[DllImport(DLLPath)] public static extern void SetFlags(int flags);
[DllImport(DLLPath)] public static extern void ClearFlags(int flags);
@ -27,11 +30,14 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void Connect(string host, UInt16 port, [MarshalAs(UnmanagedType.LPWStr)]string playerName, byte[] avatarData, UInt32 avatarSize);
[DllImport(DLLPath)] public static extern void Disconnect();
[DllImport(DLLPath)] public static extern bool IsConnected();
[DllImport(DLLPath)] public static extern void Render();
[DllImport(DLLPath)] public static extern void TakeScreenshot();
[DllImport(DLLPath)] public static extern IntPtr RegisterNotificationCallback(NotificationListener.NotificationCallback callback);
[DllImport(DLLPath)] public static extern void UnregisterNotificationCallback(IntPtr notificationListener);
[DllImport(DLLPath)] public static extern void TakeScreenshot();
[DllImport(DLLPath)] public static extern void DisplayMessage([MarshalAs(UnmanagedType.LPWStr)]string title, [MarshalAs(UnmanagedType.LPWStr)]string message);
[DllImport(DLLPath)] public static extern void MoviePlay([MarshalAs(UnmanagedType.LPWStr)]string filename);
[DllImport(DLLPath)] public static extern void MovieRecord([MarshalAs(UnmanagedType.LPWStr)]string filename, bool reset);
@ -43,6 +49,11 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void LoadState(UInt32 stateIndex);
[DllImport(DLLPath)] public static extern Int64 GetStateInfo(UInt32 stateIndex);
[DllImport(DLLPath)] public static extern void CheatAddCustom(UInt32 address, Byte value, Int32 compareValue, bool isRelativeAddress);
[DllImport(DLLPath)] public static extern void CheatAddGameGenie(string code);
[DllImport(DLLPath)] public static extern void CheatAddProActionRocky(UInt32 code);
[DllImport(DLLPath)] public static extern void CheatClear();
[DllImport(DLLPath)] public static extern void DebugInitialize();
[DllImport(DLLPath)] public static extern void DebugRelease();
[DllImport(DLLPath)] public static extern void DebugGetState(ref DebugState state);
@ -57,6 +68,10 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern Byte DebugGetMemoryValue(UInt32 addr);
[DllImport(DLLPath)] public static extern UInt32 DebugGetRelativeAddress(UInt32 addr);
public static string GetROMPath() { return Marshal.PtrToStringAuto(InteropEmu.GetROMPathWrapper()); }
public enum ConsoleNotificationType
{
GameLoaded = 0,
@ -192,4 +207,22 @@ namespace Mesen.GUI
Overflow = 0x40,
Negative = 0x80
}
public class MD5Helper
{
public static string GetMD5Hash(string filename)
{
var md5 = System.Security.Cryptography.MD5.Create();
if(filename.EndsWith(".nes", StringComparison.InvariantCultureIgnoreCase)) {
return BitConverter.ToString(md5.ComputeHash(File.ReadAllBytes(filename))).Replace("-", "");
} else if(filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) {
foreach(var entry in ZipFile.OpenRead(filename).Entries) {
if(entry.Name.EndsWith(".nes", StringComparison.InvariantCultureIgnoreCase)) {
return BitConverter.ToString(md5.ComputeHash(entry.Open())).Replace("-", "");
}
}
}
return null;
}
}
}

View file

@ -9,12 +9,14 @@
#include "../Core/GameClient.h"
#include "../Core/ClientConnectionData.h"
#include "../Core/SaveStateManager.h"
#include "../Core/CheatManager.h"
static NES::Renderer *_renderer = nullptr;
static SoundManager *_soundManager = nullptr;
static InputManager *_inputManager = nullptr;
static HWND _windowHandle = nullptr;
static HWND _viewerHandle = nullptr;
static wstring _romFilename;
typedef void (__stdcall *NotificationListenerCallback)(int);
@ -65,6 +67,12 @@ namespace InteropEmu {
Console::GetInstance()->Stop();
}
}
DllExport const wchar_t* __stdcall GetROMPath()
{
_romFilename = Console::GetROMPath();
return _romFilename.c_str();
}
DllExport void __stdcall Reset() { Console::Reset(); }
DllExport void __stdcall SetFlags(int flags) { Console::SetFlags(flags); }
DllExport void __stdcall ClearFlags(int flags) { Console::ClearFlags(flags); }
@ -117,6 +125,8 @@ namespace InteropEmu {
}
DllExport void __stdcall UnregisterNotificationCallback(INotificationListener *listener) { MessageManager::UnregisterNotificationListener(listener); }
DllExport void __stdcall DisplayMessage(wchar_t* title, wchar_t* message) { MessageManager::DisplayMessage(title, message); }
DllExport void __stdcall SaveState(uint32_t stateIndex) { SaveStateManager::SaveState(stateIndex); }
DllExport uint32_t __stdcall LoadState(uint32_t stateIndex) { return SaveStateManager::LoadState(stateIndex); }
DllExport int64_t __stdcall GetStateInfo(uint32_t stateIndex) { return SaveStateManager::GetStateInfo(stateIndex); }
@ -126,5 +136,10 @@ namespace InteropEmu {
DllExport void __stdcall MovieStop() { Movie::Stop(); }
DllExport int __stdcall MoviePlaying() { return Movie::Playing(); }
DllExport int __stdcall MovieRecording() { return Movie::Recording(); }
DllExport void __stdcall CheatAddCustom(uint32_t address, uint8_t value, int32_t compareValue, int isRelativeAddress) { CheatManager::AddCustomCode(address, value, compareValue, isRelativeAddress != 0); }
DllExport void __stdcall CheatAddGameGenie(char* code) { CheatManager::AddGameGenieCode(code); }
DllExport void __stdcall CheatAddProActionRocky(uint32_t code) { CheatManager::AddProActionRockyCode(code); }
DllExport void __stdcall CheatClear() { CheatManager::ClearCodes(); }
}
}