From 4110db8572e0cb6459899646a12777e06ec2958c Mon Sep 17 00:00:00 2001 From: piebot Date: Thu, 13 Aug 2026 09:09:09 +0300 Subject: [PATCH 1/5] add kbm support --- 4J_Input/Windows64/4J_Input.cpp | 180 ++++++++++++++++++++++ 4J_Input/Windows64/INP_Keyboard.cpp | 226 +++++++++++++++++++++++++++- 4J_Input/Windows64/INP_Keyboard.h | 78 +++++++++- 4J_Input/Windows64/INP_Main.cpp | 57 ++++--- 4J_Input/Windows64/INP_Main.h | 5 + Headers/Windows64/4J_Input.h | 52 ++++++- 6 files changed, 575 insertions(+), 23 deletions(-) diff --git a/4J_Input/Windows64/4J_Input.cpp b/4J_Input/Windows64/4J_Input.cpp index de642c5..14708b2 100644 --- a/4J_Input/Windows64/4J_Input.cpp +++ b/4J_Input/Windows64/4J_Input.cpp @@ -32,6 +32,7 @@ CKeyboard InternalKeyboard; void C_4JInput::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC) { InternalInputManager.Initialise(iInputStateC, ucMapC, ucActionC, ucMenuActionC); + InternalKeyboard.Init(); } void C_4JInput::Tick(void) @@ -39,6 +40,10 @@ void C_4JInput::Tick(void) InternalInputManager.Tick(); } +void C_4JInput::TickKBM(void) +{ + InternalKeyboard.Tick(); +} void C_4JInput::SetDeadzoneAndMovementRange(unsigned int uiDeadzone, unsigned int uiMovementRangeMax) { InternalInputManager.SetDeadzoneAndMovementRange(uiDeadzone, uiMovementRangeMax); @@ -74,6 +79,11 @@ unsigned int C_4JInput::GetValue(int iPad, unsigned char ucAction, bool bRepeat) return InternalInputManager.GetValue(iPad, ucAction, bRepeat); } +void C_4JInput::MapTouchInput(int iPad, int button) +{ + InternalInputManager.MapTouchInput(iPad, button); +} + bool C_4JInput::ButtonPressed(int iPad, unsigned char ucAction) { return InternalInputManager.ButtonPressed(iPad, ucAction); @@ -119,6 +129,11 @@ bool C_4JInput::IsPadConnected(int iPad) return InternalInputManager.IsPadConnected(iPad); } +bool C_4JInput::IsPadActive(int iPad) +{ + return InternalInputManager.IsPadActive(iPad); +} + float C_4JInput::GetJoypadStick_LX(int iPad, bool bCheckMenuDisplay) { return InternalInputManager.GetJoypadStick_LX(iPad, bCheckMenuDisplay); @@ -154,6 +169,171 @@ void C_4JInput::SetMenuDisplayed(int iPad, bool bVal) InternalInputManager.SetMenuDisplayed(iPad, bVal); } +void C_4JInput::OnKeyDown(int vkCode) +{ + InternalKeyboard.OnKeyDown(vkCode); +} + +void C_4JInput::OnKeyUp(int vkCode) +{ + InternalKeyboard.OnKeyUp(vkCode); +} + +void C_4JInput::OnChar(wchar_t ch) +{ + InternalKeyboard.OnChar(ch); +} + +bool C_4JInput::IsKeyDown(int vkCode) const +{ + return InternalKeyboard.IsKeyDown(vkCode); +} + +bool C_4JInput::IsKeyPressed(int vkCode) const +{ + return InternalKeyboard.IsKeyPressed(vkCode); +} + +bool C_4JInput::IsKeyReleased(int vkCode) const +{ + return InternalKeyboard.IsKeyReleased(vkCode); +} + +int C_4JInput::GetMouseX() const +{ + return InternalKeyboard.GetMouseX(); +} + +int C_4JInput::GetMouseY() const +{ + return InternalKeyboard.GetMouseY(); +} + +bool C_4JInput::IsMouseLDown() const +{ + return InternalKeyboard.IsLButtonDown(); +} + +bool C_4JInput::IsLButtonPressed() const +{ + return InternalKeyboard.IsLButtonPressed(); +} + +bool C_4JInput::IsLButtonReleased() const +{ + return InternalKeyboard.IsLButtonReleased(); +} + +bool C_4JInput::IsMouseRDown() const +{ + return InternalKeyboard.IsRButtonDown(); +} + +bool C_4JInput::IsRButtonPressed() const +{ + return InternalKeyboard.IsRButtonPressed(); +} + +bool C_4JInput::IsRButtonReleased() const +{ + return InternalKeyboard.IsRButtonReleased(); +} + +int C_4JInput::GetMouseWheelDelta() const +{ + return InternalKeyboard.GetMouseWheelDelta(); +} + +wchar_t C_4JInput::GetLastChar() const +{ + return InternalKeyboard.GetLastChar(); +} + +bool C_4JInput::HasChar() const +{ + return InternalKeyboard.HasChar(); +} + +wchar_t C_4JInput::GetChar(int index) const +{ + return InternalKeyboard.GetChar(index); +} + +void C_4JInput::OnMouseMove(int x, int y) +{ + InternalKeyboard.OnMouseMove(x, y); +} + +void C_4JInput::OnRawMouseDelta(int dx, int dy) +{ + InternalKeyboard.OnRawMouseDelta(dx, dy); +} + +void C_4JInput::OnLButtonDown(int x, int y) +{ + InternalKeyboard.OnLButtonDown(x, y); +} + +void C_4JInput::OnLButtonUp(int x, int y) +{ + InternalKeyboard.OnLButtonUp(x, y); +} + +void C_4JInput::OnRButtonDown(int x, int y) +{ + InternalKeyboard.OnRButtonDown(x, y); +} + +void C_4JInput::OnRButtonUp(int x, int y) +{ + InternalKeyboard.OnRButtonUp(x, y); +} + +void C_4JInput::OnMButtonDown(int x, int y) +{ + InternalKeyboard.OnMButtonDown(x, y); +} + +void C_4JInput::OnMButtonUp(int x, int y) +{ + InternalKeyboard.OnMButtonUp(x, y); +} + +void C_4JInput::OnMouseWheel(int delta, int x, int y) +{ + InternalKeyboard.OnMouseWheel(delta, x, y); +} + +void C_4JInput::SetMouseCaptured(bool captured) +{ + InternalKeyboard.SetMouseCaptured(captured); +} + +void C_4JInput::SetWindowFocused(bool focused) +{ + InternalKeyboard.SetWindowFocused(focused); +} + +bool C_4JInput::IsMouseCaptured() const +{ + return InternalKeyboard.IsMouseCaptured(); +} + +void C_4JInput::SetMousePos(int x, int y) +{ + InternalKeyboard.SetMousePos(x, y); +} + +int C_4JInput::GetRawMouseX() const +{ + return InternalKeyboard.GetRawMouseX(); +} + +int C_4JInput::GetRawMouseY() const +{ + return InternalKeyboard.GetRawMouseY(); +} + EKeyboardResult C_4JInput::RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int (*Func)(LPVOID, const bool), LPVOID lpParam, C_4JInput::EKeyboardMode eMode) { diff --git a/4J_Input/Windows64/INP_Keyboard.cpp b/4J_Input/Windows64/INP_Keyboard.cpp index 88591ae..ed4ee43 100644 --- a/4J_Input/Windows64/INP_Keyboard.cpp +++ b/4J_Input/Windows64/INP_Keyboard.cpp @@ -24,7 +24,231 @@ SOFTWARE. #include "INP_Keyboard.h" -void CKeyboard::Tick(void) {} +CKeyboard::CKeyboard() +{ + m_lParam = nullptr; + m_onInput = nullptr; + ZeroMemory(m_chrText, sizeof(m_chrText)); + + memset(m_keysPrev, 0, sizeof(m_keysPrev)); + memset(m_keysCurr, 0, sizeof(m_keysCurr)); + m_mouseX = m_mouseY = 0; + m_lButtonPrev = m_lButtonCurr = false; + m_rButtonPrev = m_rButtonCurr = false; + m_mButtonPrev = m_mButtonCurr = false; + m_mouseWheel = 0; + memset(m_charBuffer, 0, sizeof(m_charBuffer)); + m_charCount = 0; + m_mouseCaptured = false; + m_mouseDeltaX = m_mouseDeltaY = 0; + m_windowFocused = true; +} + +void CKeyboard::Init() +{ + RAWINPUTDEVICE rid; + rid.usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC + rid.usUsage = 0x02; // HID_USAGE_GENERIC_MOUSE + rid.dwFlags = 0; + rid.hwndTarget = g_hWnd; + RegisterRawInputDevices(&rid, 1, sizeof(rid)); +} + +void CKeyboard::Tick(void) +{ + memcpy(m_keysPrev, m_keysCurr, sizeof(m_keysCurr)); + m_lButtonPrev = m_lButtonCurr; + m_rButtonPrev = m_rButtonCurr; + m_mButtonPrev = m_mButtonCurr; + m_mouseWheel = 0; + m_charCount = 0; + m_mouseDeltaX = m_mouseDeltaAccumX; + m_mouseDeltaY = m_mouseDeltaAccumY; + m_mouseDeltaAccumX = 0; + m_mouseDeltaAccumY = 0; + + if (m_mouseCaptured && g_hWnd && m_windowFocused && g_hWnd) + { + RECT rc; + GetClientRect(g_hWnd, &rc); + POINT center; + center.x = (rc.right - rc.left) / 2; + center.y = (rc.bottom - rc.top) / 2; + ClientToScreen(g_hWnd, ¢er); + SetCursorPos(center.x, center.y); + } +} + +void CKeyboard::OnKeyDown(int vkCode) +{ + if (vkCode >= 0 && vkCode < MAX_KEYS) + { + m_keysCurr[vkCode] = true; + } +} + +void CKeyboard::OnKeyUp(int vkCode) +{ + if (vkCode >= 0 && vkCode < MAX_KEYS) + { + m_keysCurr[vkCode] = false; + } +} + +void CKeyboard::OnChar(wchar_t ch) +{ + if (m_charCount < MAX_CHARS_PER_FRAME) + { + m_charBuffer[m_charCount++] = ch; + } +} + +bool CKeyboard::IsKeyDown(int vkCode) const +{ + if (vkCode >= 0 && vkCode < MAX_KEYS) + return m_keysCurr[vkCode]; + return false; +} + +bool CKeyboard::IsKeyPressed(int vkCode) const +{ + if (vkCode >= 0 && vkCode < MAX_KEYS) + return m_keysCurr[vkCode] && !m_keysPrev[vkCode]; + return false; +} + +bool CKeyboard::IsKeyReleased(int vkCode) const +{ + if (vkCode >= 0 && vkCode < MAX_KEYS) + return !m_keysCurr[vkCode] && m_keysPrev[vkCode]; + return false; +} + +void CKeyboard::OnMouseMove(int x, int y) +{ + m_mouseX = x; + m_mouseY = y; +} + +void CKeyboard::OnRawMouseDelta(int dx, int dy) +{ + m_mouseDeltaAccumX += dx; + m_mouseDeltaAccumY += dy; +} + +void CKeyboard::OnLButtonDown(int x, int y) +{ + m_mouseX = x; + m_mouseY = y; + m_lButtonCurr = true; +} + +void CKeyboard::OnLButtonUp(int x, int y) +{ + m_mouseX = x; + m_mouseY = y; + m_lButtonCurr = false; +} + +void CKeyboard::OnRButtonDown(int x, int y) +{ + m_mouseX = x; + m_mouseY = y; + m_rButtonCurr = true; +} + +void CKeyboard::OnRButtonUp(int x, int y) +{ + m_mouseX = x; + m_mouseY = y; + m_rButtonCurr = false; +} + +void CKeyboard::OnMButtonDown(int x, int y) +{ + m_mouseX = x; + m_mouseY = y; + m_mButtonCurr = true; +} + +void CKeyboard::OnMButtonUp(int x, int y) +{ + m_mouseX = x; + m_mouseY = y; + m_mButtonCurr = false; +} + +void CKeyboard::OnMouseWheel(int delta, int x, int y) +{ + m_mouseX = x; + m_mouseY = y; + m_mouseWheel += delta; +} + +void CKeyboard::SetMouseCaptured(bool grabbed) +{ + if (m_mouseCaptured == grabbed) + return; + + m_mouseCaptured = grabbed; + if (grabbed && g_hWnd) + { + while (ShowCursor(FALSE) >= 0) {} + RECT rc; + GetClientRect(g_hWnd, &rc); + POINT topLeft = { rc.left, rc.top }; + POINT bottomRight = { rc.right, rc.bottom }; + ClientToScreen(g_hWnd, &topLeft); + ClientToScreen(g_hWnd, &bottomRight); + RECT clipRect = { topLeft.x, topLeft.y, bottomRight.x, bottomRight.y }; + ClipCursor(&clipRect); + + GetClientRect(g_hWnd, &rc); + POINT center; + center.x = (rc.right - rc.left) / 2; + center.y = (rc.bottom - rc.top) / 2; + ClientToScreen(g_hWnd, ¢er); + SetCursorPos(center.x, center.y); + + m_mouseDeltaAccumX = 0; + m_mouseDeltaAccumY = 0; + } + else if (!grabbed && g_hWnd) + { + while (ShowCursor(TRUE) < 0) {} + ClipCursor(nullptr); + } +} + +void CKeyboard::SetWindowFocused(bool focused) +{ + m_windowFocused = focused; + if (focused) + { + if (m_mouseCaptured) + { + while (ShowCursor(FALSE) >= 0) {} + RECT rc; + GetClientRect(g_hWnd, &rc); + POINT center; + center.x = (rc.right - rc.left) / 2; + center.y = (rc.bottom - rc.top) / 2; + ClientToScreen(g_hWnd, ¢er); + SetCursorPos(center.x, center.y); + } + else + { + while (ShowCursor(TRUE) < 0) {} + ClipCursor(nullptr); + } + } + else + { + while (ShowCursor(TRUE) < 0) {} + ClipCursor(nullptr); + } +} + EKeyboardResult CKeyboard::RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int (*Func)(LPVOID, const bool), LPVOID lpParam, C_4JInput::EKeyboardMode eMode) diff --git a/4J_Input/Windows64/INP_Keyboard.h b/4J_Input/Windows64/INP_Keyboard.h index f6e00de..1e3a021 100644 --- a/4J_Input/Windows64/INP_Keyboard.h +++ b/4J_Input/Windows64/INP_Keyboard.h @@ -32,6 +32,8 @@ void SeedEditBox(); class CKeyboard { public: + CKeyboard(); + enum EKeyboardProcessState { }; @@ -40,11 +42,83 @@ public: { }; - void Tick(void); + void Init(); + void Tick(); - EKeyboardResult RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int (*Func)(LPVOID, const bool), LPVOID lpParam, + void OnKeyDown(int vkCode); + void OnKeyUp(int vkCode); + void OnChar(wchar_t ch); + + void OnMouseMove(int x, int y); + void OnRawMouseDelta(int dx, int dy); + void OnLButtonDown(int x, int y); + void OnLButtonUp(int x, int y); + void OnRButtonDown(int x, int y); + void OnRButtonUp(int x, int y); + void OnMButtonDown(int x, int y); + void OnMButtonUp(int x, int y); + void OnMouseWheel(int delta, int x, int y); + + bool IsKeyDown(int vkCode) const; + bool IsKeyPressed(int vkCode) const; + bool IsKeyReleased(int vkCode) const; + + int GetMouseX() const { return m_mouseX; } + int GetMouseY() const { return m_mouseY; } + + int GetRawMouseX() const { return m_mouseDeltaX; } + int GetRawMouseY() const { return m_mouseDeltaY; } + + bool IsLButtonDown() const { return m_lButtonCurr; } + bool IsLButtonPressed() const { return m_lButtonCurr && !m_lButtonPrev; } + bool IsLButtonReleased() const { return !m_lButtonCurr && m_lButtonPrev; } + + bool IsRButtonDown() const { return m_rButtonCurr; } + bool IsRButtonPressed() const { return m_rButtonCurr && !m_rButtonPrev; } + bool IsRButtonReleased() const { return !m_rButtonCurr && m_rButtonPrev; } + + int GetMouseWheelDelta() const { return m_mouseWheel; } + + wchar_t GetLastChar() const { return m_charCount > 0 ? m_charBuffer[0] : 0; } + bool HasChar() const { return m_charCount > 0; } + int GetCharCount() const { return m_charCount; } + wchar_t GetChar(int index) const { return (index >= 0 && index < m_charCount) ? m_charBuffer[index] : 0; } + + void SetMouseCaptured(bool captured); + void SetWindowFocused(bool focused); + bool IsMouseCaptured() const { return m_mouseCaptured; } + + void SetMousePos(int x, int y) { m_mouseX = x; m_mouseY = y; } + + EKeyboardResult RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int (*Func)(LPVOID, const bool), LPVOID lpParam, C_4JInput::EKeyboardMode eMode); void GetText(uint16_t *UTF16String); + BYTE gap0[0x68]; +private: + static const int MAX_KEYS = 256; + static const int MAX_CHARS_PER_FRAME = 32; + + bool m_keysPrev[MAX_KEYS]; + bool m_keysCurr[MAX_KEYS]; + + int m_mouseX, m_mouseY; + bool m_lButtonPrev, m_lButtonCurr; + bool m_rButtonPrev, m_rButtonCurr; + bool m_mButtonPrev, m_mButtonCurr; + int m_mouseWheel; + + wchar_t m_charBuffer[MAX_CHARS_PER_FRAME]; + int m_charCount; + + bool m_windowFocused; + bool m_mouseCaptured; + int m_mouseDeltaX, m_mouseDeltaY; + int m_mouseDeltaAccumX, m_mouseDeltaAccumY; + + wchar_t m_chrText[128]; + LPVOID m_lParam; + int (*m_onInput)(LPVOID, LPCWSTR); + }; \ No newline at end of file diff --git a/4J_Input/Windows64/INP_Main.cpp b/4J_Input/Windows64/INP_Main.cpp index f6070a6..d1f038b 100644 --- a/4J_Input/Windows64/INP_Main.cpp +++ b/4J_Input/Windows64/INP_Main.cpp @@ -30,8 +30,6 @@ SDL_Event event; CInput::CInput() { - m_Keyboard = CKeyboard(); - m_uiSigninJoypadMask = 0; for (int i = 0; i < 4; ++i) m_bIsMenuDisplayed[i] = 0; @@ -78,6 +76,8 @@ void CInput::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char uc m_Joypads[i].m_pucLeftTriggerAxisMap = &m_Joypads[i].m_ucLeftTriggerState; m_Joypads[i].m_pucRightTriggerAxisMap = &m_Joypads[i].m_ucRightTriggerState; m_Joypads[i].m_fSensitivity = 1.0f; + + m_iTouchInputButton[i] = 0; } m_JoypadMap = (unsigned int **)operator new[](ucMapC * sizeof(int *)); @@ -96,7 +96,6 @@ void CInput::Tick(void) { HandleGamepadEvents(); UpdateJoypads(); - m_Keyboard.Tick(); } void CInput::SetJoypadValues(JOYPAD *pThisPad) @@ -338,6 +337,11 @@ unsigned char CInput::GetJoypadMapVal(int iPad) return m_Joypads[iPad].m_ucMappingValue; } +void CInput::MapTouchInput(int iPad, int button) +{ + m_iTouchInputButton[iPad] |= button; +} + void CInput::SetJoypadStickAxisMap(int iPad, unsigned int uiFrom, unsigned int uiTo) { float *pfTo = nullptr; @@ -405,6 +409,11 @@ bool CInput::IsPadConnected(int iPad) return m_Joypads[iPad].m_bIsConnected; } +bool CInput::IsPadActive(int iPad) +{ + return m_Joypads[iPad].m_bControllerActive; +} + void CInput::SetSigninJoypadMask(unsigned int mask) { m_uiSigninJoypadMask = mask; @@ -756,27 +765,39 @@ bool CInput::UpdateJoypads() if (pThisPad->m_bIsConnected) { SetJoypadValues(pThisPad); - - pThisPad->m_uiButtonsPressed = ~pThisPad->m_uiOldButtons & pThisPad->m_uiButtons; - pThisPad->m_uiButtonsReleased = ~pThisPad->m_uiButtons & pThisPad->m_uiOldButtons; - - for (int bit = 0; bit < 24; ++bit) - { - if ((pThisPad->m_uiButtonsPressed & (1 << bit)) != 0) - { - GetStartTime(i, bit); - } - else if ((pThisPad->m_uiButtons & (1 << bit)) != 0) - { - UpdateTime(i, bit); - } - } } else if (pThisPad->m_bWasConnected) { ClearJoypadValues(pThisPad); } + if (m_iTouchInputButton[i]) + { + pThisPad->m_uiButtons |= m_iTouchInputButton[i]; + } + + m_iTouchInputButton[i] = 0; + + pThisPad->m_uiButtonsPressed = ~pThisPad->m_uiOldButtons & pThisPad->m_uiButtons; + pThisPad->m_uiButtonsReleased = ~pThisPad->m_uiButtons & pThisPad->m_uiOldButtons; + + for (int bit = 0; bit < 24; ++bit) + { + if ((pThisPad->m_uiButtonsPressed & (1 << bit)) != 0) + { + GetStartTime(i, bit); + } + else if ((pThisPad->m_uiButtons & (1 << bit)) != 0) + { + UpdateTime(i, bit); + } + } + + if (pThisPad->m_uiButtonsPressed) + pThisPad->m_bControllerActive = true; + else + pThisPad->m_bControllerActive = false; + if (m_pDebugSequenceFn && (pThisPad->m_uiButtonsPressed & (_360_JOY_BUTTON_A | _360_JOY_BUTTON_B | _360_JOY_BUTTON_X | _360_JOY_BUTTON_Y | _360_JOY_BUTTON_RB | _360_JOY_BUTTON_LB)) != 0) { diff --git a/4J_Input/Windows64/INP_Main.h b/4J_Input/Windows64/INP_Main.h index 68fc73e..c8608c9 100644 --- a/4J_Input/Windows64/INP_Main.h +++ b/4J_Input/Windows64/INP_Main.h @@ -58,6 +58,7 @@ public: bool m_bIsConnected; bool m_bWasConnected; bool m_bHasConnected; + bool m_bControllerActive; unsigned int m_uiButtons; unsigned int m_uiOldButtons; @@ -125,10 +126,12 @@ public: void SetJoypadMapVal(int iPad, unsigned char ucMap); unsigned char GetJoypadMapVal(int iPad); + void MapTouchInput(int iPad, int button); void SetJoypadStickAxisMap(int iPad, unsigned int uiFrom, unsigned int uiTo); void SetJoypadStickTriggerMap(int iPad, unsigned int uiFrom, unsigned int uiTo); bool IsPadConnected(int iPad); + bool IsPadActive(int iPad); void SetSigninJoypadMask(unsigned int mask); unsigned int GetValue(int iPad, unsigned char ucAction, bool bRepeat = false); bool IsSet(int iPad, unsigned char ucAction); @@ -202,6 +205,8 @@ public: unsigned int m_uiDebugSequenceIndex; int (*m_pDebugSequenceFn)(void *); LPVOID m_pDebugSequenceParam; + + unsigned int m_iTouchInputButton[MAX_JOYPADS]; }; // Singleton diff --git a/Headers/Windows64/4J_Input.h b/Headers/Windows64/4J_Input.h index 48e1a9a..38b10c3 100644 --- a/Headers/Windows64/4J_Input.h +++ b/Headers/Windows64/4J_Input.h @@ -101,6 +101,7 @@ public: void Initialise( int iInputStateC, unsigned char ucMapC,unsigned char ucActionC, unsigned char ucMenuActionC ); void Tick(void); + void TickKBM(void); void SetDeadzoneAndMovementRange(unsigned int uiDeadzone, unsigned int uiMovementRangeMax ); void SetGameJoypadMaps(unsigned char ucMap,unsigned char ucAction,unsigned int uiActionVal); unsigned int GetGameJoypadMaps(unsigned char ucMap,unsigned char ucAction); @@ -108,6 +109,7 @@ public: unsigned char GetJoypadMapVal(int iPad); void SetJoypadSensitivity(int iPad, float fSensitivity); unsigned int GetValue(int iPad,unsigned char ucAction, bool bRepeat=false); + void MapTouchInput(int iPad, int button); bool ButtonPressed(int iPad,unsigned char ucAction=255); // toggled bool ButtonReleased(int iPad,unsigned char ucAction); //toggled bool ButtonDown(int iPad,unsigned char ucAction=255); // button held down @@ -118,8 +120,8 @@ public: void SetDebugSequence( const char *chSequenceA,int( *Func)(LPVOID),LPVOID lpParam ); FLOAT GetIdleSeconds(int iPad); bool IsPadConnected(int iPad); + bool IsPadActive(int iPad); bool IsCircleCrossSwapped(); - // In-Game values which may have been remapped due to Southpaw, swap triggers, etc float GetJoypadStick_LX(int iPad, bool bCheckMenuDisplay=true); float GetJoypadStick_LY(int iPad, bool bCheckMenuDisplay=true); @@ -130,6 +132,51 @@ public: void SetMenuDisplayed(int iPad, bool bVal); + void OnKeyDown(int vkCode); + void OnKeyUp(int vkCode); + void OnChar(wchar_t ch); + + void OnMouseMove(int x, int y); + void OnRawMouseDelta(int dx, int dy); + void OnLButtonDown(int x, int y); + void OnLButtonUp(int x, int y); + void OnRButtonDown(int x, int y); + void OnRButtonUp(int x, int y); + void OnMButtonDown(int x, int y); + void OnMButtonUp(int x, int y); + void OnMouseWheel(int delta, int x, int y); + + bool IsKeyDown(int vkCode) const; + bool IsKeyPressed(int vkCode) const; + bool IsKeyReleased(int vkCode) const; + + int GetMouseX() const; + int GetMouseY() const; + + // PIEBOT: Used to be IsLButtonDown, changed so it doesnt conflict with windowx.h + bool IsMouseLDown() const; + bool IsLButtonPressed() const; + bool IsLButtonReleased() const; + + bool IsMouseRDown() const; + bool IsRButtonPressed() const; + bool IsRButtonReleased() const; + + int GetMouseWheelDelta() const; + + wchar_t GetLastChar() const; + bool HasChar() const; + int GetCharCount() const; + wchar_t GetChar(int index) const; + + void SetMouseCaptured(bool captured); + void SetWindowFocused(bool focused); + bool IsMouseCaptured() const; + + void SetMousePos(int x, int y); + + int GetRawMouseX() const; + int GetRawMouseY() const; // EKeyboardResult RequestKeyboard(UINT uiTitle, UINT uiText, UINT uiDesc, DWORD dwPad, WCHAR *pwchResult, UINT uiResultSize,int( *Func)(LPVOID,const bool),LPVOID lpParam,EKeyboardMode eMode,C4JStringTable *pStringTable=NULL); // EKeyboardResult RequestKeyboard(UINT uiTitle, LPCWSTR pwchDefault, UINT uiDesc, DWORD dwPad, WCHAR *pwchResult, UINT uiResultSize,int( *Func)(LPVOID,const bool),LPVOID lpParam, EKeyboardMode eMode,C4JStringTable *pStringTable=NULL); EKeyboardResult RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int( *Func)(LPVOID,const bool),LPVOID lpParam,C_4JInput::EKeyboardMode eMode); @@ -166,4 +213,5 @@ public: }; // Singleton -extern C_4JInput InputManager; \ No newline at end of file +extern C_4JInput InputManager; +extern HWND g_hWnd; \ No newline at end of file -- 2.54.0 From d0db40a3ee3fe79675af0ef5f4b1254dc605242c Mon Sep 17 00:00:00 2001 From: qloak Date: Mon, 14 Sep 2026 15:46:56 -0700 Subject: [PATCH 2/5] add kbm support --- 4J_Input/Windows64/4J_Input.cpp | 195 ++++++++++++++++++++ 4J_Input/Windows64/INP_Keyboard.cpp | 275 +++++++++++++++++++++++++++- 4J_Input/Windows64/INP_Keyboard.h | 81 +++++++- 4J_Input/Windows64/INP_Main.cpp | 57 ++++-- 4J_Input/Windows64/INP_Main.h | 5 + Headers/Windows64/4J_Input.h | 55 +++++- 6 files changed, 646 insertions(+), 22 deletions(-) diff --git a/4J_Input/Windows64/4J_Input.cpp b/4J_Input/Windows64/4J_Input.cpp index cfd5344..144cd00 100644 --- a/4J_Input/Windows64/4J_Input.cpp +++ b/4J_Input/Windows64/4J_Input.cpp @@ -32,6 +32,7 @@ CKeyboard InternalKeyboard; void C_4JInput::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC) { InternalInputManager.Initialise(iInputStateC, ucMapC, ucActionC, ucMenuActionC); + InternalKeyboard.Init(); } void C_4JInput::Tick(void) @@ -39,6 +40,10 @@ void C_4JInput::Tick(void) InternalInputManager.Tick(); } +void C_4JInput::TickKBM(void) +{ + InternalKeyboard.Tick(); +} void C_4JInput::SetDeadzoneAndMovementRange(unsigned int uiDeadzone, unsigned int uiMovementRangeMax) { InternalInputManager.SetDeadzoneAndMovementRange(uiDeadzone, uiMovementRangeMax); @@ -74,6 +79,11 @@ unsigned int C_4JInput::GetValue(int iPad, unsigned char ucAction, bool bRepeat) return InternalInputManager.GetValue(iPad, ucAction, bRepeat); } +void C_4JInput::MapTouchInput(int iPad, int button) +{ + InternalInputManager.MapTouchInput(iPad, button); +} + bool C_4JInput::ButtonPressed(int iPad, unsigned char ucAction) { return InternalInputManager.ButtonPressed(iPad, ucAction); @@ -129,6 +139,11 @@ bool C_4JInput::IsSelectBackSwapped() return InternalInputManager.IsSelectBackSwapped(); } +bool C_4JInput::IsPadActive(int iPad) +{ + return InternalInputManager.IsPadActive(iPad); +} + float C_4JInput::GetJoypadStick_LX(int iPad, bool bCheckMenuDisplay) { return InternalInputManager.GetJoypadStick_LX(iPad, bCheckMenuDisplay); @@ -164,6 +179,186 @@ void C_4JInput::SetMenuDisplayed(int iPad, bool bVal) InternalInputManager.SetMenuDisplayed(iPad, bVal); } +void C_4JInput::OnKeyDown(int vkCode) +{ + InternalKeyboard.OnKeyDown(vkCode); +} + +void C_4JInput::OnKeyUp(int vkCode) +{ + InternalKeyboard.OnKeyUp(vkCode); +} + +void C_4JInput::OnChar(wchar_t ch) +{ + InternalKeyboard.OnChar(ch); +} + +bool C_4JInput::IsKeyDown(int vkCode) const +{ + return InternalKeyboard.IsKeyDown(vkCode); +} + +bool C_4JInput::IsKeyPressed(int vkCode) const +{ + return InternalKeyboard.IsKeyPressed(vkCode); +} + +bool C_4JInput::IsKeyReleased(int vkCode) const +{ + return InternalKeyboard.IsKeyReleased(vkCode); +} + +int C_4JInput::GetMouseX() const +{ + return InternalKeyboard.GetMouseX(); +} + +int C_4JInput::GetMouseY() const +{ + return InternalKeyboard.GetMouseY(); +} + +bool C_4JInput::IsMouseLDown() const +{ + return InternalKeyboard.IsLButtonDown(); +} + +bool C_4JInput::IsLButtonPressed() const +{ + return InternalKeyboard.IsLButtonPressed(); +} + +bool C_4JInput::IsLButtonReleased() const +{ + return InternalKeyboard.IsLButtonReleased(); +} + +bool C_4JInput::IsMouseRDown() const +{ + return InternalKeyboard.IsRButtonDown(); +} + +bool C_4JInput::IsRButtonPressed() const +{ + return InternalKeyboard.IsRButtonPressed(); +} + +bool C_4JInput::IsRButtonReleased() const +{ + return InternalKeyboard.IsRButtonReleased(); +} + +int C_4JInput::GetMouseWheelDelta() const +{ + return InternalKeyboard.GetMouseWheelDelta(); +} + +wchar_t C_4JInput::GetLastChar() const +{ + return InternalKeyboard.GetLastChar(); +} + +bool C_4JInput::HasChar() const +{ + return InternalKeyboard.HasChar(); +} + +int C_4JInput::GetCharCount() const +{ + return InternalKeyboard.GetCharCount(); +} + +wchar_t C_4JInput::GetChar(int index) const +{ + return InternalKeyboard.GetChar(index); +} + +int C_4JInput::GetClipboardText(wchar_t *outText, int outCapacity) const +{ + return InternalKeyboard.GetClipboardText(outText, outCapacity); +} + +bool C_4JInput::SetClipboardText(const wchar_t *text) const +{ + return InternalKeyboard.SetClipboardText(text); +} + +void C_4JInput::OnMouseMove(int x, int y) +{ + InternalKeyboard.OnMouseMove(x, y); +} + +void C_4JInput::OnRawMouseDelta(int dx, int dy) +{ + InternalKeyboard.OnRawMouseDelta(dx, dy); +} + +void C_4JInput::OnLButtonDown(int x, int y) +{ + InternalKeyboard.OnLButtonDown(x, y); +} + +void C_4JInput::OnLButtonUp(int x, int y) +{ + InternalKeyboard.OnLButtonUp(x, y); +} + +void C_4JInput::OnRButtonDown(int x, int y) +{ + InternalKeyboard.OnRButtonDown(x, y); +} + +void C_4JInput::OnRButtonUp(int x, int y) +{ + InternalKeyboard.OnRButtonUp(x, y); +} + +void C_4JInput::OnMButtonDown(int x, int y) +{ + InternalKeyboard.OnMButtonDown(x, y); +} + +void C_4JInput::OnMButtonUp(int x, int y) +{ + InternalKeyboard.OnMButtonUp(x, y); +} + +void C_4JInput::OnMouseWheel(int delta, int x, int y) +{ + InternalKeyboard.OnMouseWheel(delta, x, y); +} + +void C_4JInput::SetMouseCaptured(bool captured) +{ + InternalKeyboard.SetMouseCaptured(captured); +} + +void C_4JInput::SetWindowFocused(bool focused) +{ + InternalKeyboard.SetWindowFocused(focused); +} + +bool C_4JInput::IsMouseCaptured() const +{ + return InternalKeyboard.IsMouseCaptured(); +} + +void C_4JInput::SetMousePos(int x, int y) +{ + InternalKeyboard.SetMousePos(x, y); +} + +int C_4JInput::GetRawMouseX() const +{ + return InternalKeyboard.GetRawMouseX(); +} + +int C_4JInput::GetRawMouseY() const +{ + return InternalKeyboard.GetRawMouseY(); +} + EKeyboardResult C_4JInput::RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int (*Func)(LPVOID, const bool), LPVOID lpParam, C_4JInput::EKeyboardMode eMode) { diff --git a/4J_Input/Windows64/INP_Keyboard.cpp b/4J_Input/Windows64/INP_Keyboard.cpp index 88591ae..3fc03a7 100644 --- a/4J_Input/Windows64/INP_Keyboard.cpp +++ b/4J_Input/Windows64/INP_Keyboard.cpp @@ -24,7 +24,280 @@ SOFTWARE. #include "INP_Keyboard.h" -void CKeyboard::Tick(void) {} +CKeyboard::CKeyboard() +{ + m_lParam = nullptr; + m_onInput = nullptr; + ZeroMemory(m_chrText, sizeof(m_chrText)); + + memset(m_keysPrev, 0, sizeof(m_keysPrev)); + memset(m_keysCurr, 0, sizeof(m_keysCurr)); + m_mouseX = m_mouseY = 0; + m_lButtonPrev = m_lButtonCurr = false; + m_rButtonPrev = m_rButtonCurr = false; + m_mButtonPrev = m_mButtonCurr = false; + m_mouseWheel = 0; + memset(m_charBuffer, 0, sizeof(m_charBuffer)); + m_charCount = 0; + m_mouseCaptured = false; + m_mouseDeltaX = m_mouseDeltaY = 0; + m_windowFocused = true; +} + +void CKeyboard::Init() +{ + RAWINPUTDEVICE rid; + rid.usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC + rid.usUsage = 0x02; // HID_USAGE_GENERIC_MOUSE + rid.dwFlags = 0; + rid.hwndTarget = g_hWnd; + RegisterRawInputDevices(&rid, 1, sizeof(rid)); +} + +void CKeyboard::Tick(void) +{ + memcpy(m_keysPrev, m_keysCurr, sizeof(m_keysCurr)); + m_lButtonPrev = m_lButtonCurr; + m_rButtonPrev = m_rButtonCurr; + m_mButtonPrev = m_mButtonCurr; + m_mouseWheel = 0; + m_charCount = 0; + m_mouseDeltaX = m_mouseDeltaAccumX; + m_mouseDeltaY = m_mouseDeltaAccumY; + m_mouseDeltaAccumX = 0; + m_mouseDeltaAccumY = 0; + + if (m_mouseCaptured && g_hWnd && m_windowFocused && g_hWnd) + { + RECT rc; + GetClientRect(g_hWnd, &rc); + POINT center; + center.x = (rc.right - rc.left) / 2; + center.y = (rc.bottom - rc.top) / 2; + ClientToScreen(g_hWnd, ¢er); + SetCursorPos(center.x, center.y); + } +} + +void CKeyboard::OnKeyDown(int vkCode) +{ + if (vkCode >= 0 && vkCode < MAX_KEYS) + { + m_keysCurr[vkCode] = true; + } +} + +void CKeyboard::OnKeyUp(int vkCode) +{ + if (vkCode >= 0 && vkCode < MAX_KEYS) + { + m_keysCurr[vkCode] = false; + } +} + +void CKeyboard::OnChar(wchar_t ch) +{ + if (m_charCount < MAX_CHARS_PER_FRAME) + { + m_charBuffer[m_charCount++] = ch; + } +} + +int CKeyboard::GetClipboardText(wchar_t *outText, int outCapacity) const +{ + if (!outText || outCapacity <= 0) + return 0; + outText[0] = 0; + if (!OpenClipboard(g_hWnd)) + return 0; + int copied = 0; + HANDLE h = GetClipboardData(CF_UNICODETEXT); + if (h) + { + const wchar_t *src = (const wchar_t *)GlobalLock(h); + if (src) + { + while (src[copied] && copied + 1 < outCapacity) + { + outText[copied] = src[copied]; + ++copied; + } + outText[copied] = 0; + GlobalUnlock(h); + } + } + CloseClipboard(); + return copied; +} + +bool CKeyboard::SetClipboardText(const wchar_t *text) const +{ + if (!text) + return false; + size_t len = wcslen(text); + if (!OpenClipboard(g_hWnd)) + return false; + EmptyClipboard(); + bool ok = false; + HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, (len + 1) * sizeof(wchar_t)); + if (h) + { + memcpy(GlobalLock(h), text, (len + 1) * sizeof(wchar_t)); + GlobalUnlock(h); + ok = (SetClipboardData(CF_UNICODETEXT, h) != NULL); + if (!ok) + GlobalFree(h); + } + CloseClipboard(); + return ok; +} + +bool CKeyboard::IsKeyDown(int vkCode) const +{ + if (vkCode >= 0 && vkCode < MAX_KEYS) + return m_keysCurr[vkCode]; + return false; +} + +bool CKeyboard::IsKeyPressed(int vkCode) const +{ + if (vkCode >= 0 && vkCode < MAX_KEYS) + return m_keysCurr[vkCode] && !m_keysPrev[vkCode]; + return false; +} + +bool CKeyboard::IsKeyReleased(int vkCode) const +{ + if (vkCode >= 0 && vkCode < MAX_KEYS) + return !m_keysCurr[vkCode] && m_keysPrev[vkCode]; + return false; +} + +void CKeyboard::OnMouseMove(int x, int y) +{ + m_mouseX = x; + m_mouseY = y; +} + +void CKeyboard::OnRawMouseDelta(int dx, int dy) +{ + m_mouseDeltaAccumX += dx; + m_mouseDeltaAccumY += dy; +} + +void CKeyboard::OnLButtonDown(int x, int y) +{ + m_mouseX = x; + m_mouseY = y; + m_lButtonCurr = true; +} + +void CKeyboard::OnLButtonUp(int x, int y) +{ + m_mouseX = x; + m_mouseY = y; + m_lButtonCurr = false; +} + +void CKeyboard::OnRButtonDown(int x, int y) +{ + m_mouseX = x; + m_mouseY = y; + m_rButtonCurr = true; +} + +void CKeyboard::OnRButtonUp(int x, int y) +{ + m_mouseX = x; + m_mouseY = y; + m_rButtonCurr = false; +} + +void CKeyboard::OnMButtonDown(int x, int y) +{ + m_mouseX = x; + m_mouseY = y; + m_mButtonCurr = true; +} + +void CKeyboard::OnMButtonUp(int x, int y) +{ + m_mouseX = x; + m_mouseY = y; + m_mButtonCurr = false; +} + +void CKeyboard::OnMouseWheel(int delta, int x, int y) +{ + m_mouseX = x; + m_mouseY = y; + m_mouseWheel += delta; +} + +void CKeyboard::SetMouseCaptured(bool grabbed) +{ + if (m_mouseCaptured == grabbed) + return; + + m_mouseCaptured = grabbed; + if (grabbed && g_hWnd) + { + while (ShowCursor(FALSE) >= 0) {} + RECT rc; + GetClientRect(g_hWnd, &rc); + POINT topLeft = { rc.left, rc.top }; + POINT bottomRight = { rc.right, rc.bottom }; + ClientToScreen(g_hWnd, &topLeft); + ClientToScreen(g_hWnd, &bottomRight); + RECT clipRect = { topLeft.x, topLeft.y, bottomRight.x, bottomRight.y }; + ClipCursor(&clipRect); + + GetClientRect(g_hWnd, &rc); + POINT center; + center.x = (rc.right - rc.left) / 2; + center.y = (rc.bottom - rc.top) / 2; + ClientToScreen(g_hWnd, ¢er); + SetCursorPos(center.x, center.y); + + m_mouseDeltaAccumX = 0; + m_mouseDeltaAccumY = 0; + } + else if (!grabbed && g_hWnd) + { + while (ShowCursor(TRUE) < 0) {} + ClipCursor(nullptr); + } +} + +void CKeyboard::SetWindowFocused(bool focused) +{ + m_windowFocused = focused; + if (focused) + { + if (m_mouseCaptured) + { + while (ShowCursor(FALSE) >= 0) {} + RECT rc; + GetClientRect(g_hWnd, &rc); + POINT center; + center.x = (rc.right - rc.left) / 2; + center.y = (rc.bottom - rc.top) / 2; + ClientToScreen(g_hWnd, ¢er); + SetCursorPos(center.x, center.y); + } + else + { + while (ShowCursor(TRUE) < 0) {} + ClipCursor(nullptr); + } + } + else + { + while (ShowCursor(TRUE) < 0) {} + ClipCursor(nullptr); + } +} + EKeyboardResult CKeyboard::RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int (*Func)(LPVOID, const bool), LPVOID lpParam, C_4JInput::EKeyboardMode eMode) diff --git a/4J_Input/Windows64/INP_Keyboard.h b/4J_Input/Windows64/INP_Keyboard.h index f6e00de..92e3191 100644 --- a/4J_Input/Windows64/INP_Keyboard.h +++ b/4J_Input/Windows64/INP_Keyboard.h @@ -32,6 +32,8 @@ void SeedEditBox(); class CKeyboard { public: + CKeyboard(); + enum EKeyboardProcessState { }; @@ -40,11 +42,86 @@ public: { }; - void Tick(void); + void Init(); + void Tick(); - EKeyboardResult RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int (*Func)(LPVOID, const bool), LPVOID lpParam, + void OnKeyDown(int vkCode); + void OnKeyUp(int vkCode); + void OnChar(wchar_t ch); + + void OnMouseMove(int x, int y); + void OnRawMouseDelta(int dx, int dy); + void OnLButtonDown(int x, int y); + void OnLButtonUp(int x, int y); + void OnRButtonDown(int x, int y); + void OnRButtonUp(int x, int y); + void OnMButtonDown(int x, int y); + void OnMButtonUp(int x, int y); + void OnMouseWheel(int delta, int x, int y); + + bool IsKeyDown(int vkCode) const; + bool IsKeyPressed(int vkCode) const; + bool IsKeyReleased(int vkCode) const; + + int GetMouseX() const { return m_mouseX; } + int GetMouseY() const { return m_mouseY; } + + int GetRawMouseX() const { return m_mouseDeltaX; } + int GetRawMouseY() const { return m_mouseDeltaY; } + + bool IsLButtonDown() const { return m_lButtonCurr; } + bool IsLButtonPressed() const { return m_lButtonCurr && !m_lButtonPrev; } + bool IsLButtonReleased() const { return !m_lButtonCurr && m_lButtonPrev; } + + bool IsRButtonDown() const { return m_rButtonCurr; } + bool IsRButtonPressed() const { return m_rButtonCurr && !m_rButtonPrev; } + bool IsRButtonReleased() const { return !m_rButtonCurr && m_rButtonPrev; } + + int GetMouseWheelDelta() const { return m_mouseWheel; } + + wchar_t GetLastChar() const { return m_charCount > 0 ? m_charBuffer[0] : 0; } + bool HasChar() const { return m_charCount > 0; } + int GetCharCount() const { return m_charCount; } + wchar_t GetChar(int index) const { return (index >= 0 && index < m_charCount) ? m_charBuffer[index] : 0; } + + int GetClipboardText(wchar_t *outText, int outCapacity) const; + bool SetClipboardText(const wchar_t *text) const; + + void SetMouseCaptured(bool captured); + void SetWindowFocused(bool focused); + bool IsMouseCaptured() const { return m_mouseCaptured; } + + void SetMousePos(int x, int y) { m_mouseX = x; m_mouseY = y; } + + EKeyboardResult RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int (*Func)(LPVOID, const bool), LPVOID lpParam, C_4JInput::EKeyboardMode eMode); void GetText(uint16_t *UTF16String); + BYTE gap0[0x68]; +private: + static const int MAX_KEYS = 256; + static const int MAX_CHARS_PER_FRAME = 32; + + bool m_keysPrev[MAX_KEYS]; + bool m_keysCurr[MAX_KEYS]; + + int m_mouseX, m_mouseY; + bool m_lButtonPrev, m_lButtonCurr; + bool m_rButtonPrev, m_rButtonCurr; + bool m_mButtonPrev, m_mButtonCurr; + int m_mouseWheel; + + wchar_t m_charBuffer[MAX_CHARS_PER_FRAME]; + int m_charCount; + + bool m_windowFocused; + bool m_mouseCaptured; + int m_mouseDeltaX, m_mouseDeltaY; + int m_mouseDeltaAccumX, m_mouseDeltaAccumY; + + wchar_t m_chrText[128]; + LPVOID m_lParam; + int (*m_onInput)(LPVOID, LPCWSTR); + }; \ No newline at end of file diff --git a/4J_Input/Windows64/INP_Main.cpp b/4J_Input/Windows64/INP_Main.cpp index 65413b9..edddb38 100644 --- a/4J_Input/Windows64/INP_Main.cpp +++ b/4J_Input/Windows64/INP_Main.cpp @@ -31,8 +31,6 @@ bool m_SelectBackSwapped = false; CInput::CInput() { - m_Keyboard = CKeyboard(); - m_uiSigninJoypadMask = 0; for (int i = 0; i < 4; ++i) m_bIsMenuDisplayed[i] = 0; @@ -79,6 +77,8 @@ void CInput::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char uc m_Joypads[i].m_pucLeftTriggerAxisMap = &m_Joypads[i].m_ucLeftTriggerState; m_Joypads[i].m_pucRightTriggerAxisMap = &m_Joypads[i].m_ucRightTriggerState; m_Joypads[i].m_fSensitivity = 1.0f; + + m_iTouchInputButton[i] = 0; } m_JoypadMap = (unsigned int **)operator new[](ucMapC * sizeof(int *)); @@ -97,7 +97,6 @@ void CInput::Tick(void) { HandleGamepadEvents(); UpdateJoypads(); - m_Keyboard.Tick(); } void CInput::SetJoypadValues(JOYPAD *pThisPad) @@ -331,6 +330,11 @@ unsigned char CInput::GetJoypadMapVal(int iPad) return m_Joypads[iPad].m_ucMappingValue; } +void CInput::MapTouchInput(int iPad, int button) +{ + m_iTouchInputButton[iPad] |= button; +} + void CInput::SetJoypadStickAxisMap(int iPad, unsigned int uiFrom, unsigned int uiTo) { float *pfTo = nullptr; @@ -408,6 +412,11 @@ bool CInput::IsSelectBackSwapped() return m_SelectBackSwapped; } +bool CInput::IsPadActive(int iPad) +{ + return m_Joypads[iPad].m_bControllerActive; +} + void CInput::SetSigninJoypadMask(unsigned int mask) { m_uiSigninJoypadMask = mask; @@ -764,27 +773,39 @@ bool CInput::UpdateJoypads() if (pThisPad->m_bIsConnected) { SetJoypadValues(pThisPad); - - pThisPad->m_uiButtonsPressed = ~pThisPad->m_uiOldButtons & pThisPad->m_uiButtons; - pThisPad->m_uiButtonsReleased = ~pThisPad->m_uiButtons & pThisPad->m_uiOldButtons; - - for (int bit = 0; bit < 24; ++bit) - { - if ((pThisPad->m_uiButtonsPressed & (1 << bit)) != 0) - { - GetStartTime(i, bit); - } - else if ((pThisPad->m_uiButtons & (1 << bit)) != 0) - { - UpdateTime(i, bit); - } - } } else if (pThisPad->m_bWasConnected) { ClearJoypadValues(pThisPad); } + if (m_iTouchInputButton[i]) + { + pThisPad->m_uiButtons |= m_iTouchInputButton[i]; + } + + m_iTouchInputButton[i] = 0; + + pThisPad->m_uiButtonsPressed = ~pThisPad->m_uiOldButtons & pThisPad->m_uiButtons; + pThisPad->m_uiButtonsReleased = ~pThisPad->m_uiButtons & pThisPad->m_uiOldButtons; + + for (int bit = 0; bit < 24; ++bit) + { + if ((pThisPad->m_uiButtonsPressed & (1 << bit)) != 0) + { + GetStartTime(i, bit); + } + else if ((pThisPad->m_uiButtons & (1 << bit)) != 0) + { + UpdateTime(i, bit); + } + } + + if (pThisPad->m_uiButtonsPressed) + pThisPad->m_bControllerActive = true; + else + pThisPad->m_bControllerActive = false; + if (m_pDebugSequenceFn && (pThisPad->m_uiButtonsPressed & (_360_JOY_BUTTON_A | _360_JOY_BUTTON_B | _360_JOY_BUTTON_X | _360_JOY_BUTTON_Y | _360_JOY_BUTTON_RB | _360_JOY_BUTTON_LB)) != 0) { diff --git a/4J_Input/Windows64/INP_Main.h b/4J_Input/Windows64/INP_Main.h index a688453..86fe1cd 100644 --- a/4J_Input/Windows64/INP_Main.h +++ b/4J_Input/Windows64/INP_Main.h @@ -38,6 +38,7 @@ public: bool m_bIsConnected; bool m_bWasConnected; bool m_bHasConnected; + bool m_bControllerActive; unsigned int m_uiButtons; unsigned int m_uiOldButtons; @@ -105,12 +106,14 @@ public: void SetJoypadMapVal(int iPad, unsigned char ucMap); unsigned char GetJoypadMapVal(int iPad); + void MapTouchInput(int iPad, int button); void SetJoypadStickAxisMap(int iPad, unsigned int uiFrom, unsigned int uiTo); void SetJoypadStickTriggerMap(int iPad, unsigned int uiFrom, unsigned int uiTo); bool IsPadConnected(int iPad); void SetSelectBackSwapped(bool swapped); bool IsSelectBackSwapped(); + bool IsPadActive(int iPad); void SetSigninJoypadMask(unsigned int mask); unsigned int GetValue(int iPad, unsigned char ucAction, bool bRepeat = false); bool IsSet(int iPad, unsigned char ucAction); @@ -185,6 +188,8 @@ public: int (*m_pDebugSequenceFn)(void *); LPVOID m_pDebugSequenceParam; + unsigned int m_iTouchInputButton[MAX_JOYPADS]; + private: EControllerType GetControllerName(SDL_GamepadType type) { diff --git a/Headers/Windows64/4J_Input.h b/Headers/Windows64/4J_Input.h index 545e7a7..dbbccb2 100644 --- a/Headers/Windows64/4J_Input.h +++ b/Headers/Windows64/4J_Input.h @@ -113,6 +113,7 @@ public: void Initialise( int iInputStateC, unsigned char ucMapC,unsigned char ucActionC, unsigned char ucMenuActionC ); void Tick(void); + void TickKBM(void); void SetDeadzoneAndMovementRange(unsigned int uiDeadzone, unsigned int uiMovementRangeMax ); void SetGameJoypadMaps(unsigned char ucMap,unsigned char ucAction,unsigned int uiActionVal); unsigned int GetGameJoypadMaps(unsigned char ucMap,unsigned char ucAction); @@ -120,6 +121,7 @@ public: unsigned char GetJoypadMapVal(int iPad); void SetJoypadSensitivity(int iPad, float fSensitivity); unsigned int GetValue(int iPad,unsigned char ucAction, bool bRepeat=false); + void MapTouchInput(int iPad, int button); bool ButtonPressed(int iPad,unsigned char ucAction=255); // toggled bool ButtonReleased(int iPad,unsigned char ucAction); //toggled bool ButtonDown(int iPad,unsigned char ucAction=255); // button held down @@ -133,6 +135,8 @@ public: void SetSelectBackSwapped(bool swapped); bool IsSelectBackSwapped(); + bool IsPadActive(int iPad); + bool IsCircleCrossSwapped(); // In-Game values which may have been remapped due to Southpaw, swap triggers, etc float GetJoypadStick_LX(int iPad, bool bCheckMenuDisplay=true); float GetJoypadStick_LY(int iPad, bool bCheckMenuDisplay=true); @@ -143,6 +147,54 @@ public: void SetMenuDisplayed(int iPad, bool bVal); + void OnKeyDown(int vkCode); + void OnKeyUp(int vkCode); + void OnChar(wchar_t ch); + + void OnMouseMove(int x, int y); + void OnRawMouseDelta(int dx, int dy); + void OnLButtonDown(int x, int y); + void OnLButtonUp(int x, int y); + void OnRButtonDown(int x, int y); + void OnRButtonUp(int x, int y); + void OnMButtonDown(int x, int y); + void OnMButtonUp(int x, int y); + void OnMouseWheel(int delta, int x, int y); + + bool IsKeyDown(int vkCode) const; + bool IsKeyPressed(int vkCode) const; + bool IsKeyReleased(int vkCode) const; + + int GetMouseX() const; + int GetMouseY() const; + + // PIEBOT: Used to be IsLButtonDown, changed so it doesnt conflict with windowx.h + bool IsMouseLDown() const; + bool IsLButtonPressed() const; + bool IsLButtonReleased() const; + + bool IsMouseRDown() const; + bool IsRButtonPressed() const; + bool IsRButtonReleased() const; + + int GetMouseWheelDelta() const; + + wchar_t GetLastChar() const; + bool HasChar() const; + int GetCharCount() const; + wchar_t GetChar(int index) const; + + int GetClipboardText(wchar_t *outText, int outCapacity) const; + bool SetClipboardText(const wchar_t *text) const; + + void SetMouseCaptured(bool captured); + void SetWindowFocused(bool focused); + bool IsMouseCaptured() const; + + void SetMousePos(int x, int y); + + int GetRawMouseX() const; + int GetRawMouseY() const; // EKeyboardResult RequestKeyboard(UINT uiTitle, UINT uiText, UINT uiDesc, DWORD dwPad, WCHAR *pwchResult, UINT uiResultSize,int( *Func)(LPVOID,const bool),LPVOID lpParam,EKeyboardMode eMode,C4JStringTable *pStringTable=NULL); // EKeyboardResult RequestKeyboard(UINT uiTitle, LPCWSTR pwchDefault, UINT uiDesc, DWORD dwPad, WCHAR *pwchResult, UINT uiResultSize,int( *Func)(LPVOID,const bool),LPVOID lpParam, EKeyboardMode eMode,C4JStringTable *pStringTable=NULL); EKeyboardResult RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int( *Func)(LPVOID,const bool),LPVOID lpParam,C_4JInput::EKeyboardMode eMode); @@ -179,4 +231,5 @@ public: }; // Singleton -extern C_4JInput InputManager; \ No newline at end of file +extern C_4JInput InputManager; +extern HWND g_hWnd; \ No newline at end of file -- 2.54.0 From 1ba5902026b6fa43312e87d631a8e9822ece899e Mon Sep 17 00:00:00 2001 From: qloak Date: Mon, 14 Sep 2026 16:25:32 -0700 Subject: [PATCH 3/5] fix: default return for GetControllerType --- 4J_Input/Windows64/4J_Input.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/4J_Input/Windows64/4J_Input.cpp b/4J_Input/Windows64/4J_Input.cpp index 144cd00..8daa0a1 100644 --- a/4J_Input/Windows64/4J_Input.cpp +++ b/4J_Input/Windows64/4J_Input.cpp @@ -376,6 +376,7 @@ EControllerType C_4JInput::GetControllerType(int iPad) { return InternalInputManager.GetControllerType(iPad); //strk13r - mrow mrow mrow mrowwwwwwwwwww, i am silly kitty } + return EControllerType_Default; } bool C_4JInput::VerifyStrings(WCHAR **pwStringA, int iStringC, int (*Func)(LPVOID, STRING_VERIFY_RESPONSE *), LPVOID lpParam) -- 2.54.0 From 6195bd193de9a38e3fa7f4b3ad6d4fb241260f87 Mon Sep 17 00:00:00 2001 From: qloak Date: Mon, 14 Sep 2026 17:54:37 -0700 Subject: [PATCH 4/5] fix: pad 0 signed in when keyboard focused (KBM without gamepad) --- 4J_Input/Windows64/4J_Input.cpp | 5 +++++ 4J_Input/Windows64/INP_Keyboard.h | 1 + 4J_Profile/Windows64/PRO_Sys.cpp | 10 ++++++++-- Headers/Windows64/4J_Input.h | 1 + 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/4J_Input/Windows64/4J_Input.cpp b/4J_Input/Windows64/4J_Input.cpp index 8daa0a1..e12fa3b 100644 --- a/4J_Input/Windows64/4J_Input.cpp +++ b/4J_Input/Windows64/4J_Input.cpp @@ -344,6 +344,11 @@ bool C_4JInput::IsMouseCaptured() const return InternalKeyboard.IsMouseCaptured(); } +bool C_4JInput::IsWindowFocused() const +{ + return InternalKeyboard.IsWindowFocused(); +} + void C_4JInput::SetMousePos(int x, int y) { InternalKeyboard.SetMousePos(x, y); diff --git a/4J_Input/Windows64/INP_Keyboard.h b/4J_Input/Windows64/INP_Keyboard.h index 92e3191..2855538 100644 --- a/4J_Input/Windows64/INP_Keyboard.h +++ b/4J_Input/Windows64/INP_Keyboard.h @@ -90,6 +90,7 @@ public: void SetMouseCaptured(bool captured); void SetWindowFocused(bool focused); bool IsMouseCaptured() const { return m_mouseCaptured; } + bool IsWindowFocused() const { return m_windowFocused; } void SetMousePos(int x, int y) { m_mouseX = x; m_mouseY = y; } diff --git a/4J_Profile/Windows64/PRO_Sys.cpp b/4J_Profile/Windows64/PRO_Sys.cpp index 1be86c8..554ac86 100644 --- a/4J_Profile/Windows64/PRO_Sys.cpp +++ b/4J_Profile/Windows64/PRO_Sys.cpp @@ -7,12 +7,18 @@ wchar_t fakeGamerTagW[16] = L"PlayerName"; bool CSys::IsSignedIn(int iQuadrant) { - return InputManager.IsPadConnected(iQuadrant); //str1k3r - since we dont sign in like consoles just check if the pad is connected + if (InputManager.IsPadConnected(iQuadrant)) + return true; + //str1k3r - since we dont sign in like consoles just check if the pad is connected + //kbm - pad 0 also counts as signed in when the keyboard is available + return iQuadrant == 0 && InputManager.IsWindowFocused(); } bool CSys::IsSignedInLive(int iProf) { - return InputManager.IsPadConnected(iProf); + if (InputManager.IsPadConnected(iProf)) + return true; + return iProf == 0 && InputManager.IsWindowFocused(); } //str1k3r - set every pad that isnt pad 0 as a guest diff --git a/Headers/Windows64/4J_Input.h b/Headers/Windows64/4J_Input.h index dbbccb2..51081dd 100644 --- a/Headers/Windows64/4J_Input.h +++ b/Headers/Windows64/4J_Input.h @@ -190,6 +190,7 @@ public: void SetMouseCaptured(bool captured); void SetWindowFocused(bool focused); bool IsMouseCaptured() const; + bool IsWindowFocused() const; void SetMousePos(int x, int y); -- 2.54.0 From a4ade434ac522b0cd8f0e1249b871276efc852f3 Mon Sep 17 00:00:00 2001 From: qloak Date: Mon, 14 Sep 2026 19:05:43 -0700 Subject: [PATCH 5/5] use upstream GetControllerType disconnect handling --- 4J_Input/Windows64/4J_Input.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/4J_Input/Windows64/4J_Input.cpp b/4J_Input/Windows64/4J_Input.cpp index e12fa3b..357397a 100644 --- a/4J_Input/Windows64/4J_Input.cpp +++ b/4J_Input/Windows64/4J_Input.cpp @@ -377,11 +377,7 @@ void C_4JInput::GetText(uint16_t *UTF16String) EControllerType C_4JInput::GetControllerType(int iPad) { - if(InternalInputManager.IsPadConnected(iPad)) - { - return InternalInputManager.GetControllerType(iPad); //strk13r - mrow mrow mrow mrowwwwwwwwwww, i am silly kitty - } - return EControllerType_Default; + return InternalInputManager.GetControllerType(iPad); //strk13r - mrow mrow mrow mrowwwwwwwwwww, i am silly kitty } bool C_4JInput::VerifyStrings(WCHAR **pwStringA, int iStringC, int (*Func)(LPVOID, STRING_VERIFY_RESPONSE *), LPVOID lpParam) -- 2.54.0