diff --git a/CMakeLists.txt b/CMakeLists.txt index eb5f1c25..483ba9db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,10 +32,8 @@ add_library(lego1 SHARED LEGO1/lego/legoomni/src/common/gifmanager.cpp LEGO1/lego/legoomni/src/common/legoactioncontrolpresenter.cpp LEGO1/lego/legoomni/src/common/legobackgroundcolor.cpp - LEGO1/lego/legoomni/src/common/legocameracontroller.cpp LEGO1/lego/legoomni/src/common/legofullscreenmovie.cpp LEGO1/lego/legoomni/src/common/legogamestate.cpp - LEGO1/lego/legoomni/src/common/legonavcontroller.cpp LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp LEGO1/lego/legoomni/src/common/legoplantmanager.cpp LEGO1/lego/legoomni/src/common/legostate.cpp @@ -46,10 +44,13 @@ add_library(lego1 SHARED LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp LEGO1/lego/legoomni/src/entity/legoactor.cpp LEGO1/lego/legoomni/src/entity/legoanimactor.cpp + LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp LEGO1/lego/legoomni/src/entity/legoentity.cpp LEGO1/lego/legoomni/src/entity/legoentitypresenter.cpp LEGO1/lego/legoomni/src/entity/legojetski.cpp + LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp LEGO1/lego/legoomni/src/entity/legopathactor.cpp + LEGO1/lego/legoomni/src/entity/legopovcontroller.cpp LEGO1/lego/legoomni/src/entity/legorace.cpp LEGO1/lego/legoomni/src/entity/legoworld.cpp LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp diff --git a/LEGO1/lego/legoomni/include/legocameracontroller.h b/LEGO1/lego/legoomni/include/legocameracontroller.h index 09785df1..660ee5ae 100644 --- a/LEGO1/lego/legoomni/include/legocameracontroller.h +++ b/LEGO1/lego/legoomni/include/legocameracontroller.h @@ -1,17 +1,21 @@ #ifndef LEGOCAMERACONTROLLER_H #define LEGOCAMERACONTROLLER_H +#include "legopointofviewcontroller.h" #include "mxcore.h" +#include "mxpoint32.h" #include "realtime/matrix.h" #include "realtime/vector.h" // VTABLE: LEGO1 0x100d57b0 // SIZE 0xc8 -class LegoCameraController : public MxCore { +class LegoCameraController : public LegoPointOfViewController { public: LegoCameraController(); virtual ~LegoCameraController() override; // vtable+0x0 + virtual MxLong Notify(MxParam& p_param) override; // vtable+04 + // FUNCTION: LEGO1 0x10011ec0 inline virtual const char* ClassName() const override // vtable+0x0c { @@ -25,11 +29,22 @@ class LegoCameraController : public MxCore { return !strcmp(p_name, ClassName()) || MxCore::IsA(p_name); } - void LookAt(Vector3Impl& p_at, Vector3Impl& p_dir, Vector3Impl& p_up); + virtual void OnLButtonDown(MxPoint32 p_point) override; // vtable+0x30 + virtual void OnLButtonUp(MxPoint32 p_point) override; // vtable+0x34 + virtual void OnRButtonDown(MxPoint32 p_point) override; // vtable+0x38 + virtual void OnRButtonUp(MxPoint32 p_point) override; // vtable+0x3c + virtual void OnMouseMove(MxU8 p_modifier, MxPoint32 p_point) override; // vtable+0x40 + virtual MxResult Create(); // vtable+0x44 + + void SetWorldTransform(Vector3Impl& p_at, Vector3Impl& p_dir, Vector3Impl& p_up); void FUN_100123e0(Matrix4Data& p_transform, MxU32); Vector3Data& FUN_10012740(); Vector3Data& FUN_100127f0(); Vector3Data& FUN_100128a0(); + +private: + Matrix4Data m_matrix1; // 0x38 + Matrix4Data m_matrix2; // 0x80 }; #endif // LEGOCAMERACONTROLLER_H diff --git a/LEGO1/lego/legoomni/include/legoinputmanager.h b/LEGO1/lego/legoomni/include/legoinputmanager.h index fcb9b560..961d8ffc 100644 --- a/LEGO1/lego/legoomni/include/legoinputmanager.h +++ b/LEGO1/lego/legoomni/include/legoinputmanager.h @@ -56,6 +56,7 @@ class LegoInputManager : public MxPresenter { inline LegoControlManager* GetControlManager() { return m_controlManager; } inline LegoWorld* GetWorld() { return m_world; } + inline LegoCameraController* GetCamera() { return m_camera; } void ProcessEvents(); MxBool ProcessOneEvent(LegoEventNotificationParam& p_param); diff --git a/LEGO1/lego/legoomni/include/legonavcontroller.h b/LEGO1/lego/legoomni/include/legonavcontroller.h index c6505341..97882566 100644 --- a/LEGO1/lego/legoomni/include/legonavcontroller.h +++ b/LEGO1/lego/legoomni/include/legonavcontroller.h @@ -59,6 +59,8 @@ class LegoNavController : public MxCore { float CalculateNewAccel(int p_pos, int p_center, float p_maxAccel, int p_minAccel); float CalculateNewVel(float p_targetVel, float p_currentVel, float p_accel, float p_time); + inline void SetTrackDefaultParams(MxBool p_trackDefault) { m_trackDefault = p_trackDefault; } + private: int m_hMax; int m_vMax; diff --git a/LEGO1/lego/legoomni/include/legonotify.h b/LEGO1/lego/legoomni/include/legonotify.h new file mode 100644 index 00000000..ed4218b2 --- /dev/null +++ b/LEGO1/lego/legoomni/include/legonotify.h @@ -0,0 +1,11 @@ +#ifndef LEGONOTIFY_H +#define LEGONOTIFY_H + +enum LegoEventNotificationParamType { + c_lButtonState = 1, + c_rButtonState = 2, + c_modKey1 = 4, + c_modKey2 = 8, +}; + +#endif // LEGONOTIFY_H diff --git a/LEGO1/lego/legoomni/include/legoomni.h b/LEGO1/lego/legoomni/include/legoomni.h index 77cf47f5..fc9ba1c2 100644 --- a/LEGO1/lego/legoomni/include/legoomni.h +++ b/LEGO1/lego/legoomni/include/legoomni.h @@ -102,7 +102,6 @@ class LegoOmni : public MxOmni { LegoVideoManager* GetVideoManager() { return (LegoVideoManager*) m_videoManager; } LegoSoundManager* GetSoundManager() { return (LegoSoundManager*) m_soundManager; } - LegoInputManager* GetInputManager() { return m_inputMgr; } GifManager* GetGifManager() { return m_gifManager; } LegoWorld* GetCurrentOmniWorld() { return m_currentWorld; } @@ -116,6 +115,8 @@ class LegoOmni : public MxOmni { MxTransitionManager* GetTransitionManager() { return m_transitionManager; } MxDSAction& GetCurrentAction() { return m_action; } + inline void SetNavController(LegoNavController* p_navController) { m_navController = p_navController; } + inline void SetExit(MxBool p_exit) { m_exit = p_exit; }; private: diff --git a/LEGO1/lego/legoomni/include/legopointofviewcontroller.h b/LEGO1/lego/legoomni/include/legopointofviewcontroller.h new file mode 100644 index 00000000..f0f8c3b1 --- /dev/null +++ b/LEGO1/lego/legoomni/include/legopointofviewcontroller.h @@ -0,0 +1,94 @@ +#ifndef LEGOPOINTOFVIEWCONTROLLER_H +#define LEGOPOINTOFVIEWCONTROLLER_H + +#include "decomp.h" +#include "mxcore.h" + +#include + +class Lego3DView; +class LegoEntity; +class LegoNavController; + +////////////////////////////////////////////////////////////////////////////// +// +// LegoMouseController + +// VTABLE: LEGO1 0x100d8dd8 +// SIZE 0x20 +class LegoMouseController : public MxCore { +public: + LegoMouseController(); + virtual ~LegoMouseController() override; + + virtual void LeftDown(int, int); // vtable+0x14 + virtual void LeftDrag(int, int); // vtable+0x18 + virtual void LeftUp(int, int); // vtable+0x1c + virtual void RightDown(int, int); // vtable+0x20 + virtual void RightDrag(int, int); // vtable+0x24 + virtual void RightUp(int, int); // vtable+0x28 + +private: + BOOL m_isButtonDown; // 0x08 + undefined4 m_unk0xc; // 0x0c + MxDouble m_buttonX; // 0x10 + MxDouble m_buttonY; // 0x18 +}; + +// VTABLE: LEGO1 0x100d8e08 +// SIZE 0x38 +class LegoPointOfViewController : public LegoMouseController { +public: + LegoPointOfViewController(); + virtual ~LegoPointOfViewController() override; + + virtual MxResult Tickle() override; // vtable+0x08 + virtual void LeftDown(int p_x, int p_y) override; // vtable+0x0c + virtual void LeftDrag(int p_x, int p_y) override; // vtable+0x10 + + // FUNCTION: LEGO1 0x10011e40 + virtual void LeftUp(int p_x, int p_y) override + { + LegoMouseController::LeftUp(p_x, p_y); + AffectPointOfView(); + } + // vtable+0x14 + + // FUNCTION: LEGO1 0x10011e60 + virtual void RightDown(int p_x, int p_y) override + { + LegoMouseController::RightDown(p_x, p_y); + AffectPointOfView(); + } + // vtable+0x20 + + // FUNCTION: LEGO1 0x10011e80 + virtual void RightDrag(int p_x, int p_y) override + { + LegoMouseController::RightDrag(p_x, p_y); + AffectPointOfView(); + } + // vtable+0x24 + + // FUNCTION: LEGO1 0x10011ea0 + virtual void RightUp(int p_x, int p_y) override + { + LegoMouseController::RightUp(p_x, p_y); + AffectPointOfView(); + } // vtable+0x28 + virtual void SetEntity(LegoEntity* p_entity); // vtable+0x2c + + MxResult Create(Lego3DView* p_lego3DView); + + inline LegoEntity* GetEntity() { return m_entity; } + +protected: + void AffectPointOfView(); + + Lego3DView* m_lego3DView; // 0x20 + LegoEntity* m_entity; // 0x24 + MxDouble m_entityOffsetUp; // 0x28 + LegoNavController* m_nav; // 0x30 +}; + +#endif /* LEGOPOINTOFVIEWCONTROLLER_H */ diff --git a/LEGO1/lego/legoomni/src/build/helicopter.cpp b/LEGO1/lego/legoomni/src/build/helicopter.cpp index 87ee1dcb..f4220183 100644 --- a/LEGO1/lego/legoomni/src/build/helicopter.cpp +++ b/LEGO1/lego/legoomni/src/build/helicopter.cpp @@ -238,7 +238,7 @@ MxU32 Helicopter::VTable0xd8(MxType18NotificationParam& p_param) mat.GetMatrix()[i][2] = mat2[i][2] * c + mat2[i][1] * s; } Vector3Impl at(mat.GetMatrix()[3]), dir(mat.GetMatrix()[2]), up(mat.GetMatrix()[1]); - m_world->GetCamera()->LookAt(at, dir, up); + m_world->GetCamera()->SetWorldTransform(at, dir, up); FUN_10010c30(); break; } @@ -247,7 +247,7 @@ MxU32 Helicopter::VTable0xd8(MxType18NotificationParam& p_param) mat.SetIdentity(); Vector3Impl at(mat.GetMatrix()[3]), dir(mat.GetMatrix()[2]), up(mat.GetMatrix()[1]); at[1] = 1.25; - m_world->GetCamera()->LookAt(at, dir, up); + m_world->GetCamera()->SetWorldTransform(at, dir, up); if (GameState()->GetUnknown10() == 0) { ((Act1State*) GameState()->GetState("Act1State"))->SetUnknown18(0); VTable0xe8(0x29, TRUE, 7); diff --git a/LEGO1/lego/legoomni/src/common/legocameracontroller.cpp b/LEGO1/lego/legoomni/src/common/legocameracontroller.cpp deleted file mode 100644 index ad1dbb67..00000000 --- a/LEGO1/lego/legoomni/src/common/legocameracontroller.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "legocameracontroller.h" - -// STUB: LEGO1 0x10011d50 -LegoCameraController::LegoCameraController() -{ - // TODO -} - -// STUB: LEGO1 0x10011f70 -LegoCameraController::~LegoCameraController() -{ - // TODO -} - -// STUB: LEGO1 0x10012260 -void LegoCameraController::LookAt(Vector3Impl& p_at, Vector3Impl& p_dir, Vector3Impl& p_up) -{ -} - -// STUB: LEGO1 0x100123e0 -void LegoCameraController::FUN_100123e0(Matrix4Data& p_transform, MxU32) -{ -} - -// STUB: LEGO1 0x10012740 -Vector3Data& LegoCameraController::FUN_10012740() -{ - // Actually returns reference to a member - static Vector3Data g_v; - return g_v; -} - -// STUB: LEGO1 0x100127f0 -Vector3Data& LegoCameraController::FUN_100127f0() -{ - // Actually returns reference to a member - static Vector3Data g_v; - return g_v; -} - -// STUB: LEGO1 0x100128a0 -Vector3Data& LegoCameraController::FUN_100128a0() -{ - // Actually returns reference to a member - static Vector3Data g_v; - return g_v; -} diff --git a/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp b/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp new file mode 100644 index 00000000..34afaac0 --- /dev/null +++ b/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp @@ -0,0 +1,107 @@ +#include "legocameracontroller.h" + +#include "legoinputmanager.h" +#include "legonotify.h" +#include "legoomni.h" +#include "legovideomanager.h" + +DECOMP_SIZE_ASSERT(LegoCameraController, 0xc8); + +// FUNCTION: LEGO1 0x10011d50 +LegoCameraController::LegoCameraController() +{ + SetWorldTransform(Vector3Data(0, 0, 0), Vector3Data(0, 0, 1), Vector3Data(0, 1, 0)); +} + +// FUNCTION: LEGO1 0x10011f70 +LegoCameraController::~LegoCameraController() +{ + if (InputManager()) { + if (InputManager()->GetCamera() == this) { + InputManager()->ClearCamera(); + } + } +} + +// FUNCTION: LEGO1 0x10011ff0 +MxResult LegoCameraController::Create() +{ + InputManager()->SetCamera(this); + return LegoPointOfViewController::Create(VideoManager()->Get3DManager()->GetLego3DView()); +} + +// STUB: LEGO1 0x10012020 +MxLong LegoCameraController::Notify(MxParam& p_param) +{ + // TODO + return 0; +} + +// FUNCTION: LEGO1 0x100121b0 +void LegoCameraController::OnLButtonDown(MxPoint32 p_point) +{ + LeftDown(p_point.GetX(), p_point.GetY()); +} + +// FUNCTION: LEGO1 0x100121d0 +void LegoCameraController::OnLButtonUp(MxPoint32 p_point) +{ + LeftUp(p_point.GetX(), p_point.GetY()); +} + +// FUNCTION: LEGO1 0x100121f0 +void LegoCameraController::OnRButtonDown(MxPoint32 p_point) +{ + RightDown(p_point.GetX(), p_point.GetY()); +} + +// FUNCTION: LEGO1 0x10012210 +void LegoCameraController::OnRButtonUp(MxPoint32 p_point) +{ + RightUp(p_point.GetX(), p_point.GetY()); +} + +// FUNCTION: LEGO1 0x10012230 +void LegoCameraController::OnMouseMove(MxU8 p_modifier, MxPoint32 p_point) +{ + if (p_modifier & c_lButtonState) + LeftDrag(p_point.GetX(), p_point.GetY()); + else if (p_modifier & c_rButtonState) + RightDrag(p_point.GetX(), p_point.GetY()); +} + +// FUNCTION: LEGO1 0x10012260 +void LegoCameraController::SetWorldTransform(Vector3Impl& p_at, Vector3Impl& p_dir, Vector3Impl& p_up) +{ + CalcLocalTransform(p_at, p_dir, p_up, m_matrix1); + m_matrix2 = m_matrix1; +} + +// STUB: LEGO1 0x100123e0 +void LegoCameraController::FUN_100123e0(Matrix4Data& p_transform, MxU32) +{ +} + +// STUB: LEGO1 0x10012740 +Vector3Data& LegoCameraController::FUN_10012740() +{ + // Actually returns reference to a member + static Vector3Data g_v; + return g_v; +} + +// STUB: LEGO1 0x100127f0 +Vector3Data& LegoCameraController::FUN_100127f0() +{ + // Actually returns reference to a member + static Vector3Data g_v; + return g_v; +} + +// STUB: LEGO1 0x100128a0 +Vector3Data& LegoCameraController::FUN_100128a0() +{ + // Actually returns reference to a member + static Vector3Data g_v; + return g_v; +} diff --git a/LEGO1/lego/legoomni/src/common/legonavcontroller.cpp b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp similarity index 100% rename from LEGO1/lego/legoomni/src/common/legonavcontroller.cpp rename to LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp diff --git a/LEGO1/lego/legoomni/src/entity/legopovcontroller.cpp b/LEGO1/lego/legoomni/src/entity/legopovcontroller.cpp new file mode 100644 index 00000000..a2e1bb04 --- /dev/null +++ b/LEGO1/lego/legoomni/src/entity/legopovcontroller.cpp @@ -0,0 +1,134 @@ +#include "legonavcontroller.h" +#include "legoomni.h" +#include "legopointofviewcontroller.h" +#include "mxticklemanager.h" + +DECOMP_SIZE_ASSERT(LegoMouseController, 0x20); +DECOMP_SIZE_ASSERT(LegoPointOfViewController, 0x38); + +////////////////////////////////////////////////////////////////////// + +// FUNCTION: LEGO1 0x10065550 +LegoMouseController::LegoMouseController() +{ + m_isButtonDown = FALSE; +} + +// FUNCTION: LEGO1 0x100655d0 +LegoMouseController::~LegoMouseController() +{ +} + +// FUNCTION: LEGO1 0x10065620 +void LegoMouseController::LeftDown(int p_x, int p_y) +{ + m_isButtonDown = TRUE; + m_buttonX = p_x; + m_buttonY = p_y; +} + +// FUNCTION: LEGO1 0x10065640 +void LegoMouseController::LeftUp(int p_x, int p_y) +{ + m_isButtonDown = FALSE; + m_buttonX = p_x; + m_buttonY = p_y; +} + +// FUNCTION: LEGO1 0x10065660 +void LegoMouseController::LeftDrag(int p_x, int p_y) +{ + m_buttonX = p_x; + m_buttonY = p_y; +} + +// FUNCTION: LEGO1 0x10065680 +void LegoMouseController::RightDown(int p_x, int p_y) +{ + m_isButtonDown = TRUE; + m_buttonX = p_x; + m_buttonY = p_y; +} + +// FUNCTION: LEGO1 0x100656a0 +void LegoMouseController::RightUp(int p_x, int p_y) +{ + m_isButtonDown = FALSE; + m_buttonX = p_x; + m_buttonY = p_y; +} + +// FUNCTION: LEGO1 0x100656c0 +void LegoMouseController::RightDrag(int p_x, int p_y) +{ + m_buttonX = p_x; + m_buttonY = p_y; +} + +////////////////////////////////////////////////////////////////////// + +// FUNCTION: LEGO1 0x100656e0 +LegoPointOfViewController::LegoPointOfViewController() +{ + m_lego3DView = NULL; + m_entity = NULL; + m_nav = NULL; + // m_entityOffsetUp is a temporary kludge. It should be replaced + // by 3D camera offset and position stored in the entity since each + // entity may have a different best viewpoint. + m_entityOffsetUp = 0.0; +} + +// FUNCTION: LEGO1 0x10065770 +LegoPointOfViewController::~LegoPointOfViewController() +{ + TickleManager()->UnregisterClient(this); + if (m_nav) { + delete m_nav; + m_nav = NULL; + } +} + +// FUNCTION: LEGO1 0x100657f0 +MxResult LegoPointOfViewController::Create(Lego3DView* p_lego3DView) +{ + m_lego3DView = p_lego3DView; + m_nav = new LegoNavController(); + LegoOmni::GetInstance()->SetNavController(m_nav); + m_nav->SetTrackDefaultParams(TRUE); + TickleManager()->RegisterClient(this, 10); + return SUCCESS; +} + +// FUNCTION: LEGO1 0x100658c0 +void LegoPointOfViewController::LeftDown(int p_x, int p_y) +{ + LegoMouseController::LeftDown(p_x, p_y); + AffectPointOfView(); +} + +// FUNCTION: LEGO1 0x100658e0 +void LegoPointOfViewController::LeftDrag(int p_x, int p_y) +{ + LegoMouseController::LeftDrag(p_x, p_y); + AffectPointOfView(); +} + +// STUB: LEGO1 0x10065900 +void LegoPointOfViewController::AffectPointOfView() +{ + // TODO +} + +// STUB: LEGO1 0x10065930 +MxResult LegoPointOfViewController::Tickle() +{ + // TODO + return SUCCESS; +} + +// STUB: LEGO1 0x10065ae0 +void LegoPointOfViewController::SetEntity(LegoEntity* p_entity) +{ + // TODO +}