diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp index 80ee9f7348..1a6190925d 100644 --- a/Source/Core/Core/BootManager.cpp +++ b/Source/Core/Core/BootManager.cpp @@ -72,6 +72,7 @@ public: private: bool valid; bool bCPUThread; + bool bJITFollowBranch; bool bEnableCheats; bool bSyncGPUOnSkipIdleHack; bool bFPRF; @@ -81,6 +82,9 @@ private: bool bLowDCBZHack; bool m_EnableJIT; bool bSyncGPU; + int iSyncGpuMaxDistance; + int iSyncGpuMinDistance; + float fSyncGpuOverclock; bool bFastDiscSpeed; bool bDSPHLE; bool bHLE_BS2; @@ -103,6 +107,7 @@ void ConfigCache::SaveConfig(const SConfig& config) valid = true; bCPUThread = config.bCPUThread; + bJITFollowBranch = config.bJITFollowBranch; bEnableCheats = config.bEnableCheats; bSyncGPUOnSkipIdleHack = config.bSyncGPUOnSkipIdleHack; bFPRF = config.bFPRF; @@ -111,6 +116,9 @@ void ConfigCache::SaveConfig(const SConfig& config) bDCBZOFF = config.bDCBZOFF; m_EnableJIT = config.m_DSPEnableJIT; bSyncGPU = config.bSyncGPU; + iSyncGpuMaxDistance = config.iSyncGpuMaxDistance; + iSyncGpuMinDistance = config.iSyncGpuMinDistance; + fSyncGpuOverclock = config.fSyncGpuOverclock; bFastDiscSpeed = config.bFastDiscSpeed; bDSPHLE = config.bDSPHLE; bHLE_BS2 = config.bHLE_BS2; @@ -143,6 +151,7 @@ void ConfigCache::RestoreConfig(SConfig* config) valid = false; config->bCPUThread = bCPUThread; + config->bJITFollowBranch = bJITFollowBranch; config->bEnableCheats = bEnableCheats; config->bSyncGPUOnSkipIdleHack = bSyncGPUOnSkipIdleHack; config->bFPRF = bFPRF; @@ -152,6 +161,9 @@ void ConfigCache::RestoreConfig(SConfig* config) config->bLowDCBZHack = bLowDCBZHack; config->m_DSPEnableJIT = m_EnableJIT; config->bSyncGPU = bSyncGPU; + config->iSyncGpuMaxDistance = iSyncGpuMaxDistance; + config->iSyncGpuMinDistance = iSyncGpuMinDistance; + config->fSyncGpuOverclock = fSyncGpuOverclock; config->bFastDiscSpeed = bFastDiscSpeed; config->bDSPHLE = bDSPHLE; config->bHLE_BS2 = bHLE_BS2; @@ -240,7 +252,6 @@ bool BootCore(std::unique_ptr boot) IniFile::Section* controls_section = game_ini.GetOrCreateSection("Controls"); core_section->Get("CPUThread", &StartUp.bCPUThread, StartUp.bCPUThread); - core_section->Get("JITFollowBranch", &StartUp.bJITFollowBranch, StartUp.bJITFollowBranch); core_section->Get("EnableCheats", &StartUp.bEnableCheats, StartUp.bEnableCheats); core_section->Get("SyncOnSkipIdle", &StartUp.bSyncGPUOnSkipIdleHack, @@ -314,6 +325,7 @@ bool BootCore(std::unique_ptr boot) { // TODO: remove this once ConfigManager starts using OnionConfig. StartUp.bCPUThread = Config::Get(Config::MAIN_CPU_THREAD); + StartUp.bJITFollowBranch = Config::Get(Config::MAIN_JIT_FOLLOW_BRANCH); StartUp.bDSPHLE = Config::Get(Config::MAIN_DSP_HLE); StartUp.bFastDiscSpeed = Config::Get(Config::MAIN_FAST_DISC_SPEED); StartUp.cpu_core = Config::Get(Config::MAIN_CPU_CORE); @@ -353,6 +365,18 @@ bool BootCore(std::unique_ptr boot) StartUp.m_EXIDevice[1] = netplay_settings.m_EXIDevice[1]; config_cache.bSetEXIDevice[0] = true; config_cache.bSetEXIDevice[1] = true; + StartUp.bFPRF = netplay_settings.m_FPRF; + StartUp.bAccurateNaNs = netplay_settings.m_AccurateNaNs; + StartUp.bSyncGPUOnSkipIdleHack = netplay_settings.m_SyncOnSkipIdle; + 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.bJITFollowBranch = netplay_settings.m_JITFollowBranch; + StartUp.bFastDiscSpeed = netplay_settings.m_FastDiscSpeed; + StartUp.bMMU = netplay_settings.m_MMU; + StartUp.bFastmem = netplay_settings.m_Fastmem; + StartUp.bHLE_BS2 = netplay_settings.m_SkipIPL; } else { @@ -432,4 +456,4 @@ void RestoreConfig() config_cache.RestoreConfig(&SConfig::GetInstance()); } -} // namespace +} // namespace BootManager diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp index 027c4916a2..1c9882a951 100644 --- a/Source/Core/Core/Config/MainSettings.cpp +++ b/Source/Core/Core/Config/MainSettings.cpp @@ -16,8 +16,10 @@ namespace Config // Main.Core const ConfigInfo MAIN_SKIP_IPL{{System::Main, "Core", "SkipIPL"}, true}; +const ConfigInfo MAIN_LOAD_IPL_DUMP{{System::Main, "Core", "LoadIPLDump"}, true}; const ConfigInfo MAIN_CPU_CORE{{System::Main, "Core", "CPUCore"}, PowerPC::DefaultCPUCore()}; +const ConfigInfo MAIN_JIT_FOLLOW_BRANCH{{System::Main, "Core", "JITFollowBranch"}, true}; const ConfigInfo MAIN_FASTMEM{{System::Main, "Core", "Fastmem"}, true}; const ConfigInfo MAIN_DSP_HLE{{System::Main, "Core", "DSPHLE"}, true}; const ConfigInfo MAIN_TIMING_VARIANCE{{System::Main, "Core", "TimingVariance"}, 40}; diff --git a/Source/Core/Core/Config/MainSettings.h b/Source/Core/Core/Config/MainSettings.h index 260c16a1bc..3cfd4e3b5d 100644 --- a/Source/Core/Core/Config/MainSettings.h +++ b/Source/Core/Core/Config/MainSettings.h @@ -17,6 +17,8 @@ namespace Config { // Main.Core +extern const ConfigInfo MAIN_SKIP_IPL; +extern const ConfigInfo MAIN_LOAD_IPL_DUMP; extern const ConfigInfo MAIN_CPU_CORE; extern const ConfigInfo MAIN_JIT_FOLLOW_BRANCH; extern const ConfigInfo MAIN_FASTMEM; diff --git a/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp b/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp index 167cbecd0e..cb417d3b16 100644 --- a/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp +++ b/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp @@ -83,6 +83,7 @@ static const INIToLocationMap& GetINIToLocationMap() static const INIToSectionMap& GetINIToSectionMap() { static const INIToSectionMap ini_to_section = { + {"Core", {Config::System::Main, "Core"}}, {"Video_Hardware", {Config::System::GFX, "Hardware"}}, {"Video_Settings", {Config::System::GFX, "Settings"}}, {"Video_Enhancements", {Config::System::GFX, "Enhancements"}}, @@ -315,4 +316,4 @@ std::unique_ptr GenerateLocalGameConfigLoader(const s { return std::make_unique(id, revision, false); } -} +} // namespace ConfigLoaders diff --git a/Source/Core/Core/ConfigLoaders/NetPlayConfigLoader.cpp b/Source/Core/Core/ConfigLoaders/NetPlayConfigLoader.cpp index 4f70d58399..6aa190593c 100644 --- a/Source/Core/Core/ConfigLoaders/NetPlayConfigLoader.cpp +++ b/Source/Core/Core/ConfigLoaders/NetPlayConfigLoader.cpp @@ -9,6 +9,7 @@ #include "Common/CommonPaths.h" #include "Common/Config/Config.h" #include "Common/FileUtil.h" +#include "Core/Config/GraphicsSettings.h" #include "Core/Config/MainSettings.h" #include "Core/Config/SYSCONFSettings.h" #include "Core/NetPlayProto.h" @@ -36,11 +37,57 @@ public: layer->Set(Config::MAIN_SLOT_B, static_cast(m_settings.m_EXIDevice[1])); layer->Set(Config::MAIN_WII_SD_CARD_WRITABLE, m_settings.m_WriteToMemcard); layer->Set(Config::MAIN_REDUCE_POLLING_RATE, m_settings.m_ReducePollingRate); - layer->Set(Config::MAIN_DSP_JIT, m_settings.m_DSPEnableJIT); - layer->Set(Config::SYSCONF_PROGRESSIVE_SCAN, m_settings.m_ProgressiveScan); layer->Set(Config::SYSCONF_PAL60, m_settings.m_PAL60); + layer->Set(Config::GFX_HACK_EFB_ACCESS_ENABLE, m_settings.m_EFBAccessEnable); + layer->Set(Config::GFX_HACK_BBOX_ENABLE, m_settings.m_BBoxEnable); + layer->Set(Config::GFX_HACK_FORCE_PROGRESSIVE, m_settings.m_ForceProgressive); + layer->Set(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM, m_settings.m_EFBToTextureEnable); + layer->Set(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM, m_settings.m_XFBToTextureEnable); + layer->Set(Config::GFX_HACK_DISABLE_COPY_TO_VRAM, m_settings.m_DisableCopyToVRAM); + layer->Set(Config::GFX_HACK_IMMEDIATE_XFB, m_settings.m_ImmediateXFBEnable); + layer->Set(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES, m_settings.m_EFBEmulateFormatChanges); + layer->Set(Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES, + m_settings.m_SafeTextureCacheColorSamples); + layer->Set(Config::GFX_PERF_QUERIES_ENABLE, m_settings.m_PerfQueriesEnable); + layer->Set(Config::MAIN_FPRF, m_settings.m_FPRF); + layer->Set(Config::MAIN_ACCURATE_NANS, m_settings.m_AccurateNaNs); + layer->Set(Config::MAIN_SYNC_ON_SKIP_IDLE, m_settings.m_SyncOnSkipIdle); + layer->Set(Config::MAIN_SYNC_GPU, m_settings.m_SyncGPU); + layer->Set(Config::MAIN_SYNC_GPU_MAX_DISTANCE, m_settings.m_SyncGpuMaxDistance); + layer->Set(Config::MAIN_SYNC_GPU_MIN_DISTANCE, m_settings.m_SyncGpuMinDistance); + layer->Set(Config::MAIN_SYNC_GPU_OVERCLOCK, m_settings.m_SyncGpuOverclock); + layer->Set(Config::MAIN_JIT_FOLLOW_BRANCH, m_settings.m_JITFollowBranch); + layer->Set(Config::MAIN_FAST_DISC_SPEED, m_settings.m_FastDiscSpeed); + layer->Set(Config::MAIN_MMU, m_settings.m_MMU); + layer->Set(Config::MAIN_FASTMEM, m_settings.m_Fastmem); + layer->Set(Config::MAIN_SKIP_IPL, m_settings.m_SkipIPL); + layer->Set(Config::MAIN_LOAD_IPL_DUMP, m_settings.m_LoadIPLDump); + + if (m_settings.m_StrictSettingsSync) + { + layer->Set(Config::GFX_HACK_VERTEX_ROUDING, m_settings.m_VertexRounding); + layer->Set(Config::GFX_EFB_SCALE, m_settings.m_InternalResolution); + layer->Set(Config::GFX_HACK_COPY_EFB_SCALED, m_settings.m_EFBScaledCopy); + layer->Set(Config::GFX_FAST_DEPTH_CALC, m_settings.m_FastDepthCalc); + layer->Set(Config::GFX_ENABLE_PIXEL_LIGHTING, m_settings.m_EnablePixelLighting); + layer->Set(Config::GFX_WIDESCREEN_HACK, m_settings.m_WidescreenHack); + layer->Set(Config::GFX_ENHANCE_FORCE_FILTERING, m_settings.m_ForceFiltering); + layer->Set(Config::GFX_ENHANCE_MAX_ANISOTROPY, m_settings.m_MaxAnisotropy); + layer->Set(Config::GFX_ENHANCE_FORCE_TRUE_COLOR, m_settings.m_ForceTrueColor); + layer->Set(Config::GFX_ENHANCE_DISABLE_COPY_FILTER, m_settings.m_DisableCopyFilter); + layer->Set(Config::GFX_DISABLE_FOG, m_settings.m_DisableFog); + layer->Set(Config::GFX_ENHANCE_ARBITRARY_MIPMAP_DETECTION, + m_settings.m_ArbitraryMipmapDetection); + layer->Set(Config::GFX_ENHANCE_ARBITRARY_MIPMAP_DETECTION_THRESHOLD, + m_settings.m_ArbitraryMipmapDetectionThreshold); + layer->Set(Config::GFX_ENABLE_GPU_TEXTURE_DECODING, m_settings.m_EnableGPUTextureDecoding); + + // Disable AA as it isn't deterministic across GPUs + layer->Set(Config::GFX_MSAA, 1); + layer->Set(Config::GFX_SSAA, false); + } if (m_settings.m_SyncSaveData) { diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp index 70355dbd62..7f2c259516 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp +++ b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp @@ -11,6 +11,7 @@ #include "Common/ChunkFile.h" #include "Common/CommonPaths.h" #include "Common/CommonTypes.h" +#include "Common/Config/Config.h" #include "Common/File.h" #include "Common/FileUtil.h" #include "Common/Logging/Log.h" @@ -19,6 +20,7 @@ #include "Common/Swap.h" #include "Common/Timer.h" +#include "Core/Config/MainSettings.h" #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/CoreTiming.h" @@ -102,7 +104,8 @@ CEXIIPL::CEXIIPL() // Load whole ROM dump // Note: The Wii doesn't have a copy of the IPL, only fonts. - if (!SConfig::GetInstance().bWii && LoadFileToIPL(SConfig::GetInstance().m_strBootROM, 0)) + if (!SConfig::GetInstance().bWii && Config::Get(Config::MAIN_LOAD_IPL_DUMP) && + LoadFileToIPL(SConfig::GetInstance().m_strBootROM, 0)) { // Descramble the encrypted section (contains BS1 and BS2) Descrambler(m_ipl + 0x100, 0x1afe00); @@ -185,6 +188,17 @@ std::string CEXIIPL::FindIPLDump(const std::string& path_prefix) return ipl_dump_path; } +bool CEXIIPL::HasIPLDump() +{ + std::string ipl_rom_path = FindIPLDump(File::GetUserPath(D_GCUSER_IDX)); + + // If not found, check again in Sys folder + if (ipl_rom_path.empty()) + ipl_rom_path = FindIPLDump(File::GetSysDirectory() + GC_SYS_DIR); + + return !ipl_rom_path.empty(); +} + void CEXIIPL::LoadFontFile(const std::string& filename, u32 offset) { // Official IPL fonts are copyrighted. Dolphin ships with a set of free font alternatives but @@ -192,6 +206,13 @@ void CEXIIPL::LoadFontFile(const std::string& filename, u32 offset) // in some titles. This function check if the user has IPL dumps available and load the fonts // from those dumps instead of loading the bundled fonts + if (!Config::Get(Config::MAIN_LOAD_IPL_DUMP)) + { + // IPL loading disabled, load bundled font instead + LoadFileToIPL(filename, offset); + return; + } + // Check for IPL dumps in User folder std::string ipl_rom_path = FindIPLDump(File::GetUserPath(D_GCUSER_IDX)); diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.h b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.h index 2bbd7056ab..fec369af07 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.h +++ b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.h @@ -31,6 +31,8 @@ public: static void Descrambler(u8* data, u32 size); + static bool HasIPLDump(); + private: enum { @@ -74,6 +76,7 @@ private: u32 CommandRegion() const { return (m_address & ~(1 << 31)) >> 8; } bool LoadFileToIPL(const std::string& filename, u32 offset); void LoadFontFile(const std::string& filename, u32 offset); - std::string FindIPLDump(const std::string& path_prefix); + + static std::string FindIPLDump(const std::string& path_prefix); }; } // namespace ExpansionInterface diff --git a/Source/Core/Core/NetPlayClient.cpp b/Source/Core/Core/NetPlayClient.cpp index d29b931ae0..c668296c4f 100644 --- a/Source/Core/Core/NetPlayClient.cpp +++ b/Source/Core/Core/NetPlayClient.cpp @@ -424,6 +424,11 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet) game_status_packet << static_cast(status); Send(game_status_packet); + + sf::Packet ipl_status_packet; + ipl_status_packet << static_cast(NP_MSG_IPL_STATUS); + ipl_status_packet << ExpansionInterface::CEXIIPL::HasIPLDump(); + Send(ipl_status_packet); } break; @@ -480,6 +485,45 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet) packet >> tmp; m_net_settings.m_EXIDevice[1] = static_cast(tmp); + packet >> m_net_settings.m_EFBAccessEnable; + packet >> m_net_settings.m_BBoxEnable; + packet >> m_net_settings.m_ForceProgressive; + packet >> m_net_settings.m_EFBToTextureEnable; + packet >> m_net_settings.m_XFBToTextureEnable; + packet >> m_net_settings.m_DisableCopyToVRAM; + packet >> m_net_settings.m_ImmediateXFBEnable; + packet >> m_net_settings.m_EFBEmulateFormatChanges; + packet >> m_net_settings.m_SafeTextureCacheColorSamples; + packet >> m_net_settings.m_PerfQueriesEnable; + packet >> m_net_settings.m_FPRF; + packet >> m_net_settings.m_AccurateNaNs; + packet >> m_net_settings.m_SyncOnSkipIdle; + packet >> m_net_settings.m_SyncGPU; + packet >> m_net_settings.m_SyncGpuMaxDistance; + packet >> m_net_settings.m_SyncGpuMinDistance; + packet >> m_net_settings.m_SyncGpuOverclock; + packet >> m_net_settings.m_JITFollowBranch; + packet >> m_net_settings.m_FastDiscSpeed; + packet >> m_net_settings.m_MMU; + packet >> m_net_settings.m_Fastmem; + packet >> m_net_settings.m_SkipIPL; + packet >> m_net_settings.m_LoadIPLDump; + packet >> m_net_settings.m_VertexRounding; + packet >> m_net_settings.m_InternalResolution; + packet >> m_net_settings.m_EFBScaledCopy; + packet >> m_net_settings.m_FastDepthCalc; + packet >> m_net_settings.m_EnablePixelLighting; + packet >> m_net_settings.m_WidescreenHack; + packet >> m_net_settings.m_ForceFiltering; + packet >> m_net_settings.m_MaxAnisotropy; + packet >> m_net_settings.m_ForceTrueColor; + packet >> m_net_settings.m_DisableCopyFilter; + packet >> m_net_settings.m_DisableFog; + packet >> m_net_settings.m_ArbitraryMipmapDetection; + packet >> m_net_settings.m_ArbitraryMipmapDetectionThreshold; + packet >> m_net_settings.m_EnableGPUTextureDecoding; + packet >> m_net_settings.m_StrictSettingsSync; + g_netplay_initial_rtc = Common::PacketReadU64(packet); packet >> m_net_settings.m_SyncSaveData; diff --git a/Source/Core/Core/NetPlayProto.h b/Source/Core/Core/NetPlayProto.h index 367af26872..76b098be11 100644 --- a/Source/Core/Core/NetPlayProto.h +++ b/Source/Core/Core/NetPlayProto.h @@ -37,6 +37,44 @@ struct NetSettings bool m_OCEnable; float m_OCFactor; ExpansionInterface::TEXIDevices m_EXIDevice[2]; + bool m_EFBAccessEnable; + bool m_BBoxEnable; + bool m_ForceProgressive; + bool m_EFBToTextureEnable; + bool m_XFBToTextureEnable; + bool m_DisableCopyToVRAM; + bool m_ImmediateXFBEnable; + bool m_EFBEmulateFormatChanges; + int m_SafeTextureCacheColorSamples; + bool m_PerfQueriesEnable; + bool m_FPRF; + bool m_AccurateNaNs; + bool m_SyncOnSkipIdle; + bool m_SyncGPU; + int m_SyncGpuMaxDistance; + int m_SyncGpuMinDistance; + float m_SyncGpuOverclock; + bool m_JITFollowBranch; + bool m_FastDiscSpeed; + bool m_MMU; + bool m_Fastmem; + bool m_SkipIPL; + bool m_LoadIPLDump; + bool m_VertexRounding; + int m_InternalResolution; + bool m_EFBScaledCopy; + bool m_FastDepthCalc; + bool m_EnablePixelLighting; + bool m_WidescreenHack; + bool m_ForceFiltering; + int m_MaxAnisotropy; + bool m_ForceTrueColor; + bool m_DisableCopyFilter; + bool m_DisableFog; + bool m_ArbitraryMipmapDetection; + float m_ArbitraryMipmapDetectionThreshold; + bool m_EnableGPUTextureDecoding; + bool m_StrictSettingsSync; bool m_SyncSaveData; std::string m_SaveDataRegion; bool m_IsHosting; @@ -83,6 +121,7 @@ enum NP_MSG_STOP_GAME = 0xA2, NP_MSG_DISABLE_GAME = 0xA3, NP_MSG_GAME_STATUS = 0xA4, + NP_MSG_IPL_STATUS = 0xA5, NP_MSG_TIMEBASE = 0xB0, NP_MSG_DESYNC_DETECTED = 0xB1, diff --git a/Source/Core/Core/NetPlayServer.cpp b/Source/Core/Core/NetPlayServer.cpp index a884aa2dce..e49626976c 100644 --- a/Source/Core/Core/NetPlayServer.cpp +++ b/Source/Core/Core/NetPlayServer.cpp @@ -662,6 +662,15 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player) } break; + case NP_MSG_IPL_STATUS: + { + bool status; + packet >> status; + + m_players[player.pid].has_ipl_dump = status; + } + break; + case NP_MSG_TIMEBASE: { u64 timebase = Common::PacketReadU64(packet); @@ -861,6 +870,12 @@ void NetPlayServer::SetNetSettings(const NetSettings& settings) m_settings = settings; } +bool NetPlayServer::DoAllPlayersHaveIPLDump() const +{ + return std::all_of(m_players.begin(), m_players.end(), + [](const auto& p) { return p.second.has_ipl_dump; }); +} + // called from ---GUI--- thread bool NetPlayServer::RequestStartGame() { @@ -921,6 +936,44 @@ bool NetPlayServer::StartGame() spac << m_settings.m_ReducePollingRate; spac << m_settings.m_EXIDevice[0]; spac << m_settings.m_EXIDevice[1]; + spac << m_settings.m_EFBAccessEnable; + spac << m_settings.m_BBoxEnable; + spac << m_settings.m_ForceProgressive; + spac << m_settings.m_EFBToTextureEnable; + spac << m_settings.m_XFBToTextureEnable; + spac << m_settings.m_DisableCopyToVRAM; + spac << m_settings.m_ImmediateXFBEnable; + spac << m_settings.m_EFBEmulateFormatChanges; + spac << m_settings.m_SafeTextureCacheColorSamples; + spac << m_settings.m_PerfQueriesEnable; + spac << m_settings.m_FPRF; + spac << m_settings.m_AccurateNaNs; + spac << m_settings.m_SyncOnSkipIdle; + spac << m_settings.m_SyncGPU; + spac << m_settings.m_SyncGpuMaxDistance; + spac << m_settings.m_SyncGpuMinDistance; + spac << m_settings.m_SyncGpuOverclock; + spac << m_settings.m_JITFollowBranch; + spac << m_settings.m_FastDiscSpeed; + spac << m_settings.m_MMU; + spac << m_settings.m_Fastmem; + spac << m_settings.m_SkipIPL; + spac << m_settings.m_LoadIPLDump; + spac << m_settings.m_VertexRounding; + spac << m_settings.m_InternalResolution; + spac << m_settings.m_EFBScaledCopy; + spac << m_settings.m_FastDepthCalc; + spac << m_settings.m_EnablePixelLighting; + spac << m_settings.m_WidescreenHack; + spac << m_settings.m_ForceFiltering; + spac << m_settings.m_MaxAnisotropy; + spac << m_settings.m_ForceTrueColor; + spac << m_settings.m_DisableCopyFilter; + spac << m_settings.m_DisableFog; + spac << m_settings.m_ArbitraryMipmapDetection; + spac << m_settings.m_ArbitraryMipmapDetectionThreshold; + spac << m_settings.m_EnableGPUTextureDecoding; + spac << m_settings.m_StrictSettingsSync; Common::PacketWriteU64(spac, g_netplay_initial_rtc); spac << m_settings.m_SyncSaveData; spac << region; diff --git a/Source/Core/Core/NetPlayServer.h b/Source/Core/Core/NetPlayServer.h index 9295cc9d7e..b3484e858e 100644 --- a/Source/Core/Core/NetPlayServer.h +++ b/Source/Core/Core/NetPlayServer.h @@ -40,6 +40,7 @@ public: void SetNetSettings(const NetSettings& settings); + bool DoAllPlayersHaveIPLDump() const; bool StartGame(); bool RequestStartGame(); @@ -69,6 +70,7 @@ private: std::string name; std::string revision; PlayerGameStatus game_status; + bool has_ipl_dump; ENetPeer* socket; u32 ping; diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index 19a2320ebe..eff3bdd840 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -98,6 +98,7 @@ add_executable(dolphin-emu NetPlay/PadMappingDialog.cpp QtUtils/DoubleClickEventFilter.cpp QtUtils/ElidedButton.cpp + QtUtils/FlowLayout.cpp QtUtils/ImageConverter.cpp QtUtils/SignalDaemon.cpp QtUtils/WindowActivationEventFilter.cpp diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index b2aa6ae409..0228011308 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -148,6 +148,7 @@ + @@ -176,6 +177,7 @@ + @@ -351,6 +353,7 @@ + diff --git a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp index ce296acef8..956ca83e86 100644 --- a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp +++ b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp @@ -31,7 +31,10 @@ #include "Common/Config/Config.h" #include "Common/TraversalClient.h" +#include "Core/Config/GraphicsSettings.h" +#include "Core/Config/MainSettings.h" #include "Core/Config/SYSCONFSettings.h" +#include "Core/ConfigLoaders/GameConfigLoader.h" #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/NetPlayServer.h" @@ -40,11 +43,14 @@ #include "DolphinQt/NetPlay/GameListDialog.h" #include "DolphinQt/NetPlay/MD5Dialog.h" #include "DolphinQt/NetPlay/PadMappingDialog.h" +#include "DolphinQt/QtUtils/FlowLayout.h" #include "DolphinQt/QtUtils/QueueOnObject.h" #include "DolphinQt/QtUtils/RunOnObject.h" #include "DolphinQt/Resources.h" #include "DolphinQt/Settings.h" +#include "UICommon/GameFile.h" + #include "VideoCommon/VideoConfig.h" NetPlayDialog::NetPlayDialog(QWidget* parent) @@ -89,6 +95,7 @@ void NetPlayDialog::CreateMainLayout() m_sync_save_data_box = new QCheckBox(tr("Sync Saves")); m_record_input_box = new QCheckBox(tr("Record inputs")); m_reduce_polling_rate_box = new QCheckBox(tr("Reduce Polling Rate")); + m_strict_settings_sync_box = new QCheckBox(tr("Strict Settings Sync")); m_buffer_label = new QLabel(tr("Buffer:")); m_quit_button = new QPushButton(tr("Quit")); m_splitter = new QSplitter(Qt::Horizontal); @@ -128,6 +135,10 @@ void NetPlayDialog::CreateMainLayout() m_reduce_polling_rate_box->setToolTip( tr("This will reduce bandwidth usage by polling GameCube controllers only twice per frame. " "Does not affect Wii Remotes.")); + m_strict_settings_sync_box->setToolTip( + tr("This will sync additional graphics settings, and force everyone to the same internal " + "resolution.\nMay prevent desync in some games that use EFB reads. Please ensure everyone " + "uses the same video backend.")); m_main_layout->addWidget(m_game_button, 0, 0); m_main_layout->addWidget(m_md5_button, 0, 1); @@ -136,18 +147,25 @@ void NetPlayDialog::CreateMainLayout() m_splitter->addWidget(m_chat_box); m_splitter->addWidget(m_players_box); - auto* options_widget = new QHBoxLayout; + auto* options_widget = new QGridLayout; + auto* options_boxes = new FlowLayout; + + options_widget->addWidget(m_start_button, 0, 0, Qt::AlignVCenter); + options_widget->addWidget(m_buffer_label, 0, 1, Qt::AlignVCenter); + options_widget->addWidget(m_buffer_size_box, 0, 2, Qt::AlignVCenter); + options_widget->addWidget(m_quit_button, 0, 4, Qt::AlignVCenter); + options_boxes->addWidget(m_save_sd_box); + options_boxes->addWidget(m_load_wii_box); + options_boxes->addWidget(m_sync_save_data_box); + options_boxes->addWidget(m_record_input_box); + options_boxes->addWidget(m_reduce_polling_rate_box); + options_boxes->addWidget(m_strict_settings_sync_box); + + options_widget->addLayout(options_boxes, 0, 3, Qt::AlignTop); + options_widget->setColumnStretch(3, 1000); - options_widget->addWidget(m_start_button); - options_widget->addWidget(m_buffer_label); - options_widget->addWidget(m_buffer_size_box); - options_widget->addWidget(m_save_sd_box); - options_widget->addWidget(m_load_wii_box); - options_widget->addWidget(m_sync_save_data_box); - options_widget->addWidget(m_record_input_box); - options_widget->addWidget(m_reduce_polling_rate_box); - options_widget->addWidget(m_quit_button); m_main_layout->addLayout(options_widget, 2, 0, 1, -1, Qt::AlignRight); + m_main_layout->setRowStretch(1, 1000); setLayout(m_main_layout); } @@ -289,28 +307,97 @@ void NetPlayDialog::OnStart() return; } + if (m_strict_settings_sync_box->isChecked() && Config::Get(Config::GFX_EFB_SCALE) == 0) + { + QMessageBox::critical( + this, tr("Error"), + tr("Auto internal resolution is not allowed in strict sync mode, as it depends on window " + "size.\n\nPlease select a specific internal resolution.")); + return; + } + + const auto game = FindGameFile(m_current_game); + if (!game) + { + PanicAlertT("Selected game doesn't exist in game list!"); + return; + } + NetPlay::NetSettings settings; + // Load GameINI so we can sync the settings from it + Config::AddLayer( + ConfigLoaders::GenerateGlobalGameConfigLoader(game->GetGameID(), game->GetRevision())); + Config::AddLayer( + ConfigLoaders::GenerateLocalGameConfigLoader(game->GetGameID(), game->GetRevision())); + // Copy all relevant settings - SConfig& instance = SConfig::GetInstance(); - settings.m_CPUthread = instance.bCPUThread; - settings.m_CPUcore = instance.cpu_core; - settings.m_EnableCheats = instance.bEnableCheats; - settings.m_SelectedLanguage = instance.SelectedLanguage; - settings.m_OverrideGCLanguage = instance.bOverrideGCLanguage; + settings.m_CPUthread = Config::Get(Config::MAIN_CPU_THREAD); + settings.m_CPUcore = Config::Get(Config::MAIN_CPU_CORE); + settings.m_EnableCheats = Config::Get(Config::MAIN_ENABLE_CHEATS); + settings.m_SelectedLanguage = Config::Get(Config::MAIN_GC_LANGUAGE); + settings.m_OverrideGCLanguage = Config::Get(Config::MAIN_OVERRIDE_GC_LANGUAGE); settings.m_ProgressiveScan = Config::Get(Config::SYSCONF_PROGRESSIVE_SCAN); settings.m_PAL60 = Config::Get(Config::SYSCONF_PAL60); - settings.m_DSPHLE = instance.bDSPHLE; - settings.m_DSPEnableJIT = instance.m_DSPEnableJIT; + settings.m_DSPHLE = Config::Get(Config::MAIN_DSP_HLE); + settings.m_DSPEnableJIT = Config::Get(Config::MAIN_DSP_JIT); settings.m_WriteToMemcard = m_save_sd_box->isChecked(); settings.m_CopyWiiSave = m_load_wii_box->isChecked(); - settings.m_OCEnable = instance.m_OCEnable; - settings.m_OCFactor = instance.m_OCFactor; + settings.m_OCEnable = Config::Get(Config::MAIN_OVERCLOCK_ENABLE); + settings.m_OCFactor = Config::Get(Config::MAIN_OVERCLOCK); settings.m_ReducePollingRate = m_reduce_polling_rate_box->isChecked(); - settings.m_EXIDevice[0] = instance.m_EXIDevice[0]; - settings.m_EXIDevice[1] = instance.m_EXIDevice[1]; + settings.m_EXIDevice[0] = + static_cast(Config::Get(Config::MAIN_SLOT_A)); + settings.m_EXIDevice[1] = + static_cast(Config::Get(Config::MAIN_SLOT_B)); + settings.m_EFBAccessEnable = Config::Get(Config::GFX_HACK_EFB_ACCESS_ENABLE); + settings.m_BBoxEnable = Config::Get(Config::GFX_HACK_BBOX_ENABLE); + settings.m_ForceProgressive = Config::Get(Config::GFX_HACK_FORCE_PROGRESSIVE); + settings.m_EFBToTextureEnable = Config::Get(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM); + settings.m_XFBToTextureEnable = Config::Get(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM); + settings.m_DisableCopyToVRAM = Config::Get(Config::GFX_HACK_DISABLE_COPY_TO_VRAM); + settings.m_ImmediateXFBEnable = Config::Get(Config::GFX_HACK_IMMEDIATE_XFB); + settings.m_EFBEmulateFormatChanges = Config::Get(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES); + settings.m_SafeTextureCacheColorSamples = + Config::Get(Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES); + settings.m_PerfQueriesEnable = Config::Get(Config::GFX_PERF_QUERIES_ENABLE); + settings.m_FPRF = Config::Get(Config::MAIN_FPRF); + settings.m_AccurateNaNs = Config::Get(Config::MAIN_ACCURATE_NANS); + settings.m_SyncOnSkipIdle = Config::Get(Config::MAIN_SYNC_ON_SKIP_IDLE); + settings.m_SyncGPU = Config::Get(Config::MAIN_SYNC_GPU); + settings.m_SyncGpuMaxDistance = Config::Get(Config::MAIN_SYNC_GPU_MAX_DISTANCE); + settings.m_SyncGpuMinDistance = Config::Get(Config::MAIN_SYNC_GPU_MIN_DISTANCE); + settings.m_SyncGpuOverclock = Config::Get(Config::MAIN_SYNC_GPU_OVERCLOCK); + settings.m_JITFollowBranch = Config::Get(Config::MAIN_JIT_FOLLOW_BRANCH); + settings.m_FastDiscSpeed = Config::Get(Config::MAIN_FAST_DISC_SPEED); + settings.m_MMU = Config::Get(Config::MAIN_MMU); + settings.m_Fastmem = Config::Get(Config::MAIN_FASTMEM); + settings.m_SkipIPL = Config::Get(Config::MAIN_SKIP_IPL) || + !Settings::Instance().GetNetPlayServer()->DoAllPlayersHaveIPLDump(); + settings.m_LoadIPLDump = Config::Get(Config::MAIN_LOAD_IPL_DUMP) && + Settings::Instance().GetNetPlayServer()->DoAllPlayersHaveIPLDump(); + settings.m_VertexRounding = Config::Get(Config::GFX_HACK_VERTEX_ROUDING); + settings.m_InternalResolution = Config::Get(Config::GFX_EFB_SCALE); + settings.m_EFBScaledCopy = Config::Get(Config::GFX_HACK_COPY_EFB_SCALED); + settings.m_FastDepthCalc = Config::Get(Config::GFX_FAST_DEPTH_CALC); + settings.m_EnablePixelLighting = Config::Get(Config::GFX_ENABLE_PIXEL_LIGHTING); + settings.m_WidescreenHack = Config::Get(Config::GFX_WIDESCREEN_HACK); + settings.m_ForceFiltering = Config::Get(Config::GFX_ENHANCE_FORCE_FILTERING); + settings.m_MaxAnisotropy = Config::Get(Config::GFX_ENHANCE_MAX_ANISOTROPY); + settings.m_ForceTrueColor = Config::Get(Config::GFX_ENHANCE_FORCE_TRUE_COLOR); + settings.m_DisableCopyFilter = Config::Get(Config::GFX_ENHANCE_DISABLE_COPY_FILTER); + settings.m_DisableFog = Config::Get(Config::GFX_DISABLE_FOG); + settings.m_ArbitraryMipmapDetection = Config::Get(Config::GFX_ENHANCE_ARBITRARY_MIPMAP_DETECTION); + settings.m_ArbitraryMipmapDetectionThreshold = + Config::Get(Config::GFX_ENHANCE_ARBITRARY_MIPMAP_DETECTION_THRESHOLD); + settings.m_EnableGPUTextureDecoding = Config::Get(Config::GFX_ENABLE_GPU_TEXTURE_DECODING); + settings.m_StrictSettingsSync = m_strict_settings_sync_box->isChecked(); settings.m_SyncSaveData = m_sync_save_data_box->isChecked(); + // Unload GameINI to restore things to normal + Config::RemoveLayer(Config::LayerType::GlobalGame); + Config::RemoveLayer(Config::LayerType::LocalGame); + Settings::Instance().GetNetPlayServer()->SetNetSettings(settings); if (Settings::Instance().GetNetPlayServer()->RequestStartGame()) SetOptionsEnabled(false); @@ -354,6 +441,7 @@ void NetPlayDialog::show(std::string nickname, bool use_traversal) m_load_wii_box->setHidden(!is_hosting); m_sync_save_data_box->setHidden(!is_hosting); m_reduce_polling_rate_box->setHidden(!is_hosting); + m_strict_settings_sync_box->setHidden(!is_hosting); m_buffer_size_box->setHidden(!is_hosting); m_buffer_label->setHidden(!is_hosting); m_kick_button->setHidden(!is_hosting); @@ -564,6 +652,7 @@ void NetPlayDialog::SetOptionsEnabled(bool enabled) m_sync_save_data_box->setEnabled(enabled); m_assign_ports_button->setEnabled(enabled); m_reduce_polling_rate_box->setEnabled(enabled); + m_strict_settings_sync_box->setEnabled(enabled); } m_record_input_box->setEnabled(enabled); diff --git a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.h b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.h index 1603bc40a8..f8f9926101 100644 --- a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.h +++ b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.h @@ -105,6 +105,7 @@ private: QCheckBox* m_sync_save_data_box; QCheckBox* m_record_input_box; QCheckBox* m_reduce_polling_rate_box; + QCheckBox* m_strict_settings_sync_box; QPushButton* m_quit_button; QSplitter* m_splitter; diff --git a/Source/Core/DolphinQt/QtUtils/FlowLayout.cpp b/Source/Core/DolphinQt/QtUtils/FlowLayout.cpp new file mode 100644 index 0000000000..b20d42f96e --- /dev/null +++ b/Source/Core/DolphinQt/QtUtils/FlowLayout.cpp @@ -0,0 +1,212 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "DolphinQt/QtUtils/FlowLayout.h" + +#include + +FlowLayout::FlowLayout(QWidget* parent, int margin, int h_spacing, int v_spacing) + : QLayout(parent), m_h_space(h_spacing), m_v_space(v_spacing) +{ + setContentsMargins(margin, margin, margin, margin); +} + +FlowLayout::FlowLayout(int margin, int h_spacing, int v_spacing) + : m_h_space(h_spacing), m_v_space(v_spacing) +{ + setContentsMargins(margin, margin, margin, margin); +} + +FlowLayout::~FlowLayout() +{ + QLayoutItem* item; + while ((item = takeAt(0))) + delete item; +} + +void FlowLayout::addItem(QLayoutItem* item) +{ + m_item_list.append(item); +} + +int FlowLayout::horizontalSpacing() const +{ + if (m_h_space >= 0) + { + return m_h_space; + } + else + { + return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); + } +} + +int FlowLayout::verticalSpacing() const +{ + if (m_v_space >= 0) + { + return m_v_space; + } + else + { + return smartSpacing(QStyle::PM_LayoutVerticalSpacing); + } +} + +int FlowLayout::count() const +{ + return m_item_list.size(); +} + +QLayoutItem* FlowLayout::itemAt(int index) const +{ + return m_item_list.value(index); +} + +QLayoutItem* FlowLayout::takeAt(int index) +{ + if (index >= 0 && index < m_item_list.size()) + return m_item_list.takeAt(index); + else + return 0; +} + +Qt::Orientations FlowLayout::expandingDirections() const +{ + return 0; +} + +bool FlowLayout::hasHeightForWidth() const +{ + return true; +} + +int FlowLayout::heightForWidth(int width) const +{ + int height = doLayout(QRect(0, 0, width, 0), true); + return height; +} + +void FlowLayout::setGeometry(const QRect& rect) +{ + QLayout::setGeometry(rect); + doLayout(rect, false); +} + +QSize FlowLayout::sizeHint() const +{ + return minimumSize(); +} + +QSize FlowLayout::minimumSize() const +{ + QSize size; + for (const auto& item : m_item_list) + size = size.expandedTo(item->minimumSize()); + + size += QSize(2 * margin(), 2 * margin()); + return size; +} + +int FlowLayout::doLayout(const QRect& rect, bool testOnly) const +{ + int left, top, right, bottom; + getContentsMargins(&left, &top, &right, &bottom); + QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); + int x = effectiveRect.x(); + int y = effectiveRect.y(); + int lineHeight = 0; + + for (const auto& item : m_item_list) + { + QWidget* wid = item->widget(); + int spaceX = horizontalSpacing(); + if (spaceX == -1) + spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, + Qt::Horizontal); + int spaceY = verticalSpacing(); + if (spaceY == -1) + spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, + Qt::Vertical); + int nextX = x + item->sizeHint().width() + spaceX; + if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) + { + x = effectiveRect.x(); + y = y + lineHeight + spaceY; + nextX = x + item->sizeHint().width() + spaceX; + lineHeight = 0; + } + + if (!testOnly) + item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); + + x = nextX; + lineHeight = qMax(lineHeight, item->sizeHint().height()); + } + return y + lineHeight - rect.y() + bottom; +} + +int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const +{ + QObject* parent = this->parent(); + if (!parent) + { + return -1; + } + else if (parent->isWidgetType()) + { + QWidget* pw = static_cast(parent); + return pw->style()->pixelMetric(pm, 0, pw); + } + else + { + return static_cast(parent)->spacing(); + } +} diff --git a/Source/Core/DolphinQt/QtUtils/FlowLayout.h b/Source/Core/DolphinQt/QtUtils/FlowLayout.h new file mode 100644 index 0000000000..65955db960 --- /dev/null +++ b/Source/Core/DolphinQt/QtUtils/FlowLayout.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include +#include +#include + +class FlowLayout : public QLayout +{ +public: + explicit FlowLayout(QWidget* parent, int margin = -1, int h_spacing = -1, int v_spacing = -1); + explicit FlowLayout(int margin = -1, int h_spacing = -1, int v_spacing = -1); + ~FlowLayout(); + + void addItem(QLayoutItem* item) override; + int horizontalSpacing() const; + int verticalSpacing() const; + Qt::Orientations expandingDirections() const override; + bool hasHeightForWidth() const override; + int heightForWidth(int) const override; + int count() const override; + QLayoutItem* itemAt(int index) const override; + QSize minimumSize() const override; + void setGeometry(const QRect& rect) override; + QSize sizeHint() const override; + QLayoutItem* takeAt(int index) override; + +private: + int doLayout(const QRect& rect, bool testOnly) const; + int smartSpacing(QStyle::PixelMetric pm) const; + + QList m_item_list; + int m_h_space; + int m_v_space; +}; diff --git a/Source/Core/DolphinQt/Settings/AdvancedPane.cpp b/Source/Core/DolphinQt/Settings/AdvancedPane.cpp index 831bbb228f..3e70e385d7 100644 --- a/Source/Core/DolphinQt/Settings/AdvancedPane.cpp +++ b/Source/Core/DolphinQt/Settings/AdvancedPane.cpp @@ -13,6 +13,7 @@ #include #include +#include "Core/Config/MainSettings.h" #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/HW/SystemTimers.h" @@ -101,13 +102,15 @@ void AdvancedPane::ConnectLayout() m_cpu_clock_override_checkbox->setChecked(SConfig::GetInstance().m_OCEnable); connect(m_cpu_clock_override_checkbox, &QCheckBox::toggled, [this](bool enable_clock_override) { SConfig::GetInstance().m_OCEnable = enable_clock_override; + Config::SetBaseOrCurrent(Config::MAIN_OVERCLOCK_ENABLE, enable_clock_override); Update(); }); connect(m_cpu_clock_override_slider, &QSlider::valueChanged, [this](int oc_factor) { // Vaguely exponential scaling? - SConfig::GetInstance().m_OCFactor = - std::exp2f((m_cpu_clock_override_slider->value() - 100.f) / 25.f); + const float factor = std::exp2f((m_cpu_clock_override_slider->value() - 100.f) / 25.f); + SConfig::GetInstance().m_OCFactor = factor; + Config::SetBaseOrCurrent(Config::MAIN_OVERCLOCK, factor); Update(); }); diff --git a/Source/Core/DolphinQt/Settings/AudioPane.cpp b/Source/Core/DolphinQt/Settings/AudioPane.cpp index 8a3f1fbcd6..512b06066e 100644 --- a/Source/Core/DolphinQt/Settings/AudioPane.cpp +++ b/Source/Core/DolphinQt/Settings/AudioPane.cpp @@ -19,6 +19,7 @@ #include "AudioCommon/AudioCommon.h" #include "AudioCommon/WASAPIStream.h" +#include "Core/Config/MainSettings.h" #include "Core/ConfigManager.h" #include "Core/Core.h" @@ -222,7 +223,9 @@ void AudioPane::SaveSettings() // DSP SConfig::GetInstance().bDSPHLE = m_dsp_hle->isChecked(); + Config::SetBaseOrCurrent(Config::MAIN_DSP_HLE, m_dsp_hle->isChecked()); SConfig::GetInstance().m_DSPEnableJIT = m_dsp_lle->isChecked(); + Config::SetBaseOrCurrent(Config::MAIN_DSP_JIT, m_dsp_lle->isChecked()); // Backend const auto selection = diff --git a/Source/Core/DolphinQt/Settings/GameCubePane.cpp b/Source/Core/DolphinQt/Settings/GameCubePane.cpp index 4dff22c4bf..c9730e771a 100644 --- a/Source/Core/DolphinQt/Settings/GameCubePane.cpp +++ b/Source/Core/DolphinQt/Settings/GameCubePane.cpp @@ -341,8 +341,12 @@ void GameCubePane::SaveSettings() // IPL Settings params.bHLE_BS2 = m_skip_main_menu->isChecked(); + Config::SetBaseOrCurrent(Config::MAIN_SKIP_IPL, m_skip_main_menu->isChecked()); params.SelectedLanguage = m_language_combo->currentIndex(); + Config::SetBaseOrCurrent(Config::MAIN_GC_LANGUAGE, m_language_combo->currentIndex()); params.bOverrideGCLanguage = m_override_language_ntsc->isChecked(); + Config::SetBaseOrCurrent(Config::MAIN_OVERRIDE_GC_LANGUAGE, + m_override_language_ntsc->isChecked()); for (int i = 0; i < SLOT_COUNT; i++) { @@ -390,6 +394,18 @@ void GameCubePane::SaveSettings() } SConfig::GetInstance().m_EXIDevice[i] = dev; + switch (i) + { + case SLOT_A_INDEX: + Config::SetBaseOrCurrent(Config::MAIN_SLOT_A, dev); + break; + case SLOT_B_INDEX: + Config::SetBaseOrCurrent(Config::MAIN_SLOT_B, dev); + break; + case SLOT_SP1_INDEX: + Config::SetBaseOrCurrent(Config::MAIN_SERIAL_PORT_1, dev); + break; + } } LoadSettings(); } diff --git a/Source/Core/DolphinQt/Settings/GeneralPane.cpp b/Source/Core/DolphinQt/Settings/GeneralPane.cpp index 65b03b0260..3e9fe4a66c 100644 --- a/Source/Core/DolphinQt/Settings/GeneralPane.cpp +++ b/Source/Core/DolphinQt/Settings/GeneralPane.cpp @@ -19,6 +19,7 @@ #include #include "Core/Analytics.h" +#include "Core/Config/MainSettings.h" #include "Core/Config/UISettings.h" #include "Core/ConfigManager.h" #include "Core/Core.h" @@ -291,7 +292,9 @@ void GeneralPane::OnSaveConfig() Settings::Instance().SetAnalyticsEnabled(m_checkbox_enable_analytics->isChecked()); #endif settings.bCPUThread = m_checkbox_dualcore->isChecked(); + Config::SetBaseOrCurrent(Config::MAIN_CPU_THREAD, m_checkbox_dualcore->isChecked()); Settings::Instance().SetCheatsEnabled(m_checkbox_cheats->isChecked()); + Config::SetBaseOrCurrent(Config::MAIN_ENABLE_CHEATS, m_checkbox_cheats->isChecked()); settings.m_EmulationSpeed = m_combobox_speedlimit->currentIndex() * 0.1f; for (size_t i = 0; i < m_cpu_cores.size(); ++i) @@ -299,6 +302,7 @@ void GeneralPane::OnSaveConfig() if (m_cpu_cores[i]->isChecked()) { settings.cpu_core = PowerPC::AvailableCPUCores()[i]; + Config::SetBaseOrCurrent(Config::MAIN_CPU_CORE, PowerPC::AvailableCPUCores()[i]); break; } }