diff --git a/LEGO1/lego/legoomni/include/legocontrolmanager.h b/LEGO1/lego/legoomni/include/legocontrolmanager.h index e2861885..5b83a715 100644 --- a/LEGO1/lego/legoomni/include/legocontrolmanager.h +++ b/LEGO1/lego/legoomni/include/legocontrolmanager.h @@ -1,6 +1,7 @@ #ifndef LEGOCONTROLMANAGER_H #define LEGOCONTROLMANAGER_H +#include "legoeventnotificationparam.h" #include "mxcore.h" #include "mxpresenterlist.h" @@ -28,13 +29,20 @@ class LegoControlManager : public MxCore { void FUN_10028df0(MxPresenterList* p_presenterList); void Register(MxCore* p_listener); void Unregister(MxCore* p_listener); + MxBool FUN_10029210(LegoEventNotificationParam& p_param, MxPresenter* p_presenter); void FUN_100293c0(undefined4, const char*, undefined2); + inline undefined4 GetUnknown0x0c() { return m_unk0x0c; } + inline undefined GetUnknown0x10() { return m_unk0x10; } + // SYNTHETIC: LEGO1 0x10028d40 // LegoControlManager::`scalar deleting destructor' private: - undefined m_padding0x08[0x58]; // 0x08 + undefined4 m_unk0x08; // 0x08 + undefined4 m_unk0x0c; // 0x0c + undefined m_unk0x10; // 0x10 + undefined m_padding0x14[0x4c]; // 0x14 }; #endif // LEGOCONTROLMANAGER_H diff --git a/LEGO1/lego/legoomni/include/legoeventnotificationparam.h b/LEGO1/lego/legoomni/include/legoeventnotificationparam.h index a27ee9df..9eb6c7b5 100644 --- a/LEGO1/lego/legoomni/include/legoeventnotificationparam.h +++ b/LEGO1/lego/legoomni/include/legoeventnotificationparam.h @@ -3,6 +3,7 @@ #include "mxnotificationparam.h" #include "mxtypes.h" +#include "roi/legoroi.h" #include @@ -15,7 +16,7 @@ class LegoEventNotificationParam : public MxNotificationParam { { LegoEventNotificationParam* clone = new LegoEventNotificationParam(m_type, m_sender, m_modifier, m_x, m_y, m_key); - clone->m_unk0x1c = m_unk0x1c; + clone->m_roi = m_roi; return clone; }; // vtable+0x4 @@ -28,7 +29,7 @@ class LegoEventNotificationParam : public MxNotificationParam { MxS32 p_y, MxU8 p_key ) - : MxNotificationParam(p_type, p_sender), m_modifier(p_modifier), m_x(p_x), m_y(p_y), m_key(p_key), m_unk0x1c(0) + : MxNotificationParam(p_type, p_sender), m_modifier(p_modifier), m_x(p_x), m_y(p_y), m_key(p_key), m_roi(NULL) { } @@ -37,12 +38,14 @@ class LegoEventNotificationParam : public MxNotificationParam { inline MxS32 GetX() const { return m_x; } inline MxS32 GetY() const { return m_y; } + inline void SetROI(LegoROI* p_roi) { m_roi = p_roi; } + protected: MxU8 m_modifier; // 0x0c MxS32 m_x; // 0x10 MxS32 m_y; // 0x14 MxU8 m_key; // 0x18 - MxU32 m_unk0x1c; // 0x1c + LegoROI* m_roi; // 0x1c }; // SYNTHETIC: LEGO1 0x10028770 diff --git a/LEGO1/lego/legoomni/include/legoinputmanager.h b/LEGO1/lego/legoomni/include/legoinputmanager.h index 89e30dc7..eada8f70 100644 --- a/LEGO1/lego/legoomni/include/legoinputmanager.h +++ b/LEGO1/lego/legoomni/include/legoinputmanager.h @@ -83,8 +83,8 @@ class LegoInputManager : public MxPresenter { void ReleaseDX(); MxResult GetJoystickId(); MxResult GetJoystickState(MxU32* p_joystickX, MxU32* p_joystickY, DWORD* p_buttonsState, MxU32* p_povPosition); - void SetTimer(); - void KillTimer(); + void StartAutoDragTimer(); + void StopAutoDragTimer(); void EnableInputProcessing(); void SetCamera(LegoCameraController* p_camera); void ClearCamera(); @@ -109,6 +109,7 @@ class LegoInputManager : public MxPresenter { void ProcessEvents(); MxBool ProcessOneEvent(LegoEventNotificationParam& p_param); + MxBool FUN_1005cdf0(LegoEventNotificationParam& p_param); // SYNTHETIC: LEGO1 0x1005b8d0 // LegoInputManager::`scalar deleting destructor' @@ -122,8 +123,8 @@ class LegoInputManager : public MxPresenter { undefined4 m_unk0x6c; // 0x6c undefined4 m_unk0x70; // 0x70 undefined4 m_unk0x74; // 0x74 - UINT m_timer; // 0x78 - UINT m_timeout; // 0x7c + UINT m_autoDragTimerID; // 0x78 + UINT m_autoDragTime; // 0x7c undefined m_unk0x80; // 0x80 undefined m_unk0x81; // 0x81 LegoControlManager* m_controlManager; // 0x84 diff --git a/LEGO1/lego/legoomni/include/legovideomanager.h b/LEGO1/lego/legoomni/include/legovideomanager.h index 72cb2148..ce9963e4 100644 --- a/LEGO1/lego/legoomni/include/legovideomanager.h +++ b/LEGO1/lego/legoomni/include/legovideomanager.h @@ -31,7 +31,8 @@ class LegoVideoManager : public MxVideoManager { override; // vtable+0x2c virtual MxResult RealizePalette(MxPalette*) override; // vtable+0x30 virtual void UpdateView(MxU32 p_x, MxU32 p_y, MxU32 p_width, MxU32 p_height) override; // vtable+0x34 - virtual void VTable0x38(undefined4, undefined4); // vtable+0x38 + virtual MxPresenter* GetPresenterAt(MxS32 p_x, MxS32 p_y); // vtable+0x38 + // FUNCTION: LEGO1 0x1007ab10 virtual LegoUnknown100d9d00* VTable0x3c() { return m_unk0x100d9d00; } // vtable+0x3c diff --git a/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp b/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp index 5b51b8ec..465ccf9f 100644 --- a/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp +++ b/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp @@ -1,5 +1,8 @@ #include "legocontrolmanager.h" +#include "legoeventnotificationparam.h" +#include "mxpresenter.h" + DECOMP_SIZE_ASSERT(LegoControlManager, 0x60); // STUB: LEGO1 0x10028520 @@ -32,6 +35,12 @@ void LegoControlManager::Unregister(MxCore* p_listener) // TODO } +// STUB: LEGO1 0x10029210 +MxBool LegoControlManager::FUN_10029210(LegoEventNotificationParam& p_param, MxPresenter* p_presenter) +{ + return TRUE; +} + // STUB: LEGO1 0x100293c0 void LegoControlManager::FUN_100293c0(undefined4, const char*, undefined2) { diff --git a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp index 2a551c71..05f09061 100644 --- a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp +++ b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp @@ -2,7 +2,9 @@ #include "legocontrolmanager.h" #include "legoomni.h" +#include "legovideomanager.h" #include "mxautolocker.h" +#include "roi/legoroi.h" DECOMP_SIZE_ASSERT(LegoInputManager, 0x338) DECOMP_SIZE_ASSERT(LegoNotifyList, 0x18) @@ -23,7 +25,7 @@ LegoInputManager::LegoInputManager() m_camera = NULL; m_eventQueue = NULL; m_unk0x80 = 0; - m_timer = 0; + m_autoDragTimerID = 0; m_unk0x6c = 0; m_unk0x70 = 0; m_controlManager = NULL; @@ -39,7 +41,7 @@ LegoInputManager::LegoInputManager() m_unk0x335 = FALSE; m_unk0x336 = FALSE; m_unk0x74 = 0x19; - m_timeout = 1000; + m_autoDragTime = 1000; } // FUNCTION: LEGO1 0x1005b8b0 @@ -279,28 +281,142 @@ void LegoInputManager::ProcessEvents() } } -// STUB: LEGO1 0x1005c9c0 +// FUNCTION: LEGO1 0x1005c9c0 MxBool LegoInputManager::ProcessOneEvent(LegoEventNotificationParam& p_param) +{ + MxBool processRoi; + + if (p_param.GetType() == c_notificationKeyPress) { + if (!Lego()->IsTimerRunning() || p_param.GetKey() == 0x13) { + if (p_param.GetKey() == 0x10) { + if (m_unk0x195) { + m_unk0x80 = 0; + p_param.SetType(c_notificationDrag); + + if (m_camera) { + m_camera->Notify(p_param); + } + } + + m_unk0x195 = !m_unk0x195; + return TRUE; + } + + LegoNotifyListCursor cursor(m_keyboardNotifyList); + MxCore* target; + + while (cursor.Next(target)) { + if (target->Notify(p_param) != 0) { + return TRUE; + } + } + } + } + else { + if (!Lego()->IsTimerRunning()) { + processRoi = TRUE; + + if (m_unk0x335 != 0) { + if (p_param.GetType() == c_notificationButtonDown) { + LegoEventNotificationParam notification(c_notificationKeyPress, NULL, 0, 0, 0, ' '); + LegoNotifyListCursor cursor(m_keyboardNotifyList); + MxCore* target; + + while (cursor.Next(target)) { + if (target->Notify(notification) != 0) { + return TRUE; + } + } + } + + return TRUE; + } + + if (m_unk0x195 && p_param.GetType() == c_notificationButtonDown) { + m_unk0x195 = 0; + return TRUE; + } + + if (m_world != NULL && m_world->Notify(p_param) != 0) { + return TRUE; + } + + if (p_param.GetType() == c_notificationButtonDown) { + MxPresenter* presenter = VideoManager()->GetPresenterAt(p_param.GetX(), p_param.GetY()); + + if (presenter) { + if (presenter->GetDisplayZ() < 0) { + processRoi = FALSE; + + if (m_controlManager->FUN_10029210(p_param, presenter)) { + return TRUE; + } + } + else { + LegoROI* roi = PickROI(p_param.GetX(), p_param.GetY()); + + if (roi == NULL && m_controlManager->FUN_10029210(p_param, presenter)) { + return TRUE; + } + } + } + } + else if (p_param.GetType() == c_notificationButtonUp) { + if (g_unk0x100f31b0 != -1 || m_controlManager->GetUnknown0x10() || + m_controlManager->GetUnknown0x0c() == 1) { + MxBool result = m_controlManager->FUN_10029210(p_param, NULL); + StopAutoDragTimer(); + + m_unk0x80 = 0; + m_unk0x81 = 0; + return result; + } + } + + if (FUN_1005cdf0(p_param)) { + if (processRoi && p_param.GetType() == c_notificationType11) { + LegoROI* roi = PickROI(p_param.GetX(), p_param.GetY()); + p_param.SetROI(roi); + + if (roi && roi->GetUnk0x0c() == 1) { + for (OrientableROI* oroi = roi->GetUnknown0xd4(); oroi; oroi = oroi->GetUnknown0xd4()) + roi = (LegoROI*) oroi; + + LegoEntity* entity = roi->GetUnknown0x104(); + if (entity && entity->Notify(p_param) != 0) { + return TRUE; + } + } + } + + if (m_camera && m_camera->Notify(p_param) != 0) { + return TRUE; + } + } + } + } + + return FALSE; +} + +// STUB: LEGO1 0x1005cdf0 +MxBool LegoInputManager::FUN_1005cdf0(LegoEventNotificationParam& p_param) { // TODO return FALSE; } // FUNCTION: LEGO1 0x1005cfb0 -void LegoInputManager::SetTimer() +void LegoInputManager::StartAutoDragTimer() { - LegoOmni* omni = LegoOmni::GetInstance(); - UINT timer = ::SetTimer(omni->GetWindowHandle(), 1, m_timeout, NULL); - m_timer = timer; + m_autoDragTimerID = ::SetTimer(LegoOmni::GetInstance()->GetWindowHandle(), 1, m_autoDragTime, NULL); } // FUNCTION: LEGO1 0x1005cfd0 -void LegoInputManager::KillTimer() +void LegoInputManager::StopAutoDragTimer() { - if (m_timer != 0) { - LegoOmni* omni = LegoOmni::GetInstance(); - ::KillTimer(omni->GetWindowHandle(), m_timer); - } + if (m_autoDragTimerID) + ::KillTimer(LegoOmni::GetInstance()->GetWindowHandle(), m_autoDragTimerID); } // FUNCTION: LEGO1 0x1005cff0 diff --git a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp index f31879b3..cbb68b79 100644 --- a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp +++ b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp @@ -330,10 +330,19 @@ void LegoVideoManager::DrawFPS() // TODO } -// STUB: LEGO1 0x1007c080 -void LegoVideoManager::VTable0x38(undefined4, undefined4) +// FUNCTION: LEGO1 0x1007c080 +MxPresenter* LegoVideoManager::GetPresenterAt(MxS32 p_x, MxS32 p_y) { - // TODO + MxPresenterListCursor cursor(m_presenters); + MxPresenter* presenter; + + while (cursor.Prev(presenter)) { + if (presenter->IsHit(p_x, p_y)) { + return presenter; + } + } + + return NULL; } // FUNCTION: LEGO1 0x1007c290 diff --git a/LEGO1/lego/sources/roi/legoroi.h b/LEGO1/lego/sources/roi/legoroi.h index 9b586353..6ac30b45 100644 --- a/LEGO1/lego/sources/roi/legoroi.h +++ b/LEGO1/lego/sources/roi/legoroi.h @@ -42,6 +42,7 @@ class LegoROI : public ViewROI { inline const char* GetUnknown0xe4() { return m_unk0xe4; } inline LegoEntity* GetUnknown0x104() { return m_unk0x104; } + inline void SetUnknown0x104(LegoEntity* p_unk0x104) { m_unk0x104 = p_unk0x104; } // SYNTHETIC: LEGO1 0x100a9ad0 diff --git a/LEGO1/omni/include/mxnotificationparam.h b/LEGO1/omni/include/mxnotificationparam.h index e990abe6..a6055fa2 100644 --- a/LEGO1/omni/include/mxnotificationparam.h +++ b/LEGO1/omni/include/mxnotificationparam.h @@ -48,6 +48,8 @@ class MxNotificationParam : public MxParam { inline MxCore* GetSender() const { return m_sender; } inline NotificationId GetType() const { return m_type; } + inline void SetType(NotificationId p_type) { m_type = p_type; } + protected: NotificationId m_type; // 0x04 MxCore* m_sender; // 0x08 diff --git a/LEGO1/realtime/orientableroi.h b/LEGO1/realtime/orientableroi.h index 36b8ae50..adbd493d 100644 --- a/LEGO1/realtime/orientableroi.h +++ b/LEGO1/realtime/orientableroi.h @@ -32,6 +32,7 @@ class OrientableROI : public ROI { const float* GetWorldPosition() const { return m_local2world[3]; } const float* GetWorldDirection() const { return m_local2world[2]; } const float* GetWorldUp() const { return m_local2world[1]; } + OrientableROI* GetUnknown0xd4() const { return m_unk0xd4; } protected: MxMatrix m_local2world; // 0x10 @@ -46,7 +47,7 @@ class OrientableROI : public ROI { Mx3DPointFloat m_unk0x94; // 0x94 BoundingSphere m_world_bounding_sphere; // 0xa8 Mx3DPointFloat m_world_velocity; // 0xc0 - undefined4 m_unk0xd4; // 0xd4 + OrientableROI* m_unk0xd4; // 0xd4 undefined4 m_unk0xd8; // 0xd8 }; diff --git a/LEGO1/realtime/roi.h b/LEGO1/realtime/roi.h index 08db5080..b5cbefa5 100644 --- a/LEGO1/realtime/roi.h +++ b/LEGO1/realtime/roi.h @@ -103,6 +103,8 @@ class ROI { int GetLODCount() const { return m_lods ? m_lods->Size() : 0; } const CompoundObject* GetComp() const { return m_comp; } + inline undefined GetUnk0x0c() { return m_unk0xc; } + // SYNTHETIC: LEGO1 0x100a5d60 // ROI::`scalar deleting destructor'