ActionReplay: Fix ISOProperties corrupting active code set
ISOProperties loads codes using ActionReplay::LoadCodes which actually applies the codes to the global state. If a game is running then that games receives all the codes (and ACTIVE status) from the second game being shown in ISOProperties which is not desirable.
This commit is contained in:
parent
0fa9233c1a
commit
25b072ff2b
|
@ -19,7 +19,10 @@
|
||||||
// Zero Codes: any code with no address. These codes are used to do special operations like memory copy, etc
|
// Zero Codes: any code with no address. These codes are used to do special operations like memory copy, etc
|
||||||
// -------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
@ -81,6 +84,9 @@ static std::vector<ARCode> activeCodes;
|
||||||
static bool logSelf = false;
|
static bool logSelf = false;
|
||||||
static std::vector<std::string> arLog;
|
static std::vector<std::string> arLog;
|
||||||
|
|
||||||
|
static std::mutex s_callbacks_lock;
|
||||||
|
static std::list<std::function<void()>> s_callbacks;
|
||||||
|
|
||||||
struct ARAddr
|
struct ARAddr
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
|
@ -100,16 +106,68 @@ struct ARAddr
|
||||||
operator u32() const { return address; }
|
operator u32() const { return address; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void RunCodeChangeCallbacks()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> guard(s_callbacks_lock);
|
||||||
|
for (const auto& cb : s_callbacks)
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------
|
// ----------------------
|
||||||
// AR Remote Functions
|
// AR Remote Functions
|
||||||
void LoadCodes(const IniFile& globalIni, const IniFile& localIni, bool forceLoad)
|
void ApplyCodes(const std::vector<ARCode>& codes)
|
||||||
{
|
{
|
||||||
// Parses the Action Replay section of a game ini file.
|
if (!SConfig::GetInstance().bEnableCheats)
|
||||||
if (!SConfig::GetInstance().bEnableCheats &&
|
|
||||||
!forceLoad)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
arCodes.clear();
|
arCodes = codes;
|
||||||
|
UpdateActiveList();
|
||||||
|
RunCodeChangeCallbacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddCode(const ARCode& code)
|
||||||
|
{
|
||||||
|
if (!SConfig::GetInstance().bEnableCheats)
|
||||||
|
return;
|
||||||
|
|
||||||
|
arCodes.push_back(code);
|
||||||
|
if (code.active)
|
||||||
|
UpdateActiveList();
|
||||||
|
RunCodeChangeCallbacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
void* RegisterCodeChangeCallback(std::function<void()> callback)
|
||||||
|
{
|
||||||
|
if (!callback)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> guard(s_callbacks_lock);
|
||||||
|
s_callbacks.emplace_back(std::move(callback));
|
||||||
|
return &s_callbacks.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnregisterCodeChangeCallback(void* token)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> guard(s_callbacks_lock);
|
||||||
|
for (auto i = s_callbacks.begin(); i != s_callbacks.end(); ++i)
|
||||||
|
{
|
||||||
|
if (&*i == token)
|
||||||
|
{
|
||||||
|
s_callbacks.erase(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadAndApplyCodes(const IniFile& globalIni, const IniFile& localIni)
|
||||||
|
{
|
||||||
|
ApplyCodes(LoadCodes(globalIni, localIni));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parses the Action Replay section of a game ini file.
|
||||||
|
std::vector<ARCode> LoadCodes(const IniFile& globalIni, const IniFile& localIni)
|
||||||
|
{
|
||||||
|
std::vector<ARCode> codes;
|
||||||
|
|
||||||
std::vector<std::string> enabledLines;
|
std::vector<std::string> enabledLines;
|
||||||
std::set<std::string> enabledNames;
|
std::set<std::string> enabledNames;
|
||||||
|
@ -146,13 +204,13 @@ void LoadCodes(const IniFile& globalIni, const IniFile& localIni, bool forceLoad
|
||||||
{
|
{
|
||||||
if (currentCode.ops.size())
|
if (currentCode.ops.size())
|
||||||
{
|
{
|
||||||
arCodes.push_back(currentCode);
|
codes.push_back(currentCode);
|
||||||
currentCode.ops.clear();
|
currentCode.ops.clear();
|
||||||
}
|
}
|
||||||
if (encryptedLines.size())
|
if (encryptedLines.size())
|
||||||
{
|
{
|
||||||
DecryptARCode(encryptedLines, currentCode.ops);
|
DecryptARCode(encryptedLines, currentCode.ops);
|
||||||
arCodes.push_back(currentCode);
|
codes.push_back(currentCode);
|
||||||
currentCode.ops.clear();
|
currentCode.ops.clear();
|
||||||
encryptedLines.clear();
|
encryptedLines.clear();
|
||||||
}
|
}
|
||||||
|
@ -204,22 +262,16 @@ void LoadCodes(const IniFile& globalIni, const IniFile& localIni, bool forceLoad
|
||||||
// Handle the last code correctly.
|
// Handle the last code correctly.
|
||||||
if (currentCode.ops.size())
|
if (currentCode.ops.size())
|
||||||
{
|
{
|
||||||
arCodes.push_back(currentCode);
|
codes.push_back(currentCode);
|
||||||
}
|
}
|
||||||
if (encryptedLines.size())
|
if (encryptedLines.size())
|
||||||
{
|
{
|
||||||
DecryptARCode(encryptedLines, currentCode.ops);
|
DecryptARCode(encryptedLines, currentCode.ops);
|
||||||
arCodes.push_back(currentCode);
|
codes.push_back(currentCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateActiveList();
|
return codes;
|
||||||
}
|
|
||||||
|
|
||||||
void LoadCodes(std::vector<ARCode> &_arCodes, IniFile &globalIni, IniFile& localIni)
|
|
||||||
{
|
|
||||||
LoadCodes(globalIni, localIni, true);
|
|
||||||
_arCodes = arCodes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -270,6 +322,7 @@ void SetARCode_IsActive(bool active, size_t index)
|
||||||
}
|
}
|
||||||
arCodes[index].active = active;
|
arCodes[index].active = active;
|
||||||
UpdateActiveList();
|
UpdateActiveList();
|
||||||
|
RunCodeChangeCallbacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateActiveList()
|
void UpdateActiveList()
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
@ -31,8 +32,12 @@ struct ARCode
|
||||||
|
|
||||||
void RunAllActive();
|
void RunAllActive();
|
||||||
bool RunCode(const ARCode &arcode);
|
bool RunCode(const ARCode &arcode);
|
||||||
void LoadCodes(const IniFile &globalini, const IniFile &localIni, bool forceLoad);
|
void ApplyCodes(const std::vector<ARCode>& codes);
|
||||||
void LoadCodes(std::vector<ARCode> &_arCodes, IniFile &globalini, IniFile &localIni);
|
void AddCode(const ARCode& new_code);
|
||||||
|
void* RegisterCodeChangeCallback(std::function<void()> callback);
|
||||||
|
void UnregisterCodeChangeCallback(void* token);
|
||||||
|
void LoadAndApplyCodes(const IniFile& globalini, const IniFile& localIni);
|
||||||
|
std::vector<ARCode> LoadCodes(const IniFile& globalini, const IniFile& localIni);
|
||||||
size_t GetCodeListSize();
|
size_t GetCodeListSize();
|
||||||
ARCode GetARCode(size_t index);
|
ARCode GetARCode(size_t index);
|
||||||
void SetARCode_IsActive(bool active, size_t index);
|
void SetARCode_IsActive(bool active, size_t index);
|
||||||
|
|
|
@ -166,7 +166,7 @@ void LoadPatches()
|
||||||
IniFile localIni = SConfig::GetInstance().LoadLocalGameIni();
|
IniFile localIni = SConfig::GetInstance().LoadLocalGameIni();
|
||||||
|
|
||||||
LoadPatchSection("OnFrame", onFrame, globalIni, localIni);
|
LoadPatchSection("OnFrame", onFrame, globalIni, localIni);
|
||||||
ActionReplay::LoadCodes(globalIni, localIni, false);
|
ActionReplay::LoadAndApplyCodes(globalIni, localIni);
|
||||||
|
|
||||||
// lil silly
|
// lil silly
|
||||||
std::vector<Gecko::GeckoCode> gcodes;
|
std::vector<Gecko::GeckoCode> gcodes;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wx/button.h>
|
#include <wx/button.h>
|
||||||
|
@ -38,12 +39,19 @@
|
||||||
#include "DolphinWX/Cheats/CreateCodeDialog.h"
|
#include "DolphinWX/Cheats/CreateCodeDialog.h"
|
||||||
#include "DolphinWX/Cheats/GeckoCodeDiag.h"
|
#include "DolphinWX/Cheats/GeckoCodeDiag.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
wxDEFINE_EVENT(DOLPHIN_EVT_UPDATE_CHEAT_LIST, wxThreadEvent);
|
||||||
|
}
|
||||||
|
|
||||||
wxCheatsWindow::wxCheatsWindow(wxWindow* const parent)
|
wxCheatsWindow::wxCheatsWindow(wxWindow* const parent)
|
||||||
: wxDialog(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX | wxDIALOG_NO_PARENT)
|
: wxDialog(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX | wxDIALOG_NO_PARENT)
|
||||||
{
|
{
|
||||||
// Create the GUI controls
|
// Create the GUI controls
|
||||||
Init_ChildControls();
|
Init_ChildControls();
|
||||||
|
|
||||||
|
m_ar_callback_token = ActionReplay::RegisterCodeChangeCallback(std::bind(&wxCheatsWindow::OnActionReplayModified, this));
|
||||||
|
|
||||||
// load codes
|
// load codes
|
||||||
UpdateGUI();
|
UpdateGUI();
|
||||||
|
|
||||||
|
@ -54,6 +62,7 @@ wxCheatsWindow::wxCheatsWindow(wxWindow* const parent)
|
||||||
|
|
||||||
wxCheatsWindow::~wxCheatsWindow()
|
wxCheatsWindow::~wxCheatsWindow()
|
||||||
{
|
{
|
||||||
|
ActionReplay::UnregisterCodeChangeCallback(m_ar_callback_token);
|
||||||
main_frame->g_CheatsWindow = nullptr;
|
main_frame->g_CheatsWindow = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +135,7 @@ void wxCheatsWindow::Init_ChildControls()
|
||||||
button_cancel->Bind(wxEVT_BUTTON, &wxCheatsWindow::OnEvent_ButtonClose_Press, this);
|
button_cancel->Bind(wxEVT_BUTTON, &wxCheatsWindow::OnEvent_ButtonClose_Press, this);
|
||||||
|
|
||||||
Bind(wxEVT_CLOSE_WINDOW, &wxCheatsWindow::OnEvent_Close, this);
|
Bind(wxEVT_CLOSE_WINDOW, &wxCheatsWindow::OnEvent_Close, this);
|
||||||
Bind(UPDATE_CHEAT_LIST_EVENT, &wxCheatsWindow::OnEvent_CheatsList_Update, this);
|
Bind(DOLPHIN_EVT_UPDATE_CHEAT_LIST, &wxCheatsWindow::OnEvent_CheatsList_Update, this);
|
||||||
|
|
||||||
wxStdDialogButtonSizer* const sButtons = new wxStdDialogButtonSizer();
|
wxStdDialogButtonSizer* const sButtons = new wxStdDialogButtonSizer();
|
||||||
sButtons->AddButton(m_button_apply);
|
sButtons->AddButton(m_button_apply);
|
||||||
|
@ -232,24 +241,30 @@ void wxCheatsWindow::OnEvent_CheatsList_ItemToggled(wxCommandEvent& WXUNUSED(eve
|
||||||
{
|
{
|
||||||
if ((int)code_index.uiIndex == index)
|
if ((int)code_index.uiIndex == index)
|
||||||
{
|
{
|
||||||
|
m_ar_ignore_callback = true;
|
||||||
ActionReplay::SetARCode_IsActive(m_checklistbox_cheats_list->IsChecked(index), code_index.index);
|
ActionReplay::SetARCode_IsActive(m_checklistbox_cheats_list->IsChecked(index), code_index.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCheatsWindow::OnEvent_CheatsList_Update(wxCommandEvent& event)
|
void wxCheatsWindow::OnEvent_CheatsList_Update(wxThreadEvent&)
|
||||||
{
|
{
|
||||||
|
if (m_ar_ignore_callback)
|
||||||
|
{
|
||||||
|
m_ar_ignore_callback = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
Load_ARCodes();
|
Load_ARCodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxCheatsWindow::OnActionReplayModified()
|
||||||
|
{
|
||||||
|
// NOTE: This is an arbitrary thread context
|
||||||
|
GetEventHandler()->QueueEvent(new wxThreadEvent(DOLPHIN_EVT_UPDATE_CHEAT_LIST));
|
||||||
|
}
|
||||||
|
|
||||||
void wxCheatsWindow::OnEvent_ApplyChanges_Press(wxCommandEvent& ev)
|
void wxCheatsWindow::OnEvent_ApplyChanges_Press(wxCommandEvent& ev)
|
||||||
{
|
{
|
||||||
// Apply AR Code changes
|
|
||||||
for (const ARCodeIndex& code_index : m_index_list)
|
|
||||||
{
|
|
||||||
ActionReplay::SetARCode_IsActive(m_checklistbox_cheats_list->IsChecked(code_index.uiIndex), code_index.index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply Gecko Code changes
|
// Apply Gecko Code changes
|
||||||
Gecko::SetActiveCodes(m_geckocode_panel->GetCodes());
|
Gecko::SetActiveCodes(m_geckocode_panel->GetCodes());
|
||||||
|
|
||||||
|
@ -265,11 +280,15 @@ void wxCheatsWindow::OnEvent_ApplyChanges_Press(wxCommandEvent& ev)
|
||||||
|
|
||||||
void wxCheatsWindow::OnEvent_ButtonUpdateLog_Press(wxCommandEvent& WXUNUSED(event))
|
void wxCheatsWindow::OnEvent_ButtonUpdateLog_Press(wxCommandEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
|
wxBeginBusyCursor();
|
||||||
|
m_textctrl_log->Freeze();
|
||||||
m_textctrl_log->Clear();
|
m_textctrl_log->Clear();
|
||||||
for (const std::string& text : ActionReplay::GetSelfLog())
|
for (const std::string& text : ActionReplay::GetSelfLog())
|
||||||
{
|
{
|
||||||
m_textctrl_log->AppendText(StrToWxStr(text));
|
m_textctrl_log->AppendText(StrToWxStr(text));
|
||||||
}
|
}
|
||||||
|
m_textctrl_log->Thaw();
|
||||||
|
wxEndBusyCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCheatsWindow::OnEvent_CheckBoxEnableLogging_StateChange(wxCommandEvent& WXUNUSED(event))
|
void wxCheatsWindow::OnEvent_CheckBoxEnableLogging_StateChange(wxCommandEvent& WXUNUSED(event))
|
||||||
|
|
|
@ -72,6 +72,10 @@ private:
|
||||||
IniFile m_gameini_local;
|
IniFile m_gameini_local;
|
||||||
std::string m_gameini_local_path;
|
std::string m_gameini_local_path;
|
||||||
|
|
||||||
|
// ActionReplay::UnregisterCodeChangeCallback handle
|
||||||
|
void* m_ar_callback_token = nullptr;
|
||||||
|
bool m_ar_ignore_callback = false;
|
||||||
|
|
||||||
void Init_ChildControls();
|
void Init_ChildControls();
|
||||||
|
|
||||||
void Load_ARCodes();
|
void Load_ARCodes();
|
||||||
|
@ -86,7 +90,8 @@ private:
|
||||||
// Cheats List
|
// Cheats List
|
||||||
void OnEvent_CheatsList_ItemSelected(wxCommandEvent& event);
|
void OnEvent_CheatsList_ItemSelected(wxCommandEvent& event);
|
||||||
void OnEvent_CheatsList_ItemToggled(wxCommandEvent& event);
|
void OnEvent_CheatsList_ItemToggled(wxCommandEvent& event);
|
||||||
void OnEvent_CheatsList_Update(wxCommandEvent& event);
|
void OnEvent_CheatsList_Update(wxThreadEvent& event);
|
||||||
|
void OnActionReplayModified();
|
||||||
|
|
||||||
// Apply Changes Button
|
// Apply Changes Button
|
||||||
void OnEvent_ApplyChanges_Press(wxCommandEvent& event);
|
void OnEvent_ApplyChanges_Press(wxCommandEvent& event);
|
||||||
|
|
|
@ -14,9 +14,6 @@
|
||||||
#include "DolphinWX/WxUtils.h"
|
#include "DolphinWX/WxUtils.h"
|
||||||
#include "DolphinWX/Cheats/CreateCodeDialog.h"
|
#include "DolphinWX/Cheats/CreateCodeDialog.h"
|
||||||
|
|
||||||
// Fired when an ActionReplay code is created.
|
|
||||||
wxDEFINE_EVENT(UPDATE_CHEAT_LIST_EVENT, wxCommandEvent);
|
|
||||||
|
|
||||||
CreateCodeDialog::CreateCodeDialog(wxWindow* const parent, const u32 address)
|
CreateCodeDialog::CreateCodeDialog(wxWindow* const parent, const u32 address)
|
||||||
: wxDialog(parent, wxID_ANY, _("Create AR Code"))
|
: wxDialog(parent, wxID_ANY, _("Create AR Code"))
|
||||||
, m_code_address(address)
|
, m_code_address(address)
|
||||||
|
@ -80,24 +77,21 @@ void CreateCodeDialog::PressOK(wxCommandEvent& ev)
|
||||||
// create the new code
|
// create the new code
|
||||||
ActionReplay::ARCode new_cheat;
|
ActionReplay::ARCode new_cheat;
|
||||||
new_cheat.active = false;
|
new_cheat.active = false;
|
||||||
|
new_cheat.user_defined = true;
|
||||||
new_cheat.name = WxStrToStr(code_name);
|
new_cheat.name = WxStrToStr(code_name);
|
||||||
const ActionReplay::AREntry new_entry(m_code_address, code_value);
|
new_cheat.ops.emplace_back(ActionReplay::AREntry(m_code_address, code_value));
|
||||||
new_cheat.ops.push_back(new_entry);
|
ActionReplay::AddCode(new_cheat);
|
||||||
|
|
||||||
// pretty hacky - add the code to the gameini
|
// pretty hacky - add the code to the gameini
|
||||||
|
// FIXME: The save logic should be ActionReplay since it mirrors the parser
|
||||||
{
|
{
|
||||||
CISOProperties isoprops(GameListItem(SConfig::GetInstance().m_LastFilename, std::unordered_map<std::string, std::string>()), this);
|
CISOProperties isoprops(GameListItem(SConfig::GetInstance().m_LastFilename, {}), this);
|
||||||
// add the code to the isoproperties arcode list
|
// add the code to the isoproperties arcode list
|
||||||
isoprops.AddARCode(new_cheat);
|
isoprops.AddARCode(new_cheat);
|
||||||
// save the gameini
|
// save the gameini
|
||||||
isoprops.SaveGameConfig();
|
isoprops.SaveGameConfig();
|
||||||
isoprops.ActionReplayList_Load(); // loads the new arcodes
|
|
||||||
//ActionReplay::UpdateActiveList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Propagate back to the parent frame to update the cheat list.
|
|
||||||
GetEventHandler()->AddPendingEvent(wxCommandEvent(UPDATE_CHEAT_LIST_EVENT));
|
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,6 @@
|
||||||
class wxCheckBox;
|
class wxCheckBox;
|
||||||
class wxTextCtrl;
|
class wxTextCtrl;
|
||||||
|
|
||||||
wxDECLARE_EVENT(UPDATE_CHEAT_LIST_EVENT, wxCommandEvent);
|
|
||||||
|
|
||||||
class CreateCodeDialog final : public wxDialog
|
class CreateCodeDialog final : public wxDialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -95,6 +95,7 @@ BEGIN_EVENT_TABLE(CISOProperties, wxDialog)
|
||||||
EVT_MENU(IDM_EXTRACTDOL, CISOProperties::OnExtractDataFromHeader)
|
EVT_MENU(IDM_EXTRACTDOL, CISOProperties::OnExtractDataFromHeader)
|
||||||
EVT_MENU(IDM_CHECKINTEGRITY, CISOProperties::CheckPartitionIntegrity)
|
EVT_MENU(IDM_CHECKINTEGRITY, CISOProperties::CheckPartitionIntegrity)
|
||||||
EVT_CHOICE(ID_LANG, CISOProperties::OnChangeBannerLang)
|
EVT_CHOICE(ID_LANG, CISOProperties::OnChangeBannerLang)
|
||||||
|
EVT_CHECKLISTBOX(ID_CHEATS_LIST, CISOProperties::OnActionReplayCodeChecked)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
CISOProperties::CISOProperties(const GameListItem& game_list_item, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style)
|
CISOProperties::CISOProperties(const GameListItem& game_list_item, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style)
|
||||||
|
@ -1314,6 +1315,11 @@ void CISOProperties::ListSelectionChanged(wxCommandEvent& event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CISOProperties::OnActionReplayCodeChecked(wxCommandEvent& event)
|
||||||
|
{
|
||||||
|
arCodes[event.GetSelection()].active = Cheats->IsChecked(event.GetSelection());
|
||||||
|
}
|
||||||
|
|
||||||
void CISOProperties::PatchList_Load()
|
void CISOProperties::PatchList_Load()
|
||||||
{
|
{
|
||||||
onFrame.clear();
|
onFrame.clear();
|
||||||
|
@ -1399,9 +1405,8 @@ void CISOProperties::PatchButtonClicked(wxCommandEvent& event)
|
||||||
|
|
||||||
void CISOProperties::ActionReplayList_Load()
|
void CISOProperties::ActionReplayList_Load()
|
||||||
{
|
{
|
||||||
arCodes.clear();
|
|
||||||
Cheats->Clear();
|
Cheats->Clear();
|
||||||
ActionReplay::LoadCodes(arCodes, GameIniDefault, GameIniLocal);
|
arCodes = ActionReplay::LoadCodes(GameIniDefault, GameIniLocal);
|
||||||
|
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
for (const ActionReplay::ARCode& arCode : arCodes)
|
for (const ActionReplay::ARCode& arCode : arCodes)
|
||||||
|
@ -1422,8 +1427,7 @@ void CISOProperties::ActionReplayList_Save()
|
||||||
u32 cheats_chkbox_count = Cheats->GetCount();
|
u32 cheats_chkbox_count = Cheats->GetCount();
|
||||||
for (const ActionReplay::ARCode& code : arCodes)
|
for (const ActionReplay::ARCode& code : arCodes)
|
||||||
{
|
{
|
||||||
// Check the index against the count because of the hacky way codes are added from the "Cheat Search" dialog
|
if (code.active)
|
||||||
if ((index < cheats_chkbox_count) && Cheats->IsChecked(index))
|
|
||||||
enabledLines.push_back("$" + code.name);
|
enabledLines.push_back("$" + code.name);
|
||||||
|
|
||||||
// Do not save default cheats.
|
// Do not save default cheats.
|
||||||
|
|
|
@ -208,6 +208,7 @@ private:
|
||||||
void OnComputeMD5Sum(wxCommandEvent& event);
|
void OnComputeMD5Sum(wxCommandEvent& event);
|
||||||
void OnShowDefaultConfig(wxCommandEvent& event);
|
void OnShowDefaultConfig(wxCommandEvent& event);
|
||||||
void ListSelectionChanged(wxCommandEvent& event);
|
void ListSelectionChanged(wxCommandEvent& event);
|
||||||
|
void OnActionReplayCodeChecked(wxCommandEvent& event);
|
||||||
void PatchButtonClicked(wxCommandEvent& event);
|
void PatchButtonClicked(wxCommandEvent& event);
|
||||||
void ActionReplayButtonClicked(wxCommandEvent& event);
|
void ActionReplayButtonClicked(wxCommandEvent& event);
|
||||||
void RightClickOnBanner(wxMouseEvent& event);
|
void RightClickOnBanner(wxMouseEvent& event);
|
||||||
|
|
Loading…
Reference in New Issue