dolphin/Source/Core/DolphinWX/Config/GeneralConfigPane.cpp
Lioncash 6f473b96d0 PowerPC: Convert CPUCore enum into an enum class
Makes the enum values strongly-typed and prevents the identifiers from
polluting the PowerPC namespace. This also cleans up the parameters of
some functions where we were accepting an ambiguous int type and
expecting the correct values to be passed in.

Now those parameters accept a PowerPC::CPUCore type only, making it
immediately obvious which values should be passed in. It also turns out
we were storing these core types into other structures as plain ints,
which have also been corrected.

As this type is used directly with the configuration code, we need to
provide our own overloaded insertion (<<) and extraction (>>) operators
in order to make it compatible with it. These are fairly trivial to
implement, so there's no issue here.

A minor adjustment to TryParse() was required, as our generic function
was doing the following:

N tmp = 0;

which is problematic, as custom types may not be able to have that
assignment performed (e.g. strongly-typed enums), so we change this to:

N tmp;

which is sufficient, as the value is attempted to be initialized
immediately under that statement.
2018-06-15 10:27:59 -04:00

219 lines
8.6 KiB
C++

// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "DolphinWX/Config/GeneralConfigPane.h"
#include <map>
#include <string>
#include <vector>
#include <wx/button.h>
#include <wx/checkbox.h>
#include <wx/choice.h>
#include <wx/event.h>
#include <wx/menu.h>
#include <wx/msgdlg.h>
#include <wx/radiobox.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include "Common/Common.h"
#include "Core/Analytics.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/PowerPC/PowerPC.h"
#include "DolphinWX/WxEventUtils.h"
static const std::map<PowerPC::CPUCore, std::string> CPU_CORE_NAMES = {
{PowerPC::CPUCore::Interpreter, _trans("Interpreter (slowest)")},
{PowerPC::CPUCore::CachedInterpreter, _trans("Cached Interpreter (slower)")},
{PowerPC::CPUCore::JIT64, _trans("JIT Recompiler (recommended)")},
{PowerPC::CPUCore::JITARM64, _trans("JIT Arm64 (experimental)")},
};
GeneralConfigPane::GeneralConfigPane(wxWindow* parent, wxWindowID id) : wxPanel(parent, id)
{
InitializeGUI();
LoadGUIValues();
BindEvents();
}
void GeneralConfigPane::InitializeGUI()
{
m_throttler_array_string.Add(_("Unlimited"));
for (int i = 10; i <= 200; i += 10) // from 10% to 200%
{
if (i == 100)
m_throttler_array_string.Add(wxString::Format(_("%i%% (Normal Speed)"), i));
else
m_throttler_array_string.Add(wxString::Format(_("%i%%"), i));
}
for (PowerPC::CPUCore cpu_core : PowerPC::AvailableCPUCores())
m_cpu_engine_array_string.Add(wxGetTranslation(CPU_CORE_NAMES.at(cpu_core)));
m_dual_core_checkbox = new wxCheckBox(this, wxID_ANY, _("Enable Dual Core (speedup)"));
m_cheats_checkbox = new wxCheckBox(this, wxID_ANY, _("Enable Cheats"));
#if defined(USE_ANALYTICS) && USE_ANALYTICS
m_analytics_checkbox = new wxCheckBox(this, wxID_ANY, _("Enable Usage Statistics Reporting"));
#ifdef __APPLE__
m_analytics_new_id = new wxButton(this, wxID_ANY, _("Generate a New Statistics Identity"),
wxDefaultPosition, wxSize(350, 25));
#else
m_analytics_new_id = new wxButton(this, wxID_ANY, _("Generate a New Statistics Identity"));
#endif
#endif
m_throttler_choice =
new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_throttler_array_string);
m_cpu_engine_radiobox =
new wxRadioBox(this, wxID_ANY, _("CPU Emulation Engine"), wxDefaultPosition, wxDefaultSize,
m_cpu_engine_array_string, 0, wxRA_SPECIFY_ROWS);
m_dual_core_checkbox->SetToolTip(
_("Splits the CPU and GPU threads so they can be run on separate cores.\nProvides major "
"speed improvements on most modern PCs, but can cause occasional crashes/glitches."));
m_cheats_checkbox->SetToolTip(_("Enables the use of Action Replay and Gecko cheats."));
#if defined(USE_ANALYTICS) && USE_ANALYTICS
m_analytics_checkbox->SetToolTip(
_("Enables the collection and sharing of usage statistics data with the Dolphin development "
"team. This data is used to improve the emulator and help us understand how our users "
"interact with the system. No private data is ever collected."));
m_analytics_new_id->SetToolTip(
_("Usage statistics reporting uses a unique random per-machine identifier to distinguish "
"users from one another. This button generates a new random identifier for this machine "
"which is dissociated from the previous one."));
#endif
m_throttler_choice->SetToolTip(_("Limits the emulation speed to the specified percentage.\nNote "
"that raising or lowering the emulation speed will also raise "
"or lower the audio pitch unless audio stretching is enabled."));
const int space5 = FromDIP(5);
wxBoxSizer* const throttler_sizer = new wxBoxSizer(wxHORIZONTAL);
throttler_sizer->AddSpacer(space5);
throttler_sizer->Add(new wxStaticText(this, wxID_ANY, _("Speed Limit:")), 0,
wxALIGN_CENTER_VERTICAL | wxBOTTOM, space5);
throttler_sizer->AddSpacer(space5);
throttler_sizer->Add(m_throttler_choice, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM, space5);
throttler_sizer->AddSpacer(space5);
wxStaticBoxSizer* const basic_settings_sizer =
new wxStaticBoxSizer(wxVERTICAL, this, _("Basic Settings"));
basic_settings_sizer->AddSpacer(space5);
basic_settings_sizer->Add(m_dual_core_checkbox, 0, wxLEFT | wxRIGHT, space5);
basic_settings_sizer->AddSpacer(space5);
basic_settings_sizer->Add(m_cheats_checkbox, 0, wxLEFT | wxRIGHT, space5);
basic_settings_sizer->AddSpacer(space5);
basic_settings_sizer->Add(throttler_sizer);
#if defined(USE_ANALYTICS) && USE_ANALYTICS
wxStaticBoxSizer* const analytics_sizer =
new wxStaticBoxSizer(wxVERTICAL, this, _("Usage Statistics Reporting Settings"));
analytics_sizer->AddSpacer(space5);
analytics_sizer->Add(m_analytics_checkbox, 0, wxLEFT | wxRIGHT, space5);
analytics_sizer->AddSpacer(space5);
analytics_sizer->Add(m_analytics_new_id, 0, wxLEFT | wxRIGHT, space5);
analytics_sizer->AddSpacer(space5);
#endif
wxStaticBoxSizer* const advanced_settings_sizer =
new wxStaticBoxSizer(wxVERTICAL, this, _("Advanced Settings"));
advanced_settings_sizer->AddSpacer(space5);
advanced_settings_sizer->Add(m_cpu_engine_radiobox, 0, wxLEFT | wxRIGHT, space5);
advanced_settings_sizer->AddSpacer(space5);
wxBoxSizer* const main_sizer = new wxBoxSizer(wxVERTICAL);
main_sizer->AddSpacer(space5);
main_sizer->Add(basic_settings_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
main_sizer->AddSpacer(space5);
#if defined(USE_ANALYTICS) && USE_ANALYTICS
main_sizer->Add(analytics_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
#endif
main_sizer->AddSpacer(space5);
main_sizer->Add(advanced_settings_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
main_sizer->AddSpacer(space5);
SetSizer(main_sizer);
}
void GeneralConfigPane::LoadGUIValues()
{
const SConfig& startup_params = SConfig::GetInstance();
m_dual_core_checkbox->SetValue(startup_params.bCPUThread);
m_cheats_checkbox->SetValue(startup_params.bEnableCheats);
#if defined(USE_ANALYTICS) && USE_ANALYTICS
m_analytics_checkbox->SetValue(startup_params.m_analytics_enabled);
#endif
u32 selection = std::lround(startup_params.m_EmulationSpeed * 10.0f);
if (selection < m_throttler_array_string.size())
m_throttler_choice->SetSelection(selection);
const std::vector<PowerPC::CPUCore>& cpu_cores = PowerPC::AvailableCPUCores();
for (size_t i = 0; i < cpu_cores.size(); ++i)
{
if (cpu_cores[i] == startup_params.cpu_core)
m_cpu_engine_radiobox->SetSelection(i);
}
}
void GeneralConfigPane::BindEvents()
{
m_dual_core_checkbox->Bind(wxEVT_CHECKBOX, &GeneralConfigPane::OnDualCoreCheckBoxChanged, this);
m_dual_core_checkbox->Bind(wxEVT_UPDATE_UI, &WxEventUtils::OnEnableIfCoreNotRunning);
m_cheats_checkbox->Bind(wxEVT_CHECKBOX, &GeneralConfigPane::OnCheatCheckBoxChanged, this);
m_cheats_checkbox->Bind(wxEVT_UPDATE_UI, &WxEventUtils::OnEnableIfCoreNotRunning);
#if defined(USE_ANALYTICS) && USE_ANALYTICS
m_analytics_checkbox->Bind(wxEVT_CHECKBOX, &GeneralConfigPane::OnAnalyticsCheckBoxChanged, this);
m_analytics_new_id->Bind(wxEVT_BUTTON, &GeneralConfigPane::OnAnalyticsNewIdButtonClick, this);
#endif
m_throttler_choice->Bind(wxEVT_CHOICE, &GeneralConfigPane::OnThrottlerChoiceChanged, this);
m_cpu_engine_radiobox->Bind(wxEVT_RADIOBOX, &GeneralConfigPane::OnCPUEngineRadioBoxChanged, this);
m_cpu_engine_radiobox->Bind(wxEVT_UPDATE_UI, &WxEventUtils::OnEnableIfCoreNotRunning);
}
void GeneralConfigPane::OnDualCoreCheckBoxChanged(wxCommandEvent& event)
{
if (Core::IsRunning())
return;
SConfig::GetInstance().bCPUThread = m_dual_core_checkbox->IsChecked();
}
void GeneralConfigPane::OnCheatCheckBoxChanged(wxCommandEvent& event)
{
SConfig::GetInstance().bEnableCheats = m_cheats_checkbox->IsChecked();
}
void GeneralConfigPane::OnThrottlerChoiceChanged(wxCommandEvent& event)
{
if (m_throttler_choice->GetSelection() != wxNOT_FOUND)
SConfig::GetInstance().m_EmulationSpeed = m_throttler_choice->GetSelection() * 0.1f;
}
void GeneralConfigPane::OnCPUEngineRadioBoxChanged(wxCommandEvent& event)
{
SConfig::GetInstance().cpu_core = PowerPC::AvailableCPUCores()[event.GetSelection()];
}
void GeneralConfigPane::OnAnalyticsCheckBoxChanged(wxCommandEvent& event)
{
SConfig::GetInstance().m_analytics_enabled = m_analytics_checkbox->IsChecked();
DolphinAnalytics::Instance()->ReloadConfig();
}
void GeneralConfigPane::OnAnalyticsNewIdButtonClick(wxCommandEvent& event)
{
DolphinAnalytics::Instance()->GenerateNewIdentity();
wxMessageBox(_("New identity generated."), _("Identity Generation"), wxICON_INFORMATION);
}