mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-22 13:49:53 -06:00
CheatManager/ISOProperties: Refactor ActionReplay tabs as a class
Refactor Action Replay code into its own class like Gecko Codes.
This commit is contained in:
@ -32,6 +32,7 @@
|
||||
#include "Core/Core.h"
|
||||
#include "Core/GeckoCode.h"
|
||||
#include "Core/GeckoCodeConfig.h"
|
||||
#include "DolphinWX/Cheats/ActionReplayCodesPanel.h"
|
||||
#include "DolphinWX/Cheats/CheatSearchTab.h"
|
||||
#include "DolphinWX/Cheats/CheatsWindow.h"
|
||||
#include "DolphinWX/Cheats/CreateCodeDialog.h"
|
||||
@ -58,7 +59,7 @@ wxCheatsWindow::wxCheatsWindow(wxWindow* const parent)
|
||||
|
||||
// load codes
|
||||
UpdateGUI();
|
||||
wxTheApp->Bind(DOLPHIN_EVT_LOCAL_INI_CHANGED, &wxCheatsWindow::OnEvent_CheatsList_Update, this);
|
||||
wxTheApp->Bind(DOLPHIN_EVT_LOCAL_INI_CHANGED, &wxCheatsWindow::OnLocalGameIniModified, this);
|
||||
|
||||
SetSize(wxSize(-1, 600));
|
||||
Center();
|
||||
@ -77,31 +78,16 @@ void wxCheatsWindow::Init_ChildControls()
|
||||
|
||||
// --- Tabs ---
|
||||
// Cheats List Tab
|
||||
m_tab_cheats = new wxPanel(m_notebook_main, wxID_ANY);
|
||||
wxPanel* tab_cheats = new wxPanel(m_notebook_main, wxID_ANY);
|
||||
|
||||
m_checklistbox_cheats_list = new wxCheckListBox(m_tab_cheats, wxID_ANY, wxDefaultPosition,
|
||||
wxSize(300, 0), 0, nullptr, wxLB_HSCROLL);
|
||||
m_checklistbox_cheats_list->Bind(wxEVT_LISTBOX, &wxCheatsWindow::OnEvent_CheatsList_ItemSelected,
|
||||
this);
|
||||
|
||||
m_label_code_name = new wxStaticText(m_tab_cheats, wxID_ANY, _("Name: "), wxDefaultPosition,
|
||||
wxDefaultSize, wxST_NO_AUTORESIZE);
|
||||
m_groupbox_info = new wxStaticBox(m_tab_cheats, wxID_ANY, _("Code Info"));
|
||||
|
||||
m_label_num_codes = new wxStaticText(m_tab_cheats, wxID_ANY, _("Number Of Codes: "));
|
||||
m_listbox_codes_list = new wxListBox(m_tab_cheats, wxID_ANY, wxDefaultPosition, wxSize(120, 150),
|
||||
0, nullptr, wxLB_HSCROLL);
|
||||
|
||||
wxStaticBoxSizer* sGroupBoxInfo = new wxStaticBoxSizer(m_groupbox_info, wxVERTICAL);
|
||||
sGroupBoxInfo->Add(m_label_code_name, 0, wxEXPAND | wxALL, 5);
|
||||
sGroupBoxInfo->Add(m_label_num_codes, 0, wxALL, 5);
|
||||
sGroupBoxInfo->Add(m_listbox_codes_list, 1, wxALL, 5);
|
||||
m_ar_codes_panel =
|
||||
new ActionReplayCodesPanel(tab_cheats, ActionReplayCodesPanel::STYLE_SIDE_PANEL |
|
||||
ActionReplayCodesPanel::STYLE_MODIFY_BUTTONS);
|
||||
|
||||
wxBoxSizer* sizer_tab_cheats = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer_tab_cheats->Add(m_checklistbox_cheats_list, 1, wxEXPAND | wxTOP | wxBOTTOM | wxLEFT, 10);
|
||||
sizer_tab_cheats->Add(sGroupBoxInfo, 0, wxALIGN_LEFT | wxEXPAND | wxALL, 5);
|
||||
sizer_tab_cheats->Add(m_ar_codes_panel, 1, wxEXPAND | wxALL, 5);
|
||||
|
||||
m_tab_cheats->SetSizerAndFit(sizer_tab_cheats);
|
||||
tab_cheats->SetSizerAndFit(sizer_tab_cheats);
|
||||
|
||||
// Cheat Search Tab
|
||||
wxPanel* const tab_cheat_search = new CheatSearchTab(m_notebook_main);
|
||||
@ -134,7 +120,7 @@ void wxCheatsWindow::Init_ChildControls()
|
||||
m_tab_log->SetSizerAndFit(sTabLog);
|
||||
|
||||
// Add Tabs to Notebook
|
||||
m_notebook_main->AddPage(m_tab_cheats, _("AR Codes"));
|
||||
m_notebook_main->AddPage(tab_cheats, _("AR Codes"));
|
||||
m_geckocode_panel = new Gecko::CodeConfigPanel(m_notebook_main);
|
||||
m_notebook_main->AddPage(m_geckocode_panel, _("Gecko Codes"));
|
||||
m_notebook_main->AddPage(tab_cheat_search, _("Cheat Search"));
|
||||
@ -193,21 +179,17 @@ void wxCheatsWindow::UpdateGUI()
|
||||
|
||||
void wxCheatsWindow::Load_ARCodes()
|
||||
{
|
||||
m_checklistbox_cheats_list->Clear();
|
||||
|
||||
if (!Core::IsRunning())
|
||||
return;
|
||||
|
||||
m_checklistbox_cheats_list->Freeze();
|
||||
for (auto& code : ActionReplay::LoadCodes(m_gameini_default, m_gameini_local))
|
||||
{
|
||||
CodeData* cd = new CodeData();
|
||||
cd->code = std::move(code);
|
||||
int index = m_checklistbox_cheats_list->Append(
|
||||
wxCheckListBox::EscapeMnemonics(StrToWxStr(cd->code.name)), cd);
|
||||
m_checklistbox_cheats_list->Check(index, cd->code.active);
|
||||
m_ar_codes_panel->Clear();
|
||||
m_ar_codes_panel->Disable();
|
||||
return;
|
||||
}
|
||||
m_checklistbox_cheats_list->Thaw();
|
||||
else if (!m_ar_codes_panel->IsEnabled())
|
||||
{
|
||||
m_ar_codes_panel->Enable();
|
||||
}
|
||||
m_ar_codes_panel->LoadCodes(m_gameini_default, m_gameini_local);
|
||||
}
|
||||
|
||||
void wxCheatsWindow::Load_GeckoCodes()
|
||||
@ -220,36 +202,10 @@ void wxCheatsWindow::OnNewARCodeCreated(wxCommandEvent& ev)
|
||||
{
|
||||
auto code = static_cast<ActionReplay::ARCode*>(ev.GetClientData());
|
||||
ActionReplay::AddCode(*code);
|
||||
|
||||
CodeData* cd = new CodeData();
|
||||
cd->code = *code;
|
||||
int idx = m_checklistbox_cheats_list->Append(
|
||||
wxCheckListBox::EscapeMnemonics(StrToWxStr(code->name)), cd);
|
||||
m_checklistbox_cheats_list->Check(idx, code->active);
|
||||
m_ar_codes_panel->AppendNewCode(*code);
|
||||
}
|
||||
|
||||
void wxCheatsWindow::OnEvent_CheatsList_ItemSelected(wxCommandEvent& event)
|
||||
{
|
||||
CodeData* cd = static_cast<CodeData*>(event.GetClientObject());
|
||||
|
||||
m_label_code_name->SetLabelText(_("Name: ") + StrToWxStr(cd->code.name));
|
||||
m_label_code_name->Wrap(m_label_code_name->GetSize().GetWidth());
|
||||
m_label_code_name->InvalidateBestSize();
|
||||
m_label_num_codes->SetLabelText(
|
||||
wxString::Format("%s%zu", _("Number Of Codes: "), cd->code.ops.size()));
|
||||
|
||||
m_listbox_codes_list->Freeze();
|
||||
m_listbox_codes_list->Clear();
|
||||
for (const ActionReplay::AREntry& entry : cd->code.ops)
|
||||
{
|
||||
m_listbox_codes_list->Append(wxString::Format("%08x %08x", entry.cmd_addr, entry.value));
|
||||
}
|
||||
m_listbox_codes_list->Thaw();
|
||||
|
||||
m_tab_cheats->Layout();
|
||||
}
|
||||
|
||||
void wxCheatsWindow::OnEvent_CheatsList_Update(wxCommandEvent& ev)
|
||||
void wxCheatsWindow::OnLocalGameIniModified(wxCommandEvent& ev)
|
||||
{
|
||||
ev.Skip();
|
||||
if (WxStrToStr(ev.GetString()) != m_game_id)
|
||||
@ -264,18 +220,8 @@ void wxCheatsWindow::OnEvent_CheatsList_Update(wxCommandEvent& ev)
|
||||
|
||||
void wxCheatsWindow::OnEvent_ApplyChanges_Press(wxCommandEvent& ev)
|
||||
{
|
||||
// Convert embedded metadata back into ARCode vector and update active states
|
||||
std::vector<ActionReplay::ARCode> code_vec;
|
||||
code_vec.reserve(m_checklistbox_cheats_list->GetCount());
|
||||
for (unsigned int i = 0; i < m_checklistbox_cheats_list->GetCount(); ++i)
|
||||
{
|
||||
CodeData* cd = static_cast<CodeData*>(m_checklistbox_cheats_list->GetClientObject(i));
|
||||
cd->code.active = m_checklistbox_cheats_list->IsChecked(i);
|
||||
code_vec.push_back(cd->code);
|
||||
}
|
||||
|
||||
// Apply Action Replay code changes
|
||||
ActionReplay::ApplyCodes(code_vec);
|
||||
ActionReplay::ApplyCodes(m_ar_codes_panel->GetCodes());
|
||||
|
||||
// Apply Gecko Code changes
|
||||
Gecko::SetActiveCodes(m_geckocode_panel->GetCodes());
|
||||
@ -283,7 +229,7 @@ void wxCheatsWindow::OnEvent_ApplyChanges_Press(wxCommandEvent& ev)
|
||||
// Save gameini, with changed codes
|
||||
if (m_gameini_local_path.size())
|
||||
{
|
||||
ActionReplay::SaveCodes(&m_gameini_local, code_vec);
|
||||
m_ar_codes_panel->SaveCodes(&m_gameini_local);
|
||||
Gecko::SaveCodes(m_gameini_local, m_geckocode_panel->GetCodes());
|
||||
m_gameini_local.Save(m_gameini_local_path);
|
||||
|
||||
@ -302,9 +248,31 @@ void wxCheatsWindow::OnEvent_ButtonUpdateLog_Press(wxCommandEvent& WXUNUSED(even
|
||||
wxBeginBusyCursor();
|
||||
m_textctrl_log->Freeze();
|
||||
m_textctrl_log->Clear();
|
||||
// This horrible mess is because the Windows Textbox Widget suffers from
|
||||
// a Shlemiel The Painter problem where it keeps allocating new memory each
|
||||
// time some text is appended then memcpys to the new buffer. This happens
|
||||
// for every single line resulting in the operation taking minutes instead of
|
||||
// seconds.
|
||||
// Why not just append all of the text all at once? Microsoft decided that it
|
||||
// would be clever to accept as much text as will fit in the internal buffer
|
||||
// then silently discard the rest. We have to iteratively append the text over
|
||||
// and over until the internal buffer becomes big enough to hold all of it.
|
||||
// (wxWidgets should have hidden this platform detail but it sucks)
|
||||
wxString super_string;
|
||||
super_string.reserve(1024 * 1024);
|
||||
for (const std::string& text : ActionReplay::GetSelfLog())
|
||||
{
|
||||
m_textctrl_log->AppendText(StrToWxStr(text));
|
||||
super_string.append(StrToWxStr(text));
|
||||
}
|
||||
while (!super_string.empty())
|
||||
{
|
||||
// Read "GetLastPosition" as "Size", there's no size function.
|
||||
wxTextPos start = m_textctrl_log->GetLastPosition();
|
||||
m_textctrl_log->AppendText(super_string);
|
||||
wxTextPos end = m_textctrl_log->GetLastPosition();
|
||||
if (start == end)
|
||||
break;
|
||||
super_string.erase(0, end - start);
|
||||
}
|
||||
m_textctrl_log->Thaw();
|
||||
wxEndBusyCursor();
|
||||
|
Reference in New Issue
Block a user