diff --git a/Source/Core/Core/IOS/DolphinDevice.cpp b/Source/Core/Core/IOS/DolphinDevice.cpp index 62a5a4e30f..8048e40d25 100644 --- a/Source/Core/Core/IOS/DolphinDevice.cpp +++ b/Source/Core/Core/IOS/DolphinDevice.cpp @@ -33,24 +33,6 @@ enum }; -IPCReply GetSystemTime(const IOCtlVRequest& request) -{ - if (!request.HasNumberOfValidVectors(0, 1)) - { - return IPCReply(IPC_EINVAL); - } - - if (request.io_vectors[0].size != 4) - { - return IPCReply(IPC_EINVAL); - } - - const u32 milliseconds = Common::Timer::NowMs(); - - Memory::Write_U32(milliseconds, request.io_vectors[0].address); - return IPCReply(IPC_SUCCESS); -} - IPCReply GetVersion(const IOCtlVRequest& request) { if (!request.HasNumberOfValidVectors(0, 1)) @@ -159,6 +141,32 @@ IPCReply GetRealProductCode(const IOCtlVRequest& request) } // namespace +IPCReply DolphinDevice::GetSystemTime(const IOCtlVRequest& request) const +{ + if (!request.HasNumberOfValidVectors(0, 1)) + { + return IPCReply(IPC_EINVAL); + } + + if (request.io_vectors[0].size != 4) + { + return IPCReply(IPC_EINVAL); + } + + // 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. + // Return elapsed time instead of current timestamp to make buggy emulated code less likely to + // have issuses. + const u32 milliseconds = static_cast(m_timer.ElapsedMs()); + Memory::Write_U32(milliseconds, request.io_vectors[0].address); + return IPCReply(IPC_SUCCESS); +} + +DolphinDevice::DolphinDevice(Kernel& ios, const std::string& device_name) : Device(ios, device_name) +{ + m_timer.Start(); +} + std::optional DolphinDevice::IOCtlV(const IOCtlVRequest& request) { if (Core::WantsDeterminism()) diff --git a/Source/Core/Core/IOS/DolphinDevice.h b/Source/Core/Core/IOS/DolphinDevice.h index baa5809fee..0da464f373 100644 --- a/Source/Core/Core/IOS/DolphinDevice.h +++ b/Source/Core/Core/IOS/DolphinDevice.h @@ -3,6 +3,7 @@ #pragma once +#include "Common/Timer.h" #include "Core/IOS/Device.h" namespace IOS::HLE @@ -10,8 +11,12 @@ namespace IOS::HLE class DolphinDevice final : public Device { public: - // Inherit the constructor from the Device class, since we don't need to do anything special. - using Device::Device; + DolphinDevice(Kernel& ios, const std::string& device_name); std::optional IOCtlV(const IOCtlVRequest& request) override; + +private: + IPCReply GetSystemTime(const IOCtlVRequest& request) const; + + Common::Timer m_timer; }; } // namespace IOS::HLE