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:
parent
4dd91ec191
commit
0b5fed62c1
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -526,8 +526,8 @@ void Callback_VideoCopiedToXFB()
|
|||
frames = 0;
|
||||
Timer.Update();
|
||||
}
|
||||
PatchEngine_ApplyFramePatches();
|
||||
PatchEngine_ApplyARPatches();
|
||||
PatchEngine::ApplyFramePatches();
|
||||
PatchEngine::ApplyARPatches();
|
||||
}
|
||||
|
||||
// __________________________________________________________________________________________________
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue