From 64190988515e2ae3b1a0f94dcf4708ab8c68f0bb Mon Sep 17 00:00:00 2001 From: wheremyfoodat <gponiris2004@gmail.com> Date: Sat, 29 Apr 2023 02:45:21 +0300 Subject: [PATCH] [HID] Implement events --- include/kernel/handles.hpp | 6 ------ include/kernel/kernel.hpp | 1 + include/services/hid.hpp | 12 +++++++++++- include/services/service_manager.hpp | 1 + src/core/services/hid.cpp | 21 +++++++++++++++------ src/core/services/service_manager.cpp | 5 +++-- src/emulator.cpp | 3 +++ 7 files changed, 34 insertions(+), 15 deletions(-) diff --git a/include/kernel/handles.hpp b/include/kernel/handles.hpp index 32616c97..9b13460a 100644 --- a/include/kernel/handles.hpp +++ b/include/kernel/handles.hpp @@ -41,12 +41,6 @@ namespace KernelHandles { MinSharedMemHandle = GSPSharedMemHandle, MaxSharedMemHandle = HIDSharedMemHandle, - - HIDEvent0, - HIDEvent1, - HIDEvent2, - HIDEvent3, - HIDEvent4 }; // Returns whether "handle" belongs to one of the OS services diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp index dd6ce745..95a6bf88 100644 --- a/include/kernel/kernel.hpp +++ b/include/kernel/kernel.hpp @@ -198,4 +198,5 @@ public: void sendGPUInterrupt(GPUInterrupt type) { serviceManager.requestGPUInterrupt(type); } void signalDSPEvents() { serviceManager.signalDSPEvents(); } + void updateInputs() { serviceManager.updateInputs(); } }; \ No newline at end of file diff --git a/include/services/hid.hpp b/include/services/hid.hpp index 7629da3b..8464cd48 100644 --- a/include/services/hid.hpp +++ b/include/services/hid.hpp @@ -1,17 +1,26 @@ #pragma once +#include <array> +#include <optional> #include "helpers.hpp" #include "kernel_types.hpp" #include "logger.hpp" #include "memory.hpp" +// Circular dependency because we need HID to spawn events +class Kernel; + class HIDService { Handle handle = KernelHandles::HID; Memory& mem; + Kernel& kernel; u8* sharedMem = nullptr; // Pointer to HID shared memory bool accelerometerEnabled; + bool eventsInitialized; bool gyroEnabled; + std::array<std::optional<Handle>, 5> events; + MAKE_LOG_FUNCTION(log, hidLogger) // Service commands @@ -22,9 +31,10 @@ class HIDService { void getIPCHandles(u32 messagePointer); public: - HIDService(Memory& mem) : mem(mem) {} + HIDService(Memory& mem, Kernel& kernel) : mem(mem), kernel(kernel) {} void reset(); void handleSyncRequest(u32 messagePointer); + void updateInputs(); void setSharedMem(u8* ptr) { sharedMem = ptr; diff --git a/include/services/service_manager.hpp b/include/services/service_manager.hpp index 10d816c1..25e4d8f0 100644 --- a/include/services/service_manager.hpp +++ b/include/services/service_manager.hpp @@ -82,4 +82,5 @@ public: void setHIDSharedMem(u8* ptr) { hid.setSharedMem(ptr); } void signalDSPEvents() { dsp.signalEvents(); } + void updateInputs() { hid.updateInputs(); } }; \ No newline at end of file diff --git a/src/core/services/hid.cpp b/src/core/services/hid.cpp index e3056f70..204d2afe 100644 --- a/src/core/services/hid.cpp +++ b/src/core/services/hid.cpp @@ -1,5 +1,6 @@ #include "services/hid.hpp" #include "ipc.hpp" +#include "kernel.hpp" #include <bit> namespace HIDCommands { @@ -80,15 +81,23 @@ void HIDService::getGyroscopeCoefficient(u32 messagePointer) { void HIDService::getIPCHandles(u32 messagePointer) { log("HID::GetIPCHandles\n"); + + // Initialize HID events + if (!eventsInitialized) { + eventsInitialized = true; + + for (auto& e : events) { + e = kernel.makeEvent(ResetType::OneShot); + } + } + mem.write32(messagePointer, IPC::responseHeader(0xA, 1, 7)); mem.write32(messagePointer + 4, Result::Success); // Result code mem.write32(messagePointer + 8, 0x14000000); // Translation descriptor mem.write32(messagePointer + 12, KernelHandles::HIDSharedMemHandle); // Shared memory handle - // HID event handles - mem.write32(messagePointer + 16, KernelHandles::HIDEvent0); - mem.write32(messagePointer + 20, KernelHandles::HIDEvent1); - mem.write32(messagePointer + 24, KernelHandles::HIDEvent2); - mem.write32(messagePointer + 28, KernelHandles::HIDEvent3); - mem.write32(messagePointer + 32, KernelHandles::HIDEvent4); + // Write HID event handles + for (int i = 0; i < events.size(); i++) { + mem.write32(messagePointer + 16 + sizeof(Handle) * i, events[i].value()); + } } \ No newline at end of file diff --git a/src/core/services/service_manager.cpp b/src/core/services/service_manager.cpp index 9ab529d3..8b14e5e1 100644 --- a/src/core/services/service_manager.cpp +++ b/src/core/services/service_manager.cpp @@ -5,8 +5,9 @@ ServiceManager::ServiceManager(std::array<u32, 16>& regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel) : regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), act(mem), apt(mem, kernel), cam(mem), - cecd(mem, kernel), cfg(mem), dsp(mem, kernel), hid(mem), frd(mem), fs(mem, kernel), gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem), - ldr(mem), mic(mem), nfc(mem, kernel), nim(mem), ndm(mem), ptm(mem), y2r(mem, kernel) {} + cecd(mem, kernel), cfg(mem), dsp(mem, kernel), hid(mem, kernel), frd(mem), fs(mem, kernel), + gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem), ldr(mem), mic(mem), nfc(mem, kernel), nim(mem), ndm(mem), + ptm(mem), y2r(mem, kernel) {} static constexpr int MAX_NOTIFICATION_COUNT = 16; diff --git a/src/emulator.cpp b/src/emulator.cpp index 7f0ded12..56e555c7 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -31,6 +31,9 @@ void Emulator::run() { kernel.sendGPUInterrupt(GPUInterrupt::VBlank0); kernel.sendGPUInterrupt(GPUInterrupt::VBlank1); + // Update inputs in the HID module + kernel.updateInputs(); + SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) {