From 8e4d0f64d25aa823b728adb924fa4e3038c99dcd Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Sun, 24 Mar 2024 09:21:16 -0400 Subject: [PATCH] implement a few legonavcontroller functions --- .../legoomni/include/legocameracontroller.h | 1 + .../lego/legoomni/include/legoinputmanager.h | 6 +- .../lego/legoomni/include/legonavcontroller.h | 4 +- .../src/entity/legocameracontroller.cpp | 6 + .../legoomni/src/entity/legonavcontroller.cpp | 118 ++++++++++++++++-- .../legoomni/src/input/legoinputmanager.cpp | 65 ++++++++++ 6 files changed, 185 insertions(+), 15 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..12f7a5cb 100644 --- a/LEGO1/lego/legoomni/include/legoinputmanager.h +++ b/LEGO1/lego/legoomni/include/legoinputmanager.h @@ -113,6 +113,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_keys); // SYNTHETIC: LEGO1 0x1005b8d0 // LegoInputManager::`scalar deleting destructor' @@ -135,9 +137,7 @@ class LegoInputManager : public MxPresenter { 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 + 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..cdeca96c 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,116 @@ 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_linearVel = CalculateNewTargetVel(m_vMax - xVal, m_vMax / 2, m_maxLinearVel); + m_linearAccel = CalculateNewAccel(m_vMax - xVal, m_vMax / 2, m_maxLinearAccel, (int) m_minLinearAccel); + m_targetRotationalVel = CalculateNewTargetVel(yVal, m_hMax / 2, m_maxRotationalVel); + m_rotationalAccel = + CalculateNewAccel(yVal, 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(povPosition * 0.017453333333333335); + p_und = TRUE; + } + } + + return SUCCESS; + } + } + return FAILURE; } -// STUB: LEGO1 0x100558b0 -int LegoNavController::FUN_100558b0() +// FUNCTION: LEGO1 0x100558b0 +MxResult LegoNavController::ProcessKeyboardInput() { - // TODO - return -1; + LegoOmni* instance = LegoOmni::GetInstance(); + MxBool bool1 = FALSE; + MxBool bool2 = FALSE; + + MxU32 keys; + if (!instance->GetInputManager() || instance->GetInputManager()->FUN_1005c160(keys) == FAILURE) { + return FAILURE; + } + + if (m_unk0x6c) { + m_targetRotationalVel = 0.0; + m_targetLinearVel = 0.0; + m_rotationalAccel = m_maxRotationalDeccel; + m_linearAccel = m_maxLinearDeccel; + m_unk0x6c = FALSE; + } + else if (keys) { + m_unk0x6c = TRUE; + + MxS32 hMax; + if ((keys & 3) == 1) { + hMax = 0; + } + else if ((keys & 3) == 2) { + hMax = m_hMax; + } + else { + bool1 = TRUE; + m_rotationalAccel = m_maxRotationalDeccel; + m_targetRotationalVel = 0.0; + } + + MxS32 vMax; + if ((keys & 12) == 4) { + vMax = 0; + } + else if ((keys & 12) == 8) { + vMax = m_vMax; + } + else { + bool2 = TRUE; + m_targetLinearVel = 0.0; + m_linearAccel = m_maxRotationalDeccel; + } + + MxFloat val = keys & 0x10 ? 1.0f : 4.0f; + MxFloat val2 = keys & 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, hMax / 2, m_maxLinearAccel / val, (int) (m_minLinearAccel / val2)); + } + + return SUCCESS; + } + + return FAILURE; } // STUB: LEGO1 0x10055a60 diff --git a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp index 02a89518..c16cfda2 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() { @@ -135,6 +138,68 @@ void LegoInputManager::ReleaseDX() } } +// FUNCTION: LEGO1 0x1005c0f0 +void LegoInputManager::FUN_1005c0f0() +{ + m_unk0x94 = 0; + if (m_directInputDevice) { + HRESULT hr = m_directInputDevice->GetDeviceState(256, &m_unk0x95); + if (hr == 0x8007001E || hr == 0x8007000c) { + if (m_directInputDevice->Acquire() == S_OK) { + hr = m_directInputDevice->GetDeviceState(256, &m_unk0x95); + } + } + + if (hr == S_OK) { + m_unk0x94 = 1; + } + } +} + +// FUNCTION: LEGO1 0x1005c160 +MxResult LegoInputManager::FUN_1005c160(MxU32& p_keys) +{ + 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 value = 0; + + if ((m_unk0x95[DIK_UP] | m_unk0x95[DIK_NUMPAD8]) & 0x80) { + value = 4; + } + + if ((m_unk0x95[DIK_NUMPAD2] | m_unk0x95[DIK_DOWN]) & 0x80) { + value |= 8; + } + + if ((m_unk0x95[DIK_NUMPAD4] | m_unk0x95[DIK_LEFT]) & 0x80) { + value |= 1; + } + + if ((m_unk0x95[DIK_NUMPAD6] | m_unk0x95[DIK_RIGHT]) & 0x80) { + value |= 2; + } + + if ((m_unk0x95[DIK_LCONTROL] | m_unk0x95[DIK_RCONTROL]) & 0x80) { + value |= 16; + } + + p_keys = value; + + return SUCCESS; +} + // FUNCTION: LEGO1 0x1005c240 MxResult LegoInputManager::GetJoystickId() {