From a2fc72180dc37f91005e4de4c40e6249e141f930 Mon Sep 17 00:00:00 2001 From: ptmaster Date: Tue, 24 Dec 2024 00:41:40 +0800 Subject: [PATCH] Implement Card Only selection to Mode Unlock | fix mouse laggy on crash issue --- src/bnusio.cpp | 25 ++++++++--- src/patches/language.cpp | 1 - src/patches/versions/JPN39.cpp | 31 ++++++++++---- src/poll.h | 1 - src/pollasync.cpp | 78 +++++++++++++++++----------------- 5 files changed, 81 insertions(+), 55 deletions(-) diff --git a/src/bnusio.cpp b/src/bnusio.cpp index dcbb38f..b8f93e9 100644 --- a/src/bnusio.cpp +++ b/src/bnusio.cpp @@ -63,7 +63,8 @@ bool inited = false; bool updateByCoin = false; HWND windowHandle = nullptr; float axisThreshold = 0.6f; -u8 inputState = 0; +u8 inputState = 1 | (1 << 2); +bool globalKeyboard = false;; HKL currentLayout; namespace bnusio { @@ -304,11 +305,20 @@ UpdateLoop () { UpdatePoll (windowHandle); #endif std::vector buffer = {}; - if (IsButtonTapped (COIN_ADD)) coin_count++; - if (IsButtonTapped (SERVICE)) service_count++; - if (IsButtonTapped (TEST)) testEnabled = !testEnabled; + if (IsButtonTapped (COIN_ADD)) { + LogMessage (LogLevel::DEBUG, "Insert Coin!"); + coin_count++; + } + if (IsButtonTapped (SERVICE)) { + LogMessage (LogLevel::DEBUG, "Insert Severice Coin!"); + service_count++; + } + if (IsButtonTapped (TEST)) { + LogMessage (LogLevel::INFO, "Enter TestMode by Press TestMode Button!"); + testEnabled = !testEnabled; + } if (exited == 0 && IsButtonTapped (EXIT)) { - LogMessage (LogLevel::INFO, "Exit By Press Exit Button!"); + LogMessage (LogLevel::INFO, "Exit by Press Exit Button!"); exited += 1; testEnabled = 1; std::thread([](){patches::Plugins::Exit ();}).detach(); } if (GameVersion::CHN00 == gameVersion) { @@ -341,6 +351,7 @@ Init () { if (const auto controller = openConfigSection (config, "controller")) { drumWaitPeriod = static_cast (readConfigInt (controller, "wait_period", drumWaitPeriod)); analogInput = readConfigBool (controller, "analog_input", analogInput); + globalKeyboard = readConfigBool (controller, "global_keyboard", globalKeyboard); } auto graphics = openConfigSection (config, "graphics"); if (graphics) { @@ -369,6 +380,7 @@ Init () { const auto keyConfigPath = std::filesystem::current_path () / "keyconfig.toml"; const std::unique_ptr keyConfig_ptr (openConfig (keyConfigPath), toml_free); if (keyConfig_ptr) { + inputState = 0; if (analogInput) inputState |= (1 << 2); const toml_table_t *keyConfig = keyConfig_ptr.get (); SetConfigValue (keyConfig, "EXIT", &EXIT, &inputState); @@ -395,6 +407,9 @@ Init () { SetConfigValue (keyConfig, "P2_RIGHT_BLUE", &P2_RIGHT_BLUE, &inputState); } + LogMessage (LogLevel::INFO, "Finish Loading keyconfig.toml useKeyboard={} useMouse={} useController={}", + (inputState & 1) ? "true" : "false", (inputState & (1 << 1)) ? "true" : "false", (inputState & (1 << 2)) ? "true" : "false"); + if (!emulateUsio && !exists (std::filesystem::current_path () / "bnusio_original.dll")) { emulateUsio = true; LogMessage (LogLevel::ERROR, "bnusio_original.dll not found! usio emulation enabled"); diff --git a/src/patches/language.cpp b/src/patches/language.cpp index 8b787a6..513eb18 100644 --- a/src/patches/language.cpp +++ b/src/patches/language.cpp @@ -117,7 +117,6 @@ Init () { L"/root/menu[@id='OthersMenu']/layout[@type='Center']/select-item[@id='LanguageItem']", [](pugi::xml_node &node) { node.attribute (L"max").set_value (L"4"); - node.attribute (L"default").set_value (L"4"); node.attribute (L"replace-text").set_value (L"0:JPN, 1:ENG, 2:zh-tw, 3:KOR, 4:zh-cn"); }, [&](){ // load_setting diff --git a/src/patches/versions/JPN39.cpp b/src/patches/versions/JPN39.cpp index d3ab4e3..62a79d4 100644 --- a/src/patches/versions/JPN39.cpp +++ b/src/patches/versions/JPN39.cpp @@ -59,12 +59,23 @@ FAST_HOOK (i64, DeviceCheck, ASLR (0x140464FC0), i64 a1, i64 a2, i64 a3) { } i64 -GetUserStatus () { +GetPlayererCount () { if (appAccessor) { if (const u64 playDataManager = RefPlayDataManager (appAccessor)) return GetUserCount (playDataManager); } return -1; } +boolean +HaveCardPlayer () { + if (appAccessor) { + if (const u64 playDataManager = RefPlayDataManager (appAccessor)) { + int p1PlayerType = *(i32 *)(*(i64 *)(playDataManager + 9920) + 4); + int p2PlayerType = *(i32 *)(*(i64 *)(playDataManager + 9928) + 4); + return p1PlayerType == 2 || p2PlayerType == 2; + } + } + return false; +} TestMode::Value *unlockSongs = TestMode::CreateValue (L"ModUnlockSongs"); FAST_HOOK (bool, IsSongRelease, ASLR (0x1403F4510), i64 a1, i64 a2, int a3) { @@ -89,7 +100,8 @@ FAST_HOOK (i64, AvailableMode_Collabo024, ASLR (0x1402DE710), i64 a1) { const int tournamentMode = tournmentMode->Read (); if (tournamentMode == 1) return originalAvailableMode_Collabo024.fastcall (a1); const int status = mode024->Read (); - if (status == 1 && GetUserStatus () == 1) return lua_pushbool (a1, true); + if (status == 1 && GetPlayererCount () == 1) return lua_pushbool (a1, true); + else if (status == 2 && GetPlayererCount () == 1 && HaveCardPlayer ()) return lua_pushbool (a1, true); return originalAvailableMode_Collabo024.fastcall (a1); } FAST_HOOK (i64, AvailableMode_Collabo025, ASLR (0x1402DE6B0), i64 a1) { @@ -97,7 +109,8 @@ FAST_HOOK (i64, AvailableMode_Collabo025, ASLR (0x1402DE6B0), i64 a1) { const int tournamentMode = tournmentMode->Read (); if (tournamentMode == 1) return originalAvailableMode_Collabo025.fastcall (a1); const int status = mode025->Read (); - if (status == 1 && GetUserStatus () == 1) return lua_pushbool (a1, true); + if (status == 1 && GetPlayererCount () == 1) return lua_pushbool (a1, true); + else if (status == 2 && GetPlayererCount () == 1 && HaveCardPlayer ()) return lua_pushbool (a1, true); return originalAvailableMode_Collabo025.fastcall (a1); } FAST_HOOK (i64, AvailableMode_Collabo026, ASLR (0x1402DE670), i64 a1) { @@ -105,7 +118,8 @@ FAST_HOOK (i64, AvailableMode_Collabo026, ASLR (0x1402DE670), i64 a1) { const int tournamentMode = tournmentMode->Read (); if (tournamentMode == 1) return originalAvailableMode_Collabo026.fastcall (a1); const int status = mode026->Read (); - if (status == 1 && GetUserStatus () == 1) return lua_pushbool (a1, true); + if (status == 1 && GetPlayererCount () == 1) return lua_pushbool (a1, true); + else if (status == 2 && GetPlayererCount () == 1 && HaveCardPlayer ()) return lua_pushbool (a1, true); return originalAvailableMode_Collabo026.fastcall (a1); } FAST_HOOK (i64, AvailableMode_AprilFool001, ASLR (0x1402DE5B0), i64 a1) { @@ -114,6 +128,7 @@ FAST_HOOK (i64, AvailableMode_AprilFool001, ASLR (0x1402DE5B0), i64 a1) { if (tournamentMode == 1) return originalAvailableMode_AprilFool001.fastcall (a1); const int status = modeApril001->Read (); if (status == 1) return lua_pushbool (a1, true); + else if (status == 2 && HaveCardPlayer ()) return lua_pushbool (a1, true); return originalAvailableMode_AprilFool001.fastcall (a1); } TestMode::Value *freezeTimer = TestMode::CreateValue (L"ModFreezeTimer"); @@ -351,22 +366,22 @@ Init () { // TestMode::Menu *modeUnlock = TestMode::CreateMenu (L"MODE UNLOCK", L"ModeUnlockMenu"); TestMode::RegisterItem ( L"", + L"2:CARD ONLY\" group=\"Setting\" id=\"ModModeCollabo024\" max=\"2\" min=\"0\" default=\"0\"/>", [&] { INSTALL_FAST_HOOK (AvailableMode_Collabo024); }//, modeUnlock ); TestMode::RegisterItem ( L"", + L"1:ENABLE, 2:CARD ONLY\" group=\"Setting\" id=\"ModModeCollabo025\" max=\"2\" min=\"0\" default=\"0\"/>", [&] { INSTALL_FAST_HOOK (AvailableMode_Collabo025); }//, modeUnlock ); TestMode::RegisterItem ( L"", + L"1:ENABLE, 2:CARD ONLY\" group=\"Setting\" id=\"ModModeCollabo026\" max=\"2\" min=\"0\" default=\"0\"/>", [&] { INSTALL_FAST_HOOK (AvailableMode_Collabo026); }//, modeUnlock ); TestMode::RegisterItem ( L"", + L"2:CARD ONLY\" group=\"Setting\" id=\"ModModeAprilFool001\" max=\"2\" min=\"0\" default=\"0\"/>", [&] { INSTALL_FAST_HOOK (AvailableMode_AprilFool001); }//, modeUnlock ); // TestMode::RegisterItem (modeUnlock); diff --git a/src/poll.h b/src/poll.h index 90ec0ac..dc92682 100644 --- a/src/poll.h +++ b/src/poll.h @@ -110,5 +110,4 @@ bool IsButtonReleased (const Keybindings &bindings); #else void UpdatePoll (HWND windowHandle); void InitializeKeyboard (); -void DisposeKeyboard (); #endif \ No newline at end of file diff --git a/src/pollasync.cpp b/src/pollasync.cpp index 1366a33..9bc5422 100644 --- a/src/pollasync.cpp +++ b/src/pollasync.cpp @@ -9,8 +9,13 @@ extern bool jpLayout; extern int exited; extern u8 inputState; extern float axisThreshold; +extern bool globalKeyboardInput; bool wndForeground = false; +bool usingKeyboard = false; +bool usingMouse = false; +bool usingController = false; +bool usingSDLEvent = false; bool currentKeyboardState[0xFF] = { false }; uint8_t keyboardCount[0xFF] = { 0 }; @@ -125,17 +130,6 @@ LRESULT CALLBACK InputProc(int nCode, WPARAM wParam, LPARAM 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] = std::min (mouseWheelCount[0] + wheelDelta, maxCount); - currentMouseState.ScrolledUp = true; - } else if (wheelDelta < 0) { - mouseWheelCount[1] = std::min (mouseWheelCount[1] - wheelDelta, maxCount); - currentMouseState.ScrolledDown = true; - } - } break; default: break; } } @@ -171,16 +165,11 @@ void KeyboardMainLoop() { HINSTANCE hInstance = GetModuleHandle(NULL); HWND hwnd = CreateInvisibleWindow(hInstance); if (!hwnd) LogMessage (LogLevel::ERROR, "Failed to create window!\n"); - if (inputState & 1) { + if (usingKeyboard) { keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, InputProc, nullptr, 0); if (keyboardHook == nullptr) LogMessage (LogLevel::ERROR, "Failed to install keyboard hook!\n"); else LogMessage (LogLevel::INFO, "KeyboardLL hook installed!"); } - if (inputState & (1 << 1)) { - mouseHook = SetWindowsHookEx(WH_MOUSE_LL, InputProc, nullptr, 0); - if (mouseHook == nullptr) LogMessage (LogLevel::ERROR, "Failed to install mouse hook!\n"); - else LogMessage (LogLevel::INFO, "MouseLL hook installed!"); - } if (maxCount > 2) LogMessage (LogLevel::ERROR, "CHEATING MODE! max count is set to {}", maxCount); LogMessage (LogLevel::WARN, "(experimental) Using Async IO!"); MSG msg; @@ -189,22 +178,15 @@ void KeyboardMainLoop() { DispatchMessage(&msg); } if (keyboardHook) UnhookWindowsHookEx(keyboardHook); - if (mouseHook) UnhookWindowsHookEx(mouseHook); } void InitializeKeyboard () { - if (inputState & (1 | 1 << 1)) { + if (usingKeyboard) { std::thread (KeyboardMainLoop).detach (); } } -void -DisposeKeyboard () { - // if (keyboardHook) UnhookWindowsHookEx(keyboardHook); - // if (mouseHook) UnhookWindowsHookEx(mouseHook); -} - void CheckFlipped (uint32_t which, SDL_Gamepad *gamepad) { if (SDL_GetGamepadButtonLabel(gamepad, SDL_GAMEPAD_BUTTON_SOUTH) == SDL_GAMEPAD_BUTTON_LABEL_B) { @@ -214,8 +196,13 @@ CheckFlipped (uint32_t which, SDL_Gamepad *gamepad) { bool InitializePoll (HWND windowHandle) { + usingKeyboard = inputState & 1; + usingMouse = inputState & (1 << 1); + usingController = inputState & (1 << 2); + usingSDLEvent = usingMouse || usingController; + InitializeKeyboard (); - if (inputState & (1 << 2)) { + if (usingSDLEvent) { LogMessage (LogLevel::DEBUG, "InitializePoll"); bool hasRumble = true; wndForeground = windowHandle == GetForegroundWindow (); @@ -303,31 +290,42 @@ void UpdatePoll (HWND windowHandle) { if (!CheckForegroundWindow (windowHandle)) return; - if ((inputState & 1) && keyboardClean) { + if (usingKeyboard && keyboardClean) { keyboardClean = false; for (int i=0; i<0xFF; i++) keyboardCount[i] -= (bool)keyboardDiff[i]; memset (keyboardDiff, 0, 0XFF); } - if (inputState & (1 << 1)) { - currentMouseState.ScrolledUp = false; - currentMouseState.ScrolledDown = false; - if (mouseWheelCount[0] > 0) mouseWheelCount[0] -= (bool)mouseWheelDiff[0]; - if (mouseWheelCount[1] > 0) mouseWheelCount[1] -= (bool)mouseWheelDiff[1]; - memset (mouseWheelDiff, 0, 2); - } - // GetCursorPos (¤tMouseState.Position); // ScreenToClient (windowHandle, ¤tMouseState.Position); - if (inputState & (1 << 2)) { - for (int i=0; i 0) mouseWheelCount[0] -= (bool)mouseWheelDiff[0]; + if (mouseWheelCount[1] > 0) mouseWheelCount[1] -= (bool)mouseWheelDiff[1]; + memset (mouseWheelDiff, 0, 2); + } + + if (usingController) { + for (int i=0; i 0) { + mouseWheelCount[0] = std::min (mouseWheelCount[0] + 1, maxCount); + currentMouseState.ScrolledUp = true; + } else if (event.wheel.y < 0) { + mouseWheelCount[1] = std::min (mouseWheelCount[1] + 1, maxCount); + currentMouseState.ScrolledDown = true; + } + } break; case SDL_EVENT_GAMEPAD_ADDED: if (!SDL_IsGamepad (event.gdevice.which)) break; controller = SDL_OpenGamepad (event.gdevice.which);