Implement/match Radio/RadioState

This commit is contained in:
Christian Semmler 2024-01-30 13:24:58 -05:00
parent aaee2e134d
commit fe1e09d264
8 changed files with 177 additions and 12 deletions

View File

@ -52,6 +52,9 @@ class LegoState : public MxCore {
MxU16 m_unk0x08; // 0x08
StateStruct();
MxU32 FUN_10014d00();
MxBool FUN_10014de0(MxU32 p_objectId);
};
};

View File

@ -31,6 +31,8 @@ class MxBackgroundAudioManager : public MxCore {
return !strcmp(p_name, MxBackgroundAudioManager::ClassName()) || MxCore::IsA(p_name);
}
inline MxBool GetMusicEnabled() { return m_musicEnabled; }
void StartAction(MxParam& p_param);
void StopAction(MxParam& p_param);
MxResult PlayMusic(MxDSAction& p_action, undefined4 p_unk0x140, undefined4 p_unk0x13c);

View File

@ -43,7 +43,6 @@ class MxControlPresenter : public MxCompositePresenter {
private:
MxBool FUN_10044270(MxS32 p_x, MxS32 p_y, MxVideoPresenter* p_presenter);
void FUN_10044540(undefined2);
undefined2 m_unk0x4c; // 0x4c
MxS16 m_unk0x4e; // 0x4e

View File

@ -1,6 +1,8 @@
#ifndef RADIO_H
#define RADIO_H
#include "legocontrolmanager.h"
#include "mxactionnotificationparam.h"
#include "mxcore.h"
#include "radiostate.h"
@ -32,10 +34,15 @@ class Radio : public MxCore {
// Radio::`scalar deleting destructor'
private:
RadioState* m_state; // 0x08
MxBool m_unk0x0c; // 0x0c
RadioState* m_state; // 0x08
MxBool m_unk0x0c; // 0x0c
MxBool m_bgAudioPreviouslyEnabled; // 0x0d
void CreateRadioState();
void Play();
void Stop();
MxLong HandleEndAction(MxEndActionNotificationParam& p_param);
MxLong HandleNotification17(LegoControlManagerEvent& p_param);
};
#endif // RADIO_H

View File

@ -2,6 +2,7 @@
#define RADIOSTATE_H
#include "legostate.h"
#include "mxdsaction.h"
// VTABLE: LEGO1 0x100d6d28
// SIZE 0x30
@ -27,10 +28,17 @@ class RadioState : public LegoState {
// SYNTHETIC: LEGO1 0x1002d020
// RadioState::`scalar deleting destructor'
inline MxBool IsActive() { return m_active; }
inline void SetActive(MxBool p_active) { m_active = p_active; }
undefined4 FUN_1002d090();
MxBool FUN_1002d0c0(const MxAtomId& p_atom, MxU32 p_objectId);
private:
StateStruct m_unk0x08[3]; // 0x08
MxS16 m_unk0x2c; // 0x2c
undefined m_unk0x2e; // 0x2e
MxBool m_active; // 0x2e
};
#endif // RADIOSTATE_H

View File

@ -3,6 +3,20 @@
DECOMP_SIZE_ASSERT(LegoState, 0x08)
DECOMP_SIZE_ASSERT(LegoState::StateStruct, 0x0c)
// STUB: LEGO1 0x10014d00
MxU32 LegoState::StateStruct::FUN_10014d00()
{
// TODO
return 0;
}
// STUB: LEGO1 0x10014de0
MxBool LegoState::StateStruct::FUN_10014de0(MxU32 p_objectId)
{
// TODO
return FALSE;
}
// FUNCTION: LEGO1 0x10017c00
LegoState::StateStruct::StateStruct()
{

View File

@ -3,6 +3,8 @@
#include "legocontrolmanager.h"
#include "legogamestate.h"
#include "legoomni.h"
#include "mxbackgroundaudiomanager.h"
#include "mxcontrolpresenter.h"
#include "mxnotificationmanager.h"
DECOMP_SIZE_ASSERT(Radio, 0x10);
@ -17,15 +19,119 @@ Radio::Radio()
CreateRadioState();
}
// STUB: LEGO1 0x1002c990
// FUNCTION: LEGO1 0x1002c990
Radio::~Radio()
{
if (m_state->IsActive()) {
BackgroundAudioManager()->Stop();
m_state->SetActive(FALSE);
}
ControlManager()->Unregister(this);
NotificationManager()->Unregister(this);
}
// STUB: LEGO1 0x1002ca30
// FUNCTION: LEGO1 0x1002ca30
MxLong Radio::Notify(MxParam& p_param)
{
// TODO
MxLong result = 0;
if (m_unk0x0c) {
switch (((MxNotificationParam&) p_param).GetType()) {
case c_notificationEndAction:
result = HandleEndAction((MxEndActionNotificationParam&) p_param);
break;
case c_notificationType17:
result = HandleNotification17((LegoControlManagerEvent&) p_param);
break;
}
}
return result;
}
// FUNCTION: LEGO1 0x1002ca70
void Radio::Play()
{
if (!m_state->IsActive()) {
GetCurrentWorld();
MxDSAction action;
action.SetObjectId(m_state->FUN_1002d090());
action.SetAtomId(*g_jukeboxScript);
action.SetLoopCount(1);
m_bgAudioPreviouslyEnabled = BackgroundAudioManager()->GetMusicEnabled();
if (!m_bgAudioPreviouslyEnabled) {
BackgroundAudioManager()->Enable(TRUE);
}
BackgroundAudioManager()->PlayMusic(action, 3, 4);
m_state->SetActive(TRUE);
}
}
// FUNCTION: LEGO1 0x1002cb70
void Radio::Stop()
{
if (m_state->IsActive()) {
LegoWorld* world = GetCurrentWorld();
MxControlPresenter* presenter = (MxControlPresenter*) world->Find(world->GetAtom(), 18);
if (presenter)
presenter->VTable0x6c(0);
BackgroundAudioManager()->Stop();
BackgroundAudioManager()->Enable(m_bgAudioPreviouslyEnabled);
m_state->SetActive(FALSE);
}
}
// FUNCTION: LEGO1 0x1002cbc0
MxLong Radio::HandleNotification17(LegoControlManagerEvent& p_param)
{
MxDSAction action; // Unused
MxS32 objectId = p_param.GetClickedObjectId();
if (objectId == 18) {
if (m_state->IsActive()) {
Stop();
}
else {
Play();
}
if (GetCurrentWorld()) {
#ifdef COMPAT_MODE
MxNotificationParam param(c_notificationEndAction, this);
GetCurrentWorld()->Notify(param);
#else
GetCurrentWorld()->Notify(MxNotificationParam(c_notificationType0, this));
#endif
}
return 1;
}
return 0;
}
// FUNCTION: LEGO1 0x1002ccc0
MxLong Radio::HandleEndAction(MxEndActionNotificationParam& p_param)
{
if (m_state->IsActive() &&
m_state->FUN_1002d0c0(p_param.GetAction()->GetAtomId(), p_param.GetAction()->GetObjectId())) {
MxDSAction action;
action.SetAtomId(*g_jukeboxScript);
action.SetObjectId(m_state->FUN_1002d090());
action.SetLoopCount(1);
BackgroundAudioManager()->PlayMusic(action, 3, 4);
return 1;
}
return 0;
}

View File

@ -53,10 +53,12 @@ RadioState::RadioState()
MxS32 random = rand();
m_unk0x2c = random % 3;
m_unk0x08[0].m_unk0x08 = 0;
m_unk0x08[0].m_unk0x06 = 0;
// TODO: Most likely inline function
m_unk0x08[0].m_unk0x04 = 6;
m_unk0x08[0].m_unk0x00 = m_unk0x100f3218;
m_unk0x08[0].m_unk0x08 = 0;
m_unk0x08[0].m_unk0x06 = 0;
random = rand();
@ -78,12 +80,36 @@ RadioState::RadioState()
m_unk0x08[2].m_unk0x08 = (MxU32) random % 9;
m_unk0x2e = 0;
m_active = FALSE;
}
// STUB: LEGO1 0x1002cf50
// FUNCTION: LEGO1 0x1002cf50
MxBool RadioState::VTable0x14()
{
// TODO
return FALSE;
}
// FUNCTION: LEGO1 0x1002d090
MxU32 RadioState::FUN_1002d090()
{
if (m_unk0x2c == 2) {
m_unk0x2c = 0;
}
else {
m_unk0x2c++;
}
return m_unk0x08[m_unk0x2c].FUN_10014d00();
}
// FUNCTION: LEGO1 0x1002d0c0
MxBool RadioState::FUN_1002d0c0(const MxAtomId& p_atom, MxU32 p_objectId)
{
if (*g_jukeboxScript == p_atom) {
for (MxS16 i = 0; i < 3; i++)
if (m_unk0x08[i].FUN_10014de0(p_objectId))
return TRUE;
}
return FALSE;
}