diff --git a/CMakeLists.txt b/CMakeLists.txt index eb5f1c25..47b7cc23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,6 @@ 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 @@ -46,10 +45,12 @@ 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/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..1d8aaa9c 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); // vtable+04 + // FUNCTION: LEGO1 0x10011ec0 inline virtual const char* ClassName() const override // vtable+0x0c { @@ -25,11 +29,30 @@ class LegoCameraController : public MxCore { return !strcmp(p_name, ClassName()) || MxCore::IsA(p_name); } + virtual void OnLButtonDown(MxPoint32 p_point); // vtable+0x30 + virtual void OnLButtonUp(MxPoint32 p_point); // vtable+0x34 + virtual void OnRButtonDown(MxPoint32 p_point); // vtable+0x38 + virtual void OnRButtonUp(MxPoint32 p_point); // vtable+0x3c + virtual void OnMouseMove(MxU8 p_modifier, MxPoint32 p_point); // vtable+0x40 + virtual MxResult Initialize(); // vtable+0x44 + void LookAt(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 +}; + +// todo: move to legonotify.h +enum LegoEventNotificationParamType { + c_lButtonState = 1, + c_rButtonState = 2, + c_modKey1 = 4, + c_modKey2 = 8, }; #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/legopointofviewcontroller.h b/LEGO1/lego/legoomni/include/legopointofviewcontroller.h new file mode 100644 index 00000000..f020acfd --- /dev/null +++ b/LEGO1/lego/legoomni/include/legopointofviewcontroller.h @@ -0,0 +1,89 @@ +#ifndef LEGOPOINTOFVIEWCONTROLLER_H +#define LEGOPOINTOFVIEWCONTROLLER_H +#include "decomp.h" +#include "mxcore.h" + +class Lego3DView; +class LegoEntity; +class LegoNavController; + +////////////////////////////////////////////////////////////////////////////// +// +// LegoMouseController + +// VTABLE: LEGO1 0x10065550 +class LegoMouseController : public MxCore { +public: + LegoMouseController(); + ~LegoMouseController(); + + 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: + // note: in the leaked source code, this is a bool (which is typedefed to int) + MxU32 m_isButtonDown; // 0x08 + undefined4 m_unk0xc; // 0x0c + MxDouble m_buttonX; // 0x10 + MxDouble m_buttonY; // 0x18 +}; + +// VTABLE: LEGO1 0x100d8e08 +class LegoPointOfViewController : public LegoMouseController { +public: + LegoPointOfViewController(); + ~LegoPointOfViewController(); + + virtual MxResult Tickle(); // vtable+0x08 + + MxResult Create(Lego3DView* p_lego3DView); + + void LeftDown(int x, int y); + void LeftDrag(int x, int y); + + // FUNCTION: LEGO1 0x10011e40 + virtual void LeftUp(int x, int y) + { + LegoMouseController::LeftUp(x, y); + AffectPointOfView(); + } + override; // vtable+0x14 + + // FUNCTION: LEGO1 0x10011e60 + virtual void RightDown(int x, int y) + { + LegoMouseController::RightDown(x, y); + AffectPointOfView(); + } + override; // vtable+0x20 + + // FUNCTION: LEGO1 0x10011e80 + virtual void RightDrag(int x, int y) + { + LegoMouseController::RightDrag(x, y); + AffectPointOfView(); + } + override; // vtable+0x24 + + // FUNCTION: LEGO1 0x10011ea0 + virtual void RightUp(int x, int y) + { + LegoMouseController::RightUp(x, y); + AffectPointOfView(); + } + override; // vtable+0x28 + virtual void SetEntity(LegoEntity* p_entity); // vtable+0x2c + LegoEntity* GetEntity() { return m_entity; } + +protected: + void AffectPointOfView(); + Lego3DView* m_lego3DView; // 0x20 + LegoEntity* m_entity; // 0x24 + double m_entityOffsetUp; // 0x28 + LegoNavController* m_nav; // 0x30 +}; +#endif /* LEGOPOINTOFVIEWCONTROLLER_H */ 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..d066e08a --- /dev/null +++ b/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp @@ -0,0 +1,106 @@ +#include "legocameracontroller.h" + +#include "legoinputmanager.h" +#include "legoomni.h" +#include "legovideomanager.h" + +DECOMP_SIZE_ASSERT(LegoCameraController, 0xc8); + +// FUNCTION: LEGO1 0x10011d50 +LegoCameraController::LegoCameraController() +{ + LookAt(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::Initialize() +{ + InputManager()->SetCamera(this); + return LegoPointOfViewController::Create(VideoManager()->Get3DManager()->GetLego3DView()); +} + +// FUNCTION: LEGO1 0x10012260 +void LegoCameraController::LookAt(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; +} + +// 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()); +} diff --git a/LEGO1/lego/legoomni/src/entity/legopovcontroller.cpp b/LEGO1/lego/legoomni/src/entity/legopovcontroller.cpp new file mode 100644 index 00000000..5ca9ab5b --- /dev/null +++ b/LEGO1/lego/legoomni/src/entity/legopovcontroller.cpp @@ -0,0 +1,129 @@ +#include "legonavcontroller.h" +#include "legoomni.h" +#include "legopointofviewcontroller.h" +#include "mxticklemanager.h" + +////////////////////////////////////////////////////////////////////// + +// FUNCTION: LEGO1 0x10065550 +LegoMouseController::LegoMouseController() +{ + m_isButtonDown = 0; +} + +// FUNCTION: LEGO1 0x100655d0 +LegoMouseController::~LegoMouseController() +{ +} + +// FUNCTION: LEGO1 0x10065620 +void LegoMouseController::LeftDown(int x, int y) +{ + m_isButtonDown = 1; + m_buttonX = x; + m_buttonY = y; +} + +// FUNCTION: LEGO1 0x10065640 +void LegoMouseController::LeftUp(int x, int y) +{ + m_isButtonDown = 0; + m_buttonX = x; + m_buttonY = y; +} + +// FUNCTION: LEGO1 0x10065660 +void LegoMouseController::LeftDrag(int x, int y) +{ + m_buttonX = x; + m_buttonY = y; +} + +// FUNCTION: LEGO1 0x10065680 +void LegoMouseController::RightDown(int x, int y) +{ + m_isButtonDown = 1; + m_buttonX = x; + m_buttonY = y; +} + +// FUNCTION: LEGO1 0x100656a0 +void LegoMouseController::RightUp(int x, int y) +{ + m_isButtonDown = 0; + m_buttonX = x; + m_buttonY = y; +} + +// FUNCTION: LEGO1 0x100656c0 +void LegoMouseController::RightDrag(int x, int y) +{ + m_buttonX = x; + m_buttonY = 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(); + m_nav->SetTrackDefaultParams(TRUE); + LegoOmni::GetInstance()->GetTickleManager()->RegisterClient(this, 10); + return SUCCESS; +} + +// FUNCTION: LEGO1 0x100658c0 +void LegoPointOfViewController::LeftDown(int x, int y) +{ + LegoMouseController::LeftDown(x, y); + AffectPointOfView(); +} + +// FUNCTION: LEGO1 0x100658e0 +void LegoPointOfViewController::LeftDrag(int x, int y) +{ + LegoMouseController::LeftDrag(x, y); + AffectPointOfView(); +} + +// STUB: LEGO1 0x10065900 +void LegoPointOfViewController::AffectPointOfView() +{ + // TODO +} + +// STUB: LEGO1 0x10065ae0 +void LegoPointOfViewController::SetEntity(LegoEntity* p_entity) +{ + // TODO +} + +// STUB: LEGO1 0x10065930 +MxResult LegoPointOfViewController::Tickle() +{ // TODO + return SUCCESS; +}