diff --git a/CMakeLists.txt b/CMakeLists.txt index abf3be6..2d2b41e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,15 +94,15 @@ FetchContent_Declare( set(SAFETYHOOK_FETCH_ZYDIS ON CACHE BOOL "" FORCE) FetchContent_MakeAvailable(safetyhook) -# Fetch SDL2 +# Fetch SDL3 FetchContent_Declare( - SDL2 - URL https://github.com/libsdl-org/SDL/releases/download/release-2.26.5/SDL2-2.26.5.tar.gz + SDL3 + URL https://github.com/libsdl-org/SDL/releases/download/preview-3.1.6/SDL3-3.1.6.tar.gz ) set(SDL_SHARED OFF CACHE BOOL "" FORCE) set(SDL_STATIC ON CACHE BOOL "" FORCE) set(SDL_TEST OFF CACHE BOOL "" FORCE) -FetchContent_MakeAvailable(SDL2) +FetchContent_MakeAvailable(SDL3) # Fetch xxHash FetchContent_Declare( @@ -137,7 +137,6 @@ set(SOURCES src/patches/audio.cpp src/patches/plugins.cpp src/patches/scanner.cpp - # src/patches/qr.cpp src/patches/layeredfs.cpp src/patches/testmode.cpp src/patches/timer.cpp @@ -157,7 +156,7 @@ set_target_properties(bnusio PROPERTIES PREFIX "") target_include_directories(bnusio PRIVATE src ${tomlc99_SOURCE_DIR} - ${SDL2_SOURCE_DIR}/include + ${SDL3_SOURCE_DIR}/include ${xxhash_SOURCE_DIR} ${zlib_SOURCE_DIR} ${libtomcrypt_SOURCE_DIR}/src/headers @@ -177,7 +176,7 @@ endif() # Link libraries target_link_libraries(bnusio PRIVATE tomlc99 - SDL2-static + SDL3-static xxhash zlibstatic libtomcrypt diff --git a/src/bnusio.cpp b/src/bnusio.cpp index 7593442..0f82475 100644 --- a/src/bnusio.cpp +++ b/src/bnusio.cpp @@ -35,7 +35,7 @@ Keybindings SERVICE = {.keycodes = {VK_F2}}; Keybindings DEBUG_UP = {.keycodes = {VK_UP}}; Keybindings DEBUG_DOWN = {.keycodes = {VK_DOWN}}; Keybindings DEBUG_ENTER = {.keycodes = {VK_RETURN}}; -Keybindings COIN_ADD = {.keycodes = {VK_RETURN}, .buttons = {SDL_CONTROLLER_BUTTON_START}}; +Keybindings COIN_ADD = {.keycodes = {VK_RETURN}, .buttons = {SDL_GAMEPAD_BUTTON_START}}; Keybindings CARD_INSERT_1 = {.keycodes = {'P'}}; Keybindings CARD_INSERT_2 = {}; Keybindings QR_DATA_READ = {.keycodes = {'Q'}}; @@ -52,15 +52,17 @@ Keybindings P2_RIGHT_BLUE = {.keycodes = {'V'}}; // CARD_INSERT_1, CARD_INSERT_2, QR_DATA_READ, QR_IMAGE_READ, P1_LEFT_BLUE, P1_LEFT_RED, // P1_RIGHT_RED, P1_RIGHT_BLUE, P2_LEFT_BLUE, P2_LEFT_RED, P2_RIGHT_RED, P2_RIGHT_BLUE }; -const int exitWait = 100; -int exited = 0; -bool testEnabled = false; -int coin_count = 0; -int service_count = 0; -bool inited = false; -bool updateByCoin = false; -HWND windowHandle = nullptr; -bool usePoll = false; +const int exitWait = 100; +int exited = 0; +bool testEnabled = false; +bool insert_coin = false; +bool insert_service = false; +u16 coin_count = 0; +u16 service_count = 0; +bool inited = false; +bool updateByCoin = false; +HWND windowHandle = nullptr; +bool usePoll = false; HKL currentLayout; namespace bnusio { @@ -293,9 +295,9 @@ UpdateLoop () { #endif std::vector buffer = {}; if (IsButtonTapped (COIN_ADD)) coin_count++; - if (IsButtonTapped (SERVICE) && !testEnabled) service_count++; + if (IsButtonTapped (SERVICE)) service_count++; if (IsButtonTapped (TEST)) testEnabled = !testEnabled; - if (IsButtonTapped (EXIT)) { + if (IsButtonTapped (EXIT)) { LogMessage (LogLevel::INFO, "Exit By Press Exit Button!"); exited += 1; testEnabled = 1; patches::Plugins::Exit (); } diff --git a/src/patches/scanner.cpp b/src/patches/scanner.cpp index 251d2c2..5a574b8 100644 --- a/src/patches/scanner.cpp +++ b/src/patches/scanner.cpp @@ -47,8 +47,10 @@ namespace Card { }; namespace Internal { + enum CardErrorCode { ReadError = -201, NotSupport = -400 }; + void - AgentInsertCard (uint8_t cardData[168], bool internalInvoke) { + InsertCard (uint8_t cardData[168], bool internalInvoke) { if (callbackTouch) { state = internalInvoke ? State::Disable : State::CopyWait; patches::Plugins::UpdateStatus (1, false); @@ -68,7 +70,16 @@ namespace Card { } void - AgentInsertCardPlugin (int32_t a1, int32_t a2, uint8_t *a3, uint64_t a4) { + InsertError (CardErrorCode errorCode) { + if (callbackTouch) { + state = State::CopyWait; + patches::Plugins::UpdateStatus (1, false); + callbackTouch (0, errorCode, cardData, touchData); + } + } + + void + AgentCallbackTouch (int32_t a1, int32_t a2, uint8_t *a3, uint64_t a4) { if (callbackTouch) { state = State::CopyWait; patches::Plugins::UpdateStatus (1, false); @@ -77,10 +88,11 @@ namespace Card { } void - AgentInsertCardOfficial (int32_t a1, int32_t a2, uint8_t *a3, uint64_t a4) { + AgentCallbackTouchOfficial (int32_t a1, int32_t a2, uint8_t *a3, uint64_t a4) { if (callbackTouch) { state = State::CopyWait; patches::Plugins::UpdateStatus (1, false); + LogMessage (LogLevel::DEBUG, "Official CallbackTouch a1={} a2={}", a1, a2); if (acceptInvalidCards && !a3[0]) { char AccessId[21] = "00000000000000000001"; uint8_t UID[8] = {a3[12], a3[14], a3[15], a3[16], 0x90, 0x00, 0x00, 0x00}; @@ -105,7 +117,7 @@ namespace Card { for (size_t i = 0; i < 32; i++) *(cardData + 0x2C + i) = i < chipId.length() ? chipId[i] : 0; for (size_t i = 0; i < 20; i++) *(cardData + 0x50 + i) = i < accessCode.length() ? accessCode[i] : 0; if (!internalInvoke) LogMessage (LogLevel::INFO, "[Card] Insert Card accessCode: \"{}\" chipId: \"{}\"", accessCode, chipId); - patches::Scanner::Card::Internal::AgentInsertCard (cardData, internalInvoke); + patches::Scanner::Card::Internal::InsertCard (cardData, internalInvoke); return true; } } @@ -143,7 +155,7 @@ namespace Card { FAST_HOOK (u64, bngrw_ReqWaitTouch, PROC_ADDRESS ("bngrw.dll", "BngRwReqWaitTouch"), u32 a1, i32 a2, u32 a3, CallbackTouch callback, u64 a5) { state = State::Ready; patches::Plugins::UpdateStatus (1, true); - patches::Plugins::WaitTouch (Internal::AgentInsertCardPlugin, a5); + patches::Plugins::WaitTouch (Internal::AgentCallbackTouch, a5); callbackTouch = callback; touchData = a5; return 1; @@ -161,7 +173,7 @@ namespace Card { patches::Plugins::UpdateStatus (1, true); callbackTouch = callback; touchData = a5; - return originalbngrw_ReqWaitTouchOfficial (a1, a2, a3, Internal::AgentInsertCardOfficial, a5); + return originalbngrw_ReqWaitTouchOfficial (a1, a2, a3, Internal::AgentCallbackTouchOfficial, a5); } bool @@ -176,10 +188,12 @@ namespace Card { } if (accessCode.length() == 0 || accessCode.length() > 20) { LogMessage (LogLevel::ERROR, "[Card] Not an effective accessCode: \"{}\"", accessCode); + patches::Scanner::Card::Internal::InsertError (Internal::CardErrorCode::NotSupport); return false; } if (chipId.length() > 32) { LogMessage (LogLevel::ERROR, "[Card] Not an effective chipId: \"{}\"", chipId); + patches::Scanner::Card::Internal::InsertError (Internal::CardErrorCode::NotSupport); return false; } return patches::Scanner::Card::Internal::Commit0 (accessCode, chipId, false); @@ -226,7 +240,7 @@ namespace Card { } } namespace Qr { - std::queue> scanQueue; + std::queue *> scanQueue; State state = State::Disable; long long lastScan; @@ -256,20 +270,26 @@ namespace Qr { patches::Plugins::UsingQr (); lastScan = std::chrono::duration_cast(std::chrono::system_clock::now ().time_since_epoch ()).count (); if (state == State::CopyWait && scanQueue.size () > 0) { - std::vector data = scanQueue.front (); - if ((int)data.size () > length) { - LogMessage (LogLevel::ERROR, "[QR] Not an effective code, length: {} require: {}", data.size (), length); + std::vector *data = scanQueue.front (); + if ((int)data->size () > length) { + LogMessage (LogLevel::ERROR, "[QR] Not an effective code, length: {} require: {}", data->size (), length); } std::stringstream hexStream; hexStream << std::hex << std::uppercase << std::setfill ('0') << std::setw (2); - for (size_t i = 0; i < data.size (); i++) hexStream << static_cast (data[i]) << " "; - LogMessage (LogLevel::INFO, "[QR] Read QRData size: {} data: {}\n", data.size (), hexStream.str ()); - memcpy (dest, data.data (), data.size () + 1); + for (size_t i = 0; i < data->size (); i++) hexStream << static_cast ((*data)[i]) << " "; + LogMessage (LogLevel::INFO, "[QR] Read QRData size: {} data: {}\n", data->size (), hexStream.str ()); + size_t finalCopySize = std::min (data->size () + 1, (size_t)length); + memcpy (dest, data->data (), finalCopySize); scanQueue.pop (); + delete data; if (scanQueue.size () == 0) state = State::Ready; - return data.size (); + return finalCopySize; } else if (state == State::Disable) { - while (!scanQueue.empty ()) scanQueue.pop (); + while (!scanQueue.empty ()) { + std::vector *data = scanQueue.front (); + delete data; + scanQueue.pop (); + } state = State::Ready; patches::Plugins::UpdateStatus (2, true); } @@ -290,10 +310,10 @@ namespace Qr { LogMessage (LogLevel::ERROR, "[QR] Not an effective code, length: 0"); return false; } - if (scanQueue.empty() || scanQueue.back() != buffer) { - std::vector scanData = {}; + if (scanQueue.empty() || *scanQueue.back() != buffer) { + std::vector *scanData = new std::vector (); for (uint8_t byte_data : buffer) - scanData.push_back (byte_data); + scanData->push_back (byte_data); scanQueue.push (scanData); } if (state == State::Ready) state = State::CopyWait; diff --git a/src/poll.cpp b/src/poll.cpp index cc2d778..15092c3 100644 --- a/src/poll.cpp +++ b/src/poll.cpp @@ -2,18 +2,20 @@ #ifndef ASYNC_IO #include "polldef.h" +#include extern bool jpLayout; + bool currentKeyboardState[0xFF]; bool lastKeyboardState[0xFF]; -bool currentControllerButtonsState[SDL_CONTROLLER_BUTTON_MAX]; -bool lastControllerButtonsState[SDL_CONTROLLER_BUTTON_MAX]; +bool currentControllerButtonsState[SDL_GAMEPAD_BUTTON_COUNT]; +bool lastControllerButtonsState[SDL_GAMEPAD_BUTTON_COUNT]; SDLAxisState currentControllerAxisState; SDLAxisState lastControllerAxisState; SDL_Window *window; -SDL_GameController *controllers[255]; +SDL_Gamepad *controllers[255]; void SetKeyboardButtons () { @@ -32,7 +34,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin memset (key_bind, 0, sizeof (*key_bind)); for (size_t i = 0; i < std::size (key_bind->buttons); i++) - key_bind->buttons[i] = SDL_CONTROLLER_BUTTON_INVALID; + key_bind->buttons[i] = SDL_GAMEPAD_BUTTON_INVALID; for (int idx = 0;; idx++) { const auto [ok, u] = toml_string_at (array, idx); @@ -54,7 +56,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin case button: { *usePoll = true; for (int i = 0; i < std::size (key_bind->buttons); i++) { - if (key_bind->buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) { + if (key_bind->buttons[i] == SDL_GAMEPAD_BUTTON_INVALID) { key_bind->buttons[i] = value.button; break; } @@ -95,36 +97,51 @@ InitializePoll (const HWND windowHandle) { SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5, "1"); SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); - if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) != 0) { - if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) == 0) { + if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMEPAD | SDL_INIT_EVENTS | SDL_INIT_VIDEO) != 0) { + if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD | SDL_INIT_EVENTS | SDL_INIT_VIDEO) == 0) { hasRumble = false; } else { LogMessage (LogLevel::ERROR, - std::string ("SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO): ") + std::string ("SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMEPAD | SDL_INIT_EVENTS | SDL_INIT_VIDEO): ") + SDL_GetError ()); return false; } } if (const auto configPath = std::filesystem::current_path () / "gamecontrollerdb.txt"; - SDL_GameControllerAddMappingsFromFile (configPath.string ().c_str ()) == -1) + SDL_AddGamepadMappingsFromFile (configPath.string ().c_str ()) == -1) LogMessage (LogLevel::ERROR, "Cannot read gamecontrollerdb.txt"); - SDL_GameControllerEventState (SDL_ENABLE); - SDL_JoystickEventState (SDL_ENABLE); + SDL_SetGamepadEventsEnabled (true); + SDL_SetJoystickEventsEnabled (true); - for (int i = 0; i < SDL_NumJoysticks (); i++) { - if (!SDL_IsGameController (i)) continue; + int numJoysticks = 0; + auto* joyStickIds = SDL_GetJoysticks(&numJoysticks); + if (joyStickIds == nullptr) { + LogMessage (LogLevel::ERROR, "Error getting joystick ids"); + exit(1); + } + for (auto id:joyStickIds) { + if (!SDL_IsGamepad (id)) continue; + SDL_Gamepad *controller = SDL_OpenGamepad (id); - SDL_GameController *controller = SDL_GameControllerOpen (i); if (!controller) { - LogMessage (LogLevel::WARN, std::string ("Could not open gamecontroller ") + SDL_GameControllerNameForIndex (i) + ": " + SDL_GetError ()); + LogMessage (LogLevel::WARN, std::string ("Could not open gamecontroller ") + SDL_GetGamepadNameForID (id) + ": " + SDL_GetError ()); continue; } - controllers[i] = controller; - } - window = SDL_CreateWindowFrom (windowHandle); - if (window == nullptr) LogMessage (LogLevel::ERROR, std::string ("SDL_CreateWindowFrom (windowHandle): ") + SDL_GetError ()); + LogMessage (LogLevel::DEBUG, "Init Controller connected!"); + controllers[id] = controller; + } + SDL_free (joyStickIds); + + SDL_PropertiesID props = SDL_CreateProperties(); + if(props == 0) { + LogMessage (LogLevel::ERROR, "Unable to create SDL_Properties"); + exit(1); + } + SDL_SetPointerProperty (props, SDL_PROP_WINDOW_CREATE_WIN32_HWND_POINTER, windowHandle); + window = SDL_CreateWindowWithProperties (props); + if (window == NULL) LogMessage (LogLevel::ERROR, std::string ("SDL_CreateWindowFrom (windowHandle): ") + SDL_GetError ()); atexit (DisposePoll); return hasRumble; @@ -149,71 +166,71 @@ UpdatePoll (const HWND windowHandle) { ScreenToClient (windowHandle, ¤tMouseState.Position); SDL_Event event; - SDL_GameController *controller; + SDL_Gamepad *controller; while (SDL_PollEvent (&event) != 0) { switch (event.type) { - case SDL_CONTROLLERDEVICEADDED: - if (!SDL_IsGameController (event.cdevice.which)) break; + case SDL_EVENT_GAMEPAD_ADDED: + if (!SDL_IsGamepad (event.cdevice.which)) break; - controller = SDL_GameControllerOpen (event.cdevice.which); + controller = SDL_OpenGamepad (event.cdevice.which); if (!controller) { - LogMessage (LogLevel::ERROR, std::string ("Could not open gamecontroller ") + SDL_GameControllerNameForIndex (event.cdevice.which) + LogMessage (LogLevel::ERROR, std::string ("Could not open gamecontroller ") + SDL_GetGamepadNameForID (event.cdevice.which) + ": " + SDL_GetError ()); continue; } controllers[event.cdevice.which] = controller; break; - case SDL_CONTROLLERDEVICEREMOVED: - if (!SDL_IsGameController (event.cdevice.which)) break; - SDL_GameControllerClose (controllers[event.cdevice.which]); + case SDL_EVENT_GAMEPAD_REMOVED: + if (!SDL_IsGamepad (event.cdevice.which)) break; + SDL_CloseGamepad (controllers[event.cdevice.which]); break; - case SDL_MOUSEWHEEL: + case SDL_EVENT_MOUSE_WHEEL: if (event.wheel.y > 0) currentMouseState.ScrolledUp = true; else if (event.wheel.y < 0) currentMouseState.ScrolledDown = true; break; - case SDL_CONTROLLERBUTTONUP: - case SDL_CONTROLLERBUTTONDOWN: currentControllerButtonsState[event.cbutton.button] = event.cbutton.state; break; - case SDL_CONTROLLERAXISMOTION: - if (event.caxis.value > 1) { - switch (event.caxis.axis) { - case SDL_CONTROLLER_AXIS_LEFTX: currentControllerAxisState.LeftRight = static_cast (event.caxis.value) / 32767; break; - case SDL_CONTROLLER_AXIS_LEFTY: currentControllerAxisState.LeftDown = static_cast (event.caxis.value) / 32767; break; - case SDL_CONTROLLER_AXIS_RIGHTX: currentControllerAxisState.RightRight = static_cast (event.caxis.value) / 32767; break; - case SDL_CONTROLLER_AXIS_RIGHTY: currentControllerAxisState.RightDown = static_cast (event.caxis.value) / 32767; break; - case SDL_CONTROLLER_AXIS_TRIGGERLEFT: currentControllerAxisState.LTriggerDown = static_cast (event.caxis.value) / 32767; break; - case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: - currentControllerAxisState.RTriggerDown = static_cast (event.caxis.value) / 32767; + case SDL_EVENT_GAMEPAD_BUTTON_UP: + case SDL_EVENT_GAMEPAD_BUTTON_DOWN: currentControllerButtonsState[event.gbutton.button] = event.gbutton.down; break; + case SDL_EVENT_GAMEPAD_AXIS_MOTION: + if (event.gaxis.value > 1) { + switch (event.gaxis.axis) { + case SDL_GAMEPAD_AXIS_LEFTX: currentControllerAxisState.LeftRight = static_cast (event.gaxis.value) / 32767; break; + case SDL_GAMEPAD_AXIS_LEFTY: currentControllerAxisState.LeftDown = static_cast (event.gaxis.value) / 32767; break; + case SDL_GAMEPAD_AXIS_RIGHTX: currentControllerAxisState.RightRight = static_cast (event.gaxis.value) / 32767; break; + case SDL_GAMEPAD_AXIS_RIGHTY: currentControllerAxisState.RightDown = static_cast (event.gaxis.value) / 32767; break; + case SDL_GAMEPAD_AXIS_LEFT_TRIGGER: currentControllerAxisState.LTriggerDown = static_cast (event.gaxis.value) / 32767; break; + case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER: + currentControllerAxisState.RTriggerDown = static_cast (event.gaxis.value) / 32767; break; default: break; } - } else if (event.caxis.value < -1) { - switch (event.caxis.axis) { - case SDL_CONTROLLER_AXIS_LEFTX: currentControllerAxisState.LeftLeft = static_cast (event.caxis.value) / -32768; break; - case SDL_CONTROLLER_AXIS_LEFTY: currentControllerAxisState.LeftUp = static_cast (event.caxis.value) / -32768; break; - case SDL_CONTROLLER_AXIS_RIGHTX: currentControllerAxisState.RightLeft = static_cast (event.caxis.value) / -32768; break; - case SDL_CONTROLLER_AXIS_RIGHTY: currentControllerAxisState.RightUp = static_cast (event.caxis.value) / -32768; break; + } else if (event.gaxis.value < -1) { + switch (event.gaxis.axis) { + case SDL_GAMEPAD_AXIS_LEFTX: currentControllerAxisState.LeftLeft = static_cast (event.gaxis.value) / -32768; break; + case SDL_GAMEPAD_AXIS_LEFTY: currentControllerAxisState.LeftUp = static_cast (event.gaxis.value) / -32768; break; + case SDL_GAMEPAD_AXIS_RIGHTX: currentControllerAxisState.RightLeft = static_cast (event.gaxis.value) / -32768; break; + case SDL_GAMEPAD_AXIS_RIGHTY: currentControllerAxisState.RightUp = static_cast (event.gaxis.value) / -32768; break; default: break; } } else { - switch (event.caxis.axis) { - case SDL_CONTROLLER_AXIS_LEFTX: + switch (event.gaxis.axis) { + case SDL_GAMEPAD_AXIS_LEFTX: currentControllerAxisState.LeftRight = 0; currentControllerAxisState.LeftLeft = 0; break; - case SDL_CONTROLLER_AXIS_LEFTY: + case SDL_GAMEPAD_AXIS_LEFTY: currentControllerAxisState.LeftDown = 0; currentControllerAxisState.LeftUp = 0; break; - case SDL_CONTROLLER_AXIS_RIGHTX: + case SDL_GAMEPAD_AXIS_RIGHTX: currentControllerAxisState.RightRight = 0; currentControllerAxisState.RightLeft = 0; break; - case SDL_CONTROLLER_AXIS_RIGHTY: + case SDL_GAMEPAD_AXIS_RIGHTY: currentControllerAxisState.RightDown = 0; currentControllerAxisState.RightUp = 0; break; - case SDL_CONTROLLER_AXIS_TRIGGERLEFT: currentControllerAxisState.LTriggerDown = 0; break; - case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: currentControllerAxisState.RTriggerDown = 0; break; + case SDL_GAMEPAD_AXIS_LEFT_TRIGGER: currentControllerAxisState.LTriggerDown = 0; break; + case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER: currentControllerAxisState.RTriggerDown = 0; break; default: break; } } @@ -272,7 +289,7 @@ GetInternalButtonState (const Keybindings &bindings) { if (KeyboardIsTapped (bindings.keycodes[i])) buttons.Tapped = true; } for (size_t i = 0; i < std::size (ConfigControllerButtons); i++) { - if (bindings.buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) continue; + if (bindings.buttons[i] == SDL_GAMEPAD_BUTTON_INVALID) continue; if (ControllerButtonIsReleased (bindings.buttons[i])) buttons.Released = true; if (ControllerButtonIsDown (bindings.buttons[i])) buttons.Down = 1; if (ControllerButtonIsTapped (bindings.buttons[i])) buttons.Tapped = true; @@ -295,11 +312,12 @@ GetInternalButtonState (const Keybindings &bindings) { } void -SetRumble (const int left, const int right, const int length) { +SetRumble (int left, int right, int length) { for (auto &controller : controllers) { - if (!controller || !SDL_GameControllerHasRumble (controller)) continue; - - SDL_GameControllerRumble (controller, left, right, length); + const auto props = SDL_GetGamepadProperties(controller); + const bool hasRumble = SDL_GetBooleanProperty (props, SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN, false); + if (!controller || !hasRumble) continue; + SDL_RumbleGamepad (controller, left, right, length); } } @@ -389,32 +407,32 @@ GetMouseScrollIsTapped (const Scroll scroll) { } bool -ControllerButtonIsDown (const SDL_GameControllerButton button) { +ControllerButtonIsDown (const SDL_GamepadButton button) { return currentControllerButtonsState[button]; } bool -ControllerButtonIsUp (const SDL_GameControllerButton button) { +ControllerButtonIsUp (const SDL_GamepadButton button) { return !ControllerButtonIsDown (button); } bool -ControllerButtonWasDown (const SDL_GameControllerButton button) { +ControllerButtonWasDown (const SDL_GamepadButton button) { return lastControllerButtonsState[button]; } bool -ControllerButtonWasUp (const SDL_GameControllerButton button) { +ControllerButtonWasUp (const SDL_GamepadButton button) { return !ControllerButtonWasDown (button); } bool -ControllerButtonIsTapped (const SDL_GameControllerButton button) { +ControllerButtonIsTapped (const SDL_GamepadButton button) { return ControllerButtonIsDown (button) && ControllerButtonWasUp (button); } bool -ControllerButtonIsReleased (const SDL_GameControllerButton button) { +ControllerButtonIsReleased (const SDL_GamepadButton button) { return ControllerButtonIsUp (button) && ControllerButtonWasDown (button); } diff --git a/src/poll.h b/src/poll.h index a184ed2..29e7d8c 100644 --- a/src/poll.h +++ b/src/poll.h @@ -1,5 +1,5 @@ #pragma once -#include +#include #include "helpers.h" #include "bnusio.h" @@ -41,7 +41,7 @@ enum Scroll { MOUSE_SCROLL_INVALID, MOUSE_SCROLL_UP, MOUSE_SCROLL_DOWN }; struct Keybindings { u8 keycodes[255]; - SDL_GameControllerButton buttons[255]; + SDL_GamepadButton buttons[255]; SDLAxis axis[255]; Scroll scroll[2]; }; @@ -52,7 +52,7 @@ struct ConfigValue { EnumType type; union { u8 keycode; - SDL_GameControllerButton button; + SDL_GamepadButton button; SDLAxis axis; Scroll scroll; }; @@ -72,16 +72,16 @@ void SetConfigValue (const toml_table_t *table, const char *key, Keybindings *ke InternalButtonState GetInternalButtonState (const Keybindings &bindings); void SetRumble (int left, int right, int length); -bool KeyboardIsDown (const uint8_t keycode); -bool KeyboardIsTapped (const uint8_t keycode); +bool KeyboardIsDown (uint8_t keycode); +bool KeyboardIsTapped (uint8_t keycode); bool GetMouseScrollUp (); bool GetMouseScrollDown (); -bool GetMouseScrollIsDown (const Scroll scroll); -bool GetMouseScrollIsTapped (const Scroll scroll); -bool ControllerButtonIsDown (const SDL_GameControllerButton button); -bool ControllerButtonIsTapped (const SDL_GameControllerButton button); -float ControllerAxisIsDown (const SDLAxis axis); -bool ControllerAxisIsTapped (const SDLAxis axis); +bool GetMouseScrollIsDown (Scroll scroll); +bool GetMouseScrollIsTapped (Scroll scroll); +bool ControllerButtonIsDown (SDL_GamepadButton button); +bool ControllerButtonIsTapped (SDL_GamepadButton button); +float ControllerAxisIsDown (SDLAxis axis); +bool ControllerAxisIsTapped (SDLAxis axis); bool IsButtonTapped (const Keybindings &bindings); float IsButtonDown (const Keybindings &bindings); @@ -99,9 +99,9 @@ void SetMousePosition (const POINT newPosition); bool GetWasMouseScrollUp (); bool GetWasMouseScrollDown (); bool GetMouseScrollIsReleased (const Scroll scroll); -bool ControllerButtonWasDown (const SDL_GameControllerButton button); -bool ControllerButtonWasUp (const SDL_GameControllerButton button); -bool ControllerButtonIsReleased (const SDL_GameControllerButton button); +bool ControllerButtonWasDown (const SDL_GamepadButton button); +bool ControllerButtonWasUp (const SDL_GamepadButton button); +bool ControllerButtonIsReleased (const SDL_GamepadButton button); bool ControllerAxisIsUp (const SDLAxis axis); float ControllerAxisWasDown (const SDLAxis axis); bool ControllerAxisWasUp (const SDLAxis axis); diff --git a/src/pollasync.cpp b/src/pollasync.cpp index b9296eb..361adad 100644 --- a/src/pollasync.cpp +++ b/src/pollasync.cpp @@ -2,22 +2,21 @@ #ifdef ASYNC_IO #include "polldef.h" +#define SDL_MAIN_NOIMPL +#include + extern bool jpLayout; extern int exited; -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif - bool wndForeground = false; bool currentKeyboardState[0xFF] = { false }; uint8_t keyboardCount[0xFF] = { 0 }; uint8_t keyboardDiff[0xFF] = { 0 }; bool keyboardClean = false; -bool currentControllerButtonsState[SDL_CONTROLLER_BUTTON_MAX] = { false }; -uint8_t controllerCount[SDL_CONTROLLER_BUTTON_MAX] = { 0 }; -uint8_t controllerDiff[SDL_CONTROLLER_BUTTON_MAX] = { 0 }; +bool currentControllerButtonsState[SDL_GAMEPAD_BUTTON_COUNT] = { false }; +uint8_t controllerCount[SDL_GAMEPAD_BUTTON_COUNT] = { 0 }; +uint8_t controllerDiff[SDL_GAMEPAD_BUTTON_COUNT] = { 0 }; char currentMouseWheelDirection = 0; uint8_t mouseWheelCount[2] = { 0 }; uint8_t mouseWheelDiff[2] = { 0 }; @@ -27,7 +26,8 @@ int maxCount = 1; SDLAxisState currentControllerAxisState; SDL_Window *window; -SDL_GameController *controllers[255]; +SDL_Gamepad *controllers[255]; +bool flipped[255]; std::thread updatePollThread; @@ -48,7 +48,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin memset (key_bind, 0, sizeof (*key_bind)); for (size_t i = 0; i < std::size (key_bind->buttons); i++) - key_bind->buttons[i] = SDL_CONTROLLER_BUTTON_INVALID; + key_bind->buttons[i] = SDL_GAMEPAD_BUTTON_INVALID; for (int idx = 0;; idx++) { const auto [ok, u] = toml_string_at (array, idx); @@ -69,7 +69,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin case button: { *usePoll = true; for (int i = 0; i < std::size (key_bind->buttons); i++) { - if (key_bind->buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) { + if (key_bind->buttons[i] == SDL_GAMEPAD_BUTTON_INVALID) { key_bind->buttons[i] = value.button; break; } @@ -108,9 +108,9 @@ LRESULT CALLBACK InputProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode == HC_ACTION) { switch (wParam) { case WM_KEYDOWN: if (wndForeground) { - KBDLLHOOKSTRUCT* pKeyboard = reinterpret_cast(lParam); + auto* pKeyboard = reinterpret_cast(lParam); DWORD keyCode = pKeyboard->vkCode; - if (!currentKeyboardState[keyCode]) keyboardCount[keyCode] = MIN (keyboardCount[keyCode] + 1, maxCount); + if (!currentKeyboardState[keyCode]) keyboardCount[keyCode] = std::min (keyboardCount[keyCode] + 1, maxCount); currentKeyboardState[keyCode] = true; } break; // keyup will accepted even if you're not focus in this window @@ -123,13 +123,14 @@ LRESULT CALLBACK InputProc(int nCode, WPARAM wParam, LPARAM lParam) { MSLLHOOKSTRUCT *pMouseStruct = (MSLLHOOKSTRUCT*)lParam; int wheelDelta = GET_WHEEL_DELTA_WPARAM(pMouseStruct->mouseData); if (wheelDelta > 0) { - mouseWheelCount[0] = MIN (mouseWheelCount[0] + wheelDelta, maxCount); + mouseWheelCount[0] = std::min (mouseWheelCount[0] + wheelDelta, maxCount); currentMouseState.ScrolledUp = true; } else if (wheelDelta < 0) { - mouseWheelCount[1] = MIN (mouseWheelCount[1] - wheelDelta, maxCount); + mouseWheelCount[1] = std::min (mouseWheelCount[1] - wheelDelta, maxCount); currentMouseState.ScrolledDown = true; } } break; + default: break; } } return CallNextHookEx(keyboardHook, nCode, wParam, lParam); @@ -150,14 +151,12 @@ DisposeKeyboard () { if (mouseHook) UnhookWindowsHookEx(mouseHook); } -// void -// UpdateLoop () { -// LogMessage (LogLevel::DEBUG, "Enter Controller UpdateLoop"); - -// while (!exited) { - -// } -// } +void +CheckFlipped (uint32_t which, SDL_Gamepad *gamepad) { + if (SDL_GetGamepadButtonLabel(gamepad, SDL_GAMEPAD_BUTTON_SOUTH) == SDL_GAMEPAD_BUTTON_LABEL_B) { + flipped[which] = true; + } else flipped[which] = false; +} bool InitializePoll (HWND windowHandle) { @@ -171,44 +170,53 @@ InitializePoll (HWND windowHandle) { SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5, "1"); SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); - if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) != 0) { - if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) == 0) { + if (!SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMEPAD | SDL_INIT_EVENTS | SDL_INIT_VIDEO)) { + if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD | SDL_INIT_EVENTS | SDL_INIT_VIDEO)) { hasRumble = false; } else { - LogMessage (LogLevel::ERROR, - std::string ("SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO): ") - + SDL_GetError ()); + LogMessage (LogLevel::ERROR, std::string ("SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMEPAD | SDL_INIT_EVENTS | SDL_INIT_VIDEO): ") + SDL_GetError ()); return false; } } auto configPath = std::filesystem::current_path () / "gamecontrollerdb.txt"; - if (SDL_GameControllerAddMappingsFromFile (configPath.string ().c_str ()) == -1) + if (SDL_AddGamepadMappingsFromFile (configPath.string ().c_str ()) == -1) LogMessage (LogLevel::ERROR, "Cannot read gamecontrollerdb.txt"); - SDL_GameControllerEventState (SDL_ENABLE); - SDL_JoystickEventState (SDL_ENABLE); + SDL_SetGamepadEventsEnabled (true); + SDL_SetJoystickEventsEnabled (true); - for (int i = 0; i < SDL_NumJoysticks (); i++) { - if (!SDL_IsGameController (i)) continue; + int numJoysticks = 0; + auto* joyStickIds = SDL_GetJoysticks(&numJoysticks); + if (joyStickIds == nullptr) { + LogMessage (LogLevel::ERROR, "Error getting joystick ids"); + exit(1); + } + for (int i = 0; i < numJoysticks; i++) { + auto id = joyStickIds[i]; + if (!SDL_IsGamepad (id)) continue; + SDL_Gamepad *controller = SDL_OpenGamepad (id); - SDL_GameController *controller = SDL_GameControllerOpen (i); if (!controller) { - LogMessage (LogLevel::WARN, std::string ("Could not open gamecontroller ") + SDL_GameControllerNameForIndex (i) + ": " + SDL_GetError ()); + LogMessage (LogLevel::WARN, std::string ("Could not open gamecontroller ") + SDL_GetGamepadNameForID (id) + ": " + SDL_GetError ()); continue; } LogMessage (LogLevel::DEBUG, "Init Controller connected!"); - controllers[i] = controller; + CheckFlipped (id, controller); + controllers[id] = controller; } + SDL_free (joyStickIds); - window = SDL_CreateWindowFrom (windowHandle); + SDL_PropertiesID props = SDL_CreateProperties(); + if(props == 0) { + LogMessage (LogLevel::ERROR, "Unable to create SDL_Properties"); + exit(1); + } + SDL_SetPointerProperty (props, SDL_PROP_WINDOW_CREATE_WIN32_HWND_POINTER, windowHandle); + window = SDL_CreateWindowWithProperties (props); if (window == NULL) LogMessage (LogLevel::ERROR, std::string ("SDL_CreateWindowFrom (windowHandle): ") + SDL_GetError ()); atexit (DisposePoll); - - // updatePollThread = std::thread (UpdateLoop); - // updatePollThread.detach (); - return hasRumble; } @@ -222,6 +230,18 @@ CheckForegroundWindow (HWND processWindow) { return wndForeground; } +uint8_t +CorrectButton (uint32_t which, uint8_t button) { + if (!flipped[which]) return button; + switch (button) { + case SDL_GAMEPAD_BUTTON_SOUTH: return SDL_GAMEPAD_BUTTON_EAST; + case SDL_GAMEPAD_BUTTON_EAST: return SDL_GAMEPAD_BUTTON_SOUTH; + case SDL_GAMEPAD_BUTTON_WEST: return SDL_GAMEPAD_BUTTON_NORTH; + case SDL_GAMEPAD_BUTTON_NORTH: return SDL_GAMEPAD_BUTTON_WEST; + default: return button; + } +} + void UpdatePoll (HWND windowHandle, bool useController) { if (!CheckForegroundWindow (windowHandle)) return; @@ -240,50 +260,52 @@ UpdatePoll (HWND windowHandle, bool useController) { // GetCursorPos (¤tMouseState.Position); // ScreenToClient (windowHandle, ¤tMouseState.Position); if (useController) { - for (int i=0; i 0 ? 32767.0f : -32768.0f); + case SDL_EVENT_GAMEPAD_AXIS_MOTION: + float sensorValue = event.gaxis.value == 0 ? 0 : event.gaxis.value / (event.gaxis.value > 0 ? 32767.0f : -32768.0f); if (wndForeground || sensorValue == 0) { - switch (event.caxis.axis) { - case SDL_CONTROLLER_AXIS_LEFTX: currentControllerAxisState.LeftRight = sensorValue; break; - case SDL_CONTROLLER_AXIS_LEFTY: currentControllerAxisState.LeftDown = sensorValue; break; - case SDL_CONTROLLER_AXIS_RIGHTX: currentControllerAxisState.RightRight = sensorValue; break; - case SDL_CONTROLLER_AXIS_RIGHTY: currentControllerAxisState.RightDown = sensorValue; break; - case SDL_CONTROLLER_AXIS_TRIGGERLEFT: currentControllerAxisState.LTriggerDown = sensorValue; break; - case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: currentControllerAxisState.RTriggerDown = sensorValue; break; + switch (event.gaxis.axis) { + case SDL_GAMEPAD_AXIS_LEFTX: currentControllerAxisState.LeftRight = sensorValue; break; + case SDL_GAMEPAD_AXIS_LEFTY: currentControllerAxisState.LeftDown = sensorValue; break; + case SDL_GAMEPAD_AXIS_RIGHTX: currentControllerAxisState.RightRight = sensorValue; break; + case SDL_GAMEPAD_AXIS_RIGHTY: currentControllerAxisState.RightDown = sensorValue; break; + case SDL_GAMEPAD_AXIS_LEFT_TRIGGER: currentControllerAxisState.LTriggerDown = sensorValue; break; + case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER: currentControllerAxisState.RTriggerDown = sensorValue; break; } } break; @@ -333,8 +355,10 @@ StringToConfigEnum (const char *value) { void SetRumble (int left, int right, int length) { for (auto &controller : controllers) { - if (!controller || !SDL_GameControllerHasRumble (controller)) continue; - SDL_GameControllerRumble (controller, left, right, length); + const auto props = SDL_GetGamepadProperties(controller); + const bool hasRumble = SDL_GetBooleanProperty (props, SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN, false); + if (!controller || !hasRumble) continue; + SDL_RumbleGamepad (controller, left, right, length); } } @@ -388,13 +412,13 @@ GetMouseScrollIsTapped (const Scroll scroll) { } bool -ControllerButtonIsDown (const SDL_GameControllerButton button) { +ControllerButtonIsDown (const SDL_GamepadButton button) { return currentControllerButtonsState[button]; } int maxButtonCount = 1; bool -ControllerButtonIsTapped (const SDL_GameControllerButton button) { +ControllerButtonIsTapped (const SDL_GamepadButton button) { if (controllerCount[button] > 0) { // if (maxButtonCount < controllerCount[button]) { // maxButtonCount = controllerCount[button]; @@ -435,7 +459,7 @@ IsButtonTapped (const Keybindings &bindings) { if (KeyboardIsTapped (bindings.keycodes[i])) return true; } for (size_t i = 0; i < std::size (ConfigControllerButtons); i++) { - if (bindings.buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) continue; + if (bindings.buttons[i] == SDL_GAMEPAD_BUTTON_INVALID) continue; if (ControllerButtonIsTapped (bindings.buttons[i])) return true; } for (size_t i = 0; i < std::size (ConfigControllerAXIS); i++) { @@ -457,7 +481,7 @@ IsButtonDown (const Keybindings &bindings) { if (KeyboardIsDown (bindings.keycodes[i])) return 1.0f; } for (size_t i = 0; i < std::size (ConfigControllerButtons); i++) { - if (bindings.buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) continue; + if (bindings.buttons[i] == SDL_GAMEPAD_BUTTON_INVALID) continue; if (ControllerButtonIsDown (bindings.buttons[i])) return 1.0f; } for (size_t i = 0; i < std::size (ConfigControllerAXIS); i++) { diff --git a/src/polldef.h b/src/polldef.h index f1bbe4a..0b1ccce 100644 --- a/src/polldef.h +++ b/src/polldef.h @@ -254,29 +254,29 @@ KeyCodePair ConfigKeyboardButtons_JP[] = { struct { const char *string; - SDL_GameControllerButton button; + SDL_GamepadButton button; } ConfigControllerButtons[] = { - {"SDL_A", SDL_CONTROLLER_BUTTON_A}, - {"SDL_B", SDL_CONTROLLER_BUTTON_B}, - {"SDL_X", SDL_CONTROLLER_BUTTON_X}, - {"SDL_Y", SDL_CONTROLLER_BUTTON_Y}, - {"SDL_BACK", SDL_CONTROLLER_BUTTON_BACK}, - {"SDL_GUIDE", SDL_CONTROLLER_BUTTON_GUIDE}, - {"SDL_START", SDL_CONTROLLER_BUTTON_START}, - {"SDL_LSTICK_PRESS", SDL_CONTROLLER_BUTTON_LEFTSTICK}, - {"SDL_RSTICK_PRESS", SDL_CONTROLLER_BUTTON_RIGHTSTICK}, - {"SDL_LSHOULDER", SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, - {"SDL_RSHOULDER", SDL_CONTROLLER_BUTTON_RIGHTSHOULDER}, - {"SDL_DPAD_UP", SDL_CONTROLLER_BUTTON_DPAD_UP}, - {"SDL_DPAD_DOWN", SDL_CONTROLLER_BUTTON_DPAD_DOWN}, - {"SDL_DPAD_LEFT", SDL_CONTROLLER_BUTTON_DPAD_LEFT}, - {"SDL_DPAD_RIGHT", SDL_CONTROLLER_BUTTON_DPAD_RIGHT}, - {"SDL_MISC", SDL_CONTROLLER_BUTTON_MISC1}, - {"SDL_PADDLE1", SDL_CONTROLLER_BUTTON_PADDLE1}, - {"SDL_PADDLE2", SDL_CONTROLLER_BUTTON_PADDLE2}, - {"SDL_PADDLE3", SDL_CONTROLLER_BUTTON_PADDLE3}, - {"SDL_PADDLE4", SDL_CONTROLLER_BUTTON_PADDLE4}, - {"SDL_TOUCHPAD", SDL_CONTROLLER_BUTTON_TOUCHPAD}, + {"SDL_A", SDL_GAMEPAD_BUTTON_SOUTH}, + {"SDL_B", SDL_GAMEPAD_BUTTON_EAST}, + {"SDL_X", SDL_GAMEPAD_BUTTON_WEST}, + {"SDL_Y", SDL_GAMEPAD_BUTTON_NORTH}, + {"SDL_BACK", SDL_GAMEPAD_BUTTON_BACK}, + {"SDL_GUIDE", SDL_GAMEPAD_BUTTON_GUIDE}, + {"SDL_START", SDL_GAMEPAD_BUTTON_START}, + {"SDL_LSTICK_PRESS", SDL_GAMEPAD_BUTTON_LEFT_STICK}, + {"SDL_RSTICK_PRESS", SDL_GAMEPAD_BUTTON_RIGHT_STICK}, + {"SDL_LSHOULDER", SDL_GAMEPAD_BUTTON_LEFT_SHOULDER}, + {"SDL_RSHOULDER", SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER}, + {"SDL_DPAD_UP", SDL_GAMEPAD_BUTTON_DPAD_UP}, + {"SDL_DPAD_DOWN", SDL_GAMEPAD_BUTTON_DPAD_DOWN}, + {"SDL_DPAD_LEFT", SDL_GAMEPAD_BUTTON_DPAD_LEFT}, + {"SDL_DPAD_RIGHT", SDL_GAMEPAD_BUTTON_DPAD_RIGHT}, + {"SDL_MISC", SDL_GAMEPAD_BUTTON_MISC1}, + {"SDL_PADDLE1", SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1}, + {"SDL_PADDLE2", SDL_GAMEPAD_BUTTON_LEFT_PADDLE1}, + {"SDL_PADDLE3", SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2}, + {"SDL_PADDLE4", SDL_GAMEPAD_BUTTON_LEFT_PADDLE2}, + {"SDL_TOUCHPAD", SDL_GAMEPAD_BUTTON_TOUCHPAD}, }; struct {