From b66e28ac5eab05d901eb83917dcef8529a627fe4 Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Sun, 24 Mar 2024 10:30:12 -0400 Subject: [PATCH] implement a few legonavcontroller functions (#718) * implement a few legonavcontroller functions * Match LegoNavController::ProcessJoystickInput * Style * Match LegoNavController::ProcessKeyboardInput * Style * Fix --------- Co-authored-by: Christian Semmler --- .../legoomni/include/legocameracontroller.h | 1 + .../lego/legoomni/include/legoinputmanager.h | 19 ++- .../lego/legoomni/include/legonavcontroller.h | 4 +- .../src/entity/legocameracontroller.cpp | 6 + .../legoomni/src/entity/legonavcontroller.cpp | 123 ++++++++++++++++-- .../legoomni/src/input/legoinputmanager.cpp | 71 +++++++++- 6 files changed, 207 insertions(+), 17 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legocameracontroller.h b/LEGO1/lego/legoomni/include/legocameracontroller.h index ac8cfd5d..ea94d86b 100644 --- a/LEGO1/lego/legoomni/include/legocameracontroller.h +++ b/LEGO1/lego/legoomni/include/legocameracontroller.h @@ -37,6 +37,7 @@ class LegoCameraController : public LegoPointOfViewController { virtual MxResult Create(); // vtable+0x44 void SetWorldTransform(const Vector3& p_at, const Vector3& p_dir, const Vector3& p_up); + void FUN_10012320(MxFloat); void FUN_100123e0(const Matrix4& p_transform, MxU32 p_und); Mx3DPointFloat GetWorldUp(); Mx3DPointFloat GetWorldLocation(); diff --git a/LEGO1/lego/legoomni/include/legoinputmanager.h b/LEGO1/lego/legoomni/include/legoinputmanager.h index 69a9dc64..17867a2a 100644 --- a/LEGO1/lego/legoomni/include/legoinputmanager.h +++ b/LEGO1/lego/legoomni/include/legoinputmanager.h @@ -68,6 +68,17 @@ class LegoNotifyListCursor : public MxPtrListCursor { // SIZE 0x338 class LegoInputManager : public MxPresenter { public: + enum Keys { + c_left = 0x01, + c_right = 0x02, + c_up = 0x04, + c_down = 0x08, + c_bit5 = 0x10, + + c_leftOrRight = c_left | c_right, + c_upOrDown = c_up | c_down + }; + LegoInputManager(); ~LegoInputManager() override; @@ -113,6 +124,8 @@ class LegoInputManager : public MxPresenter { void ProcessEvents(); MxBool ProcessOneEvent(LegoEventNotificationParam& p_param); MxBool FUN_1005cdf0(LegoEventNotificationParam& p_param); + void FUN_1005c0f0(); + MxResult FUN_1005c160(MxU32& p_keyFlags); // SYNTHETIC: LEGO1 0x1005b8d0 // LegoInputManager::`scalar deleting destructor' @@ -134,10 +147,8 @@ class LegoInputManager : public MxPresenter { MxBool m_unk0x88; // 0x88 IDirectInput* m_directInput; // 0x8c IDirectInputDevice* m_directInputDevice; // 0x90 - undefined m_unk0x94; // 0x94 - undefined4 m_unk0x98; // 0x98 - undefined m_unk0x9c[0xf8]; // 0x9c - undefined m_unk0x194; // 0x194 + MxBool m_unk0x94; // 0x94 + MxU8 m_unk0x95[256]; // 0x95 MxBool m_unk0x195; // 0x195 MxS32 m_joyid; // 0x198 MxS32 m_joystickIndex; // 0x19c diff --git a/LEGO1/lego/legoomni/include/legonavcontroller.h b/LEGO1/lego/legoomni/include/legonavcontroller.h index 4003e6fd..9dfc8ccf 100644 --- a/LEGO1/lego/legoomni/include/legonavcontroller.h +++ b/LEGO1/lego/legoomni/include/legonavcontroller.h @@ -81,8 +81,8 @@ class LegoNavController : public MxCore { float CalculateNewTargetVel(int p_pos, int p_center, float p_max); float CalculateNewAccel(int p_pos, int p_center, float p_max, int p_min); - int FUN_10055750(MxBool& p_und); - int FUN_100558b0(); + MxResult ProcessJoystickInput(MxBool& p_und); + MxResult ProcessKeyboardInput(); int m_hMax; // 0x08 int m_vMax; // 0x0c diff --git a/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp b/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp index c0c48c2a..ed9820c7 100644 --- a/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp @@ -122,6 +122,12 @@ void LegoCameraController::SetWorldTransform(const Vector3& p_at, const Vector3& m_matrix2 = m_matrix1; } +// STUB: LEGO1 0x10012320 +void LegoCameraController::FUN_10012320(MxFloat) +{ + // TODO +} + // FUNCTION: LEGO1 0x100123e0 void LegoCameraController::FUN_100123e0(const Matrix4& p_transform, MxU32 p_und) { diff --git a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp index 27f9bece..011e1a63 100644 --- a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp @@ -307,8 +307,8 @@ MxBool LegoNavController::CalculateNewPosDir( float deltaTime = (currentTime - m_lastTime) / 1000.0; m_lastTime = currentTime; - if (FUN_100558b0() == -1) { - FUN_10055750(und); + if (ProcessKeyboardInput() == FAILURE) { + ProcessJoystickInput(und); } if (m_useRotationalVel) { @@ -471,18 +471,121 @@ MxResult LegoNavController::UpdateCameraLocation(MxU32 p_location) return result; } -// STUB: LEGO1 0x10055750 -int LegoNavController::FUN_10055750(MxBool& p_und) +// FUNCTION: LEGO1 0x10055750 +MxResult LegoNavController::ProcessJoystickInput(MxBool& p_und) { - // TODO - return -1; + LegoOmni* instance = LegoOmni::GetInstance(); + + if (instance->GetInputManager()) { + MxS32 joystickX; + MxS32 joystickY; + DWORD buttonState; + MxS32 povPosition; + + if (instance->GetInputManager() + ->GetJoystickState((MxU32*) &joystickX, (MxU32*) &joystickY, &buttonState, (MxU32*) &povPosition) != + FAILURE) { + MxU32 yVal = (joystickY * m_vMax) / 100; + MxU32 xVal = (joystickX * m_hMax) / 100; + + if (joystickX <= 45 || joystickX >= 55 || joystickY <= 45 || joystickY >= 55) { + m_targetLinearVel = CalculateNewTargetVel(m_vMax - yVal, m_vMax / 2, m_maxLinearVel); + m_linearAccel = CalculateNewAccel(m_vMax - yVal, m_vMax / 2, m_maxLinearAccel, (int) m_minLinearAccel); + m_targetRotationalVel = CalculateNewTargetVel(xVal, m_hMax / 2, m_maxRotationalVel); + m_rotationalAccel = + CalculateNewAccel(xVal, m_hMax / 2, m_maxRotationalAccel, (int) m_minRotationalAccel); + } + else { + m_targetRotationalVel = 0.0; + m_targetLinearVel = 0.0; + m_linearAccel = m_maxLinearDeccel; + m_rotationalAccel = m_maxRotationalDeccel; + } + + if (povPosition >= 0) { + LegoWorld* world = CurrentWorld(); + + if (world && world->GetCamera()) { + world->GetCamera()->FUN_10012320(DTOR(povPosition)); + p_und = TRUE; + } + } + + return SUCCESS; + } + } + + return FAILURE; } -// STUB: LEGO1 0x100558b0 -int LegoNavController::FUN_100558b0() +// FUNCTION: LEGO1 0x100558b0 +MxResult LegoNavController::ProcessKeyboardInput() { - // TODO - return -1; + MxBool bool1 = FALSE; + MxBool bool2 = FALSE; + LegoInputManager* inputManager = LegoOmni::GetInstance()->GetInputManager(); + MxU32 keyFlags; + + if (inputManager == NULL || inputManager->FUN_1005c160(keyFlags) == FAILURE) { + return FAILURE; + } + + if (keyFlags == 0) { + if (m_unk0x6c) { + m_targetRotationalVel = 0.0; + m_targetLinearVel = 0.0; + m_rotationalAccel = m_maxRotationalDeccel; + m_linearAccel = m_maxLinearDeccel; + m_unk0x6c = FALSE; + } + + return FAILURE; + } + + m_unk0x6c = TRUE; + + MxS32 hMax; + if ((keyFlags & LegoInputManager::c_leftOrRight) == LegoInputManager::c_left) { + hMax = 0; + } + else if ((keyFlags & LegoInputManager::c_leftOrRight) == LegoInputManager::c_right) { + hMax = m_hMax; + } + else { + m_targetRotationalVel = 0.0; + m_rotationalAccel = m_maxRotationalDeccel; + bool1 = TRUE; + } + + MxS32 vMax; + if ((keyFlags & LegoInputManager::c_upOrDown) == LegoInputManager::c_up) { + vMax = 0; + } + else if ((keyFlags & LegoInputManager::c_upOrDown) == LegoInputManager::c_down) { + vMax = m_vMax; + } + else { + m_targetLinearVel = 0.0; + m_linearAccel = m_maxLinearDeccel; + bool2 = TRUE; + } + + MxFloat val = keyFlags & 0x10 ? 1.0f : 4.0f; + MxFloat val2 = keyFlags & 0x10 ? 1.0f : 2.0f; + + if (!bool1) { + m_targetRotationalVel = CalculateNewTargetVel(hMax, m_hMax / 2, m_maxRotationalVel); + m_rotationalAccel = + CalculateNewAccel(hMax, m_hMax / 2, m_maxRotationalAccel / val, (int) (m_minRotationalAccel / val2)); + } + + if (!bool2) { + m_targetLinearVel = CalculateNewTargetVel(m_vMax - vMax, m_vMax / 2, m_maxLinearVel); + m_linearAccel = + CalculateNewAccel(m_vMax - vMax, m_vMax / 2, m_maxLinearAccel / val, (int) (m_minLinearAccel / val2)); + } + + return SUCCESS; } // STUB: LEGO1 0x10055a60 diff --git a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp index 02a89518..3e6a39dd 100644 --- a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp +++ b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp @@ -18,6 +18,9 @@ MxS32 g_unk0x100f31b0 = -1; // GLOBAL: LEGO1 0x100f31b4 const char* g_unk0x100f31b4 = NULL; +// GLOBAL: LEGO1 0x100f67b8 +MxBool g_unk0x100f67b8 = TRUE; + // FUNCTION: LEGO1 0x1005b790 LegoInputManager::LegoInputManager() { @@ -34,7 +37,7 @@ LegoInputManager::LegoInputManager() m_unk0x88 = FALSE; m_directInput = NULL; m_directInputDevice = NULL; - m_unk0x94 = 0; + m_unk0x94 = FALSE; m_unk0x195 = 0; m_joyid = -1; m_joystickIndex = -1; @@ -135,6 +138,72 @@ void LegoInputManager::ReleaseDX() } } +// FUNCTION: LEGO1 0x1005c0f0 +void LegoInputManager::FUN_1005c0f0() +{ + m_unk0x94 = FALSE; + + if (m_directInputDevice) { + HRESULT hr = m_directInputDevice->GetDeviceState(_countof(m_unk0x95), &m_unk0x95); + + if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) { + if (m_directInputDevice->Acquire() == S_OK) { + hr = m_directInputDevice->GetDeviceState(_countof(m_unk0x95), &m_unk0x95); + } + } + + if (hr == S_OK) { + m_unk0x94 = TRUE; + } + } +} + +// FUNCTION: LEGO1 0x1005c160 +MxResult LegoInputManager::FUN_1005c160(MxU32& p_keyFlags) +{ + FUN_1005c0f0(); + + if (!m_unk0x94) { + return FAILURE; + } + + if (g_unk0x100f67b8) { + if (m_unk0x95[DIK_LEFT] & 0x80 && GetAsyncKeyState(VK_LEFT) == 0) { + m_unk0x95[DIK_LEFT] = 0; + } + + if (m_unk0x95[DIK_RIGHT] & 0x80 && GetAsyncKeyState(VK_RIGHT) == 0) { + m_unk0x95[DIK_RIGHT] = 0; + } + } + + MxU32 keyFlags = 0; + + if ((m_unk0x95[DIK_NUMPAD8] | m_unk0x95[DIK_UP]) & 0x80) { + keyFlags |= c_up; + } + + if ((m_unk0x95[DIK_NUMPAD2] | m_unk0x95[DIK_DOWN]) & 0x80) { + keyFlags |= c_down; + } + + if ((m_unk0x95[DIK_NUMPAD4] | m_unk0x95[DIK_LEFT]) & 0x80) { + keyFlags |= c_left; + } + + if ((m_unk0x95[DIK_NUMPAD6] | m_unk0x95[DIK_RIGHT]) & 0x80) { + keyFlags |= c_right; + } + + if ((m_unk0x95[DIK_LCONTROL] | m_unk0x95[DIK_RCONTROL]) & 0x80) { + keyFlags |= c_bit5; + } + + p_keyFlags = keyFlags; + + return SUCCESS; +} + // FUNCTION: LEGO1 0x1005c240 MxResult LegoInputManager::GetJoystickId() {