MxQueue and parts of LegoInputManager (#268)

* MxQueue and parts of LegoInputManager

* Missed clang-format on mxqueue.h

* Fix declarations

* MxParamType -> NotificationId

---------

Co-authored-by: Christian Semmler <mail@csemmler.com>
This commit is contained in:
MS 2023-11-07 03:30:26 -05:00 committed by GitHub
parent 23f4fda304
commit 7834f18999
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 149 additions and 49 deletions

View file

@ -95,7 +95,7 @@ void IsleApp::Close()
if (Lego()) { if (Lego()) {
GameState()->Save(0); GameState()->Save(0);
if (InputManager()) { if (InputManager()) {
InputManager()->QueueEvent(KEYDOWN, 0, 0, 0, 0x20); InputManager()->QueueEvent(c_notificationKeyPress, 0, 0, 0, 0x20);
} }
VideoManager()->Get3DManager()->GetLego3DView()->GetViewManager()->RemoveAll(NULL); 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); return DefWindowProcA(hWnd, uMsg, wParam, lParam);
} }
keyCode = wParam; keyCode = wParam;
type = KEYDOWN; type = c_notificationKeyPress;
break; break;
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
g_mousemoved = 1; g_mousemoved = 1;
type = MOUSEMOVE; type = c_notificationMouseMove;
break; break;
case WM_TIMER: case WM_TIMER:
type = TIMER; type = c_notificationTimer;
break; break;
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
g_mousedown = 1; g_mousedown = 1;
type = MOUSEDOWN; type = c_notificationButtonDown;
break; break;
case WM_LBUTTONUP: case WM_LBUTTONUP:
g_mousedown = 0; g_mousedown = 0;
type = MOUSEUP; type = c_notificationButtonUp;
break; break;
case 0x5400: case 0x5400:
if (g_isle) { if (g_isle) {
@ -462,7 +462,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (InputManager()) { if (InputManager()) {
InputManager()->QueueEvent(type, wParam, LOWORD(lParam), HIWORD(lParam), keyCode); 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 x = LOWORD(lParam);
int y = HIWORD(lParam); int y = HIWORD(lParam);
if (x >= 640) { if (x >= 640) {

View file

@ -2,4 +2,4 @@
#include "decomp.h" #include "decomp.h"
DECOMP_SIZE_ASSERT(LegoEventNotificationParam, 0x1c); DECOMP_SIZE_ASSERT(LegoEventNotificationParam, 0x20);

View file

@ -7,16 +7,28 @@
// VTABLE 0x100d6aa0 // VTABLE 0x100d6aa0
class LegoEventNotificationParam : public MxNotificationParam { class LegoEventNotificationParam : public MxNotificationParam {
public: 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) virtual ~LegoEventNotificationParam() override {} // vtable+0x0 (scalar deleting destructor)
inline MxU8 GetKey() { return m_key; } inline MxU8 GetKey() const { return m_key; }
protected: protected:
MxU8 m_modifier; // 0x0c MxU8 m_modifier; // 0x0c
MxS32 m_x; // 0x10 MxS32 m_x; // 0x10
MxS32 m_y; // 0x14 MxS32 m_y; // 0x14
MxU8 m_key; // 0x18 MxU8 m_key; // 0x18
MxU32 m_unk1c; // 0x1c
}; };
#endif // LEGOEVENTNOTIFICATIONPARAM_H #endif // LEGOEVENTNOTIFICATIONPARAM_H

View file

@ -9,10 +9,10 @@ DECOMP_SIZE_ASSERT(LegoInputManager, 0x338);
// OFFSET: LEGO1 0x1005b790 // OFFSET: LEGO1 0x1005b790
LegoInputManager::LegoInputManager() LegoInputManager::LegoInputManager()
{ {
m_eventQueue = NULL; m_unk0x5c = NULL;
m_world = NULL; m_world = NULL;
m_camera = NULL; m_camera = NULL;
m_unk0x68 = NULL; m_eventQueue = NULL;
m_unk0x80 = 0; m_unk0x80 = 0;
m_timer = 0; m_timer = 0;
m_unk0x6c = 0; m_unk0x6c = 0;
@ -36,7 +36,7 @@ LegoInputManager::LegoInputManager()
// OFFSET: LEGO1 0x1005b8b0 STUB // OFFSET: LEGO1 0x1005b8b0 STUB
MxResult LegoInputManager::Tickle() MxResult LegoInputManager::Tickle()
{ {
// TODO ProcessEvents();
return SUCCESS; return SUCCESS;
} }
@ -46,30 +46,32 @@ LegoInputManager::~LegoInputManager()
Destroy(); Destroy();
} }
// OFFSET: LEGO1 0x1005b960
MxResult LegoInputManager::Create(HWND p_hwnd)
{
// TODO
if (m_eventQueue == NULL)
m_eventQueue = new LegoEventQueue();
return SUCCESS;
}
// OFFSET: LEGO1 0x1005bfe0 // OFFSET: LEGO1 0x1005bfe0
void LegoInputManager::Destroy() void LegoInputManager::Destroy()
{ {
ReleaseDX(); ReleaseDX();
if (m_unk0x5c)
delete m_unk0x5c;
m_unk0x5c = NULL;
if (m_eventQueue) if (m_eventQueue)
delete m_eventQueue; delete m_eventQueue;
m_eventQueue = NULL; m_eventQueue = NULL;
if (m_unk0x68)
delete m_unk0x68;
m_unk0x68 = NULL;
if (m_controlManager) if (m_controlManager)
delete m_controlManager; delete m_controlManager;
} }
// OFFSET: LEGO1 0x1005b960 STUB
MxResult LegoInputManager::Create(HWND p_hwnd)
{
// TODO STUB
return SUCCESS;
}
// OFFSET: LEGO1 0x1005c030 // OFFSET: LEGO1 0x1005c030
void LegoInputManager::CreateAndAcquireKeyboard(HWND hwnd) void LegoInputManager::CreateAndAcquireKeyboard(HWND hwnd)
{ {
@ -222,10 +224,34 @@ void LegoInputManager::ClearWorld()
m_world = NULL; m_world = NULL;
} }
// OFFSET: LEGO1 0x1005c740 STUB // OFFSET: LEGO1 0x1005c740
void LegoInputManager::QueueEvent(NotificationId id, unsigned char p2, MxLong p3, MxLong p4, unsigned char p5) 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 // TODO
return FALSE;
} }
// OFFSET: LEGO1 0x1005cfb0 // OFFSET: LEGO1 0x1005cfb0

View file

@ -6,21 +6,14 @@
#include "legoworld.h" #include "legoworld.h"
#include "mxlist.h" #include "mxlist.h"
#include "mxpresenter.h" #include "mxpresenter.h"
#include "mxqueue.h"
#include <dinput.h> #include <dinput.h>
enum NotificationId {
NONE = 0,
KEYDOWN = 7,
MOUSEUP = 8,
MOUSEDOWN = 9,
MOUSEMOVE = 10,
TIMER = 15
};
class LegoControlManager; class LegoControlManager;
// TODO Really a MxQueue, but we don't have one of those
class LegoEventQueue : public MxList<LegoEventNotificationParam> {}; // VTABLE 0x100d8800
class LegoEventQueue : public MxQueue<LegoEventNotificationParam> {};
// VTABLE 0x100d8760 // VTABLE 0x100d8760
// SIZE 0x338 // SIZE 0x338
@ -29,7 +22,7 @@ class LegoInputManager : public MxPresenter {
LegoInputManager(); LegoInputManager();
virtual ~LegoInputManager() override; 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 Register(MxCore*);
__declspec(dllexport) void UnRegister(MxCore*); __declspec(dllexport) void UnRegister(MxCore*);
@ -54,12 +47,15 @@ class LegoInputManager : public MxPresenter {
inline LegoControlManager* GetControlManager() { return m_controlManager; } inline LegoControlManager* GetControlManager() { return m_controlManager; }
inline LegoWorld* GetWorld() { return m_world; } inline LegoWorld* GetWorld() { return m_world; }
void ProcessEvents();
MxBool ProcessOneEvent(LegoEventNotificationParam& p_param);
// private: // private:
MxCriticalSection m_criticalSection; MxCriticalSection m_criticalSection;
LegoEventQueue* m_eventQueue; // list or hash table MxList<undefined4>* m_unk0x5c; // list or hash table
LegoCameraController* m_camera; LegoCameraController* m_camera;
LegoWorld* m_world; LegoWorld* m_world;
MxList<undefined4>* m_unk0x68; // list or hash table LegoEventQueue* m_eventQueue; // +0x68
undefined4 m_unk0x6c; undefined4 m_unk0x6c;
undefined4 m_unk0x70; undefined4 m_unk0x70;
undefined4 m_unk0x74; undefined4 m_unk0x74;
@ -84,4 +80,37 @@ class LegoInputManager : public MxPresenter {
MxBool m_unk0x336; MxBool m_unk0x336;
}; };
// OFFSET: LEGO1 0x1005bb80 TEMPLATE
// MxListParent<LegoEventNotificationParam>::Compare
// OFFSET: LEGO1 0x1005bc30 TEMPLATE
// MxListParent<LegoEventNotificationParam>::Destroy
// OFFSET: LEGO1 0x1005bc80 TEMPLATE
// MxList<LegoEventNotificationParam>::~MxList<LegoEventNotificationParam>
// OFFSET: LEGO1 0x1005bd50 TEMPLATE
// MxListParent<LegoEventNotificationParam>::`scalar deleting destructor'
// OFFSET: LEGO1 0x1005bdc0 TEMPLATE
// MxList<LegoEventNotificationParam>::`scalar deleting destructor'
// OFFSET: LEGO1 0x1005beb0 TEMPLATE
// LegoEventQueue::`scalar deleting destructor'
// OFFSET: LEGO1 0x1005bf70 TEMPLATE
// MxQueue<LegoEventNotificationParam>::`scalar deleting destructor'
// OFFSET: LEGO1 0x1005d010 TEMPLATE
// MxListEntry<LegoEventNotificationParam>::GetValue
// VTABLE 0x100d87e8 TEMPLATE
// class MxQueue<LegoEventNotificationParam>
// VTABLE 0x100d87d0 TEMPLATE
// class MxList<LegoEventNotificationParam>
// VTABLE 0x100d87b8 TEMPLATE
// class MxListParent<LegoEventNotificationParam>
#endif // LEGOINPUTMANAGER_H #endif // LEGOINPUTMANAGER_H

View file

@ -8,7 +8,12 @@
// SIZE 0x14 // SIZE 0x14
class MxActionNotificationParam : public MxNotificationParam { class MxActionNotificationParam : public MxNotificationParam {
public: 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) : MxNotificationParam(p_type, p_sender)
{ {
MxDSAction* oldAction = p_action; MxDSAction* oldAction = p_action;
@ -50,7 +55,7 @@ class MxActionNotificationParam : public MxNotificationParam {
class MxEndActionNotificationParam : public MxActionNotificationParam { class MxEndActionNotificationParam : public MxActionNotificationParam {
public: public:
inline MxEndActionNotificationParam( inline MxEndActionNotificationParam(
MxParamType p_type, NotificationId p_type,
MxCore* p_sender, MxCore* p_sender,
MxDSAction* p_action, MxDSAction* p_action,
MxBool p_reallocAction MxBool p_reallocAction

View file

@ -83,7 +83,6 @@ class MxList : protected MxListParent<T> {
MxListEntry<T>* m_first; // +0x10 MxListEntry<T>* m_first; // +0x10
MxListEntry<T>* m_last; // +0x14 MxListEntry<T>* m_last; // +0x14
private:
void _DeleteEntry(MxListEntry<T>* match); void _DeleteEntry(MxListEntry<T>* match);
MxListEntry<T>* _InsertEntry(T, MxListEntry<T>*, MxListEntry<T>*); MxListEntry<T>* _InsertEntry(T, MxListEntry<T>*, MxListEntry<T>*);
}; };

View file

@ -7,7 +7,7 @@
class MxCore; class MxCore;
enum MxParamType { enum NotificationId {
PARAM_NONE = 0, PARAM_NONE = 0,
c_notificationStartAction = 1, // 100dc210:100d8350 c_notificationStartAction = 1, // 100dc210:100d8350
c_notificationEndAction = 2, // 100d8358:100d8350 c_notificationEndAction = 2, // 100d8358:100d8350
@ -36,17 +36,20 @@ enum MxParamType {
// VTABLE 0x100d56e0 // VTABLE 0x100d56e0
class MxNotificationParam : public MxParam { class MxNotificationParam : public MxParam {
public: 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() override {} // vtable+0x0 (scalar deleting destructor)
virtual MxNotificationParam* Clone(); // vtable+0x4 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 MxCore* GetSender() const { return m_sender; }
inline NotificationId GetType() const { return m_type; }
protected: protected:
MxParamType m_type; // 0x4 NotificationId m_type; // 0x4
MxCore* m_sender; // 0x8 MxCore* m_sender; // 0x8
}; };
#endif // MXNOTIFICATIONPARAM_H #endif // MXNOTIFICATIONPARAM_H

26
LEGO1/mxqueue.h Normal file
View file

@ -0,0 +1,26 @@
#ifndef MXQUEUE_H
#define MXQUEUE_H
#include "mxlist.h"
template <class T>
class MxQueue : public MxList<T> {
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

View file

@ -42,7 +42,7 @@ class MxStreamerSubClass3 : public MxStreamerSubClass1 {
class MxStreamerNotification : public MxNotificationParam { class MxStreamerNotification : public MxNotificationParam {
public: 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) : MxNotificationParam(p_type, p_sender)
{ {
m_controller = p_ctrlr; m_controller = p_ctrlr;