#include "stdafx_gui.h" #include "Emu/System.h" #include "AutoPauseManager.h" #include #include #include "Utilities/Log.h" #include "Utilities/File.h" enum { id_add, id_remove, id_config }; //TODO::Get the enable configuration from ini. AutoPauseManagerDialog::AutoPauseManagerDialog(wxWindow* parent) : wxDialog(parent, wxID_ANY, "Auto Pause Manager") { SetMinSize(wxSize(400, 360)); wxBoxSizer* s_main = new wxBoxSizer(wxVERTICAL); m_entry_convert.clear(); m_entry_convert.str(""); m_entry_convert << "To use auto pause: enter the ID(s) of a function or a system call. Restart of the game is required to apply. You can enable/disable this in the settings."; wxStaticText* s_description = new wxStaticText(this, wxID_ANY, m_entry_convert.str(),wxDefaultPosition, wxDefaultSize, 0); s_description->Wrap(400); s_main->Add(s_description, 0, wxALL, 5); m_list = new wxListView(this); m_list->InsertColumn(0, "Call ID"); m_list->InsertColumn(1, "Type"); m_list->Bind(wxEVT_LIST_ITEM_ACTIVATED, &AutoPauseManagerDialog::OnEntryConfig, this); m_list->Bind(wxEVT_RIGHT_DOWN, &AutoPauseManagerDialog::OnRightClick, this); s_main->Add(m_list, 1, wxALL | wxEXPAND, 5); wxBoxSizer* s_action = new wxBoxSizer(wxHORIZONTAL); s_action->Add(new wxButton(this, wxID_CLEAR, wxT("Cl&ear"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5); s_action->Add(new wxButton(this, wxID_REFRESH, wxT("&Reload"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5); s_action->Add(new wxButton(this, wxID_SAVE, wxT("&Save"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5); s_action->Add(new wxButton(this, wxID_CANCEL, wxT("&Close"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5); s_main->Add(s_action, 0, wxALL, 5); Bind(wxEVT_MENU, &AutoPauseManagerDialog::OnAdd, this, id_add); Bind(wxEVT_MENU, &AutoPauseManagerDialog::OnRemove, this, id_remove); Bind(wxEVT_MENU, &AutoPauseManagerDialog::OnEntryConfig, this, id_config); Bind(wxEVT_BUTTON, &AutoPauseManagerDialog::OnClear, this, wxID_CLEAR); Bind(wxEVT_BUTTON, &AutoPauseManagerDialog::OnReload, this, wxID_REFRESH); Bind(wxEVT_BUTTON, &AutoPauseManagerDialog::OnSave, this, wxID_SAVE); Emu.Stop(); LoadEntries(); UpdateList(); SetSizerAndFit(s_main); Layout(); Centre(wxBOTH); } //Copied some from AutoPause. void AutoPauseManagerDialog::LoadEntries(void) { m_entries.clear(); m_entries.reserve(16); fs::file list("pause.bin"); if (list) { //System calls ID and Function calls ID are all u32 iirc. u32 num; size_t fmax = list.size(); size_t fcur = 0; list.seek(0); while (fcur <= fmax - sizeof(u32)) { list.read(&num, sizeof(u32)); fcur += sizeof(u32); if (num == 0xFFFFFFFF) break; m_entries.emplace_back(num); } } } //Copied some from AutoPause. //Tip: This one doesn't check for the file is being read or not. //This would always use a 0xFFFFFFFF as end of the pause.bin void AutoPauseManagerDialog::SaveEntries(void) { fs::file list("pause.bin", fom::write | fom::create | fom::trunc); //System calls ID and Function calls ID are all u32 iirc. u32 num = 0; list.seek(0); for (size_t i = 0; i < m_entries.size(); ++i) { if (num == 0xFFFFFFFF) continue; num = m_entries[i]; list.write(&num, sizeof(u32)); } num = 0xFFFFFFFF; list.write(&num, sizeof(u32)); } void AutoPauseManagerDialog::UpdateList(void) { m_list->Freeze(); m_list->DeleteAllItems(); for (size_t i = 0; i < m_entries.size(); ++i) { m_list->InsertItem(i, i); if (m_entries[i] != 0xFFFFFFFF) { m_entry_convert.clear(); m_entry_convert.str(""); m_entry_convert << std::hex << std::setw(8) << std::setfill('0') << m_entries[i]; m_list->SetItem(i, 0, m_entry_convert.str()); } else { m_list->SetItem(i, 0, "Unset"); } if (m_entries[i] < 1024) { m_list->SetItem(i, 1, "System Call"); } else { m_list->SetItem(i, 1, "Function Call"); } } m_list->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER); m_list->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER); m_list->Thaw(); } void AutoPauseManagerDialog::OnEntryConfig(wxCommandEvent& event) { int idx = m_list->GetFirstSelected(); if (idx != wxNOT_FOUND) { AutoPauseSettingsDialog(this, &m_entries[idx]).ShowModal(); UpdateList(); } } void AutoPauseManagerDialog::OnRightClick(wxMouseEvent& event) { wxMenu* menu = new wxMenu(); int idx = m_list->GetFirstSelected(); menu->Append(id_add, "&Add"); menu->Append(id_remove, "&Remove")->Enable(idx != wxNOT_FOUND); menu->AppendSeparator(); menu->Append(id_config, "&Config")->Enable(idx != wxNOT_FOUND); PopupMenu(menu); } void AutoPauseManagerDialog::OnAdd(wxCommandEvent& event) { m_entries.emplace_back(0xFFFFFFFF); UpdateList(); u32 idx = m_entries.size() - 1; for (int i = 0; i < m_list->GetItemCount(); ++i) { m_list->SetItemState(i, i == idx ? wxLIST_STATE_SELECTED : ~wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); } wxCommandEvent ce; OnEntryConfig(ce); } void AutoPauseManagerDialog::OnRemove(wxCommandEvent& event) { for (int sel = m_list->GetNextSelected(-1), offs = 0; sel != wxNOT_FOUND; sel = m_list->GetNextSelected(sel), --offs) { m_entries.erase(m_entries.begin() + (sel + offs)); } UpdateList(); } void AutoPauseManagerDialog::OnSave(wxCommandEvent& event) { SaveEntries(); LOG_SUCCESS(HLE,"Auto Pause: File pause.bin was updated."); //event.Skip(); } void AutoPauseManagerDialog::OnClear(wxCommandEvent& event) { m_entries.clear(); UpdateList(); } void AutoPauseManagerDialog::OnReload(wxCommandEvent& event) { LoadEntries(); UpdateList(); } AutoPauseSettingsDialog::AutoPauseSettingsDialog(wxWindow* parent, u32 *entry) : wxDialog(parent, wxID_ANY, "Auto Pause Setting") , m_presult(entry) { m_entry = *m_presult; //SetSizeHints(wxSize(400, -1), wxDefaultSize); SetMinSize(wxSize(400, -1)); wxBoxSizer* s_main = new wxBoxSizer(wxVERTICAL); m_entry_convert.clear(); m_entry_convert.str(""); m_entry_convert << "Specify ID of System Call or Function Call below. You need to use a Hexadecimal ID."; wxStaticText* s_description = new wxStaticText(this, wxID_ANY, m_entry_convert.str(), wxDefaultPosition, wxDefaultSize, 0); s_description->Wrap(400); s_main->Add(s_description, 0, wxALL, 5); wxBoxSizer* s_config = new wxBoxSizer(wxHORIZONTAL); m_id = new wxTextCtrl(this, wxID_STATIC, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); s_config->Add(m_id, 1, wxALL | wxEXPAND, 5); s_config->Add(new wxButton(this, wxID_OK, wxT("&OK"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5); s_config->Add(new wxButton(this, wxID_CANCEL, wxT("&Cancel"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5); s_main->Add(s_config, 0, wxEXPAND, 5); m_current_converted = new wxStaticText(this, wxID_ANY, wxT("Currently it gets an id of \"Unset\"."), wxDefaultPosition, wxDefaultSize, 0); s_main->Add(m_current_converted, 0, wxALL, 5); m_entry_convert.clear(); m_entry_convert.str(""); m_entry_convert << std::hex << std::setw(8) << std::setfill('0') << m_entry; m_id->SetValue(m_entry_convert.str()); SetTitle("Auto Pause Setting: "+m_entry_convert.str()); Bind(wxEVT_BUTTON, &AutoPauseSettingsDialog::OnOk, this, wxID_OK); Bind(wxEVT_TEXT, &AutoPauseSettingsDialog::OnUpdateValue, this, wxID_STATIC); SetSizerAndFit(s_main); //SetSize(wxSize(400, -1)); Layout(); Centre(wxBOTH); wxCommandEvent ce; OnUpdateValue(ce); } void AutoPauseSettingsDialog::OnOk(wxCommandEvent& event) { //Luckily StringStream omit those not hex. m_entry_convert.clear(); m_entry_convert.str(""); m_entry_convert << std::hex << m_id->GetValue(); m_entry_convert >> m_entry; *m_presult = m_entry; EndModal(wxID_OK); } void AutoPauseSettingsDialog::OnUpdateValue(wxCommandEvent& event) { //Luckily StringStream omit those not hex. m_entry_convert.clear(); m_entry_convert.str(""); m_entry_convert << std::hex << m_id->GetValue(); m_entry_convert >> m_entry; m_entry_convert.clear(); m_entry_convert.str(""); m_entry_convert << std::hex << /*std::setw(8) << std::setfill('0') <<*/ m_entry; m_entry_convert.clear(); if (m_entry_convert.str() == m_id->GetValue()) { m_current_converted->SetLabelText("Currently it gets an id of \"" + m_entry_convert.str() + "\" - SAME."); } else { m_current_converted->SetLabelText("Currently it gets an id of \"" + m_entry_convert.str() + "\"."); } event.Skip(); }