diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp index 9d46d1b9..ddeec2e1 100644 --- a/include/kernel/kernel.hpp +++ b/include/kernel/kernel.hpp @@ -201,5 +201,10 @@ public: void sendGPUInterrupt(GPUInterrupt type) { serviceManager.requestGPUInterrupt(type); } void signalDSPEvents() { serviceManager.signalDSPEvents(); } + + void pressKey(u32 key) { serviceManager.pressKey(key); } + void releaseKey(u32 key) { serviceManager.releaseKey(key); } + void setCirclepadX(u16 x) { serviceManager.setCirclepadX(x); } + void setCirclepadY(u16 y) { serviceManager.setCirclepadY(y); } void updateInputs() { serviceManager.updateInputs(); } }; \ No newline at end of file diff --git a/include/services/hid.hpp b/include/services/hid.hpp index 8464cd48..2199d367 100644 --- a/include/services/hid.hpp +++ b/include/services/hid.hpp @@ -34,6 +34,11 @@ public: HIDService(Memory& mem, Kernel& kernel) : mem(mem), kernel(kernel) {} void reset(); void handleSyncRequest(u32 messagePointer); + + void pressKey(u32 key); + void releaseKey(u32 key); + void setCirclepadX(u16 x); + void setCirclepadY(u16 y); void updateInputs(); void setSharedMem(u8* ptr) { diff --git a/include/services/service_manager.hpp b/include/services/service_manager.hpp index 2a50ffaf..c67794de 100644 --- a/include/services/service_manager.hpp +++ b/include/services/service_manager.hpp @@ -84,5 +84,10 @@ public: void setHIDSharedMem(u8* ptr) { hid.setSharedMem(ptr); } void signalDSPEvents() { dsp.signalEvents(); } + + void pressKey(u32 key) { hid.pressKey(key); } + void releaseKey(u32 key) { hid.releaseKey(key); } + void setCirclepadX(u16 x) { hid.setCirclepadX(x); } + void setCirclepadY(u16 y) { hid.setCirclepadY(y); } 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 21e38dba..854a4286 100644 --- a/src/core/services/hid.cpp +++ b/src/core/services/hid.cpp @@ -108,6 +108,11 @@ void HIDService::getIPCHandles(u32 messagePointer) { } } +void HIDService::pressKey(u32 key) { sharedMem[0]++; *(u32*)&sharedMem[0x28] |= key; } +void HIDService::releaseKey(u32 key) { sharedMem[0]++; *(u32*)&sharedMem[0x28] &= ~key; } +void HIDService::setCirclepadX(u16 x) { sharedMem[0]++; *(u16*)&sharedMem[0x28 + 0xC] = x; } +void HIDService::setCirclepadY(u16 y) { sharedMem[0]++; *(u16*)&sharedMem[0x28 + 0xC + 2] = y; } + // TODO: We don't currently have inputs but we must at least try to signal the HID key input events now and then void HIDService::updateInputs() { // For some reason, the original developers decided to signal the HID events each time the OS rescanned inputs diff --git a/src/emulator.cpp b/src/emulator.cpp index 56e555c7..a404e19c 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -36,10 +36,45 @@ void Emulator::run() { SDL_Event event; while (SDL_PollEvent(&event)) { - if (event.type == SDL_QUIT) { + switch (event.type) { + case SDL_QUIT: printf("Bye :(\n"); running = false; return; + case SDL_KEYDOWN: + switch (event.key.keysym.sym) { + case SDLK_z: kernel.pressKey(1 << 0); break; + case SDLK_RIGHT: kernel.pressKey(1 << 4); break; + case SDLK_LEFT: kernel.pressKey(1 << 5); break; + case SDLK_UP: kernel.pressKey(1 << 6); break; + case SDLK_DOWN: kernel.pressKey(1 << 7); break; + case SDLK_w: kernel.setCirclepadY(0x9C); break; + case SDLK_a: kernel.setCirclepadX(-0x9C); break; + case SDLK_s: kernel.setCirclepadY(-0x9C); break; + case SDLK_d: kernel.setCirclepadX(0x9C); break; + case SDLK_j: kernel.pressKey(1 << 1); break; + case SDLK_k: kernel.pressKey(1 << 10); break; + case SDLK_l: kernel.pressKey(1 << 11); break; + case SDLK_r: kernel.pressKey(1 << 8); break; + } + break; + case SDL_KEYUP: + switch (event.key.keysym.sym) { + case SDLK_z: kernel.releaseKey(1 << 0); break; + case SDLK_RIGHT: kernel.releaseKey(1 << 4); break; + case SDLK_LEFT: kernel.releaseKey(1 << 5); break; + case SDLK_UP: kernel.releaseKey(1 << 6); break; + case SDLK_DOWN: kernel.releaseKey(1 << 7); break; + case SDLK_w: kernel.setCirclepadY(0); break; + case SDLK_a: kernel.setCirclepadX(0); break; + case SDLK_s: kernel.setCirclepadY(0); break; + case SDLK_d: kernel.setCirclepadX(0); break; + case SDLK_j: kernel.releaseKey(1 << 1); break; + case SDLK_k: kernel.releaseKey(1 << 10); break; + case SDLK_l: kernel.releaseKey(1 << 11); break; + case SDLK_r: kernel.releaseKey(1 << 8); break; + } + break; } }