diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/service/ac_u.cpp | 20 | ||||
| -rw-r--r-- | src/core/hle/service/frd/frd.cpp | 12 | ||||
| -rw-r--r-- | src/core/hle/service/frd/frd.h | 9 | ||||
| -rw-r--r-- | src/core/hle/service/frd/frd_u.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/fs/fs_user.cpp | 24 | ||||
| -rw-r--r-- | src/core/hle/service/gsp_gpu.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/mic_u.cpp | 20 | ||||
| -rw-r--r-- | src/core/hle/service/service.h | 12 | ||||
| -rw-r--r-- | src/core/hw/gpu.cpp | 33 | ||||
| -rw-r--r-- | src/core/settings.cpp | 1 | ||||
| -rw-r--r-- | src/core/settings.h | 1 |
11 files changed, 122 insertions, 14 deletions
diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp index 18026975f..fe367aca5 100644 --- a/src/core/hle/service/ac_u.cpp +++ b/src/core/hle/service/ac_u.cpp @@ -230,6 +230,24 @@ static void IsConnected(Service::Interface* self) { LOG_WARNING(Service_AC, "(STUBBED) called"); } +/** + * AC_U::SetClientVersion service function + * Inputs: + * 1 : Used SDK Version + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +static void SetClientVersion(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + const u32 version = cmd_buff[1]; + self->SetVersion(version); + + LOG_WARNING(Service_AC, "(STUBBED) called, version: 0x%08X", version); + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error +} + const Interface::FunctionInfo FunctionTable[] = { {0x00010000, CreateDefaultConfig, "CreateDefaultConfig"}, {0x00040006, ConnectAsync, "ConnectAsync"}, @@ -250,7 +268,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00300004, RegisterDisconnectEvent, "RegisterDisconnectEvent"}, {0x003C0042, nullptr, "GetAPSSIDList"}, {0x003E0042, IsConnected, "IsConnected"}, - {0x00400042, nullptr, "SetClientVersion"}, + {0x00400042, SetClientVersion, "SetClientVersion"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/frd/frd.cpp b/src/core/hle/service/frd/frd.cpp index 1d16f8732..34fdf7f53 100644 --- a/src/core/hle/service/frd/frd.cpp +++ b/src/core/hle/service/frd/frd.cpp @@ -100,6 +100,18 @@ void GetMyScreenName(Service::Interface* self) { LOG_WARNING(Service_FRD, "(STUBBED) called"); } +void SetClientSdkVersion(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + const u32 version = cmd_buff[1]; + + self->SetVersion(version); + + LOG_WARNING(Service_FRD, "(STUBBED) called, version: 0x%08X", version); + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error +} + void Init() { using namespace Kernel; diff --git a/src/core/hle/service/frd/frd.h b/src/core/hle/service/frd/frd.h index c8283a7f3..e61940ea0 100644 --- a/src/core/hle/service/frd/frd.h +++ b/src/core/hle/service/frd/frd.h @@ -95,6 +95,15 @@ void GetMyFriendKey(Service::Interface* self); */ void GetMyScreenName(Service::Interface* self); +/** + * FRD::SetClientSdkVersion service function + * Inputs: + * 1 : Used SDK Version + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void SetClientSdkVersion(Service::Interface* self); + /// Initialize FRD service(s) void Init(); diff --git a/src/core/hle/service/frd/frd_u.cpp b/src/core/hle/service/frd/frd_u.cpp index bd1c9c16b..496f29ca9 100644 --- a/src/core/hle/service/frd/frd_u.cpp +++ b/src/core/hle/service/frd/frd_u.cpp @@ -58,7 +58,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x002F0040, nullptr, "AllowHalfAwake"}, {0x00300000, nullptr, "GetServerTypes"}, {0x00310082, nullptr, "GetFriendComment"}, - {0x00320042, nullptr, "SetClientSdkVersion"}, + {0x00320042, SetClientSdkVersion, "SetClientSdkVersion"}, {0x00330000, nullptr, "GetMyApproachContext"}, {0x00340046, nullptr, "AddFriendWithApproach"}, {0x00350082, nullptr, "DecryptApproachContext"}, diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index 00edc7622..9ec17b395 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -763,23 +763,27 @@ static void CreateLegacySystemSaveData(Service::Interface* self) { * FS_User::InitializeWithSdkVersion service function. * Inputs: * 0 : 0x08610042 - * 1 : Unknown - * 2 : Unknown - * 3 : Unknown + * 1 : Used SDK Version + * 2 : ProcessId Header + * 3 : placeholder for ProcessId * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ static void InitializeWithSdkVersion(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u32 unk1 = cmd_buff[1]; - u32 unk2 = cmd_buff[2]; - u32 unk3 = cmd_buff[3]; + const u32 version = cmd_buff[1]; + self->SetVersion(version); - cmd_buff[1] = RESULT_SUCCESS.raw; - - LOG_WARNING(Service_FS, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, unk3=0x%08X", unk1, unk2, - unk3); + if (cmd_buff[2] == IPC::CallingPidDesc()) { + LOG_WARNING(Service_FS, "(STUBBED) called, version: 0x%08X", version); + cmd_buff[1] = RESULT_SUCCESS.raw; + } else { + LOG_ERROR(Service_FS, "ProcessId Header must be 0x20"); + cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS, + ErrorSummary::WrongArgument, ErrorLevel::Permanent) + .raw; + } } /** diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index 710e0e485..78cb761be 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp @@ -346,7 +346,7 @@ static void SetAxiConfigQoSMode(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_WARNING(Service_GSP, "(STUBBED) called mode=0x%08X", mode); + LOG_DEBUG(Service_GSP, "(STUBBED) called mode=0x%08X", mode); } /** diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index 563341504..1f851d328 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -287,6 +287,24 @@ static void SetAllowShellClosed(Service::Interface* self) { LOG_WARNING(Service_MIC, "(STUBBED) called, allow_shell_closed=%u", allow_shell_closed); } +/** + * MIC_U::SetClientVersion service function + * Inputs: + * 1 : Used SDK Version + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +static void SetClientVersion(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + const u32 version = cmd_buff[1]; + self->SetVersion(version); + + LOG_WARNING(Service_MIC, "(STUBBED) called, version: 0x%08X", version); + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error +} + const Interface::FunctionInfo FunctionTable[] = { {0x00010042, MapSharedMem, "MapSharedMem"}, {0x00020000, UnmapSharedMem, "UnmapSharedMem"}, @@ -303,7 +321,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x000D0040, SetClamp, "SetClamp"}, {0x000E0000, GetClamp, "GetClamp"}, {0x000F0040, SetAllowShellClosed, "SetAllowShellClosed"}, - {0x00100040, nullptr, "SetClientSDKVersion"}, + {0x00100040, SetClientVersion, "SetClientVersion"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 39b5ffaae..29daacfc4 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -29,6 +29,10 @@ public: return GetPortName(); } + virtual void SetVersion(u32 raw_version) { + version.raw = raw_version; + } + typedef void (*Function)(Interface*); struct FunctionInfo { @@ -58,6 +62,14 @@ protected: void Register(const FunctionInfo* functions, size_t n); + union { + u32 raw; + BitField<0, 8, u32> major; + BitField<8, 8, u32> minor; + BitField<16, 8, u32> build; + BitField<24, 8, u32> revision; + } version = {}; + private: boost::container::flat_map<u32, FunctionInfo> m_functions; }; diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index 45dedea68..cfba82e51 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp @@ -8,7 +8,10 @@ #include "common/color.h" #include "common/common_types.h" #include "common/logging/log.h" +#include "common/math_util.h" #include "common/microprofile.h" +#include "common/thread.h" +#include "common/timer.h" #include "common/vector_math.h" #include "core/core_timing.h" #include "core/hle/service/gsp_gpu.h" @@ -35,6 +38,14 @@ const u64 frame_ticks = 268123480ull / 60; static int vblank_event; /// Total number of frames drawn static u64 frame_count; +/// Start clock for frame limiter +static u32 time_point; +/// Total delay caused by slow frames +static float time_delay; +constexpr float FIXED_FRAME_TIME = 1000.0f / 60; +// Max lag caused by slow frames. Can be adjusted to compensate for too many slow frames. Higher +// values increases time needed to limit frame rate after spikes +constexpr float MAX_LAG_TIME = 18; template <typename T> inline void Read(T& var, const u32 raw_addr) { @@ -512,6 +523,21 @@ template void Write<u32>(u32 addr, const u32 data); template void Write<u16>(u32 addr, const u16 data); template void Write<u8>(u32 addr, const u8 data); +static void FrameLimiter() { + time_delay += FIXED_FRAME_TIME; + time_delay = MathUtil::Clamp(time_delay, -MAX_LAG_TIME, MAX_LAG_TIME); + s32 desired_time = static_cast<s32>(time_delay); + s32 elapsed_time = static_cast<s32>(Common::Timer::GetTimeMs() - time_point); + + if (elapsed_time < desired_time) { + Common::SleepCurrentThread(desired_time - elapsed_time); + } + + u32 frame_time = Common::Timer::GetTimeMs() - time_point; + + time_delay -= frame_time; +} + /// Update hardware static void VBlankCallback(u64 userdata, int cycles_late) { frame_count++; @@ -528,6 +554,12 @@ static void VBlankCallback(u64 userdata, int cycles_late) { // Check for user input updates Service::HID::Update(); + if (!Settings::values.use_vsync && Settings::values.toggle_framelimit) { + FrameLimiter(); + } + + time_point = Common::Timer::GetTimeMs(); + // Reschedule recurrent event CoreTiming::ScheduleEvent(frame_ticks - cycles_late, vblank_event); } @@ -563,6 +595,7 @@ void Init() { framebuffer_sub.active_fb = 0; frame_count = 0; + time_point = Common::Timer::GetTimeMs(); vblank_event = CoreTiming::RegisterEvent("GPU::VBlankCallback", VBlankCallback); CoreTiming::ScheduleEvent(frame_ticks, vblank_event); diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 05f41f798..626e06cd9 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -21,6 +21,7 @@ void Apply() { VideoCore::g_hw_renderer_enabled = values.use_hw_renderer; VideoCore::g_shader_jit_enabled = values.use_shader_jit; VideoCore::g_scaled_resolution_enabled = values.use_scaled_resolution; + VideoCore::g_toggle_framelimit_enabled = values.toggle_framelimit; if (VideoCore::g_emu_window) { auto layout = VideoCore::g_emu_window->GetFramebufferLayout(); diff --git a/src/core/settings.h b/src/core/settings.h index 7470fdbeb..db4c8fada 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -90,6 +90,7 @@ struct Values { bool use_shader_jit; bool use_scaled_resolution; bool use_vsync; + bool toggle_framelimit; LayoutOption layout_option; bool swap_screen; |
