diff --git a/src/core/hle/service/ir/ir.cpp b/src/core/hle/service/ir/ir.cpp index b95b6b7da..c1131c764 100644 --- a/src/core/hle/service/ir/ir.cpp +++ b/src/core/hle/service/ir/ir.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include "core/hle/service/ir/ir.h" #include "core/hle/service/ir/ir_rst.h" #include "core/hle/service/ir/ir_u.h" @@ -11,26 +12,31 @@ namespace Service { namespace IR { +static std::weak_ptr current_ir_rst; + void Init() { - AddService(new IR_RST_Interface); AddService(new IR_User_Interface); InitUser(); - InitRST(); } void Shutdown() { ShutdownUser(); - ShutdownRST(); } void ReloadInputDevices() { ReloadInputDevicesUser(); - ReloadInputDevicesRST(); + + if (auto ir_rst = current_ir_rst.lock()) + ir_rst->ReloadInputDevices(); } void InstallInterfaces(SM::ServiceManager& service_manager) { std::make_shared()->InstallAsService(service_manager); + + auto ir_rst = std::make_shared(); + ir_rst->InstallAsService(service_manager); + current_ir_rst = ir_rst; } } // namespace IR diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp index 71da32f17..84690aecf 100644 --- a/src/core/hle/service/ir/ir_rst.cpp +++ b/src/core/hle/service/ir/ir_rst.cpp @@ -2,15 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include #include "common/bit_field.h" #include "core/core_timing.h" -#include "core/frontend/input.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/service/hid/hid.h" -#include "core/hle/service/ir/ir.h" #include "core/hle/service/ir/ir_rst.h" #include "core/settings.h" @@ -48,18 +45,7 @@ struct SharedMem { static_assert(sizeof(SharedMem) == 0x98, "SharedMem has wrong size!"); -static Kernel::SharedPtr update_event; -static Kernel::SharedPtr shared_memory; -static u32 next_pad_index; -static CoreTiming::EventType* update_callback_id; -static std::unique_ptr zl_button; -static std::unique_ptr zr_button; -static std::unique_ptr c_stick; -static std::atomic is_device_reload_pending; -static bool raw_c_stick; -static int update_period; - -static void LoadInputDevices() { +void IR_RST::LoadInputDevices() { zl_button = Input::CreateDevice( Settings::values.buttons[Settings::NativeButton::ZL]); zr_button = Input::CreateDevice( @@ -68,13 +54,13 @@ static void LoadInputDevices() { Settings::values.analogs[Settings::NativeAnalog::CStick]); } -static void UnloadInputDevices() { +void IR_RST::UnloadInputDevices() { zl_button = nullptr; zr_button = nullptr; c_stick = nullptr; } -static void UpdateCallback(u64 userdata, int cycles_late) { +void IR_RST::UpdateCallback(u64 userdata, int cycles_late) { SharedMem* mem = reinterpret_cast(shared_memory->GetPointer()); if (is_device_reload_pending.exchange(false)) @@ -133,30 +119,15 @@ static void UpdateCallback(u64 userdata, int cycles_late) { CoreTiming::ScheduleEvent(msToCycles(update_period) - cycles_late, update_callback_id); } -/** - * IR::GetHandles service function - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Translate header, used by the ARM11-kernel - * 3 : Shared memory handle - * 4 : Event handle - */ -static void GetHandles(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x01, 0, 0); +void IR_RST::GetHandles(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x01, 0, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 3); rb.Push(RESULT_SUCCESS); - rb.PushMoveHandles(Kernel::g_handle_table.Create(Service::IR::shared_memory).Unwrap(), - Kernel::g_handle_table.Create(Service::IR::update_event).Unwrap()); + rb.PushMoveObjects(shared_memory, update_event); } -/** - * IR::Initialize service function - * Inputs: - * 1 : pad state update period in ms - * 2 : bool output raw c-stick data - */ -static void Initialize(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x02, 2, 0); +void IR_RST::Initialize(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x02, 2, 0); update_period = static_cast(rp.Pop()); raw_c_stick = rp.Pop(); @@ -173,8 +144,8 @@ static void Initialize(Interface* self) { LOG_DEBUG(Service_IR, "called. update_period=%d, raw_c_stick=%d", update_period, raw_c_stick); } -static void Shutdown(Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x03, 1, 0); +void IR_RST::Shutdown(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x03, 0, 0); CoreTiming::UnscheduleEvent(update_callback_id, 0); UnloadInputDevices(); @@ -184,18 +155,7 @@ static void Shutdown(Interface* self) { LOG_DEBUG(Service_IR, "called"); } -const Interface::FunctionInfo FunctionTable[] = { - {0x00010000, GetHandles, "GetHandles"}, - {0x00020080, Initialize, "Initialize"}, - {0x00030000, Shutdown, "Shutdown"}, - {0x00090000, nullptr, "WriteToTwoFields"}, -}; - -IR_RST_Interface::IR_RST_Interface() { - Register(FunctionTable); -} - -void InitRST() { +IR_RST::IR_RST() : ServiceFramework("ir:rst", 1) { using namespace Kernel; // Note: these two kernel objects are even available before Initialize service function is // called. @@ -204,16 +164,23 @@ void InitRST() { 0, MemoryRegion::BASE, "IRRST:SharedMemory"); update_event = Event::Create(ResetType::OneShot, "IRRST:UpdateEvent"); - update_callback_id = CoreTiming::RegisterEvent("IRRST:UpdateCallBack", UpdateCallback); + update_callback_id = + CoreTiming::RegisterEvent("IRRST:UpdateCallBack", [this](u64 userdata, int cycles_late) { + UpdateCallback(userdata, cycles_late); + }); + + static const FunctionInfo functions[] = { + {0x00010000, &IR_RST::GetHandles, "GetHandles"}, + {0x00020080, &IR_RST::Initialize, "Initialize"}, + {0x00030000, &IR_RST::Shutdown, "Shutdown"}, + {0x00090000, nullptr, "WriteToTwoFields"}, + }; + RegisterHandlers(functions); } -void ShutdownRST() { - shared_memory = nullptr; - update_event = nullptr; - UnloadInputDevices(); -} +IR_RST::~IR_RST() = default; -void ReloadInputDevicesRST() { +void IR_RST::ReloadInputDevices() { is_device_reload_pending.store(true); } diff --git a/src/core/hle/service/ir/ir_rst.h b/src/core/hle/service/ir/ir_rst.h index d932bb7e5..621c1b51c 100644 --- a/src/core/hle/service/ir/ir_rst.h +++ b/src/core/hle/service/ir/ir_rst.h @@ -4,25 +4,76 @@ #pragma once +#include +#include +#include "core/frontend/input.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/service/service.h" +namespace Kernel { +class Event; +class SharedMemory; +} + +namespace CoreTiming { +class EventType; +}; + namespace Service { namespace IR { -class IR_RST_Interface : public Service::Interface { +/// Interface to "ir:rst" service +class IR_RST final : public ServiceFramework { public: - IR_RST_Interface(); + IR_RST(); + ~IR_RST(); + void ReloadInputDevices(); - std::string GetPortName() const override { - return "ir:rst"; - } +private: + /** + * GetHandles service function + * No input + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Handle translation descriptor + * 3 : Shared memory handle + * 4 : Event handle + */ + void GetHandles(Kernel::HLERequestContext& ctx); + + /** + * Initialize service function + * Inputs: + * 1 : pad state update period in ms + * 2 : bool output raw c-stick data + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ + void Initialize(Kernel::HLERequestContext& ctx); + + /** + * Shutdown service function + * No input + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ + void Shutdown(Kernel::HLERequestContext& ctx); + + void LoadInputDevices(); + void UnloadInputDevices(); + void UpdateCallback(u64 userdata, int cycles_late); + + Kernel::SharedPtr update_event; + Kernel::SharedPtr shared_memory; + u32 next_pad_index{0}; + CoreTiming::EventType* update_callback_id; + std::unique_ptr zl_button; + std::unique_ptr zr_button; + std::unique_ptr c_stick; + std::atomic is_device_reload_pending{false}; + bool raw_c_stick{false}; + int update_period{0}; }; -void InitRST(); -void ShutdownRST(); - -/// Reload input devices. Used when input configuration changed -void ReloadInputDevicesRST(); - } // namespace IR } // namespace Service