From 0b5fed62c1b92017ce43a87ba223763a75e7fbef Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Mon, 24 Nov 2008 19:11:15 +0000 Subject: [PATCH] ISOProperties.cpp can now toggle and remove cheats/patches. Still have to do add/edit. Put PatchEngine in it's own namespace, changed format of patches. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1289 8ced0084-cf51-0410-be5f-012b33b47a6e --- Data/User/GameConfig/G2ME01.ini | 2 - Data/User/GameConfig/G2MP01.ini | 2 - Data/User/GameConfig/GALP01.ini | 4 +- Data/User/GameConfig/GM8E01.ini | 2 - Data/User/GameConfig/GM8P01.ini | 2 - Data/User/GameConfig/GMSE01.ini | 2 - Data/User/GameConfig/GSNP8P.ini | 2 - Data/User/GameConfig/GZ2E01.ini | 2 - Data/User/GameConfig/GZLE01.ini | 28 +-- Data/User/GameConfig/GZLP01.ini | 28 +-- Source/Core/Core/Src/ActionReplay.cpp | 6 +- Source/Core/Core/Src/ActionReplay.h | 2 +- Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp | 7 +- Source/Core/Core/Src/Core.cpp | 4 +- Source/Core/Core/Src/HW/SystemTimers.cpp | 4 +- Source/Core/Core/Src/PatchEngine.cpp | 111 ++++++----- Source/Core/Core/Src/PatchEngine.h | 29 ++- Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp | 2 +- Source/Core/DolphinWX/Src/ISOProperties.cpp | 203 +++++++++++++++----- Source/Core/DolphinWX/Src/ISOProperties.h | 35 +++- 20 files changed, 308 insertions(+), 169 deletions(-) diff --git a/Data/User/GameConfig/G2ME01.ini b/Data/User/GameConfig/G2ME01.ini index 64542bb4c2..ab81243e8e 100644 --- a/Data/User/GameConfig/G2ME01.ini +++ b/Data/User/GameConfig/G2ME01.ini @@ -6,8 +6,6 @@ [EmuState] #The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 2 -[OnLoad] -#Add memory patches to be loaded once on boot here. [OnFrame] #Add memory patches to be applied every frame here. [ActionReplay] diff --git a/Data/User/GameConfig/G2MP01.ini b/Data/User/GameConfig/G2MP01.ini index 3fe3f87b8b..ab1ad5c703 100644 --- a/Data/User/GameConfig/G2MP01.ini +++ b/Data/User/GameConfig/G2MP01.ini @@ -7,8 +7,6 @@ [EmuState] #The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 2 -[OnLoad] -#Add memory patches to be loaded once on boot here. [OnFrame] #Add memory patches to be applied every frame here. [ActionReplay] diff --git a/Data/User/GameConfig/GALP01.ini b/Data/User/GameConfig/GALP01.ini index 3886b75355..5d9973c58e 100644 --- a/Data/User/GameConfig/GALP01.ini +++ b/Data/User/GameConfig/GALP01.ini @@ -4,11 +4,9 @@ [EmuState] #The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 4 -[OnLoad] -#Add memory patches to be loaded once on boot here. [OnFrame] #Add memory patches to be applied every frame here. -#0x8044CD30=dword:0xFFFFFFFF +0x8044CD30=dword:0xFFFFFFFF [ActionReplay] #Add action replay cheats here. $P1 - No Damage diff --git a/Data/User/GameConfig/GM8E01.ini b/Data/User/GameConfig/GM8E01.ini index 33c1229c1a..05e817a840 100644 --- a/Data/User/GameConfig/GM8E01.ini +++ b/Data/User/GameConfig/GM8E01.ini @@ -6,8 +6,6 @@ [EmuState] #The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 2 -[OnLoad] -#Add memory patches to be loaded once on boot here. [OnFrame] #Add memory patches to be applied every frame here. [ActionReplay] diff --git a/Data/User/GameConfig/GM8P01.ini b/Data/User/GameConfig/GM8P01.ini index 1658498f30..ecbea2b53a 100644 --- a/Data/User/GameConfig/GM8P01.ini +++ b/Data/User/GameConfig/GM8P01.ini @@ -7,8 +7,6 @@ [EmuState] #The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 2 -[OnLoad] -#Add memory patches to be loaded once on boot here. [OnFrame] #Add memory patches to be applied every frame here. [ActionReplay] diff --git a/Data/User/GameConfig/GMSE01.ini b/Data/User/GameConfig/GMSE01.ini index f0cfdf428e..d045b4231d 100644 --- a/Data/User/GameConfig/GMSE01.ini +++ b/Data/User/GameConfig/GMSE01.ini @@ -4,8 +4,6 @@ [EmuState] #The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 0 -[OnLoad] -#Add memory patches to be loaded once on boot here. [OnFrame] #Add memory patches to be applied every frame here. [ActionReplay] diff --git a/Data/User/GameConfig/GSNP8P.ini b/Data/User/GameConfig/GSNP8P.ini index 9c7083e89a..ebd741483d 100644 --- a/Data/User/GameConfig/GSNP8P.ini +++ b/Data/User/GameConfig/GSNP8P.ini @@ -4,8 +4,6 @@ [EmuState] #The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 5 -[OnLoad] -#Add memory patches to be loaded once on boot here. [OnFrame] #Add memory patches to be applied every frame here. [ActionReplay] diff --git a/Data/User/GameConfig/GZ2E01.ini b/Data/User/GameConfig/GZ2E01.ini index da5f176664..ee2e749239 100644 --- a/Data/User/GameConfig/GZ2E01.ini +++ b/Data/User/GameConfig/GZ2E01.ini @@ -4,8 +4,6 @@ [EmuState] #The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 2 -[OnLoad] -#Add memory patches to be loaded once on boot here. [OnFrame] #Add memory patches to be applied every frame here. [ActionReplay] diff --git a/Data/User/GameConfig/GZLE01.ini b/Data/User/GameConfig/GZLE01.ini index 9c881f3782..677704cc1b 100644 --- a/Data/User/GameConfig/GZLE01.ini +++ b/Data/User/GameConfig/GZLE01.ini @@ -4,22 +4,22 @@ [EmuState] #The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 2 -[OnLoad] -#Add memory patches to be loaded once on boot here. [OnFrame] #Add memory patches to be applied every frame here. -0x802904b4=dword:0x4E800020 #Fix item hang -#WARNING - cheats may screw up your save games -#0x803C4C09=byte:0x50 #Max health -#0x803C4C0B=byte:0x50 #Current health -#Hidden dungeon -#0x803C9D44=dword:0x000000FF -#0x803C9D48=dword:0x485F7465 -#0x803C9D4C=dword:0x73740000 -#Snow test room -#0x803C9D44=dword:0x000000FF -#0x803C9D48=dword:0x49546573 -#0x803C9D4C=dword:0x74363200 ++$Fix item hang +0x802904b4=dword:0x4E800020 +$Max health +0x803C4C09=byte:0x50 +$Current health +0x803C4C0B=byte:0x50 +$Hidden dungeon +0x803C9D44=dword:0x000000FF +0x803C9D48=dword:0x485F7465 +0x803C9D4C=dword:0x73740000 +$Snow test room +0x803C9D44=dword:0x000000FF +0x803C9D48=dword:0x49546573 +0x803C9D4C=dword:0x74363200 [ActionReplay] #Add action replay cheats here. #Codes by GCNHacker87 diff --git a/Data/User/GameConfig/GZLP01.ini b/Data/User/GameConfig/GZLP01.ini index 6d8bf5bcda..a14ef6eff1 100644 --- a/Data/User/GameConfig/GZLP01.ini +++ b/Data/User/GameConfig/GZLP01.ini @@ -4,22 +4,22 @@ [EmuState] #The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 2 -[OnLoad] -#Add memory patches to be loaded once on boot here. [OnFrame] #Add memory patches to be applied every frame here. -0x80295654=dword:0x4E800020 #Fix item hang -#WARNING - cheats may screw up your save games -#0x803C4C09=byte:0x50 #Max health -#0x803C4C0B=byte:0x50 #Current health -#Hidden dungeon -#0x803C9D44=dword:0x000000FF -#0x803C9D48=dword:0x485F7465 -#0x803C9D4C=dword:0x73740000 -#Snow test room -#0x803C9D44=dword:0x000000FF -#0x803C9D48=dword:0x49546573 -#0x803C9D4C=dword:0x74363200 ++$Fix item hang +0x80295654:dword:0x4E800020 +$Max health +0x803C4C09=byte:0x50 +$Current health +0x803C4C0B=byte:0x50 +$Hidden dungeon +0x803C9D44=dword:0x000000FF +0x803C9D48=dword:0x485F7465 +0x803C9D4C=dword:0x73740000 +$Snow test room +0x803C9D44=dword:0x000000FF +0x803C9D48=dword:0x49546573 +0x803C9D4C=dword:0x74363200 [ActionReplay] #Add action replay cheats here. $(M) diff --git a/Source/Core/Core/Src/ActionReplay.cpp b/Source/Core/Core/Src/ActionReplay.cpp index 253f1df534..0f0fa61ffd 100644 --- a/Source/Core/Core/Src/ActionReplay.cpp +++ b/Source/Core/Core/Src/ActionReplay.cpp @@ -65,10 +65,10 @@ bool NormalCode_Type_6(u8 subtype, u32 addr, u32 data, int *count, bool *skip); bool NormalCode_Type_7(u8 subtype, u32 addr, u32 data, int *count, bool *skip); // Parses the Action Replay section of a game ini file. -void LoadActionReplayCodes(IniFile &ini, bool bForGUI) +void LoadActionReplayCodes(IniFile &ini) { - if (!Core::GetStartupParameter().bEnableCheats && !bForGUI) - return; // If cheats are off, do not load them; but load anyway if it's for GameConfig GUI + if (!Core::GetStartupParameter().bEnableCheats) + return; // If cheats are off, do not load them std::vector lines; std::vector encryptedLines; diff --git a/Source/Core/Core/Src/ActionReplay.h b/Source/Core/Core/Src/ActionReplay.h index 4aba9af85c..ff98898c8f 100644 --- a/Source/Core/Core/Src/ActionReplay.h +++ b/Source/Core/Core/Src/ActionReplay.h @@ -32,6 +32,6 @@ struct ARCode { void ActionReplayRunAllActive(); bool RunActionReplayCode(const ARCode &arcode); -void LoadActionReplayCodes(IniFile &ini, bool bForGUI); +void LoadActionReplayCodes(IniFile &ini); #endif //_ACTIONREPLAY_H_ diff --git a/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp b/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp index 72286f5c34..0b68218aa4 100644 --- a/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp +++ b/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp @@ -153,10 +153,9 @@ void CBoot::EmulatedBIOS(bool _bDebug) LOG(MASTER_LOG, "call iAppLoaderClose"); RunFunction(iAppLoaderClose, _bDebug); - // Load patches and run startup patches + // Load patches std::string gameID = VolumeHandler::GetVolume()->GetUniqueID(); - PatchEngine_LoadPatches(gameID.c_str()); - PatchEngine_ApplyLoadPatches(); + PatchEngine::LoadPatches(gameID.c_str()); PowerPC::ppcState.DebugCount = 0; // return PC = PowerPC::ppcState.gpr[3]; @@ -359,7 +358,7 @@ bool CBoot::EmulatedBIOS_Wii(bool _bDebug) // Load patches and run startup patches std::string gameID = VolumeHandler::GetVolume()->GetUniqueID(); - PatchEngine_LoadPatches(gameID.c_str()); + PatchEngine::LoadPatches(gameID.c_str()); // return PC = PowerPC::ppcState.gpr[3]; diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index 469878154f..e6f0f74316 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -526,8 +526,8 @@ void Callback_VideoCopiedToXFB() frames = 0; Timer.Update(); } - PatchEngine_ApplyFramePatches(); - PatchEngine_ApplyARPatches(); + PatchEngine::ApplyFramePatches(); + PatchEngine::ApplyARPatches(); } // __________________________________________________________________________________________________ diff --git a/Source/Core/Core/Src/HW/SystemTimers.cpp b/Source/Core/Core/Src/HW/SystemTimers.cpp index 7da6cc1dec..e8482070d2 100644 --- a/Source/Core/Core/Src/HW/SystemTimers.cpp +++ b/Source/Core/Core/Src/HW/SystemTimers.cpp @@ -132,9 +132,9 @@ void VICallback(u64 userdata, int cyclesLate) void SICallback(u64 userdata, int cyclesLate) { // This is once per frame - good candidate for patching stuff - PatchEngine_ApplyFramePatches(); + PatchEngine::ApplyFramePatches(); // Apply AR cheats - PatchEngine_ApplyARPatches(); + PatchEngine::ApplyARPatches(); // OK, do what we are here to do. SerialInterface::UpdateDevices(); CoreTiming::ScheduleEvent(SI_PERIOD-cyclesLate, et_SI); diff --git a/Source/Core/Core/Src/PatchEngine.cpp b/Source/Core/Core/Src/PatchEngine.cpp index f54f1963de..50bdeb9643 100644 --- a/Source/Core/Core/Src/PatchEngine.cpp +++ b/Source/Core/Core/Src/PatchEngine.cpp @@ -31,46 +31,61 @@ #include #include "StringUtil.h" #include "PatchEngine.h" -#include "IniFile.h" #include "HW/Memmap.h" #include "ActionReplay.h" using namespace Common; -namespace +namespace PatchEngine { -std::vector onLoad; std::vector onFrame; std::map speedHacks; -static void LoadPatchSection(const char *section, std::vector &patches, IniFile &ini) +void LoadPatchSection(const char *section, std::vector &patches, IniFile &ini) { - std::vector keys; - ini.GetKeys(section, keys); + std::vector lines; + if (!ini.GetLines(section, lines)) + return; - for (std::vector::const_iterator iter = keys.begin(); iter != keys.end(); ++iter) + Patch currentPatch; + int index = 0; + + for (std::vector::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) { - std::string key = *iter; - std::string value; - ini.Get(section, key.c_str(), &value, "BOGUS"); - if (value != "BOGUS") + std::string line = *iter; + if (line.size()) { - std::string val(value); + if (line[0] == '+' || line[0] == '$') + { + // Take care of the previous code + if (currentPatch.name.size()) patches.push_back(currentPatch); + currentPatch.entries.clear(); + + // Set active and name + currentPatch.active = (line[0] == '+') ? true : false; + if (currentPatch.active) + currentPatch.name = line.substr(2, line.size() - 2); + else + currentPatch.name = line.substr(1, line.size() - 1); + continue; + } + std::vector items; - SplitString(val, ":", items); - if (items.size() >= 2) { - Patch p; + SplitString(line, ":", items); + if (items.size() >= 3) { + PatchEntry pE; bool success = true; - success = success && TryParseUInt(std::string(key.c_str()), &p.address); - success = success && TryParseUInt(items[1], &p.value); - p.type = (PatchType)ChooseStringFrom(items[0].c_str(), PatchTypeStrings); - success = success && (p.type != (PatchType)-1); + success = success && TryParseUInt(items[0], &pE.address); + success = success && TryParseUInt(items[2], &pE.value); + pE.type = (PatchType)ChooseStringFrom(items[1].c_str(), PatchTypeStrings); + success = success && (pE.type != (PatchType)-1); if (success) - patches.push_back(p); + currentPatch.entries.push_back(pE); } } } + if (currentPatch.name.size()) patches.push_back(currentPatch); } static void LoadSpeedhacks(const char *section, std::map &hacks, IniFile &ini) { @@ -95,10 +110,7 @@ static void LoadSpeedhacks(const char *section, std::map &hacks, IniFi } } -} // namespace - - -int PatchEngine_GetSpeedhackCycles(u32 addr) +int GetSpeedhackCycles(u32 addr) { std::map::const_iterator iter = speedHacks.find(addr); if (iter == speedHacks.end()) @@ -107,14 +119,13 @@ int PatchEngine_GetSpeedhackCycles(u32 addr) return iter->second; } -void PatchEngine_LoadPatches(const char *gameID) +void LoadPatches(const char *gameID) { IniFile ini; std::string filename = std::string(FULL_GAMECONFIG_DIR) + gameID + ".ini"; if (ini.Load(filename.c_str())) { - LoadPatchSection("OnLoad", onLoad, ini); LoadPatchSection("OnFrame", onFrame, ini); - LoadActionReplayCodes(ini, false); + LoadActionReplayCodes(ini); LoadSpeedhacks("Speedhacks", speedHacks, ini); } } @@ -123,37 +134,39 @@ void ApplyPatches(const std::vector &patches) { for (std::vector::const_iterator iter = patches.begin(); iter != patches.end(); ++iter) { - u32 addr = iter->address; - u32 value = iter->value; - switch (iter->type) + if (iter->active) { - case PATCH_8BIT: - Memory::Write_U8((u8)value, addr); - break; - case PATCH_16BIT: - Memory::Write_U16((u16)value, addr); - break; - case PATCH_32BIT: - Memory::Write_U32(value, addr); - break; - default: - //unknown patchtype - break; + for (std::vector::const_iterator iter2 = iter->entries.begin(); iter2 != iter->entries.end(); ++iter2) + { + u32 addr = iter2->address; + u32 value = iter2->value; + switch (iter2->type) + { + case PATCH_8BIT: + Memory::Write_U8((u8)value, addr); + break; + case PATCH_16BIT: + Memory::Write_U16((u16)value, addr); + break; + case PATCH_32BIT: + Memory::Write_U32(value, addr); + break; + default: + //unknown patchtype + break; + } + } } } } -void PatchEngine_ApplyLoadPatches() -{ - ApplyPatches(onLoad); -} - -void PatchEngine_ApplyFramePatches() +void ApplyFramePatches() { ApplyPatches(onFrame); } -void PatchEngine_ApplyARPatches() +void ApplyARPatches() { ActionReplayRunAllActive(); } +} // namespace diff --git a/Source/Core/Core/Src/PatchEngine.h b/Source/Core/Core/Src/PatchEngine.h index 4f843cb194..f01f670365 100644 --- a/Source/Core/Core/Src/PatchEngine.h +++ b/Source/Core/Core/Src/PatchEngine.h @@ -18,6 +18,11 @@ #ifndef _PATCHENGINE_H #define _PATCHENGINE_H +#include "IniFile.h" + +namespace PatchEngine +{ + enum PatchType { PATCH_8BIT, @@ -33,19 +38,27 @@ static const char *PatchTypeStrings[] = 0 }; -struct Patch +struct PatchEntry { - Patch() {} - Patch(PatchType _t, u32 _addr, u32 _value) : type(_t), address(_addr), value(_value) {} + PatchEntry() {} + PatchEntry(PatchType _t, u32 _addr, u32 _value) : type(_t), address(_addr), value(_value) {} PatchType type; u32 address; u32 value; }; -void PatchEngine_LoadPatches(const char *gameID); -void PatchEngine_ApplyLoadPatches(); -void PatchEngine_ApplyFramePatches(); -void PatchEngine_ApplyARPatches(); -int PatchEngine_GetSpeedhackCycles(u32 addr); +struct Patch +{ + std::string name; + std::vector entries; + bool active; +}; + +int GetSpeedhackCycles(u32 addr); +void LoadPatchSection(const char *section, std::vector &patches, IniFile &ini); +void LoadPatches(const char *gameID); +void ApplyFramePatches(); +void ApplyARPatches(); +} // namespace #endif //_PATCHENGINE_H diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index d992392524..08bedae23f 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -372,7 +372,7 @@ namespace Jit64 gpr.Start(js.gpa); fpr.Start(js.fpa); - js.downcountAmount = js.st.numCycles + PatchEngine_GetSpeedhackCycles(emaddress); + js.downcountAmount = js.st.numCycles + PatchEngine::GetSpeedhackCycles(emaddress); js.blockSize = size; // Translate instructions for (int i = 0; i < (int)size; i++) diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index 4990d67635..a6c41a0385 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -21,6 +21,12 @@ #include "VolumeCreator.h" #include "Filesystem.h" #include "ISOProperties.h" +#include "PatchEngine.h" + +DiscIO::IVolume *OpenISO = NULL; +DiscIO::IFileSystem *pFileSystem = NULL; + +std::vector onFrame; struct ARListCode { std::string name; @@ -28,22 +34,27 @@ struct ARListCode { std::vector ops; u32 uiIndex; }; +std::vector ARCodes; BEGIN_EVENT_TABLE(CISOProperties, wxDialog) EVT_CLOSE(CISOProperties::OnClose) EVT_BUTTON(ID_CLOSE, CISOProperties::OnCloseClick) + EVT_BUTTON(ID_EDITCONFIG, CISOProperties::OnEditConfig) EVT_CHOICE(ID_EMUSTATE, CISOProperties::SetRefresh) + EVT_LISTBOX(ID_PATCHES_LIST, CISOProperties::ListSelectionChanged) + EVT_BUTTON(ID_EDITPATCH, CISOProperties::PatchButtonClicked) + EVT_BUTTON(ID_ADDPATCH, CISOProperties::PatchButtonClicked) + EVT_BUTTON(ID_REMOVEPATCH, CISOProperties::PatchButtonClicked) + EVT_LISTBOX(ID_CHEATS_LIST, CISOProperties::ListSelectionChanged) + EVT_BUTTON(ID_EDITCHEAT, CISOProperties::ActionReplayButtonClicked) + EVT_BUTTON(ID_ADDCHEAT, CISOProperties::ActionReplayButtonClicked) + EVT_BUTTON(ID_REMOVECHEAT, CISOProperties::ActionReplayButtonClicked) EVT_MENU(IDM_BNRSAVEAS, CISOProperties::OnBannerImageSave) EVT_TREE_ITEM_RIGHT_CLICK(ID_TREECTRL, CISOProperties::OnRightClickOnTree) EVT_MENU(IDM_EXTRACTFILE, CISOProperties::OnExtractFile) EVT_MENU(IDM_EXTRACTDIR, CISOProperties::OnExtractDir) - EVT_BUTTON(ID_EDITCONFIG, CISOProperties::OnEditConfig) END_EVENT_TABLE() -DiscIO::IVolume *OpenISO = NULL; -DiscIO::IFileSystem *pFileSystem = NULL; -std::vector ARCodes; - CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style) : wxDialog(parent, id, title, position, size, style) { @@ -66,7 +77,6 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW fprintf(f, "# %s - %s\n", OpenISO->GetUniqueID().c_str(), OpenISO->GetName().c_str()); fprintf(f, "[Core]\n#Values set here will override the main dolphin settings.\n"); fprintf(f, "[EmuState]\n#The Emulation State. 1 is worst, 5 is best, 0 is not set.\n"); - fprintf(f, "[OnLoad]\n#Add memory patches to be loaded once on boot here.\n"); fprintf(f, "[OnFrame]\n#Add memory patches to be applied every frame here.\n"); fprintf(f, "[ActionReplay]\n#Add action replay cheats here.\n"); fclose(f); @@ -120,7 +130,6 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW m_Treectrl->Expand(RootId); SetTitle(wxString::Format(_("Properties: %s - %s"), OpenISO_.GetUniqueID().c_str(), OpenISO_.GetName().c_str())); - Fit(); } CISOProperties::~CISOProperties() @@ -187,6 +196,11 @@ void CISOProperties::CreateGUIControls() m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize); m_GameConfig = new wxPanel(m_Notebook, ID_GAMECONFIG, wxDefaultPosition, wxDefaultSize); m_Notebook->AddPage(m_GameConfig, _("GameConfig")); + m_GameConfig_Notebook = new wxNotebook(m_GameConfig, ID_GAMECONFIG_NOTEBOOK, wxDefaultPosition, wxDefaultSize); + m_PatchPage = new wxPanel(m_GameConfig_Notebook, ID_PATCH_PAGE, wxDefaultPosition, wxDefaultSize); + m_GameConfig_Notebook->AddPage(m_PatchPage, _("Patches")); + m_CheatPage = new wxPanel(m_GameConfig_Notebook, ID_ARCODE_PAGE, wxDefaultPosition, wxDefaultSize); + m_GameConfig_Notebook->AddPage(m_CheatPage, _("AR Codes")); m_Information = new wxPanel(m_Notebook, ID_INFORMATION, wxDefaultPosition, wxDefaultSize); m_Notebook->AddPage(m_Information, _("Info")); m_Filesystem = new wxPanel(m_Notebook, ID_FILESYSTEM, wxDefaultPosition, wxDefaultSize); @@ -227,34 +241,27 @@ void CISOProperties::CreateGUIControls() EmuState = new wxChoice(m_GameConfig, ID_EMUSTATE, wxDefaultPosition, wxDefaultSize, arrayStringFor_EmuState, 0, wxDefaultValidator); // Patches - sbPatches = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Patches")); + sbPatches = new wxStaticBoxSizer(wxVERTICAL, m_PatchPage, _("Patches")); sPatches = new wxBoxSizer(wxVERTICAL); - Patches = new wxCheckListBox(m_GameConfig, ID_PATCHES_LIST, wxDefaultPosition, wxDefaultSize, arrayStringFor_Patches, 0, wxDefaultValidator); + Patches = new wxCheckListBox(m_PatchPage, ID_PATCHES_LIST, wxDefaultPosition, wxDefaultSize, arrayStringFor_Patches, wxLB_HSCROLL, wxDefaultValidator); sPatchButtons = new wxBoxSizer(wxHORIZONTAL); - EditPatch = new wxButton(m_GameConfig, ID_EDITPATCH, _("Edit..."), wxDefaultPosition, wxDefaultSize, 0); - AddPatch = new wxButton(m_GameConfig, ID_ADDPATCH, _("Add..."), wxDefaultPosition, wxDefaultSize, 0); - RemovePatch = new wxButton(m_GameConfig, ID_REMOVEPATCH, _("Remove"), wxDefaultPosition, wxDefaultSize, 0); + EditPatch = new wxButton(m_PatchPage, ID_EDITPATCH, _("Edit..."), wxDefaultPosition, wxDefaultSize, 0); + AddPatch = new wxButton(m_PatchPage, ID_ADDPATCH, _("Add..."), wxDefaultPosition, wxDefaultSize, 0); + RemovePatch = new wxButton(m_PatchPage, ID_REMOVEPATCH, _("Remove"), wxDefaultPosition, wxDefaultSize, 0); EditPatch->Enable(false); RemovePatch->Enable(false); // Action Replay Cheats - sbCheats = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Action Replay Codes")); + sbCheats = new wxStaticBoxSizer(wxVERTICAL, m_CheatPage, _("Action Replay Codes")); sCheats = new wxBoxSizer(wxVERTICAL); - Cheats = new wxCheckListBox(m_GameConfig, ID_CHEATS_LIST, wxDefaultPosition, wxDefaultSize, arrayStringFor_Cheats, 0, wxDefaultValidator); + Cheats = new wxCheckListBox(m_CheatPage, ID_CHEATS_LIST, wxDefaultPosition, wxDefaultSize, arrayStringFor_Cheats, wxLB_HSCROLL, wxDefaultValidator); sCheatButtons = new wxBoxSizer(wxHORIZONTAL); - EditCheat = new wxButton(m_GameConfig, ID_EDITCHEAT, _("Edit..."), wxDefaultPosition, wxDefaultSize, 0); - AddCheat = new wxButton(m_GameConfig, ID_ADDCHEAT, _("Add..."), wxDefaultPosition, wxDefaultSize, 0); - RemoveCheat = new wxButton(m_GameConfig, ID_REMOVECHEAT, _("Remove"), wxDefaultPosition, wxDefaultSize, 0); + EditCheat = new wxButton(m_CheatPage, ID_EDITCHEAT, _("Edit..."), wxDefaultPosition, wxDefaultSize, 0); + AddCheat = new wxButton(m_CheatPage, ID_ADDCHEAT, _("Add..."), wxDefaultPosition, wxDefaultSize, 0); + RemoveCheat = new wxButton(m_CheatPage, ID_REMOVECHEAT, _("Remove"), wxDefaultPosition, wxDefaultSize, 0); EditCheat->Enable(false); RemoveCheat->Enable(false); - // Remove when cheat + patch editor works - Patches->Append(_("Not yet functional")); - Patches->Enable(false); - AddPatch->Enable(false); - AddCheat->Enable(false); - // -------------------------------------- - wxBoxSizer* sConfigPage; sConfigPage = new wxBoxSizer(wxVERTICAL); sCoreOverrides->Add(OverrideText, 0, wxEXPAND|wxALL, 5); @@ -271,6 +278,8 @@ void CISOProperties::CreateGUIControls() sbCoreOverrides->Add(sCoreOverrides, 0, wxEXPAND|wxALL, 0); sConfigPage->Add(sbCoreOverrides, 0, wxEXPAND|wxALL, 5); + wxBoxSizer* sPatchPage; + sPatchPage = new wxBoxSizer(wxVERTICAL); sPatches->Add(Patches, 1, wxEXPAND|wxALL, 0); sPatchButtons->Add(EditPatch, 0, wxEXPAND|wxALL, 0); sPatchButtons->AddStretchSpacer(); @@ -278,8 +287,12 @@ void CISOProperties::CreateGUIControls() sPatchButtons->Add(RemovePatch, 0, wxEXPAND|wxALL, 0); sPatches->Add(sPatchButtons, 0, wxEXPAND|wxALL, 0); sbPatches->Add(sPatches, 1, wxEXPAND|wxALL, 0); - sConfigPage->Add(sbPatches, 1, wxEXPAND|wxALL, 5); + sPatchPage->Add(sbPatches, 1, wxEXPAND|wxALL, 5); + m_PatchPage->SetSizer(sPatchPage); + sPatchPage->Layout(); + wxBoxSizer* sCheatPage; + sCheatPage = new wxBoxSizer(wxVERTICAL); sCheats->Add(Cheats, 1, wxEXPAND|wxALL, 0); sCheatButtons->Add(EditCheat, 0, wxEXPAND|wxALL, 0); sCheatButtons->AddStretchSpacer(); @@ -287,7 +300,12 @@ void CISOProperties::CreateGUIControls() sCheatButtons->Add(RemoveCheat, 0, wxEXPAND|wxALL, 0); sCheats->Add(sCheatButtons, 0, wxEXPAND|wxALL, 0); sbCheats->Add(sCheats, 1, wxEXPAND|wxALL, 0); - sConfigPage->Add(sbCheats, 1, wxEXPAND|wxALL, 5); + sCheatPage->Add(sbCheats, 1, wxEXPAND|wxALL, 5); + m_CheatPage->SetSizer(sCheatPage); + sCheatPage->Layout(); + + sConfigPage->Add(m_GameConfig_Notebook, 1, wxEXPAND|wxALL, 5); + m_GameConfig->SetSizer(sConfigPage); sConfigPage->Layout(); @@ -332,7 +350,7 @@ void CISOProperties::CreateGUIControls() m_CommentText = new wxStaticText(m_Information, ID_COMMENT_TEXT, _("Comment:"), wxDefaultPosition, wxDefaultSize); m_Comment = new wxTextCtrl(m_Information, ID_COMMENT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY); m_BannerText = new wxStaticText(m_Information, ID_BANNER_TEXT, _("Banner:"), wxDefaultPosition, wxDefaultSize); - m_Banner = new wxStaticBitmap(m_Information, ID_BANNER, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0); + m_Banner = new wxStaticBitmap(m_Information, ID_BANNER, wxNullBitmap, wxDefaultPosition, wxSize(96, 32), 0); wxBoxSizer* sInfoPage; sInfoPage = new wxBoxSizer(wxVERTICAL); @@ -382,6 +400,8 @@ void CISOProperties::CreateGUIControls() sTreePage->Add(sbTreectrl, 1, wxEXPAND|wxALL, 5); m_Filesystem->SetSizer(sTreePage); sTreePage->Layout(); + + Fit(); } void CISOProperties::OnClose(wxCloseEvent& WXUNUSED (event)) @@ -513,9 +533,8 @@ void CISOProperties::LoadGameConfig() } EmuState->SetSelection(iTemp); + PatchList_Load(); ActionReplayList_Load(); - - // TODO handle patches } bool CISOProperties::SaveGameConfig() @@ -547,11 +566,10 @@ bool CISOProperties::SaveGameConfig() GameIni.Set("EmuState", "EmulationStateId", EmuState->GetSelection()); + PatchList_Save(); ActionReplayList_Save(); return GameIni.Save(GameIniFile.c_str()); - - // TODO save patches } void CISOProperties::OnEditConfig(wxCommandEvent& WXUNUSED (event)) @@ -570,31 +588,104 @@ void CISOProperties::OnEditConfig(wxCommandEvent& WXUNUSED (event)) } } +void CISOProperties::ListSelectionChanged(wxCommandEvent& event) +{ + switch (event.GetId()) + { + case ID_PATCHES_LIST: + EditPatch->Enable(); + RemovePatch->Enable(); + break; + case ID_CHEATS_LIST: + EditCheat->Enable(); + RemoveCheat->Enable(); + break; + } +} + +void CISOProperties::PatchList_Load() +{ + onFrame.clear(); + PatchEngine::LoadPatchSection("OnFrame", onFrame, GameIni); + + u32 index = 0; + for (std::vector::const_iterator it = onFrame.begin(); it != onFrame.end(); ++it) + { + PatchEngine::Patch p = *it; + Patches->Append(wxString::FromAscii(p.name.c_str())); + Patches->Check(index, p.active); + ++index; + } +} + +void CISOProperties::PatchList_Save() +{ + std::vector lines; + u32 index = 0; + for (std::vector::const_iterator onFrame_it = onFrame.begin(); onFrame_it != onFrame.end(); ++onFrame_it) + { + lines.push_back(Patches->IsChecked(index) ? "+$" + onFrame_it->name : "$" + onFrame_it->name); + + for (std::vector::const_iterator iter2 = onFrame_it->entries.begin(); iter2 != onFrame_it->entries.end(); ++iter2) + { + std::string temp; + ToStringFromFormat(&temp, "0x%08X:%s:0x%08X", iter2->address, PatchEngine::PatchTypeStrings[iter2->type], iter2->value); + lines.push_back(temp); + } + ++index; + } + GameIni.SetLines("OnFrame", lines); + lines.clear(); +} + +void CISOProperties::PatchButtonClicked(wxCommandEvent& event) +{ + switch (event.GetId()) + { + case ID_EDITPATCH: + // dialog + break; + case ID_ADDPATCH: + // dialog + break; + case ID_REMOVEPATCH: + onFrame.erase(onFrame.begin() + Patches->GetSelection()); + break; + } + + PatchList_Save(); + Patches->Clear(); + PatchList_Load(); + + EditPatch->Enable(false); + RemovePatch->Enable(false); +} + void CISOProperties::ActionReplayList_Load() { ARCodes.clear(); std::vector lines; - + if (!GameIni.GetLines("ActionReplay", lines)) return; - + ARListCode code; - + for (std::vector::const_iterator it = lines.begin(); it != lines.end(); ++it) { std::string line = *it; - + if (line[0] == '+' || line[0] == '$') { // Take care of the previous code if (code.ops.size()) { - code.uiIndex = Cheats->Append(wxString::FromAscii(code.name.c_str())); + code.uiIndex = Cheats->Append(wxString::FromAscii(code.name.c_str())); ARCodes.push_back(code); Cheats->Check(code.uiIndex, code.enabled); code.ops.clear(); } - + // Give name and enabled to current code if(line.size() > 1) { @@ -609,29 +700,28 @@ void CISOProperties::ActionReplayList_Load() code.name = line.substr(1, line.size() - 1); } } - continue; } - code.ops.push_back(line); } - + if (code.ops.size()) { - code.uiIndex = Cheats->Append(wxString::FromAscii(code.name.c_str())); - ARCodes.push_back(code); - Cheats->Check(code.uiIndex, code.enabled); + code.uiIndex = Cheats->Append(wxString::FromAscii(code.name.c_str())); + ARCodes.push_back(code); + Cheats->Check(code.uiIndex, code.enabled); } } + void CISOProperties::ActionReplayList_Save() { std::vector lines; for (std::vector::const_iterator iter = ARCodes.begin(); iter != ARCodes.end(); ++iter) { ARListCode code = *iter; - + lines.push_back(Cheats->IsChecked(code.uiIndex) ? "+$" + code.name : "$" + code.name); - + for (std::vector::const_iterator iter2 = code.ops.begin(); iter2 != code.ops.end(); ++iter2) { lines.push_back(*iter2); @@ -639,3 +729,26 @@ void CISOProperties::ActionReplayList_Save() } GameIni.SetLines("ActionReplay", lines); } + +void CISOProperties::ActionReplayButtonClicked(wxCommandEvent& event) +{ + switch (event.GetId()) + { + case ID_EDITCHEAT: + // dialog + break; + case ID_ADDCHEAT: + // dialog + break; + case ID_REMOVECHEAT: + ARCodes.erase(ARCodes.begin() + Cheats->GetSelection()); + break; + } + + ActionReplayList_Save(); + Cheats->Clear(); + ActionReplayList_Load(); + + EditCheat->Enable(false); + RemoveCheat->Enable(false); +} diff --git a/Source/Core/DolphinWX/Src/ISOProperties.h b/Source/Core/DolphinWX/Src/ISOProperties.h index 026c685862..418b487730 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.h +++ b/Source/Core/DolphinWX/Src/ISOProperties.h @@ -67,6 +67,9 @@ class CISOProperties : public wxDialog wxNotebook *m_Notebook; wxPanel *m_GameConfig; + wxNotebook *m_GameConfig_Notebook; + wxPanel *m_PatchPage; + wxPanel *m_CheatPage; wxPanel *m_Information; wxPanel *m_Filesystem; @@ -76,6 +79,7 @@ class CISOProperties : public wxDialog wxCheckBox *OptimizeQuantizers; wxCheckBox *EnableProgressiveScan, *EnableWideScreen; // Wii + wxButton *EditConfig; wxStaticText *EmuStateText; wxArrayString arrayStringFor_EmuState; wxChoice *EmuState; @@ -89,8 +93,12 @@ class CISOProperties : public wxDialog wxButton *EditCheat; wxButton *AddCheat; wxButton *RemoveCheat; - wxButton *EditConfig; - + wxArrayString arrayStringFor_Speedhacks; + wxCheckListBox *Speedhacks; + wxButton *EditSpeedhack; + wxButton *AddSpeedhack; + wxButton *RemoveSpeedhack; + wxStaticText *m_NameText; wxStaticText *m_GameIDText; wxStaticText *m_CountryText; @@ -129,6 +137,10 @@ class CISOProperties : public wxDialog ID_NOTEBOOK, ID_GAMECONFIG, + ID_GAMECONFIG_NOTEBOOK, + ID_PATCH_PAGE, + ID_ARCODE_PAGE, + ID_SPEEDHACK_PAGE, ID_INFORMATION, ID_FILESYSTEM, @@ -138,6 +150,7 @@ class CISOProperties : public wxDialog ID_ENABLEPROGRESSIVESCAN, ID_ENABLEWIDESCREEN, ID_OPTIMIZEQUANTIZERS, + ID_EDITCONFIG, ID_EMUSTATE_TEXT, ID_EMUSTATE, ID_PATCHES_LIST, @@ -148,7 +161,6 @@ class CISOProperties : public wxDialog ID_EDITCHEAT, ID_ADDCHEAT, ID_REMOVECHEAT, - ID_EDITCONFIG, ID_NAME_TEXT, ID_GAMEID_TEXT, @@ -185,26 +197,31 @@ class CISOProperties : public wxDialog void CreateGUIControls(); void OnClose(wxCloseEvent& event); void OnCloseClick(wxCommandEvent& event); + void OnEditConfig(wxCommandEvent& event); + void ListSelectionChanged(wxCommandEvent& event); + void PatchButtonClicked(wxCommandEvent& event); + void ActionReplayButtonClicked(wxCommandEvent& event); void RightClickOnBanner(wxMouseEvent& event); void OnBannerImageSave(wxCommandEvent& event); void OnRightClickOnTree(wxTreeEvent& event); void OnExtractFile(wxCommandEvent& event); void OnExtractDir(wxCommandEvent& event); void SetRefresh(wxCommandEvent& event); - void OnEditConfig(wxCommandEvent& event); - void ActionReplayList_Load(); - void ActionReplayList_Save(); std::vector Our_Files; typedef std::vector::iterator fileIter; + IniFile GameIni; + std::string GameIniFile; + void CreateDirectoryTree(wxTreeItemId& parent,fileIter& begin, fileIter& end, fileIter& iterPos, char *directory); - - IniFile GameIni; - std::string GameIniFile; void LoadGameConfig(); bool SaveGameConfig(); + void PatchList_Load(); + void PatchList_Save(); + void ActionReplayList_Load(); + void ActionReplayList_Save(); }; #endif