Merge pull request #10356 from AdmiralCurtiss/config-port-core-4

Config: Port remaining Core settings to new config system (the rest).
This commit is contained in:
JMC47 2022-01-11 16:08:19 -05:00 committed by GitHub
commit c18abfaecc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 116 additions and 157 deletions

View File

@ -44,6 +44,7 @@
#include "Core/Movie.h" #include "Core/Movie.h"
#include "Core/NetPlayProto.h" #include "Core/NetPlayProto.h"
#include "Core/PowerPC/PowerPC.h" #include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"
#include "Core/WiiRoot.h" #include "Core/WiiRoot.h"
#include "DiscIO/Enums.h" #include "DiscIO/Enums.h"
@ -69,12 +70,6 @@ public:
private: private:
bool valid = false; bool valid = false;
bool bCPUThread = false;
bool bMMU = false;
bool bSyncGPU = false;
int iSyncGpuMaxDistance = 0;
int iSyncGpuMinDistance = 0;
float fSyncGpuOverclock = 0;
std::array<WiimoteSource, MAX_BBMOTES> iWiimoteSource{}; std::array<WiimoteSource, MAX_BBMOTES> iWiimoteSource{};
}; };
@ -82,13 +77,6 @@ void ConfigCache::SaveConfig(const SConfig& config)
{ {
valid = true; valid = true;
bCPUThread = config.bCPUThread;
bMMU = config.bMMU;
bSyncGPU = config.bSyncGPU;
iSyncGpuMaxDistance = config.iSyncGpuMaxDistance;
iSyncGpuMinDistance = config.iSyncGpuMinDistance;
fSyncGpuOverclock = config.fSyncGpuOverclock;
for (int i = 0; i != MAX_BBMOTES; ++i) for (int i = 0; i != MAX_BBMOTES; ++i)
iWiimoteSource[i] = WiimoteCommon::GetSource(i); iWiimoteSource[i] = WiimoteCommon::GetSource(i);
@ -103,13 +91,6 @@ void ConfigCache::RestoreConfig(SConfig* config)
valid = false; valid = false;
config->bCPUThread = bCPUThread;
config->bMMU = bMMU;
config->bSyncGPU = bSyncGPU;
config->iSyncGpuMaxDistance = iSyncGpuMaxDistance;
config->iSyncGpuMinDistance = iSyncGpuMinDistance;
config->fSyncGpuOverclock = fSyncGpuOverclock;
// Only change these back if they were actually set by game ini, since they can be changed while a // Only change these back if they were actually set by game ini, since they can be changed while a
// game is running. // game is running.
if (config->bWii) if (config->bWii)
@ -143,13 +124,8 @@ bool BootCore(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi)
IniFile game_ini = StartUp.LoadGameIni(); IniFile game_ini = StartUp.LoadGameIni();
// General settings // General settings
IniFile::Section* core_section = game_ini.GetOrCreateSection("Core");
IniFile::Section* controls_section = game_ini.GetOrCreateSection("Controls"); IniFile::Section* controls_section = game_ini.GetOrCreateSection("Controls");
core_section->Get("CPUThread", &StartUp.bCPUThread, StartUp.bCPUThread);
core_section->Get("MMU", &StartUp.bMMU, StartUp.bMMU);
core_section->Get("SyncGPU", &StartUp.bSyncGPU, StartUp.bSyncGPU);
// Wii settings // Wii settings
if (StartUp.bWii) if (StartUp.bWii)
{ {
@ -180,9 +156,6 @@ bool BootCore(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi)
// Movie settings // Movie settings
if (Movie::IsPlayingInput() && Movie::IsConfigSaved()) if (Movie::IsPlayingInput() && Movie::IsConfigSaved())
{ {
// TODO: remove this once ConfigManager starts using OnionConfig.
StartUp.bCPUThread = Config::Get(Config::MAIN_CPU_THREAD);
StartUp.bSyncGPU = Config::Get(Config::MAIN_SYNC_GPU);
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
{ {
if (Movie::IsUsingMemcard(i) && Movie::IsStartingFromClearSave() && !StartUp.bWii) if (Movie::IsUsingMemcard(i) && Movie::IsStartingFromClearSave() && !StartUp.bWii)
@ -203,13 +176,7 @@ bool BootCore(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi)
{ {
const NetPlay::NetSettings& netplay_settings = NetPlay::GetNetSettings(); const NetPlay::NetSettings& netplay_settings = NetPlay::GetNetSettings();
Config::AddLayer(ConfigLoaders::GenerateNetPlayConfigLoader(netplay_settings)); Config::AddLayer(ConfigLoaders::GenerateNetPlayConfigLoader(netplay_settings));
StartUp.bCPUThread = netplay_settings.m_CPUthread;
StartUp.bCopyWiiSaveNetplay = netplay_settings.m_CopyWiiSave; StartUp.bCopyWiiSaveNetplay = netplay_settings.m_CopyWiiSave;
StartUp.bSyncGPU = netplay_settings.m_SyncGPU;
StartUp.iSyncGpuMaxDistance = netplay_settings.m_SyncGpuMaxDistance;
StartUp.iSyncGpuMinDistance = netplay_settings.m_SyncGpuMinDistance;
StartUp.fSyncGpuOverclock = netplay_settings.m_SyncGpuOverclock;
StartUp.bMMU = netplay_settings.m_MMU;
} }
else else
{ {
@ -263,6 +230,8 @@ bool BootCore(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi)
if (!boot->riivolution_patches.empty()) if (!boot->riivolution_patches.empty())
Config::SetCurrent(Config::MAIN_FAST_DISC_SPEED, true); Config::SetCurrent(Config::MAIN_FAST_DISC_SPEED, true);
Core::System::GetInstance().Initialize();
Core::UpdateWantDeterminism(/*initial*/ true); Core::UpdateWantDeterminism(/*initial*/ true);
if (StartUp.bWii) if (StartUp.bWii)

View File

@ -117,6 +117,13 @@ bool IsSettingSaveable(const Config::Location& config_location)
&Config::GetInfoForSIDevice(1).GetLocation(), &Config::GetInfoForSIDevice(1).GetLocation(),
&Config::GetInfoForSIDevice(2).GetLocation(), &Config::GetInfoForSIDevice(2).GetLocation(),
&Config::GetInfoForSIDevice(3).GetLocation(), &Config::GetInfoForSIDevice(3).GetLocation(),
&Config::MAIN_CPU_THREAD.GetLocation(),
&Config::MAIN_MMU.GetLocation(),
&Config::MAIN_BB_DUMP_PORT.GetLocation(),
&Config::MAIN_SYNC_GPU.GetLocation(),
&Config::MAIN_SYNC_GPU_MAX_DISTANCE.GetLocation(),
&Config::MAIN_SYNC_GPU_MIN_DISTANCE.GetLocation(),
&Config::MAIN_SYNC_GPU_OVERCLOCK.GetLocation(),
// UI.General // UI.General

View File

@ -84,50 +84,13 @@ SConfig::~SConfig()
void SConfig::SaveSettings() void SConfig::SaveSettings()
{ {
NOTICE_LOG_FMT(BOOT, "Saving settings to {}", File::GetUserPath(F_DOLPHINCONFIG_IDX)); NOTICE_LOG_FMT(BOOT, "Saving settings to {}", File::GetUserPath(F_DOLPHINCONFIG_IDX));
IniFile ini;
ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX)); // load first to not kill unknown stuff
SaveCoreSettings(ini);
ini.Save(File::GetUserPath(F_DOLPHINCONFIG_IDX));
Config::Save(); Config::Save();
} }
void SConfig::SaveCoreSettings(IniFile& ini)
{
IniFile::Section* core = ini.GetOrCreateSection("Core");
core->Set("CPUThread", bCPUThread);
core->Set("SyncGPU", bSyncGPU);
core->Set("SyncGpuMaxDistance", iSyncGpuMaxDistance);
core->Set("SyncGpuMinDistance", iSyncGpuMinDistance);
core->Set("SyncGpuOverclock", fSyncGpuOverclock);
core->Set("MMU", bMMU);
}
void SConfig::LoadSettings() void SConfig::LoadSettings()
{ {
Config::Load();
INFO_LOG_FMT(BOOT, "Loading Settings from {}", File::GetUserPath(F_DOLPHINCONFIG_IDX)); INFO_LOG_FMT(BOOT, "Loading Settings from {}", File::GetUserPath(F_DOLPHINCONFIG_IDX));
IniFile ini; Config::Load();
ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX));
LoadCoreSettings(ini);
}
void SConfig::LoadCoreSettings(IniFile& ini)
{
IniFile::Section* core = ini.GetOrCreateSection("Core");
core->Get("CPUThread", &bCPUThread, true);
core->Get("MMU", &bMMU, bMMU);
core->Get("BBDumpPort", &iBBDumpPort, -1);
core->Get("SyncGPU", &bSyncGPU, false);
core->Get("SyncGpuMaxDistance", &iSyncGpuMaxDistance, 200000);
core->Get("SyncGpuMinDistance", &iSyncGpuMinDistance, -200000);
core->Get("SyncGpuOverclock", &fSyncGpuOverclock, 1.0f);
} }
void SConfig::ResetRunningGameMetadata() void SConfig::ResetRunningGameMetadata()
@ -243,10 +206,6 @@ void SConfig::LoadDefaults()
bAutomaticStart = false; bAutomaticStart = false;
bBootToPause = false; bBootToPause = false;
bCPUThread = false;
bMMU = false;
iBBDumpPort = -1;
bSyncGPU = false;
bWii = false; bWii = false;
ResetRunningGameMetadata(); ResetRunningGameMetadata();

View File

@ -56,17 +56,8 @@ struct SConfig
bool bJITNoBlockCache = false; bool bJITNoBlockCache = false;
bool bJITNoBlockLinking = false; bool bJITNoBlockLinking = false;
bool bCPUThread = true;
bool bCopyWiiSaveNetplay = true; bool bCopyWiiSaveNetplay = true;
bool bMMU = false;
int iBBDumpPort = 0;
bool bSyncGPU = false;
int iSyncGpuMaxDistance;
int iSyncGpuMinDistance;
float fSyncGpuOverclock;
bool bWii = false; bool bWii = false;
bool m_is_mios = false; bool m_is_mios = false;
@ -134,10 +125,6 @@ private:
SConfig(); SConfig();
~SConfig(); ~SConfig();
void SaveCoreSettings(IniFile& ini);
void LoadCoreSettings(IniFile& ini);
void SetRunningGameMetadata(const std::string& game_id, const std::string& gametdb_id, void SetRunningGameMetadata(const std::string& game_id, const std::string& gametdb_id,
u64 title_id, u16 revision, DiscIO::Region region); u64 title_id, u16 revision, DiscIO::Region region);

View File

@ -67,6 +67,7 @@
#include "Core/PowerPC/JitInterface.h" #include "Core/PowerPC/JitInterface.h"
#include "Core/PowerPC/PowerPC.h" #include "Core/PowerPC/PowerPC.h"
#include "Core/State.h" #include "Core/State.h"
#include "Core/System.h"
#include "Core/WiiRoot.h" #include "Core/WiiRoot.h"
#ifdef USE_MEMORYWATCHER #ifdef USE_MEMORYWATCHER
@ -202,8 +203,7 @@ bool IsCPUThread()
bool IsGPUThread() bool IsGPUThread()
{ {
const SConfig& _CoreParameter = SConfig::GetInstance(); if (Core::System::GetInstance().IsDualCoreMode())
if (_CoreParameter.bCPUThread)
{ {
return (s_emu_thread.joinable() && (s_emu_thread.get_id() == std::this_thread::get_id())); return (s_emu_thread.joinable() && (s_emu_thread.get_id() == std::this_thread::get_id()));
} }
@ -238,7 +238,8 @@ bool Init(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi)
HostDispatchJobs(); HostDispatchJobs();
INFO_LOG_FMT(BOOT, "Starting core = {} mode", SConfig::GetInstance().bWii ? "Wii" : "GameCube"); INFO_LOG_FMT(BOOT, "Starting core = {} mode", SConfig::GetInstance().bWii ? "Wii" : "GameCube");
INFO_LOG_FMT(BOOT, "CPU Thread separate = {}", SConfig::GetInstance().bCPUThread ? "Yes" : "No"); INFO_LOG_FMT(BOOT, "CPU Thread separate = {}",
Core::System::GetInstance().IsDualCoreMode() ? "Yes" : "No");
Host_UpdateMainFrame(); // Disable any menus or buttons at boot Host_UpdateMainFrame(); // Disable any menus or buttons at boot
@ -272,8 +273,6 @@ void Stop() // - Hammertime!
if (GetState() == State::Stopping || GetState() == State::Uninitialized) if (GetState() == State::Stopping || GetState() == State::Uninitialized)
return; return;
const SConfig& _CoreParameter = SConfig::GetInstance();
s_is_stopping = true; s_is_stopping = true;
s_timer.Stop(); s_timer.Stop();
@ -291,7 +290,7 @@ void Stop() // - Hammertime!
INFO_LOG_FMT(CONSOLE, "{}", StopMessage(true, "Stop CPU")); INFO_LOG_FMT(CONSOLE, "{}", StopMessage(true, "Stop CPU"));
CPU::Stop(); CPU::Stop();
if (_CoreParameter.bCPUThread) if (Core::System::GetInstance().IsDualCoreMode())
{ {
// Video_EnterLoop() should now exit so that EmuThread() // Video_EnterLoop() should now exit so that EmuThread()
// will continue concurrently with the rest of the commands // will continue concurrently with the rest of the commands
@ -333,8 +332,7 @@ static void CpuThread(const std::optional<std::string>& savestate_path, bool del
{ {
DeclareAsCPUThread(); DeclareAsCPUThread();
const SConfig& _CoreParameter = SConfig::GetInstance(); if (Core::System::GetInstance().IsDualCoreMode())
if (_CoreParameter.bCPUThread)
Common::SetCurrentThreadName("CPU thread"); Common::SetCurrentThreadName("CPU thread");
else else
Common::SetCurrentThreadName("CPU-GPU thread"); Common::SetCurrentThreadName("CPU-GPU thread");
@ -413,8 +411,7 @@ static void FifoPlayerThread(const std::optional<std::string>& savestate_path,
{ {
DeclareAsCPUThread(); DeclareAsCPUThread();
const SConfig& _CoreParameter = SConfig::GetInstance(); if (Core::System::GetInstance().IsDualCoreMode())
if (_CoreParameter.bCPUThread)
Common::SetCurrentThreadName("FIFO player thread"); Common::SetCurrentThreadName("FIFO player thread");
else else
Common::SetCurrentThreadName("FIFO-GPU thread"); Common::SetCurrentThreadName("FIFO-GPU thread");
@ -446,6 +443,7 @@ static void FifoPlayerThread(const std::optional<std::string>& savestate_path,
// See the BootManager.cpp file description for a complete call schedule. // See the BootManager.cpp file description for a complete call schedule.
static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi) static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi)
{ {
const Core::System& system = Core::System::GetInstance();
const SConfig& core_parameter = SConfig::GetInstance(); const SConfig& core_parameter = SConfig::GetInstance();
CallOnStateChangedCallbacks(State::Starting); CallOnStateChangedCallbacks(State::Starting);
Common::ScopeGuard flag_guard{[] { Common::ScopeGuard flag_guard{[] {
@ -647,7 +645,7 @@ static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi
} }
// ENTER THE VIDEO THREAD LOOP // ENTER THE VIDEO THREAD LOOP
if (core_parameter.bCPUThread) if (system.IsDualCoreMode())
{ {
// This thread, after creating the EmuWindow, spawns a CPU // This thread, after creating the EmuWindow, spawns a CPU
// thread, and then takes over and becomes the video thread // thread, and then takes over and becomes the video thread
@ -930,8 +928,6 @@ void Callback_NewField()
void UpdateTitle(u32 ElapseTime) void UpdateTitle(u32 ElapseTime)
{ {
SConfig& _CoreParameter = SConfig::GetInstance();
if (ElapseTime == 0) if (ElapseTime == 0)
ElapseTime = 1; ElapseTime = 1;
@ -942,8 +938,9 @@ void UpdateTitle(u32 ElapseTime)
// Settings are shown the same for both extended and summary info // Settings are shown the same for both extended and summary info
const std::string SSettings = fmt::format( const std::string SSettings = fmt::format(
"{} {} | {} | {}", PowerPC::GetCPUName(), _CoreParameter.bCPUThread ? "DC" : "SC", "{} {} | {} | {}", PowerPC::GetCPUName(),
g_video_backend->GetDisplayName(), Config::Get(Config::MAIN_DSP_HLE) ? "HLE" : "LLE"); Core::System::GetInstance().IsDualCoreMode() ? "DC" : "SC", g_video_backend->GetDisplayName(),
Config::Get(Config::MAIN_DSP_HLE) ? "HLE" : "LLE");
std::string SFPS; std::string SFPS;
if (Movie::IsPlayingInput()) if (Movie::IsPlayingInput())

View File

@ -359,9 +359,9 @@ void DolphinAnalytics::MakePerGameBuilder()
builder.AddData("cfg-dsp-hle", Config::Get(Config::MAIN_DSP_HLE)); builder.AddData("cfg-dsp-hle", Config::Get(Config::MAIN_DSP_HLE));
builder.AddData("cfg-dsp-jit", Config::Get(Config::MAIN_DSP_JIT)); builder.AddData("cfg-dsp-jit", Config::Get(Config::MAIN_DSP_JIT));
builder.AddData("cfg-dsp-thread", Config::Get(Config::MAIN_DSP_THREAD)); builder.AddData("cfg-dsp-thread", Config::Get(Config::MAIN_DSP_THREAD));
builder.AddData("cfg-cpu-thread", SConfig::GetInstance().bCPUThread); builder.AddData("cfg-cpu-thread", Config::Get(Config::MAIN_CPU_THREAD));
builder.AddData("cfg-fastmem", Config::Get(Config::MAIN_FASTMEM)); builder.AddData("cfg-fastmem", Config::Get(Config::MAIN_FASTMEM));
builder.AddData("cfg-syncgpu", SConfig::GetInstance().bSyncGPU); builder.AddData("cfg-syncgpu", Config::Get(Config::MAIN_SYNC_GPU));
builder.AddData("cfg-audio-backend", Config::Get(Config::MAIN_AUDIO_BACKEND)); builder.AddData("cfg-audio-backend", Config::Get(Config::MAIN_AUDIO_BACKEND));
builder.AddData("cfg-oc-enable", Config::Get(Config::MAIN_OVERCLOCK_ENABLE)); builder.AddData("cfg-oc-enable", Config::Get(Config::MAIN_OVERCLOCK_ENABLE));
builder.AddData("cfg-oc-factor", Config::Get(Config::MAIN_OVERCLOCK)); builder.AddData("cfg-oc-factor", Config::Get(Config::MAIN_OVERCLOCK));

View File

@ -33,6 +33,7 @@
#include "Core/HW/WII_IPC.h" #include "Core/HW/WII_IPC.h"
#include "Core/PowerPC/JitCommon/JitBase.h" #include "Core/PowerPC/JitCommon/JitBase.h"
#include "Core/PowerPC/PowerPC.h" #include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"
#include "VideoCommon/CommandProcessor.h" #include "VideoCommon/CommandProcessor.h"
#include "VideoCommon/PixelEngine.h" #include "VideoCommon/PixelEngine.h"
@ -260,7 +261,7 @@ void Init()
false}; false};
const bool wii = SConfig::GetInstance().bWii; const bool wii = SConfig::GetInstance().bWii;
const bool mmu = SConfig::GetInstance().bMMU; const bool mmu = Core::System::GetInstance().IsMMUMode();
bool fake_vmem = false; bool fake_vmem = false;
#ifndef _ARCH_32 #ifndef _ARCH_32

View File

@ -303,11 +303,11 @@ void Wiimote::Read()
if (result > 0) if (result > 0)
{ {
if (SConfig::GetInstance().iBBDumpPort > 0 && m_index == WIIMOTE_BALANCE_BOARD) if (m_balance_board_dump_port > 0 && m_index == WIIMOTE_BALANCE_BOARD)
{ {
static sf::UdpSocket Socket; static sf::UdpSocket Socket;
Socket.send((char*)rpt.data(), rpt.size(), sf::IpAddress::LocalHost, Socket.send((char*)rpt.data(), rpt.size(), sf::IpAddress::LocalHost,
SConfig::GetInstance().iBBDumpPort); m_balance_board_dump_port);
} }
// Add it to queue // Add it to queue
@ -324,11 +324,10 @@ bool Wiimote::Write()
Report const& rpt = m_write_reports.Front(); Report const& rpt = m_write_reports.Front();
if (SConfig::GetInstance().iBBDumpPort > 0 && m_index == WIIMOTE_BALANCE_BOARD) if (m_balance_board_dump_port > 0 && m_index == WIIMOTE_BALANCE_BOARD)
{ {
static sf::UdpSocket Socket; static sf::UdpSocket Socket;
Socket.send((char*)rpt.data(), rpt.size(), sf::IpAddress::LocalHost, Socket.send((char*)rpt.data(), rpt.size(), sf::IpAddress::LocalHost, m_balance_board_dump_port);
SConfig::GetInstance().iBBDumpPort);
} }
int ret = IOWrite(rpt.data(), rpt.size()); int ret = IOWrite(rpt.data(), rpt.size());
@ -816,6 +815,7 @@ void Wiimote::ThreadFunc()
void Wiimote::RefreshConfig() void Wiimote::RefreshConfig()
{ {
m_speaker_enabled_in_dolphin_config = Config::Get(Config::MAIN_WIIMOTE_ENABLE_SPEAKER); m_speaker_enabled_in_dolphin_config = Config::Get(Config::MAIN_WIIMOTE_ENABLE_SPEAKER);
m_balance_board_dump_port = Config::Get(Config::MAIN_BB_DUMP_PORT);
} }
int Wiimote::GetIndex() const int Wiimote::GetIndex() const

View File

@ -148,6 +148,7 @@ private:
Common::SPSCQueue<Report> m_write_reports; Common::SPSCQueue<Report> m_write_reports;
bool m_speaker_enabled_in_dolphin_config = false; bool m_speaker_enabled_in_dolphin_config = false;
int m_balance_board_dump_port = 0;
size_t m_config_changed_callback_id; size_t m_config_changed_callback_id;
}; };

View File

@ -48,7 +48,7 @@ JitArm64::~JitArm64() = default;
void JitArm64::Init() void JitArm64::Init()
{ {
const size_t child_code_size = SConfig::GetInstance().bMMU ? FARCODE_SIZE_MMU : FARCODE_SIZE; const size_t child_code_size = m_mmu_enabled ? FARCODE_SIZE_MMU : FARCODE_SIZE;
AllocCodeSpace(CODE_SIZE + child_code_size); AllocCodeSpace(CODE_SIZE + child_code_size);
AddChildCodeSpace(&m_far_code, child_code_size); AddChildCodeSpace(&m_far_code, child_code_size);

View File

@ -10,6 +10,7 @@
#include "Core/HW/CPU.h" #include "Core/HW/CPU.h"
#include "Core/PowerPC/PPCAnalyst.h" #include "Core/PowerPC/PPCAnalyst.h"
#include "Core/PowerPC/PowerPC.h" #include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"
const u8* JitBase::Dispatch(JitBase& jit) const u8* JitBase::Dispatch(JitBase& jit)
{ {
@ -55,6 +56,7 @@ void JitBase::RefreshConfig()
m_fprf = Config::Get(Config::MAIN_FPRF); m_fprf = Config::Get(Config::MAIN_FPRF);
m_accurate_nans = Config::Get(Config::MAIN_ACCURATE_NANS); m_accurate_nans = Config::Get(Config::MAIN_ACCURATE_NANS);
m_fastmem_enabled = Config::Get(Config::MAIN_FASTMEM); m_fastmem_enabled = Config::Get(Config::MAIN_FASTMEM);
m_mmu_enabled = Core::System::GetInstance().IsMMUMode();
analyzer.SetDebuggingEnabled(m_enable_debugging); analyzer.SetDebuggingEnabled(m_enable_debugging);
analyzer.SetBranchFollowingEnabled(Config::Get(Config::MAIN_JIT_FOLLOW_BRANCH)); analyzer.SetBranchFollowingEnabled(Config::Get(Config::MAIN_JIT_FOLLOW_BRANCH));
analyzer.SetFloatExceptionsEnabled(m_enable_float_exceptions); analyzer.SetFloatExceptionsEnabled(m_enable_float_exceptions);
@ -80,7 +82,7 @@ void JitBase::UpdateMemoryAndExceptionOptions()
{ {
bool any_watchpoints = PowerPC::memchecks.HasAny(); bool any_watchpoints = PowerPC::memchecks.HasAny();
jo.fastmem = m_fastmem_enabled && jo.fastmem_arena && (MSR.DR || !any_watchpoints); jo.fastmem = m_fastmem_enabled && jo.fastmem_arena && (MSR.DR || !any_watchpoints);
jo.memcheck = SConfig::GetInstance().bMMU || any_watchpoints; jo.memcheck = m_mmu_enabled || any_watchpoints;
jo.fp_exceptions = m_enable_float_exceptions; jo.fp_exceptions = m_enable_float_exceptions;
jo.div_by_zero_exceptions = m_enable_div_by_zero_exceptions; jo.div_by_zero_exceptions = m_enable_div_by_zero_exceptions;
} }

View File

@ -133,6 +133,7 @@ protected:
bool m_fprf = false; bool m_fprf = false;
bool m_accurate_nans = false; bool m_accurate_nans = false;
bool m_fastmem_enabled = false; bool m_fastmem_enabled = false;
bool m_mmu_enabled = false;
void RefreshConfig(); void RefreshConfig();

View File

@ -21,6 +21,7 @@
#include "Core/PowerPC/GDBStub.h" #include "Core/PowerPC/GDBStub.h"
#include "Core/PowerPC/JitInterface.h" #include "Core/PowerPC/JitInterface.h"
#include "Core/PowerPC/PowerPC.h" #include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"
#include "VideoCommon/VideoBackendBase.h" #include "VideoCommon/VideoBackendBase.h"
@ -1147,7 +1148,7 @@ TranslateResult JitCache_TranslateAddress(u32 address)
static void GenerateDSIException(u32 effective_address, bool write) static void GenerateDSIException(u32 effective_address, bool write)
{ {
// DSI exceptions are only supported in MMU mode. // DSI exceptions are only supported in MMU mode.
if (!SConfig::GetInstance().bMMU) if (!Core::System::GetInstance().IsMMUMode())
{ {
PanicAlertFmt("Invalid {} {:#010x}, PC = {:#010x}", write ? "write to" : "read from", PanicAlertFmt("Invalid {} {:#010x}, PC = {:#010x}", write ? "write to" : "read from",
effective_address, PC); effective_address, PC);

View File

@ -3,6 +3,8 @@
#include "Core/System.h" #include "Core/System.h"
#include "Core/Config/MainSettings.h"
namespace Core namespace Core
{ {
struct System::Impl struct System::Impl
@ -14,4 +16,10 @@ System::System() : m_impl{std::make_unique<Impl>()}
} }
System::~System() = default; System::~System() = default;
void System::Initialize()
{
m_separate_cpu_and_gpu_threads = Config::Get(Config::MAIN_CPU_THREAD);
m_mmu_enabled = Config::Get(Config::MAIN_MMU);
}
} // namespace Core } // namespace Core

View File

@ -26,10 +26,18 @@ public:
return instance; return instance;
} }
void Initialize();
bool IsDualCoreMode() const { return m_separate_cpu_and_gpu_threads; }
bool IsMMUMode() const { return m_mmu_enabled; }
private: private:
System(); System();
struct Impl; struct Impl;
std::unique_ptr<Impl> m_impl; std::unique_ptr<Impl> m_impl;
bool m_separate_cpu_and_gpu_threads = false;
bool m_mmu_enabled = false;
}; };
} // namespace Core } // namespace Core

View File

@ -178,7 +178,7 @@ void AdvancedPane::ConnectLayout()
}); });
connect(m_enable_mmu_checkbox, &QCheckBox::toggled, this, connect(m_enable_mmu_checkbox, &QCheckBox::toggled, this,
[](bool checked) { SConfig::GetInstance().bMMU = checked; }); [](bool checked) { Config::SetBaseOrCurrent(Config::MAIN_MMU, checked); });
m_cpu_clock_override_checkbox->setChecked(Config::Get(Config::MAIN_OVERCLOCK_ENABLE)); m_cpu_clock_override_checkbox->setChecked(Config::Get(Config::MAIN_OVERCLOCK_ENABLE));
connect(m_cpu_clock_override_checkbox, &QCheckBox::toggled, [this](bool enable_clock_override) { connect(m_cpu_clock_override_checkbox, &QCheckBox::toggled, [this](bool enable_clock_override) {
@ -243,7 +243,7 @@ void AdvancedPane::Update()
} }
m_cpu_emulation_engine_combobox->setEnabled(!running); m_cpu_emulation_engine_combobox->setEnabled(!running);
m_enable_mmu_checkbox->setChecked(SConfig::GetInstance().bMMU); m_enable_mmu_checkbox->setChecked(Config::Get(Config::MAIN_MMU));
m_enable_mmu_checkbox->setEnabled(!running); m_enable_mmu_checkbox->setEnabled(!running);
QFont bf = font(); QFont bf = font();

View File

@ -252,7 +252,7 @@ void GeneralPane::LoadConfig()
#if defined(USE_ANALYTICS) && USE_ANALYTICS #if defined(USE_ANALYTICS) && USE_ANALYTICS
m_checkbox_enable_analytics->setChecked(Settings::Instance().IsAnalyticsEnabled()); m_checkbox_enable_analytics->setChecked(Settings::Instance().IsAnalyticsEnabled());
#endif #endif
m_checkbox_dualcore->setChecked(SConfig::GetInstance().bCPUThread); m_checkbox_dualcore->setChecked(Config::Get(Config::MAIN_CPU_THREAD));
m_checkbox_cheats->setChecked(Settings::Instance().GetCheatsEnabled()); m_checkbox_cheats->setChecked(Settings::Instance().GetCheatsEnabled());
m_checkbox_override_region_settings->setChecked( m_checkbox_override_region_settings->setChecked(
Config::Get(Config::MAIN_OVERRIDE_REGION_SETTINGS)); Config::Get(Config::MAIN_OVERRIDE_REGION_SETTINGS));
@ -263,7 +263,7 @@ void GeneralPane::LoadConfig()
int selection = qRound(Config::Get(Config::MAIN_EMULATION_SPEED) * 10); int selection = qRound(Config::Get(Config::MAIN_EMULATION_SPEED) * 10);
if (selection < m_combobox_speedlimit->count()) if (selection < m_combobox_speedlimit->count())
m_combobox_speedlimit->setCurrentIndex(selection); m_combobox_speedlimit->setCurrentIndex(selection);
m_checkbox_dualcore->setChecked(SConfig::GetInstance().bCPUThread); m_checkbox_dualcore->setChecked(Config::Get(Config::MAIN_CPU_THREAD));
const auto fallback = Settings::Instance().GetFallbackRegion(); const auto fallback = Settings::Instance().GetFallbackRegion();
@ -346,7 +346,6 @@ void GeneralPane::OnSaveConfig()
Settings::Instance().SetAnalyticsEnabled(m_checkbox_enable_analytics->isChecked()); Settings::Instance().SetAnalyticsEnabled(m_checkbox_enable_analytics->isChecked());
DolphinAnalytics::Instance().ReloadConfig(); DolphinAnalytics::Instance().ReloadConfig();
#endif #endif
settings.bCPUThread = m_checkbox_dualcore->isChecked();
Config::SetBaseOrCurrent(Config::MAIN_CPU_THREAD, m_checkbox_dualcore->isChecked()); Config::SetBaseOrCurrent(Config::MAIN_CPU_THREAD, m_checkbox_dualcore->isChecked());
Settings::Instance().SetCheatsEnabled(m_checkbox_cheats->isChecked()); Settings::Instance().SetCheatsEnabled(m_checkbox_cheats->isChecked());
Config::SetBaseOrCurrent(Config::MAIN_OVERRIDE_REGION_SETTINGS, Config::SetBaseOrCurrent(Config::MAIN_OVERRIDE_REGION_SETTINGS,

View File

@ -17,6 +17,7 @@
#include "Core/HW/GPFifo.h" #include "Core/HW/GPFifo.h"
#include "Core/HW/MMIO.h" #include "Core/HW/MMIO.h"
#include "Core/HW/ProcessorInterface.h" #include "Core/HW/ProcessorInterface.h"
#include "Core/System.h"
#include "VideoCommon/Fifo.h" #include "VideoCommon/Fifo.h"
namespace CommandProcessor namespace CommandProcessor
@ -42,7 +43,7 @@ static Common::Flag s_interrupt_waiting;
static bool IsOnThread() static bool IsOnThread()
{ {
return SConfig::GetInstance().bCPUThread; return Core::System::GetInstance().IsDualCoreMode();
} }
static void UpdateInterrupts_Wrapper(u64 userdata, s64 cyclesLate) static void UpdateInterrupts_Wrapper(u64 userdata, s64 cyclesLate)

View File

@ -19,6 +19,7 @@
#include "Core/CoreTiming.h" #include "Core/CoreTiming.h"
#include "Core/HW/Memmap.h" #include "Core/HW/Memmap.h"
#include "Core/Host.h" #include "Core/Host.h"
#include "Core/System.h"
#include "VideoCommon/AsyncRequests.h" #include "VideoCommon/AsyncRequests.h"
#include "VideoCommon/CPMemory.h" #include "VideoCommon/CPMemory.h"
@ -71,6 +72,20 @@ static std::atomic<int> s_sync_ticks;
static bool s_syncing_suspended; static bool s_syncing_suspended;
static Common::Event s_sync_wakeup_event; static Common::Event s_sync_wakeup_event;
static std::optional<size_t> s_config_callback_id = std::nullopt;
static bool s_config_sync_gpu = false;
static int s_config_sync_gpu_max_distance = 0;
static int s_config_sync_gpu_min_distance = 0;
static float s_config_sync_gpu_overclock = 0.0f;
static void RefreshConfig()
{
s_config_sync_gpu = Config::Get(Config::MAIN_SYNC_GPU);
s_config_sync_gpu_max_distance = Config::Get(Config::MAIN_SYNC_GPU_MAX_DISTANCE);
s_config_sync_gpu_min_distance = Config::Get(Config::MAIN_SYNC_GPU_MIN_DISTANCE);
s_config_sync_gpu_overclock = Config::Get(Config::MAIN_SYNC_GPU_OVERCLOCK);
}
void DoState(PointerWrap& p) void DoState(PointerWrap& p)
{ {
p.DoArray(s_video_buffer, FIFO_SIZE); p.DoArray(s_video_buffer, FIFO_SIZE);
@ -95,9 +110,7 @@ void PauseAndLock(bool doLock, bool unpauseOnUnlock)
SyncGPU(SyncGPUReason::Other); SyncGPU(SyncGPUReason::Other);
EmulatorState(false); EmulatorState(false);
const SConfig& param = SConfig::GetInstance(); if (!Core::System::GetInstance().IsDualCoreMode() || s_use_deterministic_gpu_thread)
if (!param.bCPUThread || s_use_deterministic_gpu_thread)
return; return;
s_gpu_mainloop.WaitYield(std::chrono::milliseconds(100), Host_YieldToUI); s_gpu_mainloop.WaitYield(std::chrono::milliseconds(100), Host_YieldToUI);
@ -111,10 +124,14 @@ void PauseAndLock(bool doLock, bool unpauseOnUnlock)
void Init() void Init()
{ {
if (!s_config_callback_id)
s_config_callback_id = Config::AddConfigChangedCallback(RefreshConfig);
RefreshConfig();
// Padded so that SIMD overreads in the vertex loader are safe // Padded so that SIMD overreads in the vertex loader are safe
s_video_buffer = static_cast<u8*>(Common::AllocateMemoryPages(FIFO_SIZE + 4)); s_video_buffer = static_cast<u8*>(Common::AllocateMemoryPages(FIFO_SIZE + 4));
ResetVideoBuffer(); ResetVideoBuffer();
if (SConfig::GetInstance().bCPUThread) if (Core::System::GetInstance().IsDualCoreMode())
s_gpu_mainloop.Prepare(); s_gpu_mainloop.Prepare();
s_sync_ticks.store(0); s_sync_ticks.store(0);
} }
@ -132,6 +149,12 @@ void Shutdown()
s_video_buffer_seen_ptr = nullptr; s_video_buffer_seen_ptr = nullptr;
s_fifo_aux_write_ptr = nullptr; s_fifo_aux_write_ptr = nullptr;
s_fifo_aux_read_ptr = nullptr; s_fifo_aux_read_ptr = nullptr;
if (s_config_callback_id)
{
Config::RemoveConfigChangedCallback(*s_config_callback_id);
s_config_callback_id = std::nullopt;
}
} }
// May be executed from any thread, even the graphics thread. // May be executed from any thread, even the graphics thread.
@ -297,10 +320,8 @@ void RunGpuLoop()
AsyncRequests::GetInstance()->SetEnable(true); AsyncRequests::GetInstance()->SetEnable(true);
AsyncRequests::GetInstance()->SetPassthrough(false); AsyncRequests::GetInstance()->SetPassthrough(false);
const SConfig& param = SConfig::GetInstance();
s_gpu_mainloop.Run( s_gpu_mainloop.Run(
[&param] { [] {
// Run events from the CPU thread. // Run events from the CPU thread.
AsyncRequests::GetInstance()->PullEvents(); AsyncRequests::GetInstance()->PullEvents();
@ -331,7 +352,7 @@ void RunGpuLoop()
fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) && fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) &&
fifo.CPReadWriteDistance.load(std::memory_order_relaxed) && !AtBreakpoint()) fifo.CPReadWriteDistance.load(std::memory_order_relaxed) && !AtBreakpoint())
{ {
if (param.bSyncGPU && s_sync_ticks.load() < param.iSyncGpuMinDistance) if (s_config_sync_gpu && s_sync_ticks.load() < s_config_sync_gpu_min_distance)
break; break;
u32 cyclesExecuted = 0; u32 cyclesExecuted = 0;
@ -363,12 +384,12 @@ void RunGpuLoop()
CommandProcessor::SetCPStatusFromGPU(); CommandProcessor::SetCPStatusFromGPU();
if (param.bSyncGPU) if (s_config_sync_gpu)
{ {
cyclesExecuted = (int)(cyclesExecuted / param.fSyncGpuOverclock); cyclesExecuted = (int)(cyclesExecuted / s_config_sync_gpu_overclock);
int old = s_sync_ticks.fetch_sub(cyclesExecuted); int old = s_sync_ticks.fetch_sub(cyclesExecuted);
if (old >= param.iSyncGpuMaxDistance && if (old >= s_config_sync_gpu_max_distance &&
old - (int)cyclesExecuted < param.iSyncGpuMaxDistance) old - (int)cyclesExecuted < s_config_sync_gpu_max_distance)
s_sync_wakeup_event.Set(); s_sync_wakeup_event.Set();
} }
@ -383,7 +404,7 @@ void RunGpuLoop()
if (s_sync_ticks.load() > 0) if (s_sync_ticks.load() > 0)
{ {
int old = s_sync_ticks.exchange(0); int old = s_sync_ticks.exchange(0);
if (old >= param.iSyncGpuMaxDistance) if (old >= s_config_sync_gpu_max_distance)
s_sync_wakeup_event.Set(); s_sync_wakeup_event.Set();
} }
@ -400,9 +421,7 @@ void RunGpuLoop()
void FlushGpu() void FlushGpu()
{ {
const SConfig& param = SConfig::GetInstance(); if (!Core::System::GetInstance().IsDualCoreMode() || s_use_deterministic_gpu_thread)
if (!param.bCPUThread || s_use_deterministic_gpu_thread)
return; return;
s_gpu_mainloop.Wait(); s_gpu_mainloop.Wait();
@ -423,17 +442,16 @@ bool AtBreakpoint()
void RunGpu() void RunGpu()
{ {
const SConfig& param = SConfig::GetInstance(); const bool is_dual_core = Core::System::GetInstance().IsDualCoreMode();
// wake up GPU thread // wake up GPU thread
if (param.bCPUThread && !s_use_deterministic_gpu_thread) if (is_dual_core && !s_use_deterministic_gpu_thread)
{ {
s_gpu_mainloop.Wakeup(); s_gpu_mainloop.Wakeup();
} }
// if the sync GPU callback is suspended, wake it up. // if the sync GPU callback is suspended, wake it up.
if (!SConfig::GetInstance().bCPUThread || s_use_deterministic_gpu_thread || if (!is_dual_core || s_use_deterministic_gpu_thread || s_config_sync_gpu)
SConfig::GetInstance().bSyncGPU)
{ {
if (s_syncing_suspended) if (s_syncing_suspended)
{ {
@ -447,7 +465,7 @@ static int RunGpuOnCpu(int ticks)
{ {
CommandProcessor::SCPFifoStruct& fifo = CommandProcessor::fifo; CommandProcessor::SCPFifoStruct& fifo = CommandProcessor::fifo;
bool reset_simd_state = false; bool reset_simd_state = false;
int available_ticks = int(ticks * SConfig::GetInstance().fSyncGpuOverclock) + s_sync_ticks.load(); int available_ticks = int(ticks * s_config_sync_gpu_overclock) + s_sync_ticks.load();
while (fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) && while (fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) &&
fifo.CPReadWriteDistance.load(std::memory_order_relaxed) && !AtBreakpoint() && fifo.CPReadWriteDistance.load(std::memory_order_relaxed) && !AtBreakpoint() &&
available_ticks >= 0) available_ticks >= 0)
@ -508,7 +526,6 @@ void UpdateWantDeterminism(bool want)
{ {
// We are paused (or not running at all yet), so // We are paused (or not running at all yet), so
// it should be safe to change this. // it should be safe to change this.
const SConfig& param = SConfig::GetInstance();
bool gpu_thread = false; bool gpu_thread = false;
switch (Config::GetGPUDeterminismMode()) switch (Config::GetGPUDeterminismMode())
{ {
@ -523,7 +540,7 @@ void UpdateWantDeterminism(bool want)
break; break;
} }
gpu_thread = gpu_thread && param.bCPUThread; gpu_thread = gpu_thread && Core::System::GetInstance().IsDualCoreMode();
if (s_use_deterministic_gpu_thread != gpu_thread) if (s_use_deterministic_gpu_thread != gpu_thread)
{ {
@ -550,8 +567,6 @@ bool UseDeterministicGPUThread()
*/ */
static int WaitForGpuThread(int ticks) static int WaitForGpuThread(int ticks)
{ {
const SConfig& param = SConfig::GetInstance();
int old = s_sync_ticks.fetch_add(ticks); int old = s_sync_ticks.fetch_add(ticks);
int now = old + ticks; int now = old + ticks;
@ -560,15 +575,15 @@ static int WaitForGpuThread(int ticks)
return -1; return -1;
// Wakeup GPU // Wakeup GPU
if (old < param.iSyncGpuMinDistance && now >= param.iSyncGpuMinDistance) if (old < s_config_sync_gpu_min_distance && now >= s_config_sync_gpu_min_distance)
RunGpu(); RunGpu();
// If the GPU is still sleeping, wait for a longer time // If the GPU is still sleeping, wait for a longer time
if (now < param.iSyncGpuMinDistance) if (now < s_config_sync_gpu_min_distance)
return GPU_TIME_SLOT_SIZE + param.iSyncGpuMinDistance - now; return GPU_TIME_SLOT_SIZE + s_config_sync_gpu_min_distance - now;
// Wait for GPU // Wait for GPU
if (now >= param.iSyncGpuMaxDistance) if (now >= s_config_sync_gpu_max_distance)
s_sync_wakeup_event.Wait(); s_sync_wakeup_event.Wait();
return GPU_TIME_SLOT_SIZE; return GPU_TIME_SLOT_SIZE;
@ -579,11 +594,11 @@ static void SyncGPUCallback(u64 ticks, s64 cyclesLate)
ticks += cyclesLate; ticks += cyclesLate;
int next = -1; int next = -1;
if (!SConfig::GetInstance().bCPUThread || s_use_deterministic_gpu_thread) if (!Core::System::GetInstance().IsDualCoreMode() || s_use_deterministic_gpu_thread)
{ {
next = RunGpuOnCpu((int)ticks); next = RunGpuOnCpu((int)ticks);
} }
else if (SConfig::GetInstance().bSyncGPU) else if (s_config_sync_gpu)
{ {
next = WaitForGpuThread((int)ticks); next = WaitForGpuThread((int)ticks);
} }
@ -597,9 +612,9 @@ void SyncGPUForRegisterAccess()
{ {
SyncGPU(SyncGPUReason::Other); SyncGPU(SyncGPUReason::Other);
if (!SConfig::GetInstance().bCPUThread || s_use_deterministic_gpu_thread) if (!Core::System::GetInstance().IsDualCoreMode() || s_use_deterministic_gpu_thread)
RunGpuOnCpu(GPU_TIME_SLOT_SIZE); RunGpuOnCpu(GPU_TIME_SLOT_SIZE);
else if (SConfig::GetInstance().bSyncGPU) else if (s_config_sync_gpu)
WaitForGpuThread(GPU_TIME_SLOT_SIZE); WaitForGpuThread(GPU_TIME_SLOT_SIZE);
} }

View File

@ -10,11 +10,14 @@
#include "Common/ChunkFile.h" #include "Common/ChunkFile.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
#include "Core/Core.h" #include "Core/Core.h"
#include "Core/CoreTiming.h" #include "Core/CoreTiming.h"
#include "Core/HW/MMIO.h" #include "Core/HW/MMIO.h"
#include "Core/HW/ProcessorInterface.h" #include "Core/HW/ProcessorInterface.h"
#include "Core/System.h"
#include "VideoCommon/BoundingBox.h" #include "VideoCommon/BoundingBox.h"
#include "VideoCommon/Fifo.h" #include "VideoCommon/Fifo.h"
#include "VideoCommon/PerfQueryBase.h" #include "VideoCommon/PerfQueryBase.h"
@ -286,7 +289,7 @@ static void RaiseEvent(int cycles_into_future)
CoreTiming::FromThread from = CoreTiming::FromThread::NON_CPU; CoreTiming::FromThread from = CoreTiming::FromThread::NON_CPU;
s64 cycles = 0; // we don't care about timings for dual core mode. s64 cycles = 0; // we don't care about timings for dual core mode.
if (!SConfig::GetInstance().bCPUThread || Fifo::UseDeterministicGPUThread()) if (!Core::System::GetInstance().IsDualCoreMode() || Fifo::UseDeterministicGPUThread())
{ {
from = CoreTiming::FromThread::CPU; from = CoreTiming::FromThread::CPU;

View File

@ -13,7 +13,6 @@
#include "Common/ChunkFile.h" #include "Common/ChunkFile.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/Config/Config.h"
#include "Common/Event.h" #include "Common/Event.h"
#include "Common/FileUtil.h" #include "Common/FileUtil.h"
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
@ -21,6 +20,7 @@
#include "Core/Config/MainSettings.h" #include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
#include "Core/Core.h" #include "Core/Core.h"
#include "Core/System.h"
// TODO: ugly // TODO: ugly
#ifdef _WIN32 #ifdef _WIN32
@ -289,7 +289,7 @@ void VideoBackendBase::PopulateBackendInfoFromUI()
void VideoBackendBase::DoState(PointerWrap& p) void VideoBackendBase::DoState(PointerWrap& p)
{ {
if (!SConfig::GetInstance().bCPUThread) if (!Core::System::GetInstance().IsDualCoreMode())
{ {
VideoCommon_DoState(p); VideoCommon_DoState(p);
return; return;