MxTickleManager mostly done (#94)

* Checkpoint to show MxTickleManager::SetClientTickleInterval match.

* Match MxTickleManager::~MxTickleManager, obliterate MxTickleManager::SetClientTickleInterval.

* Make conditional more realistic, move MxTime to mxtypes.h, add TODO for MxTickleManager::Tickle.
This commit is contained in:
pewpew 2023-08-03 13:19:05 -05:00 committed by GitHub
parent 932baa2a87
commit 0f92e345b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 184 additions and 11 deletions

View file

@ -150,6 +150,7 @@ add_library(lego1 SHARED
LEGO1/mxstring.cpp
LEGO1/mxstringvariable.cpp
LEGO1/mxthread.cpp
LEGO1/mxticklemanager.cpp
LEGO1/mxtimer.cpp
LEGO1/mxtransitionmanager.cpp
LEGO1/mxunknown100dc6b0.cpp

View file

@ -121,7 +121,7 @@ BOOL IsleApp::SetupLegoOmni()
BOOL failure = Lego()->Create(MxOmniCreateParam(mediaPath, (struct HWND__ *) m_windowHandle, m_videoParam, MxOmniCreateFlags())) == FAILURE;
if (!failure) {
VariableTable()->SetVariable("ACTOR_01", "");
TickleManager()->vtable1c(VideoManager(), 10);
TickleManager()->SetClientTickleInterval(VideoManager(), 10);
result = TRUE;
}

View file

@ -41,7 +41,7 @@ MxNotificationManager::~MxNotificationManager()
delete m_queue;
m_queue = NULL;
TickleManager()->Unregister(this);
TickleManager()->UnregisterClient(this);
}
// OFFSET: LEGO1 0x100ac800
@ -80,7 +80,7 @@ MxResult MxNotificationManager::Create(MxS32 p_unk1, MxS32 p_unk2)
result = FAILURE;
}
else {
TickleManager()->Register(this, 10);
TickleManager()->RegisterClient(this, 10);
}
return result;

113
LEGO1/mxticklemanager.cpp Normal file
View file

@ -0,0 +1,113 @@
#include "mxomni.h"
#include "mxticklemanager.h"
#include "mxtimer.h"
#include "mxtypes.h"
#include "decomp.h"
#define TICKLE_MANAGER_FLAG_DESTROY 0x1
DECOMP_SIZE_ASSERT(MxTickleClient, 0x10);
DECOMP_SIZE_ASSERT(MxTickleManager, 0x14);
// OFFSET: LEGO1 0x100bdd10
MxTickleClient::MxTickleClient(MxCore *p_client, MxTime p_interval)
{
m_flags = 0;
m_client = p_client;
m_interval = p_interval;
m_lastUpdateTime = -m_interval;
}
// OFFSET: LEGO1 0x100bdd30
MxTickleManager::~MxTickleManager()
{
while (m_clients.size() != 0) {
MxTickleClient *client = m_clients.front();
m_clients.pop_front();
delete client;
}
}
// TODO: Match.
// OFFSET: LEGO1 0x100bdde0
MxResult MxTickleManager::Tickle()
{
MxTime time = Timer()->GetTime();
MxTickleClientPtrList::iterator it = m_clients.begin();
while (it != m_clients.end()) {
MxTickleClient *client = *it;
if ((client->GetFlags() & TICKLE_MANAGER_FLAG_DESTROY) == 0) {
if (client->GetLastUpdateTime() >= time)
client->SetLastUpdateTime(-client->GetTickleInterval());
if ((client->GetTickleInterval() + client->GetLastUpdateTime()) < time) {
client->GetClient()->Tickle();
client->SetLastUpdateTime(time);
}
it++;
}
else {
m_clients.erase(it++);
delete client;
}
}
return SUCCESS;
}
// OFFSET: LEGO1 0x100bde80
void MxTickleManager::RegisterClient(MxCore *p_client, MxTime p_interval)
{
MxTime interval = GetClientTickleInterval(p_client);
if (interval == TICKLE_MANAGER_NOT_FOUND) {
MxTickleClient *client = new MxTickleClient(p_client, p_interval);
if (client != NULL)
m_clients.push_back(client);
}
}
// OFFSET: LEGO1 0x100bdf60
void MxTickleManager::UnregisterClient(MxCore *p_client)
{
MxTickleClientPtrList::iterator it = m_clients.begin();
while (it != m_clients.end()) {
MxTickleClient *client = *it;
if (client->GetClient() == p_client) {
client->SetFlags(client->GetFlags() | TICKLE_MANAGER_FLAG_DESTROY);
return;
}
it++;
}
}
// OFFSET: LEGO1 0x100bdfa0
void MxTickleManager::SetClientTickleInterval(MxCore *p_client, MxTime p_interval)
{
for (MxTickleClientPtrList::iterator it = m_clients.begin(); it != m_clients.end(); it++) {
MxTickleClient *client = *it;
if ((client->GetClient() == p_client) && ((client->GetFlags() & TICKLE_MANAGER_FLAG_DESTROY) == 0)) {
client->SetTickleInterval(p_interval);
return;
}
}
}
// OFFSET: LEGO1 0x100be000
MxTime MxTickleManager::GetClientTickleInterval(MxCore *p_client)
{
MxTickleClientPtrList::iterator it = m_clients.begin();
while (it != m_clients.end()) {
MxTickleClient *client = *it;
if ((client->GetClient() == p_client) && ((client->GetFlags() & TICKLE_MANAGER_FLAG_DESTROY) == 0))
return client->GetTickleInterval();
it++;
}
return TICKLE_MANAGER_NOT_FOUND;
}

View file

@ -2,20 +2,77 @@
#define MXTICKLEMANAGER_H
#include "mxcore.h"
#include "mxtypes.h"
#include "compat.h"
class MxTickleClient
{
public:
MxTickleClient(MxCore *p_client, MxTime p_interval);
inline MxCore *GetClient() const
{
return m_client;
}
inline MxTime GetTickleInterval() const
{
return m_interval;
}
inline MxTime GetLastUpdateTime() const
{
return m_lastUpdateTime;
}
inline MxU16 GetFlags() const
{
return m_flags;
}
inline void SetTickleInterval(MxTime p_interval)
{
m_interval = p_interval;
}
inline void SetLastUpdateTime(MxTime p_lastUpdateTime)
{
m_lastUpdateTime = p_lastUpdateTime;
}
inline void SetFlags(MxU16 flags)
{
m_flags = flags;
}
private:
MxCore *m_client; // 0x0
MxTime m_interval; // 0x4
MxTime m_lastUpdateTime; // 0x8
MxU16 m_flags; // 0xc
};
class MxTickleClientPtrList : public List<MxTickleClient *>
{};
// VTABLE 0x100d86d8
class MxTickleManager : public MxCore
{
public:
virtual ~MxTickleManager();
inline MxTickleManager() : MxCore(), m_clients() {}
virtual ~MxTickleManager(); // vtable+0x0 (scalar deleting destructor)
virtual MxLong Tickle();
virtual const char *ClassName() const;
virtual MxBool IsA(const char *name) const;
virtual void Register(MxCore *p_listener, int p_milliseconds);
virtual void Unregister(MxCore *p_listener);
virtual void vtable1c(void *v, int p);
virtual void vtable20();
virtual MxResult Tickle(); // vtable+0x8
virtual void RegisterClient(MxCore *p_client, MxTime p_interval); // vtable+0x14
virtual void UnregisterClient(MxCore *p_client); // vtable+0x18
virtual void SetClientTickleInterval(MxCore *p_client, MxTime p_interval); // vtable+0x1c
virtual MxTime GetClientTickleInterval(MxCore *p_client); // vtable+0x20
private:
MxTickleClientPtrList m_clients; // 0x8
};
#define TICKLE_MANAGER_NOT_FOUND 0x80000000
#endif // MXTICKLEMANAGER_H

View file

@ -25,6 +25,8 @@ typedef int MxLong;
typedef unsigned int MxULong;
#endif
typedef MxS32 MxTime;
typedef MxLong MxResult;
const MxResult SUCCESS = 0;
const MxResult FAILURE = -1;