diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp index d2a1f86841..7a17307af9 100644 --- a/Source/Core/Core/BootManager.cpp +++ b/Source/Core/Core/BootManager.cpp @@ -93,10 +93,6 @@ bool BootCore(std::unique_ptr boot, const WindowSystemInfo& wsi) Config::AddLayer(ConfigLoaders::GenerateNetPlayConfigLoader(*netplay_settings)); StartUp.bCopyWiiSaveNetplay = netplay_settings->copy_wii_save; } - else - { - g_SRAM_netplay_initialized = false; - } // Override out-of-region languages/countries to prevent games from crashing or behaving oddly if (!Config::Get(Config::MAIN_OVERRIDE_REGION_SETTINGS)) diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index a3d2379db7..913c9956e9 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -511,7 +511,7 @@ static void EmuThread(std::unique_ptr boot, WindowSystemInfo wsi AudioCommon::InitSoundStream(); Common::ScopeGuard audio_guard{&AudioCommon::ShutdownSoundStream}; - HW::Init(); + HW::Init(NetPlay::IsNetPlayRunning() ? &(boot_session_data.GetNetplaySettings()->sram) : nullptr); Common::ScopeGuard hw_guard{[] { // We must set up this flag before executing HW::Shutdown() diff --git a/Source/Core/Core/HW/EXI/EXI.cpp b/Source/Core/Core/HW/EXI/EXI.cpp index c480e09235..76d5356db1 100644 --- a/Source/Core/Core/HW/EXI/EXI.cpp +++ b/Source/Core/Core/HW/EXI/EXI.cpp @@ -8,6 +8,7 @@ #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" +#include "Common/IOFile.h" #include "Core/Config/MainSettings.h" #include "Core/ConfigManager.h" @@ -20,11 +21,11 @@ #include "Core/HW/Sram.h" #include "Core/HW/SystemTimers.h" #include "Core/Movie.h" +#include "Core/System.h" #include "DiscIO/Enums.h" -Sram g_SRAM; -bool g_SRAM_netplay_initialized = false; +bool s_using_overridden_sram = false; namespace ExpansionInterface { @@ -102,11 +103,18 @@ u8 SlotToEXIDevice(Slot slot) } } -void Init() +void Init(const Sram* override_sram) { - if (!g_SRAM_netplay_initialized) + auto& sram = Core::System::GetInstance().GetSRAM(); + if (override_sram) { - InitSRAM(); + sram = *override_sram; + s_using_overridden_sram = true; + } + else + { + InitSRAM(&sram, SConfig::GetInstance().m_strSRAM); + s_using_overridden_sram = false; } CEXIMemoryCard::Init(); @@ -118,9 +126,9 @@ void Init() size_mbits = Memcard::MBIT_SIZE_MEMORY_CARD_59 << size_override; const bool shift_jis = Config::ToGameCubeRegion(SConfig::GetInstance().m_region) == DiscIO::Region::NTSC_J; - const CardFlashId& flash_id = g_SRAM.settings_ex.flash_id[Memcard::SLOT_A]; - const u32 rtc_bias = g_SRAM.settings.rtc_bias; - const u32 sram_language = static_cast(g_SRAM.settings.language); + const CardFlashId& flash_id = sram.settings_ex.flash_id[Memcard::SLOT_A]; + const u32 rtc_bias = sram.settings.rtc_bias; + const u32 sram_language = static_cast(sram.settings.language); const u64 format_time = Common::Timer::GetLocalTimeSinceJan1970() - ExpansionInterface::CEXIIPL::GC_EPOCH; @@ -151,6 +159,13 @@ void Shutdown() channel.reset(); CEXIMemoryCard::Shutdown(); + + if (!s_using_overridden_sram) + { + File::IOFile file(SConfig::GetInstance().m_strSRAM, "wb"); + auto& sram = Core::System::GetInstance().GetSRAM(); + file.WriteArray(&sram, 1); + } } void DoState(PointerWrap& p) diff --git a/Source/Core/Core/HW/EXI/EXI.h b/Source/Core/Core/HW/EXI/EXI.h index 01661a0920..c18070f514 100644 --- a/Source/Core/Core/HW/EXI/EXI.h +++ b/Source/Core/Core/HW/EXI/EXI.h @@ -10,6 +10,7 @@ #include "Core/CoreTiming.h" class PointerWrap; +struct Sram; namespace CoreTiming { @@ -51,7 +52,7 @@ constexpr bool IsMemcardSlot(Slot slot) u8 SlotToEXIChannel(Slot slot); u8 SlotToEXIDevice(Slot slot); -void Init(); +void Init(const Sram* override_sram); void Shutdown(); void DoState(PointerWrap& p); void PauseAndLock(bool doLock, bool unpauseOnUnlock); diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp index 6f4d7ad2c2..f331f86284 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp +++ b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp @@ -28,6 +28,7 @@ #include "Core/HW/SystemTimers.h" #include "Core/Movie.h" #include "Core/NetPlayProto.h" +#include "Core/System.h" #include "DiscIO/Enums.h" @@ -129,28 +130,25 @@ CEXIIPL::CEXIIPL() LoadFontFile((File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + FONT_WINDOWS_1252), 0x1fcf00); } + auto& sram = Core::System::GetInstance().GetSRAM(); + // Clear RTC - g_SRAM.rtc = 0; + sram.rtc = 0; // We Overwrite language selection here since it's possible on the GC to change the language as // you please - g_SRAM.settings.language = Config::Get(Config::MAIN_GC_LANGUAGE); - g_SRAM.settings.rtc_bias = 0; - FixSRAMChecksums(); + sram.settings.language = Config::Get(Config::MAIN_GC_LANGUAGE); + sram.settings.rtc_bias = 0; + FixSRAMChecksums(&sram); } -CEXIIPL::~CEXIIPL() -{ - // SRAM - if (!g_SRAM_netplay_initialized) - { - File::IOFile file(SConfig::GetInstance().m_strSRAM, "wb"); - file.WriteArray(&g_SRAM, 1); - } -} +CEXIIPL::~CEXIIPL() = default; + void CEXIIPL::DoState(PointerWrap& p) { - p.Do(g_SRAM); + auto& sram = Core::System::GetInstance().GetSRAM(); + + p.Do(sram); p.Do(g_rtc_flags); p.Do(m_command); p.Do(m_command_bytes_received); @@ -253,7 +251,8 @@ void CEXIIPL::SetCS(int cs) void CEXIIPL::UpdateRTC() { - g_SRAM.rtc = GetEmulatedTime(GC_EPOCH); + auto& sram = Core::System::GetInstance().GetSRAM(); + sram.rtc = GetEmulatedTime(GC_EPOCH); } bool CEXIIPL::IsPresent() const @@ -343,11 +342,12 @@ void CEXIIPL::TransferByte(u8& data) } else if (IN_RANGE(SRAM)) { + auto& sram = Core::System::GetInstance().GetSRAM(); u32 dev_addr = DEV_ADDR_CURSOR(SRAM); if (m_command.is_write()) - g_SRAM[dev_addr] = data; + sram[dev_addr] = data; else - data = g_SRAM[dev_addr]; + data = sram[dev_addr]; } else if (IN_RANGE(UART)) { diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp index 5e012e44db..0a48ffe7b9 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp +++ b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp @@ -34,6 +34,7 @@ #include "Core/HW/Sram.h" #include "Core/HW/SystemTimers.h" #include "Core/Movie.h" +#include "Core/System.h" #include "DiscIO/Enums.h" namespace ExpansionInterface @@ -141,7 +142,8 @@ CEXIMemoryCard::CEXIMemoryCard(const Slot slot, bool gci_folder, m_memory_card_size = m_memory_card->GetCardId() * SIZE_TO_Mb; std::array header{}; m_memory_card->Read(0, static_cast(header.size()), header.data()); - SetCardFlashID(header.data(), m_card_slot); + auto& sram = Core::System::GetInstance().GetSRAM(); + SetCardFlashID(&sram, header.data(), m_card_slot); } std::pair diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp b/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp index 23bca41df1..033bcd1952 100644 --- a/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp +++ b/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp @@ -30,6 +30,7 @@ #include "Core/HW/EXI/EXI_DeviceIPL.h" #include "Core/HW/GCMemcard/GCMemcard.h" #include "Core/HW/Sram.h" +#include "Core/System.h" #define SIZE_TO_Mb (1024 * 8 * 16) #define MC_HDR_SIZE 0xA000 @@ -59,10 +60,11 @@ MemoryCard::MemoryCard(const std::string& filename, ExpansionInterface::Slot car m_memcard_data = std::make_unique(m_memory_card_size); // Fills in the first 5 blocks (MC_HDR_SIZE bytes) - const CardFlashId& flash_id = g_SRAM.settings_ex.flash_id[Memcard::SLOT_A]; + auto& sram = Core::System::GetInstance().GetSRAM(); + const CardFlashId& flash_id = sram.settings_ex.flash_id[Memcard::SLOT_A]; const bool shift_jis = m_filename.find(".JAP.raw") != std::string::npos; - const u32 rtc_bias = g_SRAM.settings.rtc_bias; - const u32 sram_language = static_cast(g_SRAM.settings.language); + const u32 rtc_bias = sram.settings.rtc_bias; + const u32 sram_language = static_cast(sram.settings.language); const u64 format_time = Common::Timer::GetLocalTimeSinceJan1970() - ExpansionInterface::CEXIIPL::GC_EPOCH; Memcard::GCMemcard::Format(&m_memcard_data[0], flash_id, size_mbits, shift_jis, rtc_bias, diff --git a/Source/Core/Core/HW/HW.cpp b/Source/Core/Core/HW/HW.cpp index 9b9251c201..0cecd485c5 100644 --- a/Source/Core/Core/HW/HW.cpp +++ b/Source/Core/Core/HW/HW.cpp @@ -29,7 +29,7 @@ namespace HW { -void Init() +void Init(const Sram* override_sram) { CoreTiming::Init(); SystemTimers::PreInit(); @@ -41,7 +41,7 @@ void Init() VideoInterface::Init(); SerialInterface::Init(); ProcessorInterface::Init(); - ExpansionInterface::Init(); // Needs to be initialized before Memory + ExpansionInterface::Init(override_sram); // Needs to be initialized before Memory HSP::Init(); Memory::Init(); // Needs to be initialized before AddressSpace AddressSpace::Init(); diff --git a/Source/Core/Core/HW/HW.h b/Source/Core/Core/HW/HW.h index a527f65f85..1122ca5e2d 100644 --- a/Source/Core/Core/HW/HW.h +++ b/Source/Core/Core/HW/HW.h @@ -4,10 +4,11 @@ #pragma once class PointerWrap; +struct Sram; namespace HW { -void Init(); +void Init(const Sram* override_sram); void Shutdown(); void DoState(PointerWrap& p); } // namespace HW diff --git a/Source/Core/Core/HW/Sram.cpp b/Source/Core/Core/HW/Sram.cpp index 1f8b29116a..b177ed6443 100644 --- a/Source/Core/Core/HW/Sram.cpp +++ b/Source/Core/Core/HW/Sram.cpp @@ -9,7 +9,6 @@ #include "Common/MsgHandler.h" #include "Common/Swap.h" -#include "Core/ConfigManager.h" #include "Core/HW/EXI/EXI.h" // English @@ -58,24 +57,24 @@ const SRAM sram_dump_german = {{ }}; #endif -void InitSRAM() +void InitSRAM(Sram* sram, const std::string& filename) { - File::IOFile file(SConfig::GetInstance().m_strSRAM, "rb"); + File::IOFile file(filename, "rb"); if (file) { - if (!file.ReadArray(&g_SRAM, 1)) + if (!file.ReadArray(sram, 1)) { ERROR_LOG_FMT(EXPANSIONINTERFACE, "EXI IPL-DEV: Could not read all of SRAM"); - g_SRAM = sram_dump; + *sram = sram_dump; } } else { - g_SRAM = sram_dump; + *sram = sram_dump; } } -void SetCardFlashID(const u8* buffer, ExpansionInterface::Slot card_slot) +void SetCardFlashID(Sram* sram, const u8* buffer, ExpansionInterface::Slot card_slot) { u8 card_index; switch (card_slot) @@ -96,25 +95,25 @@ void SetCardFlashID(const u8* buffer, ExpansionInterface::Slot card_slot) for (int i = 0; i < 12; i++) { rand = (((rand * (u64)0x0000000041c64e6dULL) + (u64)0x0000000000003039ULL) >> 16); - csum += g_SRAM.settings_ex.flash_id[card_index][i] = buffer[i] - ((u8)rand & 0xff); + csum += sram->settings_ex.flash_id[card_index][i] = buffer[i] - ((u8)rand & 0xff); rand = (((rand * (u64)0x0000000041c64e6dULL) + (u64)0x0000000000003039ULL) >> 16); rand &= (u64)0x0000000000007fffULL; } - g_SRAM.settings_ex.flash_id_checksum[card_index] = csum ^ 0xFF; + sram->settings_ex.flash_id_checksum[card_index] = csum ^ 0xFF; } -void FixSRAMChecksums() +void FixSRAMChecksums(Sram* sram) { // 16bit big-endian additive checksum u16 checksum = 0; u16 checksum_inv = 0; - for (auto p = reinterpret_cast(&g_SRAM.settings.rtc_bias); - p != reinterpret_cast(&g_SRAM.settings_ex); p++) + for (auto p = reinterpret_cast(&sram->settings.rtc_bias); + p != reinterpret_cast(&sram->settings_ex); p++) { u16 value = Common::FromBigEndian(*p); checksum += value; checksum_inv += ~value; } - g_SRAM.settings.checksum = checksum; - g_SRAM.settings.checksum_inv = checksum_inv; + sram->settings.checksum = checksum; + sram->settings.checksum_inv = checksum_inv; } diff --git a/Source/Core/Core/HW/Sram.h b/Source/Core/Core/HW/Sram.h index 92262ca331..c58d8ad73c 100644 --- a/Source/Core/Core/HW/Sram.h +++ b/Source/Core/Core/HW/Sram.h @@ -34,6 +34,7 @@ distribution. #pragma once #include +#include #include "Common/CommonTypes.h" #include "Common/Swap.h" @@ -133,9 +134,6 @@ static_assert(sizeof(Sram) == 0x44); #pragma pack(pop) -void InitSRAM(); -void SetCardFlashID(const u8* buffer, ExpansionInterface::Slot card_slot); -void FixSRAMChecksums(); - -extern Sram g_SRAM; -extern bool g_SRAM_netplay_initialized; +void InitSRAM(Sram* sram, const std::string& filename); +void SetCardFlashID(Sram* sram, const u8* buffer, ExpansionInterface::Slot card_slot); +void FixSRAMChecksums(Sram* sram); diff --git a/Source/Core/Core/NetPlayClient.cpp b/Source/Core/Core/NetPlayClient.cpp index 090ff2353f..9c744420e5 100644 --- a/Source/Core/Core/NetPlayClient.cpp +++ b/Source/Core/Core/NetPlayClient.cpp @@ -432,10 +432,6 @@ void NetPlayClient::OnData(sf::Packet& packet) OnDesyncDetected(packet); break; - case MessageID::SyncGCSRAM: - OnSyncGCSRAM(packet); - break; - case MessageID::SyncSaveData: OnSyncSaveData(packet); break; @@ -893,6 +889,9 @@ void NetPlayClient::OnStartGame(sf::Packet& packet) packet >> m_net_settings.use_fma; packet >> m_net_settings.hide_remote_gbas; + for (size_t i = 0; i < sizeof(m_net_settings.sram); ++i) + packet >> m_net_settings.sram[i]; + m_net_settings.is_hosting = m_local_player->IsHost(); } @@ -960,20 +959,6 @@ void NetPlayClient::OnDesyncDetected(sf::Packet& packet) m_dialog->OnDesync(frame, player); } -void NetPlayClient::OnSyncGCSRAM(sf::Packet& packet) -{ - const size_t sram_settings_len = sizeof(g_SRAM) - offsetof(Sram, settings); - u8 sram[sram_settings_len]; - for (u8& cell : sram) - packet >> cell; - - { - std::lock_guard lkg(m_crit.game); - memcpy(&g_SRAM.settings, sram, sram_settings_len); - g_SRAM_netplay_initialized = true; - } -} - void NetPlayClient::OnSyncSaveData(sf::Packet& packet) { SyncSaveDataID sub_id; diff --git a/Source/Core/Core/NetPlayClient.h b/Source/Core/Core/NetPlayClient.h index 36fa2cc31a..5e7fe3a3c5 100644 --- a/Source/Core/Core/NetPlayClient.h +++ b/Source/Core/Core/NetPlayClient.h @@ -281,7 +281,6 @@ private: void OnPing(sf::Packet& packet); void OnPlayerPingData(sf::Packet& packet); void OnDesyncDetected(sf::Packet& packet); - void OnSyncGCSRAM(sf::Packet& packet); void OnSyncSaveData(sf::Packet& packet); void OnSyncSaveDataNotify(sf::Packet& packet); void OnSyncSaveDataRaw(sf::Packet& packet); diff --git a/Source/Core/Core/NetPlayProto.h b/Source/Core/Core/NetPlayProto.h index cc8eb77e23..cd78e6700b 100644 --- a/Source/Core/Core/NetPlayProto.h +++ b/Source/Core/Core/NetPlayProto.h @@ -12,6 +12,7 @@ #include "Core/Config/SYSCONFSettings.h" #include "Core/HW/EXI/EXI.h" #include "Core/HW/EXI/EXI_Device.h" +#include "Core/HW/Sram.h" namespace DiscIO { @@ -105,6 +106,8 @@ struct NetSettings bool use_fma = false; bool hide_remote_gbas = false; + Sram sram; + // These aren't sent over the network directly bool is_hosting = false; std::array gba_rom_paths{}; @@ -180,7 +183,6 @@ enum class MessageID : u8 Pong = 0xE1, PlayerPingData = 0xE2, - SyncGCSRAM = 0xF0, SyncSaveData = 0xF1, SyncCodes = 0xF2, }; diff --git a/Source/Core/Core/NetPlayServer.cpp b/Source/Core/Core/NetPlayServer.cpp index 64656c64f3..f521e20a24 100644 --- a/Source/Core/Core/NetPlayServer.cpp +++ b/Source/Core/Core/NetPlayServer.cpp @@ -1436,20 +1436,9 @@ bool NetPlayServer::StartGame() const std::string region = Config::GetDirectoryForRegion( Config::ToGameCubeRegion(m_dialog->FindGameFile(m_selected_game_identifier)->GetRegion())); - // sync GC SRAM with clients - if (!g_SRAM_netplay_initialized) - { - SConfig::GetInstance().m_strSRAM = File::GetUserPath(F_GCSRAM_IDX); - InitSRAM(); - g_SRAM_netplay_initialized = true; - } - sf::Packet srampac; - srampac << MessageID::SyncGCSRAM; - for (size_t i = 0; i < sizeof(g_SRAM) - offsetof(Sram, settings); ++i) - { - srampac << g_SRAM[offsetof(Sram, settings) + i]; - } - SendAsyncToClients(std::move(srampac), 1); + // load host's GC SRAM + SConfig::GetInstance().m_strSRAM = File::GetUserPath(F_GCSRAM_IDX); + InitSRAM(&m_settings.sram, SConfig::GetInstance().m_strSRAM); // tell clients to start game sf::Packet spac; @@ -1544,6 +1533,9 @@ bool NetPlayServer::StartGame() spac << m_settings.use_fma; spac << m_settings.hide_remote_gbas; + for (size_t i = 0; i < sizeof(m_settings.sram); ++i) + spac << m_settings.sram[i]; + SendAsyncToClients(std::move(spac)); m_start_pending = false; diff --git a/Source/Core/Core/System.cpp b/Source/Core/Core/System.cpp index cf8be13ab9..b6ec853f2d 100644 --- a/Source/Core/Core/System.cpp +++ b/Source/Core/Core/System.cpp @@ -10,6 +10,7 @@ #include "Core/HW/AudioInterface.h" #include "Core/HW/DVD/DVDInterface.h" #include "Core/HW/DVD/DVDThread.h" +#include "Core/HW/Sram.h" namespace Core { @@ -22,6 +23,7 @@ struct System::Impl AudioInterface::AudioInterfaceState m_audio_interface_state; DVDInterface::DVDInterfaceState m_dvd_interface_state; DVDThread::DVDThreadState m_dvd_thread_state; + Sram m_sram; }; System::System() : m_impl{std::make_unique()} @@ -80,4 +82,9 @@ DVDThread::DVDThreadState& System::GetDVDThreadState() const { return m_impl->m_dvd_thread_state; } + +Sram& System::GetSRAM() const +{ + return m_impl->m_sram; +} } // namespace Core diff --git a/Source/Core/Core/System.h b/Source/Core/Core/System.h index 83b93d4b19..a616bfbe71 100644 --- a/Source/Core/Core/System.h +++ b/Source/Core/Core/System.h @@ -6,6 +6,7 @@ #include class SoundStream; +struct Sram; namespace AudioInterface { @@ -56,6 +57,7 @@ public: AudioInterface::AudioInterfaceState& GetAudioInterfaceState() const; DVDInterface::DVDInterfaceState& GetDVDInterfaceState() const; DVDThread::DVDThreadState& GetDVDThreadState() const; + Sram& GetSRAM() const; private: System();