From 9950209bbfa4bd32b63482785181e52bba726310 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 29 Oct 2016 14:01:00 +0200 Subject: [PATCH] EXI_DeviceIPL: Unify GetGCTime epoch handling --- Source/Core/Core/Boot/Boot_BS2Emu.cpp | 2 +- Source/Core/Core/HW/EXI_DeviceIPL.cpp | 25 ++++--------------- Source/Core/Core/HW/EXI_DeviceIPL.h | 11 +++++--- Source/Core/Core/HW/GCMemcard.h | 2 +- Source/Core/Core/HW/SystemTimers.cpp | 2 +- .../Core/IPC_HLE/WII_IPC_HLE_Device_net.h | 17 ++++++------- Source/Core/Core/Movie.cpp | 4 +-- Source/Core/Core/NetPlayClient.cpp | 6 ++--- Source/Core/Core/NetPlayProto.h | 2 +- Source/Core/Core/NetPlayServer.cpp | 10 ++++---- 10 files changed, 35 insertions(+), 46 deletions(-) diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index 7825f0132a..817c5d4bcc 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -87,7 +87,7 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader) PowerPC::HostWrite_U32(0x4c000064, 0x80000800); // Write default FPU Handler: rfi PowerPC::HostWrite_U32(0x4c000064, 0x80000C00); // Write default Syscall Handler: rfi - PowerPC::HostWrite_U64((u64)CEXIIPL::GetGCTime() * (u64)40500000, + PowerPC::HostWrite_U64((u64)CEXIIPL::GetEmulatedTime(CEXIIPL::GC_EPOCH) * (u64)40500000, 0x800030D8); // Preset time base ticks // HIO checks this // PowerPC::HostWrite_U16(0x8200, 0x000030e6); // Console type diff --git a/Source/Core/Core/HW/EXI_DeviceIPL.cpp b/Source/Core/Core/HW/EXI_DeviceIPL.cpp index 2208582edf..650a688365 100644 --- a/Source/Core/Core/HW/EXI_DeviceIPL.cpp +++ b/Source/Core/Core/HW/EXI_DeviceIPL.cpp @@ -33,8 +33,6 @@ static const char iplverPAL[0x100] = "(C) 1999-2001 Nintendo. All rights reserv static const char iplverNTSC[0x100] = "(C) 1999-2001 Nintendo. All rights reserved." "(C) 1999 ArtX Inc. All rights reserved."; -static constexpr u32 cJanuary2000 = 0x386D4380; // Seconds between 1.1.1970 and 1.1.2000 - // bootrom descrambler reversed by segher // Copyright 2008 Segher Boessenkool void CEXIIPL::Descrambler(u8* data, u32 size) @@ -231,16 +229,8 @@ void CEXIIPL::SetCS(int _iCS) void CEXIIPL::UpdateRTC() { - // Seconds between 1.1.2000 and 4.1.2008 16:00:38 - static constexpr u32 WII_BIAS = 0x0F1114A6; - - u32 rtc; - - if (SConfig::GetInstance().bWii) - rtc = Common::swap32(GetGCTime() - WII_BIAS); - else - rtc = Common::swap32(GetGCTime()); - + u32 epoch = SConfig::GetInstance().bWii ? WII_EPOCH : GC_EPOCH; + u32 rtc = Common::swap32(GetEmulatedTime(epoch)); std::memcpy(m_RTC, &rtc, sizeof(u32)); } @@ -405,7 +395,7 @@ void CEXIIPL::TransferByte(u8& _uByte) m_uPosition++; } -u32 CEXIIPL::GetGCTime() +u32 CEXIIPL::GetEmulatedTime(u32 epoch) { u64 ltime = 0; @@ -418,7 +408,7 @@ u32 CEXIIPL::GetGCTime() } else if (NetPlay::IsNetPlayRunning()) { - ltime = NetPlay_GetGCTime(); + ltime = NetPlay_GetEmulatedTime(); // let's keep time moving forward, regardless of what it starts at ltime += CoreTiming::GetTicks() / SystemTimers::GetTicksPerSecond(); @@ -429,10 +419,5 @@ u32 CEXIIPL::GetGCTime() ltime = Common::Timer::GetLocalTimeSinceJan1970() - SystemTimers::GetLocalTimeRTCOffset(); } - return ((u32)ltime - cJanuary2000); -} - -u32 CEXIIPL::GetGCTimeJan1970() -{ - return GetGCTime() + cJanuary2000; + return static_cast(ltime) - epoch; } diff --git a/Source/Core/Core/HW/EXI_DeviceIPL.h b/Source/Core/Core/HW/EXI_DeviceIPL.h index 7a5c76cff9..e43fb4efdd 100644 --- a/Source/Core/Core/HW/EXI_DeviceIPL.h +++ b/Source/Core/Core/HW/EXI_DeviceIPL.h @@ -20,9 +20,14 @@ public: bool IsPresent() const override; void DoState(PointerWrap& p) override; - static u32 GetGCTime(); - static u32 GetGCTimeJan1970(); - static u64 NetPlay_GetGCTime(); + static constexpr u32 UNIX_EPOCH = 0; // 1970-01-01 00:00:00 + static constexpr u32 GC_EPOCH = 0x386D4380; // 2000-01-01 00:00:00 + static constexpr u32 WII_EPOCH = 0x477E5826; // 2008-01-04 16:00:38 + // The Wii epoch is suspiciously random, and the Wii was even + // released before it, but apparently it works anyway? + + static u32 GetEmulatedTime(u32 epoch); + static u64 NetPlay_GetEmulatedTime(); static void Descrambler(u8* data, u32 size); diff --git a/Source/Core/Core/HW/GCMemcard.h b/Source/Core/Core/HW/GCMemcard.h index b4c850ea30..6f35a703c3 100644 --- a/Source/Core/Core/HW/GCMemcard.h +++ b/Source/Core/Core/HW/GCMemcard.h @@ -131,7 +131,7 @@ struct Header // Offset Size Description memset(this, 0xFF, BLOCK_SIZE); *(u16*)SizeMb = BE16(sizeMb); Encoding = BE16(ascii ? 0 : 1); - u64 rand = CEXIIPL::GetGCTime(); + u64 rand = CEXIIPL::GetEmulatedTime(CEXIIPL::GC_EPOCH); formatTime = Common::swap64(rand); for (int i = 0; i < 12; i++) { diff --git a/Source/Core/Core/HW/SystemTimers.cpp b/Source/Core/Core/HW/SystemTimers.cpp index ac75dfbd58..fbd886e2d6 100644 --- a/Source/Core/Core/HW/SystemTimers.cpp +++ b/Source/Core/Core/HW/SystemTimers.cpp @@ -253,7 +253,7 @@ void Init() Common::Timer::GetLocalTimeSinceJan1970() - SConfig::GetInstance().m_customRTCValue; } CoreTiming::SetFakeTBStartValue((u64)(s_cpu_core_clock / TIMER_RATIO) * - (u64)CEXIIPL::GetGCTime()); + (u64)CEXIIPL::GetEmulatedTime(CEXIIPL::GC_EPOCH)); CoreTiming::SetFakeTBStartTicks(CoreTiming::GetTicks()); CoreTiming::SetFakeDecStartValue(0xFFFFFFFF); diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h index e340347416..3ffc104f01 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h @@ -515,20 +515,19 @@ private: u64 rtc; s64 utcdiff; - // TODO: depending on CEXIIPL is a hack which I don't feel like removing - // because the function itself is pretty hackish; wait until I re-port my - // netplay rewrite; also, is that random 16:00:38 actually meaningful? - // seems very very doubtful since Wii was released in 2006 - - // Seconds between 1.1.2000 and 4.1.2008 16:00:38 - static const u64 wii_bias = 0x477E5826 - 0x386D4380; + // TODO: depending on CEXIIPL is a hack which I don't feel like + // removing because the function itself is pretty hackish; + // wait until I re-port my netplay rewrite // Returns seconds since Wii epoch // +/- any bias set from IOCTL_NW24_SET_UNIVERSAL_TIME - u64 GetAdjustedUTC() const { return CEXIIPL::GetGCTime() - wii_bias + utcdiff; } + u64 GetAdjustedUTC() const { return CEXIIPL::GetEmulatedTime(CEXIIPL::WII_EPOCH) + utcdiff; } // Store the difference between what the Wii thinks is UTC and // what the host OS thinks - void SetAdjustedUTC(u64 wii_utc) { utcdiff = CEXIIPL::GetGCTime() - wii_bias - wii_utc; } + void SetAdjustedUTC(u64 wii_utc) + { + utcdiff = CEXIIPL::GetEmulatedTime(CEXIIPL::WII_EPOCH) - wii_utc; + } }; enum NET_IOCTL diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp index 1fe88259cc..1112f788dd 100644 --- a/Source/Core/Core/Movie.cpp +++ b/Source/Core/Core/Movie.cpp @@ -180,7 +180,7 @@ std::string GetInputDisplay() // NOTE: GPU Thread std::string GetRTCDisplay() { - time_t current_time = CEXIIPL::GetGCTimeJan1970(); + time_t current_time = CEXIIPL::GetEmulatedTime(CEXIIPL::UNIX_EPOCH); tm* gm_time = gmtime(¤t_time); char buffer[256]; strftime(buffer, sizeof(buffer), "Date/Time: %c", gm_time); @@ -552,7 +552,7 @@ bool BeginRecordingInput(int controllers) if (NetPlay::IsNetPlayRunning()) { s_bNetPlay = true; - s_recordingStartTime = CEXIIPL::NetPlay_GetGCTime(); + s_recordingStartTime = CEXIIPL::NetPlay_GetEmulatedTime(); } else if (SConfig::GetInstance().bEnableCustomRTC) { diff --git a/Source/Core/Core/NetPlayClient.cpp b/Source/Core/Core/NetPlayClient.cpp index dd33824fd2..a9697ac058 100644 --- a/Source/Core/Core/NetPlayClient.cpp +++ b/Source/Core/Core/NetPlayClient.cpp @@ -423,7 +423,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet) u32 time_low, time_high; packet >> time_low; packet >> time_high; - g_netplay_initial_gctime = time_low | ((u64)time_high << 32); + g_netplay_initial_rtc = time_low | ((u64)time_high << 32); } m_dialog->OnMsgStartGame(); @@ -1282,12 +1282,12 @@ bool WiimoteEmu::Wiimote::NetPlay_GetWiimoteData(int wiimote, u8* data, u8 size, // so all players' games get the same time // // also called from ---GUI--- thread when starting input recording -u64 CEXIIPL::NetPlay_GetGCTime() +u64 CEXIIPL::NetPlay_GetEmulatedTime() { std::lock_guard lk(crit_netplay_client); if (netplay_client) - return g_netplay_initial_gctime; + return g_netplay_initial_rtc; else return 0; } diff --git a/Source/Core/Core/NetPlayProto.h b/Source/Core/Core/NetPlayProto.h index ffaf47a2bd..f5ced9b781 100644 --- a/Source/Core/Core/NetPlayProto.h +++ b/Source/Core/Core/NetPlayProto.h @@ -27,7 +27,7 @@ struct NetSettings }; extern NetSettings g_NetPlaySettings; -extern u64 g_netplay_initial_gctime; +extern u64 g_netplay_initial_rtc; struct Rpt : public std::vector { diff --git a/Source/Core/Core/NetPlayServer.cpp b/Source/Core/Core/NetPlayServer.cpp index 1dbdd9bc96..1d70799ce4 100644 --- a/Source/Core/Core/NetPlayServer.cpp +++ b/Source/Core/Core/NetPlayServer.cpp @@ -27,7 +27,7 @@ #include #endif -u64 g_netplay_initial_gctime = 1272737767; +u64 g_netplay_initial_rtc = 1272737767; NetPlayServer::~NetPlayServer() { @@ -789,9 +789,9 @@ bool NetPlayServer::StartGame() AdjustPadBufferSize(m_target_buffer_size); if (SConfig::GetInstance().bEnableCustomRTC) - g_netplay_initial_gctime = SConfig::GetInstance().m_customRTCValue; + g_netplay_initial_rtc = SConfig::GetInstance().m_customRTCValue; else - g_netplay_initial_gctime = Common::Timer::GetLocalTimeSinceJan1970(); + g_netplay_initial_rtc = Common::Timer::GetLocalTimeSinceJan1970(); // tell clients to start game auto spac = std::make_unique(); @@ -811,8 +811,8 @@ bool NetPlayServer::StartGame() *spac << m_settings.m_OCFactor; *spac << m_settings.m_EXIDevice[0]; *spac << m_settings.m_EXIDevice[1]; - *spac << (u32)g_netplay_initial_gctime; - *spac << (u32)(g_netplay_initial_gctime >> 32); + *spac << (u32)g_netplay_initial_rtc; + *spac << (u32)(g_netplay_initial_rtc >> 32); SendAsyncToClients(std::move(spac));