Implement a few registrationbook methods (#703)

* Implement a few registrationbook methods

* Match RegistrationBook::HandleKeyPress

* Match RegistrationBook::CreateSurface

---------

Co-authored-by: Christian Semmler <mail@csemmler.com>
This commit is contained in:
Misha 2024-03-20 12:26:10 -04:00 committed by GitHub
parent 556c7698d8
commit e5fa35fd99
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 145 additions and 31 deletions

View file

@ -45,32 +45,33 @@ class RegistrationBook : public LegoWorld {
// RegistrationBook::`scalar deleting destructor' // RegistrationBook::`scalar deleting destructor'
private: private:
undefined4 m_unk0xf8; // 0xf8 MxS32 m_registerDialogueTimer; // 0xf8
undefined m_unk0xfc; // 0xfc undefined m_unk0xfc; // 0xfc
undefined m_unk0xfd[3]; // 0xfd undefined m_unk0xfd[3]; // 0xfd
MxStillPresenter* m_alphabet[26]; // 0x100 MxStillPresenter* m_alphabet[26]; // 0x100
MxStillPresenter* m_name[10][7]; // 0x168 MxStillPresenter* m_name[10][7]; // 0x168
struct { struct {
MxS16 m_letters[7]; // 0x00 MxS16 m_letters[7]; // 0x00
undefined2 m_unk0x0e; // 0x0e MxS16 m_cursorPos; // 0x0e
} m_unk0x280; // 0x280 } m_unk0x280; // 0x280
MxControlPresenter* m_checkmark[10]; // 0x290 MxControlPresenter* m_checkmark[10]; // 0x290
undefined2 m_unk0x2b8; // 0x2b8 undefined2 m_unk0x2b8; // 0x2b8
InfocenterState* m_infocenterState; // 0x2bc InfocenterState* m_infocenterState; // 0x2bc
undefined m_unk0x2c0; // 0x2c0 undefined m_unk0x2c0; // 0x2c0
undefined m_unk0x2c1; // 0x2c1 undefined m_unk0x2c1; // 0x2c1
undefined m_unk0x2c2[0x02]; // 0x2c2 undefined m_unk0x2c2[0x02]; // 0x2c2
undefined4 m_unk0x2c4; // 0x2c4 LPDIRECTDRAWSURFACE m_checkboxHilite; // 0x2c4
undefined4 m_unk0x2c8; // 0x2c8 LPDIRECTDRAWSURFACE m_checkboxSurface; // 0x2c8
LPDIRECTDRAWSURFACE m_unk0x2cc; // 0x2cc LPDIRECTDRAWSURFACE m_checkboxNormal; // 0x2cc
MxLong HandleEndAction(MxEndActionNotificationParam& p_param); MxLong HandleEndAction(MxEndActionNotificationParam& p_param);
MxLong HandleKeyPress(MxS8 p_key); MxLong HandleKeyPress(MxU8 p_key);
MxLong HandleClick(LegoControlManagerEvent& p_param); MxLong HandleClick(LegoControlManagerEvent& p_param);
MxLong HandleNotification19(MxParam& p_param); MxLong HandleNotification19(MxParam& p_param);
void FUN_100775c0(MxS16 p_playerIndex); void FUN_100775c0(MxS16 p_playerIndex);
void WriteInfocenterLetters(MxS16); void WriteInfocenterLetters(MxS16);
void FUN_100778c0(); void FUN_100778c0();
MxBool CreateSurface();
}; };
#endif // REGISTRATIONBOOK_H #endif // REGISTRATIONBOOK_H

View file

@ -9,6 +9,7 @@
#include "misc.h" #include "misc.h"
#include "mxactionnotificationparam.h" #include "mxactionnotificationparam.h"
#include "mxbackgroundaudiomanager.h" #include "mxbackgroundaudiomanager.h"
#include "mxdisplaysurface.h"
#include "mxmisc.h" #include "mxmisc.h"
#include "mxnotificationmanager.h" #include "mxnotificationmanager.h"
#include "mxtimer.h" #include "mxtimer.h"
@ -20,12 +21,18 @@ DECOMP_SIZE_ASSERT(RegistrationBook, 0x2d0)
// GLOBAL: LEGO1 0x100d9924 // GLOBAL: LEGO1 0x100d9924
const char* g_infoman = "infoman"; const char* g_infoman = "infoman";
// GLOBAL: LEGO1 0x100f7964
MxLong g_checkboxBlinkTimer = 0;
// GLOBAL: LEGO1 0x100f7968
MxBool g_nextCheckbox = FALSE;
// FUNCTION: LEGO1 0x10076d20 // FUNCTION: LEGO1 0x10076d20
RegistrationBook::RegistrationBook() : m_unk0xf8(0x80000000), m_unk0xfc(1) RegistrationBook::RegistrationBook() : m_registerDialogueTimer(0x80000000), m_unk0xfc(1)
{ {
memset(m_alphabet, 0, sizeof(m_alphabet)); memset(m_alphabet, 0, sizeof(m_alphabet));
memset(m_name, 0, sizeof(m_name)); memset(m_name, 0, sizeof(m_name));
m_unk0x280.m_unk0x0e = 0; m_unk0x280.m_cursorPos = 0;
memset(m_checkmark, 0, sizeof(m_checkmark)); memset(m_checkmark, 0, sizeof(m_checkmark));
memset(&m_unk0x280, -1, sizeof(m_unk0x280) - 2); memset(&m_unk0x280, -1, sizeof(m_unk0x280) - 2);
@ -36,9 +43,9 @@ RegistrationBook::RegistrationBook() : m_unk0xf8(0x80000000), m_unk0xfc(1)
NotificationManager()->Register(this); NotificationManager()->Register(this);
m_unk0x2c1 = 0; m_unk0x2c1 = 0;
m_unk0x2c4 = 0; m_checkboxHilite = NULL;
m_unk0x2c8 = 0; m_checkboxSurface = NULL;
m_unk0x2cc = 0; m_checkboxNormal = NULL;
} }
// FUNCTION: LEGO1 0x10076f50 // FUNCTION: LEGO1 0x10076f50
@ -62,8 +69,8 @@ RegistrationBook::~RegistrationBook()
ControlManager()->Unregister(this); ControlManager()->Unregister(this);
NotificationManager()->Unregister(this); NotificationManager()->Unregister(this);
if (m_unk0x2cc) { if (m_checkboxNormal) {
m_unk0x2cc->Release(); m_checkboxNormal->Release();
} }
} }
@ -99,11 +106,11 @@ MxLong RegistrationBook::Notify(MxParam& p_param)
result = HandleEndAction((MxEndActionNotificationParam&) p_param); result = HandleEndAction((MxEndActionNotificationParam&) p_param);
break; break;
case c_notificationKeyPress: case c_notificationKeyPress:
m_unk0xf8 = Timer()->GetTime(); m_registerDialogueTimer = Timer()->GetTime();
result = HandleKeyPress(((LegoEventNotificationParam&) p_param).GetKey()); result = HandleKeyPress(((LegoEventNotificationParam&) p_param).GetKey());
break; break;
case c_notificationButtonDown: case c_notificationButtonDown:
m_unk0xf8 = Timer()->GetTime(); m_registerDialogueTimer = Timer()->GetTime();
break; break;
case c_notificationClick: case c_notificationClick:
result = HandleClick((LegoControlManagerEvent&) p_param); result = HandleClick((LegoControlManagerEvent&) p_param);
@ -139,17 +146,65 @@ MxLong RegistrationBook::HandleEndAction(MxEndActionNotificationParam& p_param)
case RegbookScript::c_iic007in_PlayWav: case RegbookScript::c_iic007in_PlayWav:
case RegbookScript::c_iic008in_PlayWav: case RegbookScript::c_iic008in_PlayWav:
BackgroundAudioManager()->RaiseVolume(); BackgroundAudioManager()->RaiseVolume();
m_unk0xf8 = Timer()->GetTime(); m_registerDialogueTimer = Timer()->GetTime();
break; break;
} }
return 1; return 1;
} }
// STUB: LEGO1 0x100772d0 // FUNCTION: LEGO1 0x100772d0
MxLong RegistrationBook::HandleKeyPress(MxS8 p_key) MxLong RegistrationBook::HandleKeyPress(MxU8 p_key)
{ {
return 0; MxS16 key;
if (p_key >= 'a' && p_key <= 'z') {
key = p_key - ' ';
}
else {
key = p_key;
}
if ((key < 'A' || key > 'Z') && key != '\b') {
if (key == ' ') {
DeleteObjects(&m_atom, RegbookScript::c_iic006in_RunAnim, RegbookScript::c_iic008in_PlayWav);
BackgroundAudioManager()->RaiseVolume();
}
}
else if (key != '\b' && m_unk0x280.m_cursorPos < 7) {
m_name[0][m_unk0x280.m_cursorPos] = m_alphabet[key - 'A']->Clone();
if (m_name[0][m_unk0x280.m_cursorPos] != NULL) {
m_alphabet[key - 'A']->GetAction()->SetUnknown24(m_alphabet[key - 'A']->GetAction()->GetUnknown24() + 1);
m_name[0][m_unk0x280.m_cursorPos]->Enable(TRUE);
m_name[0][m_unk0x280.m_cursorPos]->SetTickleState(MxPresenter::e_repeating);
m_name[0][m_unk0x280.m_cursorPos]->SetPosition(m_unk0x280.m_cursorPos * 23 + 343, 121);
if (m_unk0x280.m_cursorPos == 0) {
m_checkmark[0]->Enable(TRUE);
}
m_unk0x280.m_letters[m_unk0x280.m_cursorPos] = key - 'A';
m_unk0x280.m_cursorPos++;
}
}
else {
if (key == '\b' && m_unk0x280.m_cursorPos > 0) {
m_unk0x280.m_cursorPos--;
m_name[0][m_unk0x280.m_cursorPos]->Enable(FALSE);
delete m_name[0][m_unk0x280.m_cursorPos];
m_name[0][m_unk0x280.m_cursorPos] = NULL;
if (m_unk0x280.m_cursorPos == 0) {
m_checkmark[0]->Enable(FALSE);
}
m_unk0x280.m_letters[m_unk0x280.m_cursorPos] = -1;
}
}
return 1;
} }
// FUNCTION: LEGO1 0x100774a0 // FUNCTION: LEGO1 0x100774a0
@ -342,14 +397,40 @@ inline void RegistrationBook::PlayAction(MxU32 p_objectId)
Start(&action); Start(&action);
} }
// STUB: LEGO1 0x10077fd0 // FUNCTION: LEGO1 0x10077fd0
MxResult RegistrationBook::Tickle() MxResult RegistrationBook::Tickle()
{ {
if (!m_worldStarted) { if (!m_worldStarted) {
LegoWorld::Tickle(); LegoWorld::Tickle();
} }
else { else {
// TODO MxLong time = Timer()->GetTime();
if (m_registerDialogueTimer != 0x80000000 && m_registerDialogueTimer + 30000 <= time) {
m_registerDialogueTimer = 0x80000000;
PlayAction(RegbookScript::c_iic007in_PlayWav);
}
if (g_checkboxBlinkTimer + 500 <= time) {
g_checkboxBlinkTimer = time;
if (m_checkboxHilite) {
DDBLTFX op;
op.dwSize = sizeof(op);
op.dwROP = 0xcc0020;
if (g_nextCheckbox) {
m_checkboxSurface->Blt(NULL, m_checkboxHilite, NULL, DDBLT_ROP, &op);
}
else {
m_checkboxSurface->Blt(NULL, m_checkboxNormal, NULL, DDBLT_ROP, &op);
}
}
else {
CreateSurface();
}
g_nextCheckbox = !g_nextCheckbox;
}
} }
return SUCCESS; return SUCCESS;
@ -377,6 +458,38 @@ MxLong RegistrationBook::HandleNotification19(MxParam& p_param)
return 0; return 0;
} }
// FUNCTION: LEGO1 0x10078350
MxBool RegistrationBook::CreateSurface()
{
MxCompositePresenterList* list = m_checkmark[0]->GetList();
MxStillPresenter *presenter, *uninitialized;
if (list) {
if (list->begin() != list->end()) {
presenter = (MxStillPresenter*) list->front();
}
else {
presenter = uninitialized; // intentionally uninitialized variable
}
if (presenter) {
m_checkboxSurface = presenter->VTable0x78();
}
presenter = (MxStillPresenter*) Find("MxStillPresenter", "CheckHiLite_Bitmap");
if (presenter) {
m_checkboxHilite = presenter->VTable0x78();
}
if (m_checkboxSurface && m_checkboxHilite) {
m_checkboxNormal = MxDisplaySurface::CopySurface(m_checkboxSurface);
return TRUE;
}
}
return FALSE;
}
// FUNCTION: LEGO1 0x100783e0 // FUNCTION: LEGO1 0x100783e0
MxBool RegistrationBook::VTable0x64() MxBool RegistrationBook::VTable0x64()
{ {

View file

@ -47,7 +47,7 @@ class MxCompositePresenter : public MxPresenter {
return TRUE; return TRUE;
} // vtable+0x64 } // vtable+0x64
inline MxCompositePresenterList& GetList() { return m_list; } inline MxCompositePresenterList* GetList() { return &m_list; }
protected: protected:
MxCompositePresenterList m_list; // 0x40 MxCompositePresenterList m_list; // 0x40

View file

@ -119,7 +119,7 @@ MxBool ContainsPresenter(MxCompositePresenterList& p_presenterList, MxPresenter*
{ {
for (MxCompositePresenterList::iterator it = p_presenterList.begin(); it != p_presenterList.end(); it++) { for (MxCompositePresenterList::iterator it = p_presenterList.begin(); it != p_presenterList.end(); it++) {
if (p_presenter == *it || ((*it)->IsA("MxCompositePresenter") && if (p_presenter == *it || ((*it)->IsA("MxCompositePresenter") &&
ContainsPresenter(((MxCompositePresenter*) *it)->GetList(), p_presenter))) { ContainsPresenter(*((MxCompositePresenter*) *it)->GetList(), p_presenter))) {
return TRUE; return TRUE;
} }
} }