Merge pull request #11269 from vabold/dolphindevice-get-time

Add DolphinDevice::GetSystemTime to allow for accurate Unix timestamp generation
This commit is contained in:
Admiral H. Curtiss 2022-11-15 03:48:57 +01:00 committed by GitHub
commit c9e74801ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 7 deletions

View File

@ -26,7 +26,7 @@ namespace
{ {
enum enum
{ {
IOCTL_DOLPHIN_GET_SYSTEM_TIME = 0x01, IOCTL_DOLPHIN_GET_ELAPSED_TIME = 0x01,
IOCTL_DOLPHIN_GET_VERSION = 0x02, IOCTL_DOLPHIN_GET_VERSION = 0x02,
IOCTL_DOLPHIN_GET_SPEED_LIMIT = 0x03, IOCTL_DOLPHIN_GET_SPEED_LIMIT = 0x03,
IOCTL_DOLPHIN_SET_SPEED_LIMIT = 0x04, IOCTL_DOLPHIN_SET_SPEED_LIMIT = 0x04,
@ -34,7 +34,8 @@ enum
IOCTL_DOLPHIN_GET_REAL_PRODUCTCODE = 0x06, IOCTL_DOLPHIN_GET_REAL_PRODUCTCODE = 0x06,
IOCTL_DOLPHIN_DISCORD_SET_CLIENT = 0x07, IOCTL_DOLPHIN_DISCORD_SET_CLIENT = 0x07,
IOCTL_DOLPHIN_DISCORD_SET_PRESENCE = 0x08, IOCTL_DOLPHIN_DISCORD_SET_PRESENCE = 0x08,
IOCTL_DOLPHIN_DISCORD_RESET = 0x09 IOCTL_DOLPHIN_DISCORD_RESET = 0x09,
IOCTL_DOLPHIN_GET_SYSTEM_TIME = 0x0A,
}; };
@ -207,7 +208,7 @@ IPCReply ResetDiscord(const IOCtlVRequest& request)
} // namespace } // namespace
IPCReply DolphinDevice::GetSystemTime(const IOCtlVRequest& request) const IPCReply DolphinDevice::GetElapsedTime(const IOCtlVRequest& request) const
{ {
if (!request.HasNumberOfValidVectors(0, 1)) if (!request.HasNumberOfValidVectors(0, 1))
{ {
@ -222,12 +223,32 @@ IPCReply DolphinDevice::GetSystemTime(const IOCtlVRequest& request) const
// This ioctl is used by emulated software to judge if emulation is running too fast or slow. // This ioctl is used by emulated software to judge if emulation is running too fast or slow.
// By using Common::Timer, the same clock Dolphin uses internally for the same task is exposed. // By using Common::Timer, the same clock Dolphin uses internally for the same task is exposed.
// Return elapsed time instead of current timestamp to make buggy emulated code less likely to // Return elapsed time instead of current timestamp to make buggy emulated code less likely to
// have issuses. // have issues.
const u32 milliseconds = static_cast<u32>(m_timer.ElapsedMs()); const u32 milliseconds = static_cast<u32>(m_timer.ElapsedMs());
Memory::Write_U32(milliseconds, request.io_vectors[0].address); Memory::Write_U32(milliseconds, request.io_vectors[0].address);
return IPCReply(IPC_SUCCESS); return IPCReply(IPC_SUCCESS);
} }
IPCReply DolphinDevice::GetSystemTime(const IOCtlVRequest& request) const
{
if (!request.HasNumberOfValidVectors(0, 1))
{
return IPCReply(IPC_EINVAL);
}
if (request.io_vectors[0].size != 8)
{
return IPCReply(IPC_EINVAL);
}
// Write Unix timestamp in milliseconds to memory address
const u64 milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
Memory::Write_U64(milliseconds, request.io_vectors[0].address);
return IPCReply(IPC_SUCCESS);
}
DolphinDevice::DolphinDevice(Kernel& ios, const std::string& device_name) : Device(ios, device_name) DolphinDevice::DolphinDevice(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
{ {
m_timer.Start(); m_timer.Start();
@ -240,8 +261,8 @@ std::optional<IPCReply> DolphinDevice::IOCtlV(const IOCtlVRequest& request)
switch (request.request) switch (request.request)
{ {
case IOCTL_DOLPHIN_GET_SYSTEM_TIME: case IOCTL_DOLPHIN_GET_ELAPSED_TIME:
return GetSystemTime(request); return GetElapsedTime(request);
case IOCTL_DOLPHIN_GET_VERSION: case IOCTL_DOLPHIN_GET_VERSION:
return GetVersion(request); return GetVersion(request);
case IOCTL_DOLPHIN_GET_SPEED_LIMIT: case IOCTL_DOLPHIN_GET_SPEED_LIMIT:
@ -258,6 +279,8 @@ std::optional<IPCReply> DolphinDevice::IOCtlV(const IOCtlVRequest& request)
return SetDiscordPresence(request); return SetDiscordPresence(request);
case IOCTL_DOLPHIN_DISCORD_RESET: case IOCTL_DOLPHIN_DISCORD_RESET:
return ResetDiscord(request); return ResetDiscord(request);
case IOCTL_DOLPHIN_GET_SYSTEM_TIME:
return GetSystemTime(request);
default: default:
return IPCReply(IPC_EINVAL); return IPCReply(IPC_EINVAL);

View File

@ -15,6 +15,7 @@ public:
std::optional<IPCReply> IOCtlV(const IOCtlVRequest& request) override; std::optional<IPCReply> IOCtlV(const IOCtlVRequest& request) override;
private: private:
IPCReply GetElapsedTime(const IOCtlVRequest& request) const;
IPCReply GetSystemTime(const IOCtlVRequest& request) const; IPCReply GetSystemTime(const IOCtlVRequest& request) const;
Common::Timer m_timer; Common::Timer m_timer;

View File

@ -290,7 +290,9 @@ void UpdateDiscordPresence(int party_size, SecretType type, const std::string& s
discord_presence.smallImageText = "Dolphin is an emulator for the GameCube and the Wii."; discord_presence.smallImageText = "Dolphin is an emulator for the GameCube and the Wii.";
} }
discord_presence.details = title.empty() ? "Not in-game" : title.c_str(); discord_presence.details = title.empty() ? "Not in-game" : title.c_str();
discord_presence.startTimestamp = std::time(nullptr); discord_presence.startTimestamp = std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
if (party_size > 0) if (party_size > 0)
{ {