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
This commit is contained in:
Shawn Hoffman 2008-11-24 19:11:15 +00:00
parent 4dd91ec191
commit 0b5fed62c1
20 changed files with 308 additions and 169 deletions

View File

@ -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]

View File

@ -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]

View File

@ -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

View File

@ -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]

View File

@ -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]

View File

@ -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]

View File

@ -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]

View File

@ -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]

View File

@ -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

View File

@ -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)

View File

@ -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<std::string> lines;
std::vector<std::string> encryptedLines;

View File

@ -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_

View File

@ -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];

View File

@ -526,8 +526,8 @@ void Callback_VideoCopiedToXFB()
frames = 0;
Timer.Update();
}
PatchEngine_ApplyFramePatches();
PatchEngine_ApplyARPatches();
PatchEngine::ApplyFramePatches();
PatchEngine::ApplyARPatches();
}
// __________________________________________________________________________________________________

View File

@ -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);

View File

@ -31,46 +31,61 @@
#include <map>
#include "StringUtil.h"
#include "PatchEngine.h"
#include "IniFile.h"
#include "HW/Memmap.h"
#include "ActionReplay.h"
using namespace Common;
namespace
namespace PatchEngine
{
std::vector<Patch> onLoad;
std::vector<Patch> onFrame;
std::map<u32, int> speedHacks;
static void LoadPatchSection(const char *section, std::vector<Patch> &patches, IniFile &ini)
void LoadPatchSection(const char *section, std::vector<Patch> &patches, IniFile &ini)
{
std::vector<std::string> keys;
ini.GetKeys(section, keys);
std::vector<std::string> lines;
if (!ini.GetLines(section, lines))
return;
for (std::vector<std::string>::const_iterator iter = keys.begin(); iter != keys.end(); ++iter)
Patch currentPatch;
int index = 0;
for (std::vector<std::string>::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<std::string> 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<u32, int> &hacks, IniFile &ini) {
@ -95,10 +110,7 @@ static void LoadSpeedhacks(const char *section, std::map<u32, int> &hacks, IniFi
}
}
} // namespace
int PatchEngine_GetSpeedhackCycles(u32 addr)
int GetSpeedhackCycles(u32 addr)
{
std::map<u32, int>::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<Patch> &patches)
{
for (std::vector<Patch>::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<PatchEntry>::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

View File

@ -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<PatchEntry> entries;
bool active;
};
int GetSpeedhackCycles(u32 addr);
void LoadPatchSection(const char *section, std::vector<Patch> &patches, IniFile &ini);
void LoadPatches(const char *gameID);
void ApplyFramePatches();
void ApplyARPatches();
} // namespace
#endif //_PATCHENGINE_H

View File

@ -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++)

View File

@ -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<PatchEngine::Patch> onFrame;
struct ARListCode {
std::string name;
@ -28,22 +34,27 @@ struct ARListCode {
std::vector<std::string> ops;
u32 uiIndex;
};
std::vector<ARListCode> 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<ARListCode> 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<PatchEngine::Patch>::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<std::string> lines;
u32 index = 0;
for (std::vector<PatchEngine::Patch>::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<PatchEngine::PatchEntry>::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<std::string> lines;
if (!GameIni.GetLines("ActionReplay", lines))
return;
ARListCode code;
for (std::vector<std::string>::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<std::string> lines;
for (std::vector<ARListCode>::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<std::string>::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);
}

View File

@ -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<const DiscIO::SFileInfo *> Our_Files;
typedef std::vector<const DiscIO::SFileInfo *>::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