mirror of
https://github.com/SourMesen/Mesen.git
synced 2025-04-02 10:52:48 -04:00
Added cheat code support - Supports Game Genie, Pro Action Rocky and Custom codes
This commit is contained in:
parent
8bff3c7283
commit
c895d1252e
20 changed files with 338 additions and 542 deletions
|
@ -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
37
Core/CheatManager.h
Normal 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);
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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>
|
|
@ -10,6 +10,8 @@ enum class ConsoleNotificationType
|
|||
GameResumed = 4,
|
||||
GameStopped = 5,
|
||||
CodeBreak = 6,
|
||||
CheatAdded = 7,
|
||||
CheatRemoved = 8
|
||||
};
|
||||
|
||||
class INotificationListener
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace Mesen.GUI.Config
|
|||
public ServerInfo ServerInfo;
|
||||
public List<string> RecentFiles;
|
||||
public List<CheatInfo> Cheats;
|
||||
public bool ShowOnlyCheatsForCurrentGame;
|
||||
|
||||
public Configuration()
|
||||
{
|
||||
|
|
15
GUI.NET/Forms/Cheats/frmCheat.Designer.cs
generated
15
GUI.NET/Forms/Cheats/frmCheat.Designer.cs
generated
|
@ -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";
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
3
GUI.NET/Forms/Cheats/frmCheatList.Designer.cs
generated
3
GUI.NET/Forms/Cheats/frmCheatList.Designer.cs
generated
|
@ -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";
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(); }
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue