Merge pull request #4399 from JosJuice/unify-getgctime

EXI_DeviceIPL: Unify GetGCTime epoch handling
This commit is contained in:
Markus Wick 2016-10-31 12:47:06 +01:00 committed by GitHub
commit 4eb5892e1a
10 changed files with 35 additions and 63 deletions

View File

@ -87,7 +87,7 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
PowerPC::HostWrite_U32(0x4c000064, 0x80000800); // Write default FPU Handler: rfi PowerPC::HostWrite_U32(0x4c000064, 0x80000800); // Write default FPU Handler: rfi
PowerPC::HostWrite_U32(0x4c000064, 0x80000C00); // Write default Syscall 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 0x800030D8); // Preset time base ticks
// HIO checks this // HIO checks this
// PowerPC::HostWrite_U16(0x8200, 0x000030e6); // Console type // PowerPC::HostWrite_U16(0x8200, 0x000030e6); // Console type

View File

@ -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." static const char iplverNTSC[0x100] = "(C) 1999-2001 Nintendo. All rights reserved."
"(C) 1999 ArtX Inc. 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 // bootrom descrambler reversed by segher
// Copyright 2008 Segher Boessenkool <segher@kernel.crashing.org> // Copyright 2008 Segher Boessenkool <segher@kernel.crashing.org>
void CEXIIPL::Descrambler(u8* data, u32 size) void CEXIIPL::Descrambler(u8* data, u32 size)
@ -231,16 +229,8 @@ void CEXIIPL::SetCS(int _iCS)
void CEXIIPL::UpdateRTC() void CEXIIPL::UpdateRTC()
{ {
// Seconds between 1.1.2000 and 4.1.2008 16:00:38 u32 epoch = SConfig::GetInstance().bWii ? WII_EPOCH : GC_EPOCH;
static constexpr u32 WII_BIAS = 0x0F1114A6; u32 rtc = Common::swap32(GetEmulatedTime(epoch));
u32 rtc;
if (SConfig::GetInstance().bWii)
rtc = Common::swap32(GetGCTime() - WII_BIAS);
else
rtc = Common::swap32(GetGCTime());
std::memcpy(m_RTC, &rtc, sizeof(u32)); std::memcpy(m_RTC, &rtc, sizeof(u32));
} }
@ -405,7 +395,7 @@ void CEXIIPL::TransferByte(u8& _uByte)
m_uPosition++; m_uPosition++;
} }
u32 CEXIIPL::GetGCTime() u32 CEXIIPL::GetEmulatedTime(u32 epoch)
{ {
u64 ltime = 0; u64 ltime = 0;
@ -418,7 +408,7 @@ u32 CEXIIPL::GetGCTime()
} }
else if (NetPlay::IsNetPlayRunning()) else if (NetPlay::IsNetPlayRunning())
{ {
ltime = NetPlay_GetGCTime(); ltime = NetPlay_GetEmulatedTime();
// let's keep time moving forward, regardless of what it starts at // let's keep time moving forward, regardless of what it starts at
ltime += CoreTiming::GetTicks() / SystemTimers::GetTicksPerSecond(); ltime += CoreTiming::GetTicks() / SystemTimers::GetTicksPerSecond();
@ -429,27 +419,5 @@ u32 CEXIIPL::GetGCTime()
ltime = Common::Timer::GetLocalTimeSinceJan1970() - SystemTimers::GetLocalTimeRTCOffset(); ltime = Common::Timer::GetLocalTimeSinceJan1970() - SystemTimers::GetLocalTimeRTCOffset();
} }
return ((u32)ltime - cJanuary2000); return static_cast<u32>(ltime) - epoch;
#if 0
// (mb2): I think we can get rid of the IPL bias.
// I know, it's another hack so I let the previous code for a while.
// Get SRAM bias
u32 Bias;
for (int i = 0; i < 4; i++)
{
((u8*)&Bias)[i] = sram_dump[0xc + (i^3)];
}
// Get the time ...
u64 ltime = Common::Timer::GetTimeSinceJan1970();
return ((u32)ltime - cJanuary2000 - Bias);
#endif
}
u32 CEXIIPL::GetGCTimeJan1970()
{
return GetGCTime() + cJanuary2000;
} }

View File

@ -20,9 +20,14 @@ public:
bool IsPresent() const override; bool IsPresent() const override;
void DoState(PointerWrap& p) override; void DoState(PointerWrap& p) override;
static u32 GetGCTime(); static constexpr u32 UNIX_EPOCH = 0; // 1970-01-01 00:00:00
static u32 GetGCTimeJan1970(); static constexpr u32 GC_EPOCH = 0x386D4380; // 2000-01-01 00:00:00
static u64 NetPlay_GetGCTime(); 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); static void Descrambler(u8* data, u32 size);

View File

@ -131,7 +131,7 @@ struct Header // Offset Size Description
memset(this, 0xFF, BLOCK_SIZE); memset(this, 0xFF, BLOCK_SIZE);
*(u16*)SizeMb = BE16(sizeMb); *(u16*)SizeMb = BE16(sizeMb);
Encoding = BE16(ascii ? 0 : 1); Encoding = BE16(ascii ? 0 : 1);
u64 rand = CEXIIPL::GetGCTime(); u64 rand = CEXIIPL::GetEmulatedTime(CEXIIPL::GC_EPOCH);
formatTime = Common::swap64(rand); formatTime = Common::swap64(rand);
for (int i = 0; i < 12; i++) for (int i = 0; i < 12; i++)
{ {

View File

@ -253,7 +253,7 @@ void Init()
Common::Timer::GetLocalTimeSinceJan1970() - SConfig::GetInstance().m_customRTCValue; Common::Timer::GetLocalTimeSinceJan1970() - SConfig::GetInstance().m_customRTCValue;
} }
CoreTiming::SetFakeTBStartValue((u64)(s_cpu_core_clock / TIMER_RATIO) * CoreTiming::SetFakeTBStartValue((u64)(s_cpu_core_clock / TIMER_RATIO) *
(u64)CEXIIPL::GetGCTime()); (u64)CEXIIPL::GetEmulatedTime(CEXIIPL::GC_EPOCH));
CoreTiming::SetFakeTBStartTicks(CoreTiming::GetTicks()); CoreTiming::SetFakeTBStartTicks(CoreTiming::GetTicks());
CoreTiming::SetFakeDecStartValue(0xFFFFFFFF); CoreTiming::SetFakeDecStartValue(0xFFFFFFFF);

View File

@ -515,20 +515,19 @@ private:
u64 rtc; u64 rtc;
s64 utcdiff; s64 utcdiff;
// TODO: depending on CEXIIPL is a hack which I don't feel like removing // TODO: depending on CEXIIPL is a hack which I don't feel like
// because the function itself is pretty hackish; wait until I re-port my // removing because the function itself is pretty hackish;
// netplay rewrite; also, is that random 16:00:38 actually meaningful? // wait until I re-port my netplay rewrite
// 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;
// Returns seconds since Wii epoch // Returns seconds since Wii epoch
// +/- any bias set from IOCTL_NW24_SET_UNIVERSAL_TIME // +/- 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 // Store the difference between what the Wii thinks is UTC and
// what the host OS thinks // 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 enum NET_IOCTL

View File

@ -180,7 +180,7 @@ std::string GetInputDisplay()
// NOTE: GPU Thread // NOTE: GPU Thread
std::string GetRTCDisplay() std::string GetRTCDisplay()
{ {
time_t current_time = CEXIIPL::GetGCTimeJan1970(); time_t current_time = CEXIIPL::GetEmulatedTime(CEXIIPL::UNIX_EPOCH);
tm* gm_time = gmtime(&current_time); tm* gm_time = gmtime(&current_time);
char buffer[256]; char buffer[256];
strftime(buffer, sizeof(buffer), "Date/Time: %c", gm_time); strftime(buffer, sizeof(buffer), "Date/Time: %c", gm_time);
@ -552,7 +552,7 @@ bool BeginRecordingInput(int controllers)
if (NetPlay::IsNetPlayRunning()) if (NetPlay::IsNetPlayRunning())
{ {
s_bNetPlay = true; s_bNetPlay = true;
s_recordingStartTime = CEXIIPL::NetPlay_GetGCTime(); s_recordingStartTime = CEXIIPL::NetPlay_GetEmulatedTime();
} }
else if (SConfig::GetInstance().bEnableCustomRTC) else if (SConfig::GetInstance().bEnableCustomRTC)
{ {

View File

@ -423,7 +423,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
u32 time_low, time_high; u32 time_low, time_high;
packet >> time_low; packet >> time_low;
packet >> time_high; 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(); 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 // so all players' games get the same time
// //
// also called from ---GUI--- thread when starting input recording // also called from ---GUI--- thread when starting input recording
u64 CEXIIPL::NetPlay_GetGCTime() u64 CEXIIPL::NetPlay_GetEmulatedTime()
{ {
std::lock_guard<std::mutex> lk(crit_netplay_client); std::lock_guard<std::mutex> lk(crit_netplay_client);
if (netplay_client) if (netplay_client)
return g_netplay_initial_gctime; return g_netplay_initial_rtc;
else else
return 0; return 0;
} }

View File

@ -27,7 +27,7 @@ struct NetSettings
}; };
extern NetSettings g_NetPlaySettings; extern NetSettings g_NetPlaySettings;
extern u64 g_netplay_initial_gctime; extern u64 g_netplay_initial_rtc;
struct Rpt : public std::vector<u8> struct Rpt : public std::vector<u8>
{ {

View File

@ -27,7 +27,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#endif #endif
u64 g_netplay_initial_gctime = 1272737767; u64 g_netplay_initial_rtc = 1272737767;
NetPlayServer::~NetPlayServer() NetPlayServer::~NetPlayServer()
{ {
@ -789,9 +789,9 @@ bool NetPlayServer::StartGame()
AdjustPadBufferSize(m_target_buffer_size); AdjustPadBufferSize(m_target_buffer_size);
if (SConfig::GetInstance().bEnableCustomRTC) if (SConfig::GetInstance().bEnableCustomRTC)
g_netplay_initial_gctime = SConfig::GetInstance().m_customRTCValue; g_netplay_initial_rtc = SConfig::GetInstance().m_customRTCValue;
else else
g_netplay_initial_gctime = Common::Timer::GetLocalTimeSinceJan1970(); g_netplay_initial_rtc = Common::Timer::GetLocalTimeSinceJan1970();
// tell clients to start game // tell clients to start game
auto spac = std::make_unique<sf::Packet>(); auto spac = std::make_unique<sf::Packet>();
@ -811,8 +811,8 @@ bool NetPlayServer::StartGame()
*spac << m_settings.m_OCFactor; *spac << m_settings.m_OCFactor;
*spac << m_settings.m_EXIDevice[0]; *spac << m_settings.m_EXIDevice[0];
*spac << m_settings.m_EXIDevice[1]; *spac << m_settings.m_EXIDevice[1];
*spac << (u32)g_netplay_initial_gctime; *spac << (u32)g_netplay_initial_rtc;
*spac << (u32)(g_netplay_initial_gctime >> 32); *spac << (u32)(g_netplay_initial_rtc >> 32);
SendAsyncToClients(std::move(spac)); SendAsyncToClients(std::move(spac));