From cb0d4692ff797b53dc4c903d8184d95bd2c506e8 Mon Sep 17 00:00:00 2001 From: ptmaster Date: Sun, 8 Dec 2024 19:41:25 +0800 Subject: [PATCH] detail fix & optimize & clean up --- src/bnusio.cpp | 106 ++++++++++++----------- src/bnusio.h | 2 +- src/patches/versions/JPN39.cpp | 34 ++++---- src/poll.cpp | 6 +- src/poll.h | 5 +- src/pollasync.cpp | 149 +++++++++++++++++++-------------- 6 files changed, 163 insertions(+), 139 deletions(-) diff --git a/src/bnusio.cpp b/src/bnusio.cpp index 230447d..7d91a41 100644 --- a/src/bnusio.cpp +++ b/src/bnusio.cpp @@ -48,6 +48,9 @@ Keybindings P2_LEFT_BLUE = {.keycodes = {'Z'}}; Keybindings P2_LEFT_RED = {.keycodes = {'X'}}; Keybindings P2_RIGHT_RED = {.keycodes = {'C'}}; Keybindings P2_RIGHT_BLUE = {.keycodes = {'V'}}; +// Keybindings ALL[] = { EXIT, TEST, SERVICE, DEBUG_UP, DEBUG_DOWN, DEBUG_ENTER, COIN_ADD, +// 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 }; int exited = 0; bool testEnabled = false; @@ -56,6 +59,7 @@ int service_count = 0; bool inited = false; bool updateByCoin = false; HWND windowHandle = nullptr; +bool usePoll = false; HKL currentLayout; namespace bnusio { @@ -119,6 +123,7 @@ bnusio_GetSwIn () { return sw; } +bool waitAll = false; u16 drumWaitPeriod = 4; bool valueStates[] = {false, false, false, false, false, false, false, false}; @@ -148,7 +153,7 @@ bnusio_GetAnalogIn (const u8 which) { else return 0; } const auto button = analogButtons[which]; - const int blue = !(which % 4 % 3); + const bool blue = !(which % 4 % 3); const int player = which / 4; u16 analogValue = 0; @@ -157,20 +162,21 @@ bnusio_GetAnalogIn (const u8 which) { for (int i=0; i<8; i++) if (cooldown[i] > 0) cooldown[i]--; } if (buttonWaitPeriod[player] == 0 && !buttonQueue[player].empty () && buttonQueue[player].front () == which) { - buttonQueue[player].pop (); buttonWaitPeriod[player] = drumWaitPeriod; + buttonQueue[player].pop (); const u16 hitValue = !valueStates[which] ? 50 : 51; valueStates[which] = !valueStates[which]; analogValue = (hitValue << 15) / 100 + 1; } if (IsButtonTapped (*button)) { - if (drumWaitPeriod > 0) { - if (blue && buttonWaitPeriod[player] > 0) buttonQueue[player].push (which); - buttonWaitPeriod[player] = drumWaitPeriod; - } else if (blue && cooldown[which] > 0) return 0; + if ((waitAll || blue) && buttonWaitPeriod[player] > 0) { + buttonQueue[player].push (which); + return analogValue; + } else if ((waitAll || blue) && cooldown[which] > 0) return 0; + buttonWaitPeriod[player] = drumWaitPeriod; + if (waitAll || blue) cooldown[which] = 4; - if (blue) cooldown[which] = 4; const u16 hitValue = !valueStates[which] ? 50 : 51; valueStates[which] = !valueStates[which]; analogValue = (hitValue << 15) / 100 + 1; @@ -185,30 +191,6 @@ u16 __fastcall bnusio_GetCoin (i32 a1) { u16 __fastcall bnusio_GetService (i32 a1) { return service_count; } } -void -InspectWaitTouch (const i32 a1, const i32 a2, u8 _cardData[168], const u64 _touchData) { - if (AreAllBytesZero (_cardData, 0x00, 168)) // This happens when you enter test mode. - return touchCallback (a1, a2, _cardData, _touchData); - - const bool valid = !AreAllBytesZero (_cardData, 0x50, 21); - if (valid) { - LogMessage (LogLevel::DEBUG, "Card is valid"); - } else { - memcpy (_cardData + 0x50, _cardData + 0x2C, 16); // 16 to match felica lite serial number length - LogMessage (LogLevel::DEBUG, "Card is usually not supported"); - } - - std::ostringstream oss; - for (size_t i = 0; i < 168; ++i) { - oss << std::setw (2) << std::setfill ('0') << std::hex << static_cast (_cardData[i]) << " "; - if ((i + 1) % 21 == 0) oss << "\n"; - } - - LogMessage (LogLevel::DEBUG, "A1: %d, A2: %d, Card data: \n%s", a1, a2, oss.str ().c_str ()); - - if (touchCallback) return valid ? touchCallback (a1, a2, _cardData, _touchData) : touchCallback (0, 0, _cardData, _touchData); -} - FUNCTION_PTR (i64, bnusio_Open_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_Open")); FUNCTION_PTR (i64, bnusio_Close_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_Close")); FUNCTION_PTR (u64, bnusio_Communication_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_Communication"), i32); @@ -272,6 +254,8 @@ UpdateLoop () { syncCV.wait (syncLock); #endif if (exited && ++exited >= 120) ExitProcess (0); + +#ifndef ASYNC_IO if (!inited) { windowHandle = FindWindowA ("nuFoundation.Window", nullptr); InitializePoll (windowHandle); @@ -285,7 +269,6 @@ UpdateLoop () { inited = true; } -#ifndef ASYNC_IO UpdatePoll (windowHandle); #endif std::vector buffer = {}; @@ -324,8 +307,8 @@ Init () { if (config_ptr) { const toml_table_t *config = config_ptr.get (); if (const auto controller = openConfigSection (config, "controller")) { - drumWaitPeriod = static_cast (readConfigInt (controller, "wait_period", drumWaitPeriod)); - analogInput = readConfigBool (controller, "analog_input", analogInput); + drumWaitPeriod = static_cast (readConfigInt (controller, "wait_period", drumWaitPeriod)); + analogInput = readConfigBool (controller, "analog_input", analogInput); if (analogInput) LogMessage (LogLevel::WARN, "Using analog input mode. All the keyboard drum inputs have been disabled."); } auto graphics = openConfigSection (config, "graphics"); @@ -342,28 +325,31 @@ Init () { const std::unique_ptr keyConfig_ptr (openConfig (keyConfigPath), toml_free); if (keyConfig_ptr) { const toml_table_t *keyConfig = keyConfig_ptr.get (); - SetConfigValue (keyConfig, "EXIT", &EXIT); + SetConfigValue (keyConfig, "EXIT", &EXIT, &usePoll); - SetConfigValue (keyConfig, "TEST", &TEST); - SetConfigValue (keyConfig, "SERVICE", &SERVICE); - SetConfigValue (keyConfig, "DEBUG_UP", &DEBUG_UP); - SetConfigValue (keyConfig, "DEBUG_DOWN", &DEBUG_DOWN); - SetConfigValue (keyConfig, "DEBUG_ENTER", &DEBUG_ENTER); + SetConfigValue (keyConfig, "TEST", &TEST, &usePoll); + SetConfigValue (keyConfig, "SERVICE", &SERVICE, &usePoll); + SetConfigValue (keyConfig, "DEBUG_UP", &DEBUG_UP, &usePoll); + SetConfigValue (keyConfig, "DEBUG_DOWN", &DEBUG_DOWN, &usePoll); + SetConfigValue (keyConfig, "DEBUG_ENTER", &DEBUG_ENTER, &usePoll); - SetConfigValue (keyConfig, "COIN_ADD", &COIN_ADD); - SetConfigValue (keyConfig, "CARD_INSERT_1", &CARD_INSERT_1); - SetConfigValue (keyConfig, "CARD_INSERT_2", &CARD_INSERT_2); - SetConfigValue (keyConfig, "QR_DATA_READ", &QR_DATA_READ); - SetConfigValue (keyConfig, "QR_IMAGE_READ", &QR_IMAGE_READ); + SetConfigValue (keyConfig, "COIN_ADD", &COIN_ADD, &usePoll); + SetConfigValue (keyConfig, "CARD_INSERT_1", &CARD_INSERT_1, &usePoll); + SetConfigValue (keyConfig, "CARD_INSERT_2", &CARD_INSERT_2, &usePoll); + SetConfigValue (keyConfig, "QR_DATA_READ", &QR_DATA_READ, &usePoll); + SetConfigValue (keyConfig, "QR_IMAGE_READ", &QR_IMAGE_READ, &usePoll); - SetConfigValue (keyConfig, "P1_LEFT_BLUE", &P1_LEFT_BLUE); - SetConfigValue (keyConfig, "P1_LEFT_RED", &P1_LEFT_RED); - SetConfigValue (keyConfig, "P1_RIGHT_RED", &P1_RIGHT_RED); - SetConfigValue (keyConfig, "P1_RIGHT_BLUE", &P1_RIGHT_BLUE); - SetConfigValue (keyConfig, "P2_LEFT_BLUE", &P2_LEFT_BLUE); - SetConfigValue (keyConfig, "P2_LEFT_RED", &P2_LEFT_RED); - SetConfigValue (keyConfig, "P2_RIGHT_RED", &P2_RIGHT_RED); - SetConfigValue (keyConfig, "P2_RIGHT_BLUE", &P2_RIGHT_BLUE); + SetConfigValue (keyConfig, "P1_LEFT_BLUE", &P1_LEFT_BLUE, &usePoll); + SetConfigValue (keyConfig, "P1_LEFT_RED", &P1_LEFT_RED, &usePoll); + SetConfigValue (keyConfig, "P1_RIGHT_RED", &P1_RIGHT_RED, &usePoll); + SetConfigValue (keyConfig, "P1_RIGHT_BLUE", &P1_RIGHT_BLUE, &usePoll); + SetConfigValue (keyConfig, "P2_LEFT_BLUE", &P2_LEFT_BLUE, &usePoll); + SetConfigValue (keyConfig, "P2_LEFT_RED", &P2_LEFT_RED, &usePoll); + SetConfigValue (keyConfig, "P2_RIGHT_RED", &P2_RIGHT_RED, &usePoll); + SetConfigValue (keyConfig, "P2_RIGHT_BLUE", &P2_RIGHT_BLUE, &usePoll); + if (!usePoll) { + LogMessage (LogLevel::WARN, "Only Keyboard config detected, disable poll!"); + } } if (!emulateUsio && !exists (std::filesystem::current_path () / "bnusio_original.dll")) { @@ -430,7 +416,19 @@ Init () { #ifdef ASYNC_UPDATE void Update () { - if (inited) UpdatePoll (windowHandle); + if (!inited) { + windowHandle = FindWindowA ("nuFoundation.Window", nullptr); + if (usePoll) InitializePoll (windowHandle); + if (autoIme) { + currentLayout = GetKeyboardLayout (0); + auto engLayout = LoadKeyboardLayout (TEXT ("00000409"), KLF_ACTIVATE); + ActivateKeyboardLayout (engLayout, KLF_SETFORPROCESS); + } + + patches::Plugins::Init (); + inited = true; + } + UpdatePoll (windowHandle, usePoll); syncCV.notify_all (); } #endif diff --git a/src/bnusio.h b/src/bnusio.h index c964101..b0f7588 100644 --- a/src/bnusio.h +++ b/src/bnusio.h @@ -1,5 +1,5 @@ #pragma once -// #define ASYNC_UPDATE +#define ASYNC_UPDATE namespace bnusio { void Init (); void Update (); diff --git a/src/patches/versions/JPN39.cpp b/src/patches/versions/JPN39.cpp index fb71d0b..bf3c357 100644 --- a/src/patches/versions/JPN39.cpp +++ b/src/patches/versions/JPN39.cpp @@ -387,21 +387,21 @@ HOOK (i32, SetMasterVolumeSpeaker, ASLR (0x140160330), i32 a1) { return originalSetMasterVolumeSpeaker (a1 > 100 ? 100 : a1); } -std::string *fontName = nullptr; -HOOK (u8, SetupFontInfo, ASLR (0x14049D820), u64 a1, u64 a2, size_t a3, u64 a4) { - LogMessage (LogLevel::HOOKS, "SetupFontInfo was called"); - if (fontName != nullptr) delete fontName; - fontName = new std::string (reinterpret_cast (a1) + 120); - return originalSetupFontInfo (a1, a2, a3, a4); -} +// std::string *fontName = nullptr; +// HOOK (u8, SetupFontInfo, ASLR (0x14049D820), u64 a1, u64 a2, size_t a3, u64 a4) { +// LogMessage (LogLevel::HOOKS, "SetupFontInfo was called"); +// if (fontName != nullptr) delete fontName; +// fontName = new std::string (reinterpret_cast (a1) + 120); +// return originalSetupFontInfo (a1, a2, a3, a4); +// } -HOOK (u32, ReadFontInfoInt, ASLR (0x14049EAC0), u64 a1, u64 a2) { - LogMessage (LogLevel::HOOKS, "ReadFontInfoInt was called"); - const std::string attribute (reinterpret_cast (a2)); - u32 result = originalReadFontInfoInt (a1, a2); - if (fontName->starts_with ("cn_") && attribute == "offsetV") result += 1; - return result; -} +// HOOK (u32, ReadFontInfoInt, ASLR (0x14049EAC0), u64 a1, u64 a2) { +// LogMessage (LogLevel::HOOKS, "ReadFontInfoInt was called"); +// const std::string attribute (reinterpret_cast (a2)); +// u32 result = originalReadFontInfoInt (a1, a2); +// if (fontName->starts_with ("cn_") && attribute == "offsetV") result += 1; +// return result; +// } MID_HOOK (AttractDemo, ASLR (0x14045A720), SafetyHookContext &ctx) { if (TestMode::ReadTestModeValue (L"AttractDemoItem") == 1) ctx.r14 = 0; @@ -501,7 +501,6 @@ Init () { i32 yRes = 1080; bool vsync = false; bool unlockSongs = true; - bool fixLanguage = false; bool chsPatch = false; bool useLayeredfs = false; @@ -511,7 +510,6 @@ Init () { if (auto patches = openConfigSection (config_ptr.get (), "patches")) { unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs); if (auto jpn39 = openConfigSection (patches, "jpn39")) { - fixLanguage = readConfigBool (jpn39, "fix_language", fixLanguage); chsPatch = readConfigBool (jpn39, "chs_patch", chsPatch); } } @@ -733,8 +731,8 @@ Init () { WRITE_MEMORY (ASLR (0x140CD1E68), wchar_t, L"加載中..\0"); WRITE_MEMORY (ASLR (0x140CD1E50), wchar_t, L"加載中...\0"); INSTALL_MID_HOOK (ChangeLanguageType); - INSTALL_HOOK (SetupFontInfo); - INSTALL_HOOK (ReadFontInfoInt); + // INSTALL_HOOK (SetupFontInfo); + // INSTALL_HOOK (ReadFontInfoInt); } LayeredFs::RegisterBefore ([=] (const std::string &originalFileName, const std::string ¤tFileName) -> std::string { diff --git a/src/poll.cpp b/src/poll.cpp index ae6887e..cc2d778 100644 --- a/src/poll.cpp +++ b/src/poll.cpp @@ -23,7 +23,7 @@ SetKeyboardButtons () { } void -SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bind) { +SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bind, bool *usePoll) { const toml_array_t *array = toml_array_in (table, key); if (!array) { LogMessage (LogLevel::WARN, std::string (key) + ": Cannot find array"); @@ -42,6 +42,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin switch (value.type) { case keycode: { + *usePoll = true; for (int i = 0; i < std::size (key_bind->keycodes); i++) { if (key_bind->keycodes[i] == 0) { key_bind->keycodes[i] = value.keycode; @@ -51,6 +52,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin break; } case button: { + *usePoll = true; for (int i = 0; i < std::size (key_bind->buttons); i++) { if (key_bind->buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) { key_bind->buttons[i] = value.button; @@ -60,6 +62,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin break; } case axis: { + *usePoll = true; for (int i = 0; i < std::size (key_bind->axis); i++) { if (key_bind->axis[i] == 0) { key_bind->axis[i] = value.axis; @@ -68,6 +71,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin } } case scroll: { + *usePoll = true; for (int i = 0; i < std::size (key_bind->scroll); i++) { if (key_bind->scroll[i] == 0) { key_bind->scroll[i] = value.scroll; diff --git a/src/poll.h b/src/poll.h index e16d1f3..a184ed2 100644 --- a/src/poll.h +++ b/src/poll.h @@ -65,11 +65,10 @@ struct InternalButtonState { }; bool InitializePoll (HWND windowHandle); -void UpdatePoll (HWND windowHandle); void DisposePoll (); void SetKeyboardButtons (); ConfigValue StringToConfigEnum (const char *value); -void SetConfigValue (const toml_table_t *table, const char *key, Keybindings *keybind); +void SetConfigValue (const toml_table_t *table, const char *key, Keybindings *keybind, bool *usePoll); InternalButtonState GetInternalButtonState (const Keybindings &bindings); void SetRumble (int left, int right, int length); @@ -87,6 +86,7 @@ bool IsButtonTapped (const Keybindings &bindings); float IsButtonDown (const Keybindings &bindings); #ifndef ASYNC_IO +void UpdatePoll (HWND windowHandle); bool KeyboardIsUp (const u8 keycode); bool KeyboardIsReleased (u8 keycode); bool KeyboardWasDown (u8 keycode); @@ -108,6 +108,7 @@ bool ControllerAxisWasUp (const SDLAxis axis); bool ControllerAxisIsReleased (const SDLAxis axis); bool IsButtonReleased (const Keybindings &bindings); #else +void UpdatePoll (HWND windowHandle, bool useController); void InitializeKeyboard (); void DisposeKeyboard (); #endif \ No newline at end of file diff --git a/src/pollasync.cpp b/src/pollasync.cpp index a4b3992..964ac83 100644 --- a/src/pollasync.cpp +++ b/src/pollasync.cpp @@ -38,7 +38,7 @@ SetKeyboardButtons () { } void -SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bind) { +SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bind, bool *usePoll) { const toml_array_t *array = toml_array_in (table, key); if (!array) { LogMessage (LogLevel::WARN, std::string (key) + ": Cannot find array"); @@ -66,6 +66,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin break; } case button: { + *usePoll = true; for (int i = 0; i < std::size (key_bind->buttons); i++) { if (key_bind->buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) { key_bind->buttons[i] = value.button; @@ -75,6 +76,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin break; } case axis: { + *usePoll = true; for (int i = 0; i < std::size (key_bind->axis); i++) { if (key_bind->axis[i] == 0) { key_bind->axis[i] = value.axis; @@ -98,19 +100,35 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin // 钩子句柄 HHOOK keyboardHook; +HHOOK mouseHook; // 钩子回调函数 -LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { +LRESULT CALLBACK InputProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode == HC_ACTION) { - KBDLLHOOKSTRUCT* pKeyboard = reinterpret_cast(lParam); - DWORD keyCode = pKeyboard->vkCode; switch (wParam) { case WM_KEYDOWN: if (wndForeground) { + KBDLLHOOKSTRUCT* pKeyboard = reinterpret_cast(lParam); + DWORD keyCode = pKeyboard->vkCode; if (!currentKeyboardState[keyCode]) keyboardCount[keyCode] = MIN (keyboardCount[keyCode] + 1, maxCount); currentKeyboardState[keyCode] = true; } break; // keyup will accepted even if you're not focus in this window - case WM_KEYUP: currentKeyboardState[keyCode] = false; break; + case WM_KEYUP: { + KBDLLHOOKSTRUCT* pKeyboard = reinterpret_cast(lParam); + DWORD keyCode = pKeyboard->vkCode; + currentKeyboardState[keyCode] = false; + } break; + case WM_MOUSEWHEEL: if (wndForeground) { + MSLLHOOKSTRUCT *pMouseStruct = (MSLLHOOKSTRUCT*)lParam; + int wheelDelta = GET_WHEEL_DELTA_WPARAM(pMouseStruct->mouseData); + if (wheelDelta > 0) { + mouseWheelCount[0] = MIN (mouseWheelCount[0] + wheelDelta, maxCount); + currentMouseState.ScrolledUp = true; + } else if (wheelDelta < 0) { + mouseWheelCount[1] = MIN (mouseWheelCount[1] - wheelDelta, maxCount); + currentMouseState.ScrolledDown = true; + } + } break; } } return CallNextHookEx(keyboardHook, nCode, wParam, lParam); @@ -118,14 +136,17 @@ LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { void InitializeKeyboard () { - keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, nullptr, 0); + keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, InputProc, nullptr, 0); if (keyboardHook == nullptr) LogMessage (LogLevel::ERROR, "Failed to install keyboard hook!\n"); + mouseHook = SetWindowsHookEx(WH_MOUSE_LL, InputProc, nullptr, 0); + if (maxCount > 1) LogMessage (LogLevel::ERROR, "CHEATING MODE! max count is set to {}", maxCount); atexit (DisposeKeyboard); } void DisposeKeyboard () { if (keyboardHook) UnhookWindowsHookEx(keyboardHook); + if (mouseHook) UnhookWindowsHookEx(mouseHook); } // void @@ -201,7 +222,7 @@ CheckForegroundWindow (HWND processWindow) { } void -UpdatePoll (HWND windowHandle) { +UpdatePoll (HWND windowHandle, bool useController) { if (!CheckForegroundWindow (windowHandle)) return; currentMouseState.ScrolledUp = false; @@ -215,65 +236,67 @@ UpdatePoll (HWND windowHandle) { // GetCursorPos (¤tMouseState.Position); // ScreenToClient (windowHandle, ¤tMouseState.Position); - SDL_Event event; - SDL_GameController *controller; - while (SDL_PollEvent (&event) != 0) { - // LogMessage (LogLevel::DEBUG, "Receive SDL Event! type={}", (u64)event.type); - switch (event.type) { - case SDL_CONTROLLERDEVICEADDED: - if (!SDL_IsGameController (event.cdevice.which)) break; - controller = SDL_GameControllerOpen (event.cdevice.which); - if (!controller) { - LogMessage (LogLevel::ERROR, std::string ("Could not open gamecontroller ") + SDL_GameControllerNameForIndex (event.cdevice.which) - + ": " + SDL_GetError ()); - continue; - } - LogMessage (LogLevel::DEBUG, "Controller connected!"); - controllers[event.cdevice.which] = controller; - break; - case SDL_CONTROLLERDEVICEREMOVED: - LogMessage (LogLevel::DEBUG, "Controller removed!"); - if (!SDL_IsGameController (event.cdevice.which)) break; - SDL_GameControllerClose (controllers[event.cdevice.which]); - break; - case SDL_MOUSEWHEEL: - if (wndForeground) { - // LogMessage (LogLevel::DEBUG, "Mouse Wheel moves {}", event.wheel.y); - if (event.wheel.y > 0) { - mouseWheelCount[0] = MIN (mouseWheelCount[0] + event.wheel.y, maxCount); - mouseWheelCount[1] = 0; - currentMouseState.ScrolledUp = true; - } else if (event.wheel.y < 0) { - mouseWheelCount[1] = MIN (mouseWheelCount[1] - event.wheel.y, maxCount); - mouseWheelCount[0] = 0; - currentMouseState.ScrolledDown = true; + if (useController) { + SDL_Event event; + SDL_GameController *controller; + while (SDL_PollEvent (&event) != 0) { + // LogMessage (LogLevel::DEBUG, "Receive SDL Event! type={}", (u64)event.type); + switch (event.type) { + case SDL_CONTROLLERDEVICEADDED: + if (!SDL_IsGameController (event.cdevice.which)) break; + controller = SDL_GameControllerOpen (event.cdevice.which); + if (!controller) { + LogMessage (LogLevel::ERROR, std::string ("Could not open gamecontroller ") + SDL_GameControllerNameForIndex (event.cdevice.which) + + ": " + SDL_GetError ()); + continue; } - } - break; - case SDL_CONTROLLERBUTTONUP: - // keyup will accepted even if you're not focus in this window - currentControllerButtonsState[event.cbutton.button] = false; break; - case SDL_CONTROLLERBUTTONDOWN: - if (wndForeground) { - if (!currentControllerButtonsState[event.cbutton.button]) { - controllerCount[event.cbutton.button] = MIN (controllerCount[event.cbutton.button] + 1, maxCount); - } - currentControllerButtonsState[event.cbutton.button] = true; - } else LogMessage (LogLevel::WARN, "Controller button pressed but window not focused!"); - break; - case SDL_CONTROLLERAXISMOTION: - float sensorValue = event.caxis.value == 0 ? 0 : event.caxis.value / (event.caxis.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; + LogMessage (LogLevel::DEBUG, "Controller connected!"); + controllers[event.cdevice.which] = controller; + break; + case SDL_CONTROLLERDEVICEREMOVED: + LogMessage (LogLevel::DEBUG, "Controller removed!"); + if (!SDL_IsGameController (event.cdevice.which)) break; + SDL_GameControllerClose (controllers[event.cdevice.which]); + break; + // case SDL_MOUSEWHEEL: + // if (wndForeground) { + // // LogMessage (LogLevel::DEBUG, "Mouse Wheel moves {}", event.wheel.y); + // if (event.wheel.y > 0) { + // mouseWheelCount[0] = MIN (mouseWheelCount[0] + event.wheel.y, maxCount); + // // mouseWheelCount[1] = 0; + // currentMouseState.ScrolledUp = true; + // } else if (event.wheel.y < 0) { + // mouseWheelCount[1] = MIN (mouseWheelCount[1] - event.wheel.y, maxCount); + // // mouseWheelCount[0] = 0; + // currentMouseState.ScrolledDown = true; + // } + // } + // break; + case SDL_CONTROLLERBUTTONUP: + // keyup will accepted even if you're not focus in this window + currentControllerButtonsState[event.cbutton.button] = false; break; + case SDL_CONTROLLERBUTTONDOWN: + if (wndForeground) { + if (!currentControllerButtonsState[event.cbutton.button]) { + controllerCount[event.cbutton.button] = MIN (controllerCount[event.cbutton.button] + 1, maxCount); + } + currentControllerButtonsState[event.cbutton.button] = true; + } else LogMessage (LogLevel::WARN, "Controller button pressed but window not focused!"); + break; + case SDL_CONTROLLERAXISMOTION: + float sensorValue = event.caxis.value == 0 ? 0 : event.caxis.value / (event.caxis.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; + } } + break; } - break; } } }