From 7d54887d634777a3eb1929d0a10d315f5585c24a Mon Sep 17 00:00:00 2001 From: Simone Date: Fri, 19 Jan 2024 16:28:57 +0100 Subject: [PATCH] input --- external/parallel-rdp/ParallelRDPWrapper.cpp | 56 ---------- external/parallel-rdp/ParallelRDPWrapper.hpp | 11 -- src/backend/Core.cpp | 1 - src/backend/core/mmio/PIF.cpp | 48 +++++++-- src/backend/core/mmio/PIF.hpp | 3 +- src/backend/core/mmio/PIF/Device.cpp | 108 +------------------ src/frontend/KaizenQt.cpp | 45 +++++++- src/frontend/KaizenQt.hpp | 6 +- src/frontend/RenderWidget.hpp | 5 +- 9 files changed, 95 insertions(+), 188 deletions(-) diff --git a/external/parallel-rdp/ParallelRDPWrapper.cpp b/external/parallel-rdp/ParallelRDPWrapper.cpp index ddb24dab..23fbbc73 100644 --- a/external/parallel-rdp/ParallelRDPWrapper.cpp +++ b/external/parallel-rdp/ParallelRDPWrapper.cpp @@ -66,62 +66,6 @@ void SetFramerateUnlocked(bool unlocked) { } } -class SDLWSIPlatform final : public Vulkan::WSIPlatform { -public: - SDLWSIPlatform(SDL_Window* window) : window(window) {} - - std::vector get_instance_extensions() override { - const char* extensions[64]; - unsigned int num_extensions = 64; - - if (!SDL_Vulkan_GetInstanceExtensions(window, &num_extensions, extensions)) { - Util::panic("SDL_Vulkan_GetInstanceExtensions failed: {}", SDL_GetError()); - } - auto vec = std::vector(); - - for (unsigned int i = 0; i < num_extensions; i++) { - vec.push_back(extensions[i]); - } - - return vec; - } - - VkSurfaceKHR create_surface(VkInstance instance, VkPhysicalDevice gpu) override { - VkSurfaceKHR vk_surface; - if (!SDL_Vulkan_CreateSurface(window, instance, &vk_surface)) { - Util::panic("Failed to create Vulkan window surface: {}", SDL_GetError()); - } - return vk_surface; - } - - uint32_t get_surface_width() override { - return 640; - } - - uint32_t get_surface_height() override { - return 480; - } - - bool alive(Vulkan::WSI &wsi_) override { - return true; - } - - void poll_input() override { } - - void event_frame_tick(double frame, double elapsed) override { } - - const VkApplicationInfo *get_application_info() override { - return &appInfo; - } - - VkApplicationInfo appInfo { - .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, - .apiVersion = VK_API_VERSION_1_1 - }; -private: - SDL_Window* window; -}; - Program* fullscreen_quad_program; WSI* LoadWSIPlatform(Vulkan::InstanceFactory* instanceFactory, std::unique_ptr&& wsi_platform, std::unique_ptr&& newWindowInfo) { diff --git a/external/parallel-rdp/ParallelRDPWrapper.hpp b/external/parallel-rdp/ParallelRDPWrapper.hpp index 560b653a..341d382a 100644 --- a/external/parallel-rdp/ParallelRDPWrapper.hpp +++ b/external/parallel-rdp/ParallelRDPWrapper.hpp @@ -12,17 +12,6 @@ public: virtual ~ParallelRdpWindowInfo() = default; }; -class SDLParallelRdpWindowInfo : public ParallelRdpWindowInfo { - SDL_Window* window; -public: - SDLParallelRdpWindowInfo(SDL_Window* window) : window(window) {} - CoordinatePair get_window_size() { - int width, height; - SDL_GetWindowSize(window, &width, &height); - return CoordinatePair{ static_cast(width), static_cast(height) }; - } -}; - static Vulkan::WSI* wsi; VkRenderPass GetVkRenderPass(); diff --git a/src/backend/Core.cpp b/src/backend/Core.cpp index 70e2f8de..d069a36c 100644 --- a/src/backend/Core.cpp +++ b/src/backend/Core.cpp @@ -17,7 +17,6 @@ u32 PopStalledCycles() { } Core::Core() { - SDL_Init(SDL_INIT_EVERYTHING); if(SDL_GameControllerAddMappingsFromFile("resources/gamecontrollerdb.txt") < 0) { Util::warn("Failed to load game controller DB"); } diff --git a/src/backend/core/mmio/PIF.cpp b/src/backend/core/mmio/PIF.cpp index 1d21615b..fc6ceadc 100644 --- a/src/backend/core/mmio/PIF.cpp +++ b/src/backend/core/mmio/PIF.cpp @@ -186,7 +186,6 @@ void PIF::ProcessCommands(Mem &mem) { channel++; break; case 1: - UpdateController(); if(!ReadButtons(res)) { cmd[1] |= 0x80; } @@ -334,12 +333,47 @@ void PIF::EepromWrite(const u8* cmd, u8* res, const Mem& mem) { } } -void PIF::UpdateController() { - //if(Netplay::connected) { - // Util::panic("Netplay!!!"); - //} else { - PollController(); - //} +void PIF::UpdateController(u32 value) { + bool A = (value >> 31) & 1; + bool B = (value >> 30) & 1; + bool Z = (value >> 29) & 1; + bool START = (value >> 28) & 1; + bool DUP = (value >> 27) & 1; + bool DDOWN = (value >> 26) & 1; + bool DLEFT = (value >> 25) & 1; + bool DRIGHT = (value >> 24) & 1; + bool L = (value >> 21) & 1; + bool R = (value >> 20) & 1; + bool CUP = (value >> 19) & 1; + bool CDOWN = (value >> 18) & 1; + bool CLEFT = (value >> 17) & 1; + bool CRIGHT = (value >> 16) & 1; + s8 x = (s8(value >> 8)) & 0xFF; + s8 y = (s8(value)) & 0xFF; + + joybusDevices[channel].controller.a = A; + joybusDevices[channel].controller.b = B; + joybusDevices[channel].controller.z = Z; + joybusDevices[channel].controller.start = START; + joybusDevices[channel].controller.dp_up = DUP; + joybusDevices[channel].controller.dp_down = DDOWN; + joybusDevices[channel].controller.dp_left = DLEFT; + joybusDevices[channel].controller.dp_right = DRIGHT; + joybusDevices[channel].controller.joy_reset = L && R && START; + joybusDevices[channel].controller.l = L; + joybusDevices[channel].controller.r = R; + joybusDevices[channel].controller.c_up = CUP; + joybusDevices[channel].controller.c_down = CDOWN; + joybusDevices[channel].controller.c_left = CLEFT; + joybusDevices[channel].controller.c_right = CRIGHT; + joybusDevices[channel].controller.joy_x = x; + joybusDevices[channel].controller.joy_y = -y; + + if (joybusDevices[channel].controller.joy_reset) { + joybusDevices[channel].controller.start = false; + joybusDevices[channel].controller.joy_x = 0; + joybusDevices[channel].controller.joy_y = 0; + } } void PIF::DoPIFHLE(Mem& mem, Registers& regs, bool pal, CICType cicType) { diff --git a/src/backend/core/mmio/PIF.hpp b/src/backend/core/mmio/PIF.hpp index 54409216..b5c83d1a 100644 --- a/src/backend/core/mmio/PIF.hpp +++ b/src/backend/core/mmio/PIF.hpp @@ -115,8 +115,7 @@ struct PIF { void CICChallenge(); static void ExecutePIF(Mem& mem, Registers& regs); static void DoPIFHLE(Mem& mem, Registers& regs, bool pal, CICType cicType); - void PollController(); - void UpdateController(); + void UpdateController(u32); bool ReadButtons(u8*) const; void ControllerID(u8*) const; void MempakRead(const u8*, u8*); diff --git a/src/backend/core/mmio/PIF/Device.cpp b/src/backend/core/mmio/PIF/Device.cpp index d9eacb9e..8b699696 100644 --- a/src/backend/core/mmio/PIF/Device.cpp +++ b/src/backend/core/mmio/PIF/Device.cpp @@ -23,110 +23,6 @@ void PIF::InitDevices(SaveType saveType) { joybusDevices[5].type = JOYBUS_NONE; } -#define GET_BUTTON(gamecontroller, i) SDL_GameControllerGetButton(gamecontroller, i) -#define GET_AXIS(gamecontroller, axis) SDL_GameControllerGetAxis(gamecontroller, axis) - -void PIF::PollController() { - if(gamepadConnected) { - bool A = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_A); - bool B = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_X); - bool Z = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_TRIGGERLEFT) == SDL_JOYSTICK_AXIS_MAX; - bool START = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_START); - bool DUP = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_UP); - bool DDOWN = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_DOWN); - bool DLEFT = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_LEFT); - bool DRIGHT = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); - bool L = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); - bool R = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); - bool CUP = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTY) <= -127; - bool CDOWN = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTY) >= 127; - bool CLEFT = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTX) <= -127; - bool CRIGHT = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTX) >= 127; - - joybusDevices[channel].controller.a = A; - joybusDevices[channel].controller.b = B; - joybusDevices[channel].controller.z = Z; - joybusDevices[channel].controller.start = START; - joybusDevices[channel].controller.dp_up = DUP; - joybusDevices[channel].controller.dp_down = DDOWN; - joybusDevices[channel].controller.dp_left = DLEFT; - joybusDevices[channel].controller.dp_right = DRIGHT; - joybusDevices[channel].controller.joy_reset = L && R && START; - joybusDevices[channel].controller.l = L; - joybusDevices[channel].controller.r = R; - joybusDevices[channel].controller.c_up = CUP; - joybusDevices[channel].controller.c_down = CDOWN; - joybusDevices[channel].controller.c_left = CLEFT; - joybusDevices[channel].controller.c_right = CRIGHT; - - float xclamped = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_LEFTX); - if(xclamped < 0) { - xclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN)); - } else { - xclamped /= SDL_JOYSTICK_AXIS_MAX; - } - - xclamped *= 86; - - float yclamped = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_LEFTY); - if(yclamped < 0) { - yclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN)); - } else { - yclamped /= SDL_JOYSTICK_AXIS_MAX; - } - - yclamped *= 86; - - joybusDevices[channel].controller.joy_x = xclamped; - joybusDevices[channel].controller.joy_y = -yclamped; - - if (joybusDevices[channel].controller.joy_reset) { - joybusDevices[channel].controller.start = false; - joybusDevices[channel].controller.joy_x = 0; - joybusDevices[channel].controller.joy_y = 0; - } - } else { - const uint8_t* state = SDL_GetKeyboardState(nullptr); - joybusDevices[channel].controller.a = state[SDL_SCANCODE_X]; - joybusDevices[channel].controller.b = state[SDL_SCANCODE_C]; - joybusDevices[channel].controller.z = state[SDL_SCANCODE_Z]; - joybusDevices[channel].controller.start = state[SDL_SCANCODE_RETURN]; - joybusDevices[channel].controller.dp_up = state[SDL_SCANCODE_PAGEUP]; - joybusDevices[channel].controller.dp_down = state[SDL_SCANCODE_PAGEDOWN]; - joybusDevices[channel].controller.dp_left = state[SDL_SCANCODE_HOME]; - joybusDevices[channel].controller.dp_right = state[SDL_SCANCODE_END]; - joybusDevices[channel].controller.joy_reset = state[SDL_SCANCODE_RETURN] && state[SDL_SCANCODE_A] && state[SDL_SCANCODE_S]; - joybusDevices[channel].controller.l = state[SDL_SCANCODE_A]; - joybusDevices[channel].controller.r = state[SDL_SCANCODE_S]; - joybusDevices[channel].controller.c_up = state[SDL_SCANCODE_I]; - joybusDevices[channel].controller.c_down = state[SDL_SCANCODE_K]; - joybusDevices[channel].controller.c_left = state[SDL_SCANCODE_J]; - joybusDevices[channel].controller.c_right = state[SDL_SCANCODE_L]; - - s8 xaxis = 0, yaxis = 0; - if (state[SDL_SCANCODE_LEFT]) { - xaxis = -86; - } else if (state[SDL_SCANCODE_RIGHT]) { - xaxis = 86; - } - - if (state[SDL_SCANCODE_DOWN]) { - yaxis = -86; - } else if (state[SDL_SCANCODE_UP]) { - yaxis = 86; - } - - joybusDevices[channel].controller.joy_x = xaxis; - joybusDevices[channel].controller.joy_y = yaxis; - - if (joybusDevices[channel].controller.joy_reset) { - joybusDevices[channel].controller.start = false; - joybusDevices[channel].controller.joy_x = 0; - joybusDevices[channel].controller.joy_y = 0; - } - } -} - void PIF::ControllerID(u8 *res) const { if (channel < 6) { switch (joybusDevices[channel].type) { @@ -197,6 +93,8 @@ bool PIF::ReadButtons(u8* res) const { res[2] = 0x00; res[3] = 0x00; return false; // Device not present + case JOYBUS_4KB_EEPROM: + case JOYBUS_16KB_EEPROM: case JOYBUS_CONTROLLER: if (TasMovieLoaded()) { Controller controller = TasNextInputs(); @@ -216,8 +114,6 @@ bool PIF::ReadButtons(u8* res) const { case JOYBUS_MOUSE: case JOYBUS_RANDNET_KEYBOARD: case JOYBUS_DENSHA_DE_GO: - case JOYBUS_4KB_EEPROM: - case JOYBUS_16KB_EEPROM: return false; } diff --git a/src/frontend/KaizenQt.cpp b/src/frontend/KaizenQt.cpp index 6bad74a9..76992eb5 100644 --- a/src/frontend/KaizenQt.cpp +++ b/src/frontend/KaizenQt.cpp @@ -1,9 +1,11 @@ #include #include #include +#include +#include #include -KaizenQt::KaizenQt() noexcept { +KaizenQt::KaizenQt() noexcept : QWidget(nullptr) { mainWindow = new MainWindowController(); emuThread = new EmuThread( std::move(mainWindow->view.vulkanWidget->instance), @@ -13,6 +15,11 @@ KaizenQt::KaizenQt() noexcept { ConnectMainWindowSignalsToSlots(); + grabKeyboard(); + setAcceptDrops(true); + setFocusPolicy(Qt::FocusPolicy::StrongFocus); + setFocus(); + mainWindow->show(); } @@ -26,7 +33,43 @@ void KaizenQt::ConnectMainWindowSignalsToSlots() noexcept { connect(mainWindow, &MainWindowController::Pause, emuThread, &EmuThread::TogglePause); } +void KaizenQt::dragEnterEvent(QDragEnterEvent* event) { + if (event->mimeData()->hasUrls()) { + event->acceptProposedAction(); + } +} + +void KaizenQt::dropEvent(QDropEvent* event) { + auto path = event->mimeData()->urls()[0].toLocalFile(); + LoadROM(path); +} + void KaizenQt::LoadROM(const QString& file_name) noexcept { emuThread->start(); emuThread->core.LoadROM(file_name.toStdString()); +} + +void KaizenQt::keyPressEvent(QKeyEvent* e) { + u32 data = 0; + emuThread->core.cpu->mem.mmio.si.pif.UpdateController(data); + if (e->key() == Qt::Key::Key_X) data |= (1 << 31); + if (e->key() == Qt::Key::Key_C) data |= (1 << 30); + if (e->key() == Qt::Key::Key_Z) data |= (1 << 29); + if (e->key() == Qt::Key::Key_Enter + || e->key() == Qt::Key::Key_Return) data |= (1 << 28); + if (e->key() == Qt::Key::Key_I) data |= (1 << 27); + if (e->key() == Qt::Key::Key_K) data |= (1 << 26); + if (e->key() == Qt::Key::Key_J) data |= (1 << 25); + if (e->key() == Qt::Key::Key_L) data |= (1 << 24); + if (e->key() == Qt::Key::Key_A) data |= (1 << 21); + if (e->key() == Qt::Key::Key_S) data |= (1 << 20); + if (e->key() == Qt::Key::Key_8) data |= (1 << 19); + if (e->key() == Qt::Key::Key_2) data |= (1 << 18); + if (e->key() == Qt::Key::Key_4) data |= (1 << 17); + if (e->key() == Qt::Key::Key_6) data |= (1 << 16); + if (e->key() == Qt::Key::Key_Up) data |= 127; + if (e->key() == Qt::Key::Key_Down) data |= -127; + if (e->key() == Qt::Key::Key_Left) data |= u32(-127) << 8; + if (e->key() == Qt::Key::Key_Right) data |= u32(127) << 8; + emuThread->core.cpu->mem.mmio.si.pif.UpdateController(data); } \ No newline at end of file diff --git a/src/frontend/KaizenQt.hpp b/src/frontend/KaizenQt.hpp index 20e1bc92..7aef086f 100644 --- a/src/frontend/KaizenQt.hpp +++ b/src/frontend/KaizenQt.hpp @@ -22,11 +22,15 @@ static inline CompositorCategory GetOSCompositorCategory() { return CompositorCategory::Windows; } -class KaizenQt : public QObject { +class KaizenQt : public QWidget { Q_OBJECT public: KaizenQt() noexcept; void LoadROM(const QString& path) noexcept; + void dropEvent(QDropEvent*) override; + void dragEnterEvent(QDragEnterEvent*) override; +protected: + void keyPressEvent(QKeyEvent* event) override; private: void ConnectMainWindowSignalsToSlots() noexcept; MainWindowController* mainWindow; diff --git a/src/frontend/RenderWidget.hpp b/src/frontend/RenderWidget.hpp index 4993d6a7..0abbc31a 100644 --- a/src/frontend/RenderWidget.hpp +++ b/src/frontend/RenderWidget.hpp @@ -5,6 +5,7 @@ #include #include #include +#include struct QtInstanceFactory : Vulkan::InstanceFactory { VkInstance create_instance(const VkInstanceCreateInfo *info) override { @@ -71,9 +72,7 @@ public: return true; } - void poll_input() override { - SDL_PumpEvents(); - } + void poll_input() override {} void event_frame_tick(double frame, double elapsed) override { }