diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 8c38315e..775f038c 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -95,7 +95,7 @@ void IsleApp::Close() if (Lego()) { GameState()->Save(0); if (InputManager()) { - InputManager()->QueueEvent(KEYDOWN, 0, 0, 0, 0x20); + InputManager()->QueueEvent(c_notificationKeyPress, 0, 0, 0, 0x20); } VideoManager()->Get3DManager()->GetLego3DView()->GetViewManager()->RemoveAll(NULL); @@ -431,22 +431,22 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return DefWindowProcA(hWnd, uMsg, wParam, lParam); } keyCode = wParam; - type = KEYDOWN; + type = c_notificationKeyPress; break; case WM_MOUSEMOVE: g_mousemoved = 1; - type = MOUSEMOVE; + type = c_notificationMouseMove; break; case WM_TIMER: - type = TIMER; + type = c_notificationTimer; break; case WM_LBUTTONDOWN: g_mousedown = 1; - type = MOUSEDOWN; + type = c_notificationButtonDown; break; case WM_LBUTTONUP: g_mousedown = 0; - type = MOUSEUP; + type = c_notificationButtonUp; break; case 0x5400: if (g_isle) { @@ -462,7 +462,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (InputManager()) { InputManager()->QueueEvent(type, wParam, LOWORD(lParam), HIWORD(lParam), keyCode); } - if (g_isle && g_isle->m_drawCursor && type == MOUSEMOVE) { + if (g_isle && g_isle->m_drawCursor && type == c_notificationMouseMove) { int x = LOWORD(lParam); int y = HIWORD(lParam); if (x >= 640) { diff --git a/LEGO1/legoeventnotificationparam.cpp b/LEGO1/legoeventnotificationparam.cpp index 70e0de00..b6abd2c4 100644 --- a/LEGO1/legoeventnotificationparam.cpp +++ b/LEGO1/legoeventnotificationparam.cpp @@ -2,4 +2,4 @@ #include "decomp.h" -DECOMP_SIZE_ASSERT(LegoEventNotificationParam, 0x1c); +DECOMP_SIZE_ASSERT(LegoEventNotificationParam, 0x20); diff --git a/LEGO1/legoeventnotificationparam.h b/LEGO1/legoeventnotificationparam.h index f53fb822..3916771d 100644 --- a/LEGO1/legoeventnotificationparam.h +++ b/LEGO1/legoeventnotificationparam.h @@ -7,16 +7,28 @@ // VTABLE 0x100d6aa0 class LegoEventNotificationParam : public MxNotificationParam { public: - inline LegoEventNotificationParam() : MxNotificationParam((MxParamType) 0, NULL) {} + inline LegoEventNotificationParam() : MxNotificationParam(PARAM_NONE, NULL) {} + inline LegoEventNotificationParam( + NotificationId p_type, + MxCore* p_sender, + MxU8 p_modifier, + MxS32 p_x, + 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_unk1c(0) + { + } virtual ~LegoEventNotificationParam() override {} // vtable+0x0 (scalar deleting destructor) - inline MxU8 GetKey() { return m_key; } + inline MxU8 GetKey() const { return m_key; } protected: MxU8 m_modifier; // 0x0c MxS32 m_x; // 0x10 MxS32 m_y; // 0x14 MxU8 m_key; // 0x18 + MxU32 m_unk1c; // 0x1c }; #endif // LEGOEVENTNOTIFICATIONPARAM_H diff --git a/LEGO1/legoinputmanager.cpp b/LEGO1/legoinputmanager.cpp index 0ff25bc5..e9a82cc6 100644 --- a/LEGO1/legoinputmanager.cpp +++ b/LEGO1/legoinputmanager.cpp @@ -9,10 +9,10 @@ DECOMP_SIZE_ASSERT(LegoInputManager, 0x338); // OFFSET: LEGO1 0x1005b790 LegoInputManager::LegoInputManager() { - m_eventQueue = NULL; + m_unk0x5c = NULL; m_world = NULL; m_camera = NULL; - m_unk0x68 = NULL; + m_eventQueue = NULL; m_unk0x80 = 0; m_timer = 0; m_unk0x6c = 0; @@ -36,7 +36,7 @@ LegoInputManager::LegoInputManager() // OFFSET: LEGO1 0x1005b8b0 STUB MxResult LegoInputManager::Tickle() { - // TODO + ProcessEvents(); return SUCCESS; } @@ -46,30 +46,32 @@ LegoInputManager::~LegoInputManager() Destroy(); } +// OFFSET: LEGO1 0x1005b960 +MxResult LegoInputManager::Create(HWND p_hwnd) +{ + // TODO + if (m_eventQueue == NULL) + m_eventQueue = new LegoEventQueue(); + return SUCCESS; +} + // OFFSET: LEGO1 0x1005bfe0 void LegoInputManager::Destroy() { ReleaseDX(); + if (m_unk0x5c) + delete m_unk0x5c; + m_unk0x5c = NULL; + if (m_eventQueue) delete m_eventQueue; m_eventQueue = NULL; - if (m_unk0x68) - delete m_unk0x68; - m_unk0x68 = NULL; - if (m_controlManager) delete m_controlManager; } -// OFFSET: LEGO1 0x1005b960 STUB -MxResult LegoInputManager::Create(HWND p_hwnd) -{ - // TODO STUB - return SUCCESS; -} - // OFFSET: LEGO1 0x1005c030 void LegoInputManager::CreateAndAcquireKeyboard(HWND hwnd) { @@ -222,10 +224,34 @@ void LegoInputManager::ClearWorld() m_world = NULL; } -// OFFSET: LEGO1 0x1005c740 STUB -void LegoInputManager::QueueEvent(NotificationId id, unsigned char p2, MxLong p3, MxLong p4, unsigned char p5) +// OFFSET: LEGO1 0x1005c740 +void LegoInputManager::QueueEvent(NotificationId p_id, MxU8 p_modifier, MxLong p_x, MxLong p_y, MxU8 p_key) +{ + LegoEventNotificationParam param = LegoEventNotificationParam(p_id, NULL, p_modifier, p_x, p_y, p_key); + + if (((!m_unk0x88) || ((m_unk0x335 && (param.GetType() == c_notificationButtonDown)))) || + ((m_unk0x336 && (p_key == ' ')))) { + ProcessOneEvent(param); + } +} + +// OFFSET: LEGO1 0x1005c820 +void LegoInputManager::ProcessEvents() +{ + MxAutoLocker lock(&m_criticalSection); + + LegoEventNotificationParam event; + while (m_eventQueue->Dequeue(event)) { + if (ProcessOneEvent(event)) + break; + } +} + +// OFFSET: LEGO1 0x1005c9c0 STUB +MxBool LegoInputManager::ProcessOneEvent(LegoEventNotificationParam& p_param) { // TODO + return FALSE; } // OFFSET: LEGO1 0x1005cfb0 diff --git a/LEGO1/legoinputmanager.h b/LEGO1/legoinputmanager.h index e657f81e..c583a64a 100644 --- a/LEGO1/legoinputmanager.h +++ b/LEGO1/legoinputmanager.h @@ -6,21 +6,14 @@ #include "legoworld.h" #include "mxlist.h" #include "mxpresenter.h" +#include "mxqueue.h" #include -enum NotificationId { - NONE = 0, - KEYDOWN = 7, - MOUSEUP = 8, - MOUSEDOWN = 9, - MOUSEMOVE = 10, - TIMER = 15 -}; - class LegoControlManager; -// TODO Really a MxQueue, but we don't have one of those -class LegoEventQueue : public MxList {}; + +// VTABLE 0x100d8800 +class LegoEventQueue : public MxQueue {}; // VTABLE 0x100d8760 // SIZE 0x338 @@ -29,7 +22,7 @@ class LegoInputManager : public MxPresenter { LegoInputManager(); virtual ~LegoInputManager() override; - __declspec(dllexport) void QueueEvent(NotificationId id, unsigned char p2, MxLong p3, MxLong p4, unsigned char p5); + __declspec(dllexport) void QueueEvent(NotificationId p_id, MxU8 p_modifier, MxLong p_x, MxLong p_y, MxU8 p_key); __declspec(dllexport) void Register(MxCore*); __declspec(dllexport) void UnRegister(MxCore*); @@ -54,12 +47,15 @@ class LegoInputManager : public MxPresenter { inline LegoControlManager* GetControlManager() { return m_controlManager; } inline LegoWorld* GetWorld() { return m_world; } + void ProcessEvents(); + MxBool ProcessOneEvent(LegoEventNotificationParam& p_param); + // private: MxCriticalSection m_criticalSection; - LegoEventQueue* m_eventQueue; // list or hash table + MxList* m_unk0x5c; // list or hash table LegoCameraController* m_camera; LegoWorld* m_world; - MxList* m_unk0x68; // list or hash table + LegoEventQueue* m_eventQueue; // +0x68 undefined4 m_unk0x6c; undefined4 m_unk0x70; undefined4 m_unk0x74; @@ -84,4 +80,37 @@ class LegoInputManager : public MxPresenter { MxBool m_unk0x336; }; +// OFFSET: LEGO1 0x1005bb80 TEMPLATE +// MxListParent::Compare + +// OFFSET: LEGO1 0x1005bc30 TEMPLATE +// MxListParent::Destroy + +// OFFSET: LEGO1 0x1005bc80 TEMPLATE +// MxList::~MxList + +// OFFSET: LEGO1 0x1005bd50 TEMPLATE +// MxListParent::`scalar deleting destructor' + +// OFFSET: LEGO1 0x1005bdc0 TEMPLATE +// MxList::`scalar deleting destructor' + +// OFFSET: LEGO1 0x1005beb0 TEMPLATE +// LegoEventQueue::`scalar deleting destructor' + +// OFFSET: LEGO1 0x1005bf70 TEMPLATE +// MxQueue::`scalar deleting destructor' + +// OFFSET: LEGO1 0x1005d010 TEMPLATE +// MxListEntry::GetValue + +// VTABLE 0x100d87e8 TEMPLATE +// class MxQueue + +// VTABLE 0x100d87d0 TEMPLATE +// class MxList + +// VTABLE 0x100d87b8 TEMPLATE +// class MxListParent + #endif // LEGOINPUTMANAGER_H diff --git a/LEGO1/mxactionnotificationparam.h b/LEGO1/mxactionnotificationparam.h index 3255f91d..7f825a21 100644 --- a/LEGO1/mxactionnotificationparam.h +++ b/LEGO1/mxactionnotificationparam.h @@ -8,7 +8,12 @@ // SIZE 0x14 class MxActionNotificationParam : public MxNotificationParam { public: - inline MxActionNotificationParam(MxParamType p_type, MxCore* p_sender, MxDSAction* p_action, MxBool p_reallocAction) + inline MxActionNotificationParam( + NotificationId p_type, + MxCore* p_sender, + MxDSAction* p_action, + MxBool p_reallocAction + ) : MxNotificationParam(p_type, p_sender) { MxDSAction* oldAction = p_action; @@ -50,7 +55,7 @@ class MxActionNotificationParam : public MxNotificationParam { class MxEndActionNotificationParam : public MxActionNotificationParam { public: inline MxEndActionNotificationParam( - MxParamType p_type, + NotificationId p_type, MxCore* p_sender, MxDSAction* p_action, MxBool p_reallocAction diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index 8ef91333..1d8e26c3 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -83,7 +83,6 @@ class MxList : protected MxListParent { MxListEntry* m_first; // +0x10 MxListEntry* m_last; // +0x14 -private: void _DeleteEntry(MxListEntry* match); MxListEntry* _InsertEntry(T, MxListEntry*, MxListEntry*); }; diff --git a/LEGO1/mxnotificationparam.h b/LEGO1/mxnotificationparam.h index 36c21b24..ec58fde6 100644 --- a/LEGO1/mxnotificationparam.h +++ b/LEGO1/mxnotificationparam.h @@ -7,7 +7,7 @@ class MxCore; -enum MxParamType { +enum NotificationId { PARAM_NONE = 0, c_notificationStartAction = 1, // 100dc210:100d8350 c_notificationEndAction = 2, // 100d8358:100d8350 @@ -36,17 +36,20 @@ enum MxParamType { // VTABLE 0x100d56e0 class MxNotificationParam : public MxParam { public: - inline MxNotificationParam(MxParamType p_type, MxCore* p_sender) : MxParam(), m_type(p_type), m_sender(p_sender) {} + inline MxNotificationParam(NotificationId p_type, MxCore* p_sender) : MxParam(), m_type(p_type), m_sender(p_sender) + { + } virtual ~MxNotificationParam() override {} // vtable+0x0 (scalar deleting destructor) virtual MxNotificationParam* Clone(); // vtable+0x4 - inline MxParamType GetNotification() const { return m_type; } + inline NotificationId GetNotification() const { return m_type; } inline MxCore* GetSender() const { return m_sender; } + inline NotificationId GetType() const { return m_type; } protected: - MxParamType m_type; // 0x4 - MxCore* m_sender; // 0x8 + NotificationId m_type; // 0x4 + MxCore* m_sender; // 0x8 }; #endif // MXNOTIFICATIONPARAM_H diff --git a/LEGO1/mxqueue.h b/LEGO1/mxqueue.h new file mode 100644 index 00000000..fd22cb0a --- /dev/null +++ b/LEGO1/mxqueue.h @@ -0,0 +1,26 @@ +#ifndef MXQUEUE_H +#define MXQUEUE_H + +#include "mxlist.h" + +template +class MxQueue : public MxList { +public: + void Enqueue(T& p_obj) + { + // TODO + } + + MxBool Dequeue(T& p_obj) + { + MxBool has_next = (m_first != NULL); + if (m_first) { + p_obj = m_first->GetValue(); + _DeleteEntry(m_first); + } + + return has_next; + } +}; + +#endif // MXQUEUE_H diff --git a/LEGO1/mxstreamer.h b/LEGO1/mxstreamer.h index f7d1d448..6e0500cb 100644 --- a/LEGO1/mxstreamer.h +++ b/LEGO1/mxstreamer.h @@ -42,7 +42,7 @@ class MxStreamerSubClass3 : public MxStreamerSubClass1 { class MxStreamerNotification : public MxNotificationParam { public: - inline MxStreamerNotification(MxParamType p_type, MxCore* p_sender, MxStreamController* p_ctrlr) + inline MxStreamerNotification(NotificationId p_type, MxCore* p_sender, MxStreamController* p_ctrlr) : MxNotificationParam(p_type, p_sender) { m_controller = p_ctrlr;