2015-05-24 04:55:12 +00:00
|
|
|
// Copyright 2010 Dolphin Emulator Project
|
2015-05-17 23:08:10 +00:00
|
|
|
// Licensed under GPLv2+
|
2013-04-18 03:43:35 +00:00
|
|
|
// Refer to the license.txt file included.
|
2010-07-22 01:48:48 +00:00
|
|
|
|
2014-02-17 10:18:15 +00:00
|
|
|
#include <sstream>
|
2014-02-22 22:36:30 +00:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
#include <wx/button.h>
|
|
|
|
#include <wx/checklst.h>
|
|
|
|
#include <wx/listbox.h>
|
2014-07-25 01:46:46 +00:00
|
|
|
#include <wx/msgdlg.h>
|
2014-02-22 22:36:30 +00:00
|
|
|
#include <wx/panel.h>
|
|
|
|
#include <wx/sizer.h>
|
|
|
|
#include <wx/stattext.h>
|
|
|
|
#include <wx/textctrl.h>
|
2010-07-23 05:22:12 +00:00
|
|
|
|
2014-09-08 01:06:58 +00:00
|
|
|
#include "Common/CommonTypes.h"
|
2014-02-22 22:36:30 +00:00
|
|
|
#include "Common/StringUtil.h"
|
2014-02-17 10:18:15 +00:00
|
|
|
#include "Core/Core.h"
|
2014-02-22 22:36:30 +00:00
|
|
|
#include "Core/GeckoCode.h"
|
|
|
|
#include "Core/GeckoCodeConfig.h"
|
2014-10-18 21:32:50 +00:00
|
|
|
#include "DolphinWX/Cheats/GeckoCodeDiag.h"
|
2016-06-24 08:43:46 +00:00
|
|
|
#include "DolphinWX/WxUtils.h"
|
2010-07-23 05:22:12 +00:00
|
|
|
|
2016-07-23 01:05:22 +00:00
|
|
|
wxDEFINE_EVENT(DOLPHIN_EVT_GECKOCODE_TOGGLED, wxCommandEvent);
|
|
|
|
|
2010-07-22 01:48:48 +00:00
|
|
|
namespace Gecko
|
|
|
|
{
|
2017-11-02 13:32:16 +00:00
|
|
|
static const char str_name[] = wxTRANSLATE("Name:");
|
|
|
|
static const char str_notes[] = wxTRANSLATE("Notes:");
|
|
|
|
static const char str_creator[] = wxTRANSLATE("Creator:");
|
2010-07-22 01:48:48 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
CodeConfigPanel::CodeConfigPanel(wxWindow* const parent) : wxPanel(parent)
|
2010-07-22 01:48:48 +00:00
|
|
|
{
|
2016-06-24 08:43:46 +00:00
|
|
|
m_listbox_gcodes = new wxCheckListBox(this, wxID_ANY);
|
|
|
|
m_listbox_gcodes->Bind(wxEVT_LISTBOX, &CodeConfigPanel::UpdateInfoBox, this);
|
|
|
|
m_listbox_gcodes->Bind(wxEVT_CHECKLISTBOX, &CodeConfigPanel::ToggleCode, this);
|
|
|
|
|
2016-10-03 06:56:45 +00:00
|
|
|
m_infobox.label_name = new wxStaticText(this, wxID_ANY, wxGetTranslation(str_name));
|
|
|
|
m_infobox.label_creator = new wxStaticText(this, wxID_ANY, wxGetTranslation(str_creator));
|
|
|
|
m_infobox.label_notes = new wxStaticText(this, wxID_ANY, wxGetTranslation(str_notes));
|
2016-06-24 08:43:46 +00:00
|
|
|
m_infobox.textctrl_notes = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
|
2016-10-03 06:56:45 +00:00
|
|
|
wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY);
|
|
|
|
m_infobox.listbox_codes =
|
|
|
|
new wxListBox(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1, 48)));
|
2016-06-24 08:43:46 +00:00
|
|
|
|
|
|
|
// TODO: buttons to add/edit codes
|
|
|
|
|
|
|
|
// sizers
|
2016-10-03 06:56:45 +00:00
|
|
|
const int space5 = FromDIP(5);
|
2016-06-24 08:43:46 +00:00
|
|
|
wxBoxSizer* const sizer_infobox = new wxBoxSizer(wxVERTICAL);
|
2016-10-03 06:56:45 +00:00
|
|
|
sizer_infobox->Add(m_infobox.label_name);
|
|
|
|
sizer_infobox->Add(m_infobox.label_creator, 0, wxTOP, space5);
|
|
|
|
sizer_infobox->Add(m_infobox.label_notes, 0, wxTOP, space5);
|
|
|
|
sizer_infobox->Add(m_infobox.textctrl_notes, 0, wxEXPAND | wxTOP, space5);
|
|
|
|
sizer_infobox->Add(m_infobox.listbox_codes, 1, wxEXPAND | wxTOP, space5);
|
2016-06-24 08:43:46 +00:00
|
|
|
|
|
|
|
// button sizer
|
|
|
|
wxBoxSizer* const sizer_buttons = new wxBoxSizer(wxHORIZONTAL);
|
2016-10-03 06:56:45 +00:00
|
|
|
btn_download = new wxButton(this, wxID_ANY, _("Download Codes (WiiRD Database)"));
|
2016-06-24 08:43:46 +00:00
|
|
|
btn_download->Disable();
|
|
|
|
btn_download->Bind(wxEVT_BUTTON, &CodeConfigPanel::DownloadCodes, this);
|
|
|
|
sizer_buttons->AddStretchSpacer(1);
|
2016-10-03 06:56:45 +00:00
|
|
|
sizer_buttons->Add(WxUtils::GiveMinSizeDIP(btn_download, wxSize(128, -1)), 1, wxEXPAND);
|
2016-06-24 08:43:46 +00:00
|
|
|
|
|
|
|
wxBoxSizer* const sizer_main = new wxBoxSizer(wxVERTICAL);
|
2016-10-03 06:56:45 +00:00
|
|
|
sizer_main->AddSpacer(space5);
|
|
|
|
sizer_main->Add(m_listbox_gcodes, 1, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
|
|
|
sizer_main->AddSpacer(space5);
|
|
|
|
sizer_main->Add(sizer_infobox, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
|
|
|
sizer_main->AddSpacer(space5);
|
|
|
|
sizer_main->Add(sizer_buttons, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
|
|
|
sizer_main->AddSpacer(space5);
|
2016-06-24 08:43:46 +00:00
|
|
|
|
|
|
|
SetSizerAndFit(sizer_main);
|
2010-07-22 01:48:48 +00:00
|
|
|
}
|
|
|
|
|
2013-05-04 17:27:39 +00:00
|
|
|
void CodeConfigPanel::UpdateCodeList(bool checkRunning)
|
2010-07-22 01:48:48 +00:00
|
|
|
{
|
2016-06-24 08:43:46 +00:00
|
|
|
// disable the button if it doesn't have an effect
|
|
|
|
btn_download->Enable((!checkRunning || Core::IsRunning()) && !m_gameid.empty());
|
|
|
|
|
|
|
|
m_listbox_gcodes->Clear();
|
|
|
|
// add the codes to the listbox
|
|
|
|
for (const GeckoCode& code : m_gcodes)
|
|
|
|
{
|
2016-10-03 06:56:45 +00:00
|
|
|
m_listbox_gcodes->Append(m_listbox_gcodes->EscapeMnemonics(StrToWxStr(code.name)));
|
2016-06-24 08:43:46 +00:00
|
|
|
if (code.enabled)
|
|
|
|
{
|
|
|
|
m_listbox_gcodes->Check(m_listbox_gcodes->GetCount() - 1, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
wxCommandEvent evt;
|
|
|
|
UpdateInfoBox(evt);
|
2010-07-22 01:48:48 +00:00
|
|
|
}
|
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
void CodeConfigPanel::LoadCodes(const IniFile& globalIni, const IniFile& localIni,
|
|
|
|
const std::string& gameid, bool checkRunning)
|
2010-07-23 05:22:12 +00:00
|
|
|
{
|
2016-06-24 08:43:46 +00:00
|
|
|
m_gameid = gameid;
|
2010-07-23 05:22:12 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
m_gcodes.clear();
|
|
|
|
if (!checkRunning || Core::IsRunning())
|
2017-03-21 20:24:16 +00:00
|
|
|
m_gcodes = Gecko::LoadCodes(globalIni, localIni);
|
2010-07-23 05:22:12 +00:00
|
|
|
|
2016-06-24 08:43:46 +00:00
|
|
|
UpdateCodeList(checkRunning);
|
2010-07-23 05:22:12 +00:00
|
|
|
}
|
|
|
|
|
2010-07-22 01:48:48 +00:00
|
|
|
void CodeConfigPanel::ToggleCode(wxCommandEvent& evt)
|
|
|
|
{
|
2016-06-24 08:43:46 +00:00
|
|
|
const int sel = evt.GetInt(); // this right?
|
|
|
|
if (sel > -1)
|
2016-07-23 01:05:22 +00:00
|
|
|
{
|
2016-06-24 08:43:46 +00:00
|
|
|
m_gcodes[sel].enabled = m_listbox_gcodes->IsChecked(sel);
|
2016-07-23 01:05:22 +00:00
|
|
|
|
|
|
|
wxCommandEvent toggle_event(DOLPHIN_EVT_GECKOCODE_TOGGLED, GetId());
|
|
|
|
toggle_event.SetClientData(&m_gcodes[sel]);
|
|
|
|
GetEventHandler()->ProcessEvent(toggle_event);
|
|
|
|
}
|
2010-07-22 01:48:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodeConfigPanel::UpdateInfoBox(wxCommandEvent&)
|
|
|
|
{
|
2016-06-24 08:43:46 +00:00
|
|
|
m_infobox.listbox_codes->Clear();
|
|
|
|
const int sel = m_listbox_gcodes->GetSelection();
|
|
|
|
|
|
|
|
if (sel > -1)
|
|
|
|
{
|
2016-10-03 06:56:45 +00:00
|
|
|
m_infobox.label_name->SetLabel(wxGetTranslation(str_name) + StrToWxStr(m_gcodes[sel].name));
|
2016-06-24 08:43:46 +00:00
|
|
|
|
|
|
|
// notes textctrl
|
|
|
|
m_infobox.textctrl_notes->Clear();
|
|
|
|
for (const std::string& note : m_gcodes[sel].notes)
|
|
|
|
{
|
|
|
|
m_infobox.textctrl_notes->AppendText(StrToWxStr(note));
|
|
|
|
}
|
|
|
|
m_infobox.textctrl_notes->ScrollLines(-99); // silly
|
|
|
|
|
2016-10-03 06:56:45 +00:00
|
|
|
m_infobox.label_creator->SetLabel(wxGetTranslation(str_creator) +
|
2016-06-24 08:43:46 +00:00
|
|
|
StrToWxStr(m_gcodes[sel].creator));
|
|
|
|
|
|
|
|
// add codes to info listbox
|
|
|
|
for (const GeckoCode::Code& code : m_gcodes[sel].codes)
|
|
|
|
{
|
|
|
|
m_infobox.listbox_codes->Append(wxString::Format("%08X %08X", code.address, code.data));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-10-03 06:56:45 +00:00
|
|
|
m_infobox.label_name->SetLabel(wxGetTranslation(str_name));
|
2016-06-24 08:43:46 +00:00
|
|
|
m_infobox.textctrl_notes->Clear();
|
2016-10-03 06:56:45 +00:00
|
|
|
m_infobox.label_creator->SetLabel(wxGetTranslation(str_creator));
|
2016-06-24 08:43:46 +00:00
|
|
|
}
|
2010-07-22 01:48:48 +00:00
|
|
|
}
|
|
|
|
|
2010-07-23 05:22:12 +00:00
|
|
|
void CodeConfigPanel::DownloadCodes(wxCommandEvent&)
|
2010-07-22 01:48:48 +00:00
|
|
|
{
|
2016-06-24 08:43:46 +00:00
|
|
|
if (m_gameid.empty())
|
|
|
|
return;
|
|
|
|
|
2017-02-10 03:22:51 +00:00
|
|
|
bool succeeded;
|
|
|
|
std::vector<GeckoCode> gcodes = Gecko::DownloadCodes(m_gameid, &succeeded);
|
|
|
|
if (!succeeded)
|
2016-06-24 08:43:46 +00:00
|
|
|
{
|
2017-02-10 03:22:51 +00:00
|
|
|
WxUtils::ShowErrorDialog(_("Failed to download codes."));
|
|
|
|
return;
|
2016-06-24 08:43:46 +00:00
|
|
|
}
|
|
|
|
|
2017-02-10 03:22:51 +00:00
|
|
|
if (!gcodes.size())
|
2016-06-24 08:43:46 +00:00
|
|
|
{
|
2017-02-10 03:22:51 +00:00
|
|
|
wxMessageBox(_("File contained no codes."));
|
|
|
|
return;
|
|
|
|
}
|
2016-06-24 08:43:46 +00:00
|
|
|
|
2017-02-10 03:22:51 +00:00
|
|
|
unsigned long added_count = 0;
|
2016-06-24 08:43:46 +00:00
|
|
|
|
2017-02-10 03:22:51 +00:00
|
|
|
// append the codes to the code list
|
|
|
|
for (const GeckoCode& code : gcodes)
|
|
|
|
{
|
|
|
|
// only add codes which do not already exist
|
|
|
|
auto existing_gcodes_iter = m_gcodes.begin();
|
|
|
|
auto existing_gcodes_end = m_gcodes.end();
|
|
|
|
for (;; ++existing_gcodes_iter)
|
2016-06-24 08:43:46 +00:00
|
|
|
{
|
2017-02-10 03:22:51 +00:00
|
|
|
if (existing_gcodes_end == existing_gcodes_iter)
|
2016-06-24 08:43:46 +00:00
|
|
|
{
|
2017-02-10 03:22:51 +00:00
|
|
|
m_gcodes.push_back(code);
|
|
|
|
++added_count;
|
|
|
|
break;
|
2016-06-24 08:43:46 +00:00
|
|
|
}
|
|
|
|
|
2017-02-10 03:22:51 +00:00
|
|
|
// code exists
|
|
|
|
if (*existing_gcodes_iter == code)
|
2016-06-24 08:43:46 +00:00
|
|
|
break;
|
|
|
|
}
|
2017-02-10 03:22:51 +00:00
|
|
|
}
|
2016-06-24 08:43:46 +00:00
|
|
|
|
2017-02-10 03:22:51 +00:00
|
|
|
wxMessageBox(wxString::Format(_("Downloaded %lu codes. (added %lu)"),
|
|
|
|
(unsigned long)gcodes.size(), added_count));
|
2016-06-24 08:43:46 +00:00
|
|
|
|
2017-02-10 03:22:51 +00:00
|
|
|
// refresh the list
|
|
|
|
UpdateCodeList();
|
2010-07-22 07:55:35 +00:00
|
|
|
}
|
2010-07-23 05:22:12 +00:00
|
|
|
}
|