isle-portable/LEGO1/lego/legoomni/src/worlds/historybook.cpp
2026-01-08 02:10:10 +01:00

224 lines
5.8 KiB
C++

#include "historybook.h"
#include "jukebox.h"
#include "jukebox_actions.h"
#include "legocontrolmanager.h"
#include "legoinputmanager.h"
#include "misc.h"
#include "mxmisc.h"
#include "mxnotificationmanager.h"
#include "mxstillpresenter.h"
#include "mxtransitionmanager.h"
#include <mortar/mortar_log.h>
DECOMP_SIZE_ASSERT(HistoryBook, 0x3e4)
// FUNCTION: LEGO1 0x100822f0
HistoryBook::HistoryBook()
{
memset(m_alphabet, 0, sizeof(m_alphabet));
memset(m_intAlphabet, 0, sizeof(m_intAlphabet));
memset(m_name, 0, sizeof(m_name));
memset(m_scores, 0, sizeof(m_scores));
NotificationManager()->Register(this);
}
// FUNCTION: LEGO1 0x100824d0
// FUNCTION: BETA10 0x1002b63e
HistoryBook::~HistoryBook()
{
for (MxS16 scoreIndex = 0; scoreIndex < GameState()->m_history.GetCount(); scoreIndex++) {
if (m_scores[scoreIndex]) {
delete m_scores[scoreIndex]->GetAction();
delete m_scores[scoreIndex];
m_scores[scoreIndex] = NULL;
}
for (MxS16 letterIndex = 0; letterIndex < (MxS16) sizeOfArray(m_name[0]); letterIndex++) {
if (m_name[scoreIndex][letterIndex]) {
delete m_name[scoreIndex][letterIndex]->GetAction();
delete m_name[scoreIndex][letterIndex];
m_name[scoreIndex][letterIndex] = NULL;
}
}
}
InputManager()->UnRegister(this);
if (InputManager()->GetWorld() == this) {
InputManager()->ClearWorld();
}
ControlManager()->Unregister(this);
NotificationManager()->Unregister(this);
}
// FUNCTION: LEGO1 0x10082610
MxResult HistoryBook::Create(MxDSAction& p_dsAction)
{
MxResult result = LegoWorld::Create(p_dsAction);
if (result == SUCCESS) {
InputManager()->SetWorld(this);
ControlManager()->Register(this);
}
InputManager()->SetCamera(NULL);
InputManager()->Register(this);
GameState()->m_currentArea = LegoGameState::Area::e_histbook;
GameState()->StopArea(LegoGameState::Area::e_previousArea);
return result;
}
// FUNCTION: LEGO1 0x10082680
// FUNCTION: BETA10 0x1002b907
MxLong HistoryBook::Notify(MxParam& p_param)
{
MxNotificationParam& param = (MxNotificationParam&) p_param;
LegoWorld::Notify(p_param);
if (m_worldStarted) {
switch (param.GetNotification()) {
case c_notificationButtonUp:
m_destLocation = LegoGameState::Area::e_infoscor;
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
break;
case c_notificationTransitioned:
GameState()->SwitchArea(m_destLocation);
break;
}
}
return 0;
}
// FUNCTION: LEGO1 0x100826f0
// FUNCTION: BETA10 0x1002b9b9
void HistoryBook::ReadyWorld()
{
undefined2 dummy1 = 0x90, dummy2 = 0x79, dummy3 = 0xc8, dummy4 = 0x17, dummy5 = 0x1b;
#ifndef BETA10
LegoWorld::ReadyWorld();
#endif
GameState()->m_history.WriteScoreHistory();
char bitmap[] = "A_Bitmap";
MxS16 i;
for (i = 0; i < 26; i++) {
// TODO: This might be an inline function.
// See also `RegistrationBook::ReadyWorld()`.
if (i < 26) {
m_alphabet[i] = (MxStillPresenter*) Find("MxStillPresenter", bitmap);
assert(m_alphabet[i]);
bitmap[0]++;
}
}
for (i = 0; i < sizeOfArray(m_intAlphabet); i++) {
m_intAlphabet[i] = (MxStillPresenter*) Find("MxStillPresenter", LegoGameState::g_intCharacters[i].m_bitmap);
}
m_intAlphabetOffset = 0;
for (i = 0; i < sizeOfArray(m_intAlphabet); i++) {
if (!m_intAlphabet[i]) {
m_intAlphabetOffset++;
}
else {
break;
}
}
MxStillPresenter* scoreboxMaster = (MxStillPresenter*) Find("MxStillPresenter", "ScoreBox");
MxU8 scoreColors[3] =
{0x76, 0x4c, 0x38}; // yellow - #FFB900, blue - #00548C, red - #CB1220, background - #CECECE, border - #74818B
MxS32 scoreY;
for (i = 0, scoreY = 0x79; i < GameState()->m_history.GetCount(); i++, scoreY += 0x1b) {
LegoGameState::ScoreItem* score = GameState()->m_history.GetScore(i);
m_scores[i] = scoreboxMaster->Clone();
MxS32 scoreX = 0x90;
if (i >= 10) {
if (i == 10) {
scoreY = 0x79;
}
scoreX = 0x158;
}
for (MxS32 scoreState = 0, scoreboxX = 1; scoreState < 5; scoreState++, scoreboxX += 5) {
for (MxS32 scoreBoxColumn = 0, scoreboxY = 1; scoreBoxColumn < 5; scoreBoxColumn++, scoreboxY += 5) {
MxU8 color = score->m_scores[scoreState][scoreBoxColumn];
if (color > 0) {
for (MxS32 lax = 0; lax < 4; lax++) {
#ifdef BETA10
memset(m_scores[i]->GetBitmapStart(scoreboxX, scoreboxY + lax), scoreColors[color - 1], 4);
#else
if (m_scores[i]->GetAlphaMask() != NULL) {
// memset(NULL, scoreColors[color - 1], 4);
}
else {
memset(
m_scores[i]->GetBitmap()->GetStart(scoreboxX, lax + scoreboxY),
scoreColors[color - 1],
4
);
}
#endif
}
}
}
}
m_scores[i]->Enable(TRUE);
m_scores[i]->SetTickleState(MxPresenter::e_repeating);
m_scores[i]->SetPosition(scoreX + 0xa1, scoreY);
#ifdef BETA10
for (MxS16 j = 0; score->m_name.m_letters[j] != -1; j++, scoreX += 0x17)
#else
for (MxS16 j = 0; j < (MxS16) sizeOfArray(m_name[0]) && score->m_name.m_letters[j] != -1; j++, scoreX += 0x17)
#endif
{
MxStillPresenter** intoAlphabet = [this,
index = score->m_name.m_letters[j]]() mutable -> MxStillPresenter** {
if (index < sizeOfArray(m_alphabet)) {
return &m_alphabet[index];
}
index -= sizeOfArray(m_alphabet);
index += m_intAlphabetOffset;
if (index >= sizeOfArray(m_intAlphabet) || !m_intAlphabet[index]) {
MORTAR_Log("Warning: international character not present in current game. Falling back to X");
return &m_alphabet[MORTARK_X - MORTARK_A];
}
return &m_intAlphabet[index];
}();
m_name[i][j] = (*intoAlphabet)->Clone();
assert(m_name[i][j]);
m_name[i][j]->Enable(TRUE);
m_name[i][j]->SetTickleState(MxPresenter::e_repeating);
m_name[i][j]->SetPosition(scoreX, scoreY);
}
}
#ifndef BETA10
PlayMusic(JukeboxScript::c_InformationCenter_Music);
#endif
}
// FUNCTION: LEGO1 0x10082a10
MxBool HistoryBook::Escape()
{
m_destLocation = LegoGameState::Area::e_infomain;
return TRUE;
}