Permalink
Browse files

NetPlay: Improve settings synchronization and UI

Most settings which affect determinism will now be synced on NetPlay.
Additionally, there's a strict sync mode which will sync various
enhancements to prevent desync in games that use EFB reads.

This also adds a check for all players having the IPL.bin file, and
doesn't load it for anyone if someone is missing it. This prevents
desyncs caused by mismatched system fonts.

Additionally, the NetPlay window was getting too wide with checkboxes,
so FlowLayout has been introduced to make the checkboxes take up
multiple rows dynamically. However, there's some minor vertical
centering issues I haven't been able to solve, but it's better than a
ridiculously wide window.
  • Loading branch information...
Techjar committed Jul 19, 2018
1 parent c141511 commit 7036299a92c3a2b550be052a710ef564bfd3af0d
@@ -72,6 +72,7 @@ struct ConfigCache
private:
bool valid;
bool bCPUThread;
bool bJITFollowBranch;
bool bEnableCheats;
bool bSyncGPUOnSkipIdleHack;
bool bFPRF;
@@ -81,6 +82,9 @@ struct ConfigCache
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<BootParameters> 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<BootParameters> 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<BootParameters> 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
@@ -16,8 +16,10 @@ namespace Config
// Main.Core
const ConfigInfo<bool> MAIN_SKIP_IPL{{System::Main, "Core", "SkipIPL"}, true};
const ConfigInfo<bool> MAIN_LOAD_IPL_DUMP{{System::Main, "Core", "LoadIPLDump"}, true};
const ConfigInfo<PowerPC::CPUCore> MAIN_CPU_CORE{{System::Main, "Core", "CPUCore"},
PowerPC::DefaultCPUCore()};
const ConfigInfo<bool> MAIN_JIT_FOLLOW_BRANCH{{System::Main, "Core", "JITFollowBranch"}, true};
const ConfigInfo<bool> MAIN_FASTMEM{{System::Main, "Core", "Fastmem"}, true};
const ConfigInfo<bool> MAIN_DSP_HLE{{System::Main, "Core", "DSPHLE"}, true};
const ConfigInfo<int> MAIN_TIMING_VARIANCE{{System::Main, "Core", "TimingVariance"}, 40};
@@ -17,6 +17,8 @@ namespace Config
{
// Main.Core
extern const ConfigInfo<bool> MAIN_SKIP_IPL;
extern const ConfigInfo<bool> MAIN_LOAD_IPL_DUMP;
extern const ConfigInfo<PowerPC::CPUCore> MAIN_CPU_CORE;
extern const ConfigInfo<bool> MAIN_JIT_FOLLOW_BRANCH;
extern const ConfigInfo<bool> MAIN_FASTMEM;
@@ -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<Config::ConfigLayerLoader> GenerateLocalGameConfigLoader(const s
{
return std::make_unique<INIGameConfigLayerLoader>(id, revision, false);
}
}
} // namespace ConfigLoaders
@@ -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 @@ class NetPlayConfigLayerLoader final : public Config::ConfigLayerLoader
layer->Set(Config::MAIN_SLOT_B, static_cast<int>(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)
{
@@ -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,13 +188,31 @@ 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
// unfortunately the bundled fonts have different padding, causing issues with misplaced text
// 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));
@@ -31,6 +31,8 @@ class CEXIIPL : public IEXIDevice
static void Descrambler(u8* data, u32 size);
static bool HasIPLDump();
private:
enum
{
@@ -74,6 +76,7 @@ class CEXIIPL : public IEXIDevice
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
@@ -424,6 +424,11 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
game_status_packet << static_cast<u32>(status);
Send(game_status_packet);
sf::Packet ipl_status_packet;
ipl_status_packet << static_cast<MessageId>(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<ExpansionInterface::TEXIDevices>(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;
@@ -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,
Oops, something went wrong.

0 comments on commit 7036299

Please sign in to comment.