mirror of
https://github.com/isledecomp/isle.git
synced 2025-10-24 08:54:15 +00:00
385 lines
8.8 KiB
C++
385 lines
8.8 KiB
C++
#include "mxbackgroundaudiomanager.h"
|
|
|
|
#include "legomain.h"
|
|
#include "misc.h"
|
|
#include "mxaudiopresenter.h"
|
|
#include "mxdssound.h"
|
|
#include "mxmisc.h"
|
|
#include "mxnotificationmanager.h"
|
|
#include "mxpresenter.h"
|
|
#include "mxstreamer.h"
|
|
#include "mxticklemanager.h"
|
|
#include "mxutilities.h"
|
|
#include "mxwavepresenter.h"
|
|
|
|
DECOMP_SIZE_ASSERT(MxBackgroundAudioManager, 0x150)
|
|
|
|
// FUNCTION: LEGO1 0x1007ea90
|
|
// FUNCTION: BETA10 0x100e8530
|
|
MxBackgroundAudioManager::MxBackgroundAudioManager()
|
|
{
|
|
NotificationManager()->Register(this);
|
|
m_activePresenter = NULL;
|
|
m_pendingPresenter = NULL;
|
|
m_tickleState = MxPresenter::e_idle;
|
|
m_speed = 0;
|
|
m_targetVolume = 0;
|
|
m_volumeSuppressionAmount = 0;
|
|
m_enabled = FALSE;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007ec20
|
|
MxBackgroundAudioManager::~MxBackgroundAudioManager()
|
|
{
|
|
TickleManager()->UnregisterClient(this);
|
|
NotificationManager()->Unregister(this);
|
|
DestroyMusic();
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007ece0
|
|
MxResult MxBackgroundAudioManager::Create(MxAtomId& p_script, MxU32 p_frequencyMS)
|
|
{
|
|
MxResult result = OpenMusic(p_script);
|
|
|
|
if (result == SUCCESS) {
|
|
TickleManager()->RegisterClient(this, p_frequencyMS);
|
|
m_enabled = TRUE;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007ed20
|
|
MxResult MxBackgroundAudioManager::OpenMusic(MxAtomId& p_script)
|
|
{
|
|
if (m_script.GetInternal()) {
|
|
DestroyMusic();
|
|
}
|
|
|
|
MxResult result = FAILURE;
|
|
|
|
if (Streamer()->Open(p_script.GetInternal(), 0)) {
|
|
m_script = p_script;
|
|
result = SUCCESS;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007ed70
|
|
void MxBackgroundAudioManager::DestroyMusic()
|
|
{
|
|
if (m_script.GetInternal()) {
|
|
MxDSAction ds;
|
|
ds.SetAtomId(m_script);
|
|
ds.SetUnknown24(-2);
|
|
DeleteObject(ds);
|
|
Streamer()->Close(m_script.GetInternal());
|
|
m_enabled = FALSE;
|
|
}
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007ee40
|
|
MxResult MxBackgroundAudioManager::Tickle()
|
|
{
|
|
switch (m_tickleState) {
|
|
case MxPresenter::e_starting:
|
|
FadeToTargetVolume();
|
|
break;
|
|
case MxPresenter::e_streaming:
|
|
MakePendingPresenterActive();
|
|
break;
|
|
case MxPresenter::e_repeating:
|
|
FadeInPendingPresenter();
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007ee70
|
|
void MxBackgroundAudioManager::MakePendingPresenterActive()
|
|
{
|
|
if (m_activePresenter && m_activePresenter->GetAction()) {
|
|
DeleteObject(*m_pendingPresenter->GetAction());
|
|
}
|
|
|
|
if (m_pendingPresenter) {
|
|
m_activePresenter = m_pendingPresenter;
|
|
m_action1 = m_action2;
|
|
m_pendingPresenter = NULL;
|
|
m_action2.SetObjectId(-1);
|
|
m_action2.SetAtomId(MxAtomId());
|
|
m_tickleState = MxPresenter::e_idle;
|
|
}
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007ef40
|
|
void MxBackgroundAudioManager::FadeInPendingPresenter()
|
|
{
|
|
MxS32 compare, volume;
|
|
|
|
if (m_activePresenter == NULL) {
|
|
if (m_pendingPresenter) {
|
|
if (m_volumeSuppressionAmount != 0) {
|
|
compare = 30;
|
|
}
|
|
else {
|
|
compare = m_targetVolume;
|
|
}
|
|
|
|
volume = m_pendingPresenter->GetVolume();
|
|
if (volume < compare) {
|
|
if (m_speed + m_pendingPresenter->GetVolume() <= compare) {
|
|
compare = m_speed + m_pendingPresenter->GetVolume();
|
|
}
|
|
|
|
m_pendingPresenter->SetVolume(compare);
|
|
}
|
|
else {
|
|
m_pendingPresenter->SetVolume(compare);
|
|
m_activePresenter = m_pendingPresenter;
|
|
m_action1 = m_action2;
|
|
m_pendingPresenter = NULL;
|
|
m_action2.SetObjectId(-1);
|
|
m_action2.SetAtomId(MxAtomId());
|
|
m_tickleState = MxPresenter::e_idle;
|
|
}
|
|
}
|
|
}
|
|
else if (m_activePresenter->GetAction() != NULL) {
|
|
if (m_activePresenter->GetVolume() == 0) {
|
|
DeleteObject(*m_activePresenter->GetAction());
|
|
}
|
|
else {
|
|
if (m_activePresenter->GetVolume() - m_speed > 0) {
|
|
volume = m_activePresenter->GetVolume() - m_speed;
|
|
}
|
|
else {
|
|
volume = 0;
|
|
}
|
|
|
|
m_activePresenter->SetVolume(volume);
|
|
}
|
|
}
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007f0e0
|
|
// FUNCTION: BETA10 0x100e8d8d
|
|
void MxBackgroundAudioManager::FadeToTargetVolume()
|
|
{
|
|
MxS32 volume, compare;
|
|
|
|
if (m_activePresenter != NULL) {
|
|
volume = m_activePresenter->GetVolume();
|
|
|
|
if (m_volumeSuppressionAmount != 0) {
|
|
compare = 30;
|
|
}
|
|
else {
|
|
compare = m_targetVolume;
|
|
}
|
|
|
|
if (volume < compare) {
|
|
m_activePresenter->SetVolume(volume + m_speed < compare ? volume + m_speed : compare);
|
|
}
|
|
else if (compare < volume) {
|
|
m_activePresenter->SetVolume(volume - m_speed > compare ? volume - m_speed : compare);
|
|
}
|
|
else {
|
|
m_activePresenter->SetVolume(volume);
|
|
m_tickleState = MxPresenter::e_idle;
|
|
}
|
|
}
|
|
else {
|
|
m_tickleState = MxPresenter::e_idle;
|
|
}
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007f170
|
|
// FUNCTION: BETA10 0x100e8eb6
|
|
MxLong MxBackgroundAudioManager::Notify(MxParam& p_param)
|
|
{
|
|
MxNotificationParam& param = (MxNotificationParam&) p_param;
|
|
|
|
switch (param.GetNotification()) {
|
|
case c_notificationStartAction:
|
|
StartAction(p_param);
|
|
return 1;
|
|
case c_notificationEndAction:
|
|
StopAction(p_param);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007f1b0
|
|
void MxBackgroundAudioManager::StartAction(MxParam& p_param)
|
|
{
|
|
// TODO: the sender is most likely a MxAudioPresenter?
|
|
m_pendingPresenter = (MxAudioPresenter*) ((MxNotificationParam&) p_param).GetSender();
|
|
m_action2.SetAtomId(m_pendingPresenter->GetAction()->GetAtomId());
|
|
m_action2.SetObjectId(m_pendingPresenter->GetAction()->GetObjectId());
|
|
m_targetVolume = ((MxDSSound*) (m_pendingPresenter->GetAction()))->GetVolume();
|
|
m_pendingPresenter->SetVolume(0);
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007f200
|
|
void MxBackgroundAudioManager::StopAction(MxParam& p_param)
|
|
{
|
|
if (((MxNotificationParam&) p_param).GetSender() == m_activePresenter) {
|
|
m_activePresenter = NULL;
|
|
m_action1.SetAtomId(MxAtomId());
|
|
m_action1.SetObjectId(-1);
|
|
}
|
|
else if (((MxNotificationParam&) p_param).GetSender() == m_pendingPresenter) {
|
|
m_pendingPresenter = NULL;
|
|
m_action2.SetAtomId(MxAtomId());
|
|
m_action2.SetObjectId(-1);
|
|
}
|
|
|
|
Lego()->HandleEndAction(p_param);
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007f2f0
|
|
// FUNCTION: BETA10 0x100e90fc
|
|
MxResult MxBackgroundAudioManager::PlayMusic(
|
|
MxDSAction& p_action,
|
|
MxS32 p_speed,
|
|
MxPresenter::TickleState p_tickleState
|
|
)
|
|
{
|
|
assert(p_speed > 0);
|
|
|
|
if (!m_enabled) {
|
|
return SUCCESS;
|
|
}
|
|
|
|
if (m_action2.GetObjectId() == -1 && m_action1.GetObjectId() != p_action.GetObjectId()) {
|
|
MxDSAction action;
|
|
action.SetAtomId(GetCurrentAction().GetAtomId());
|
|
action.SetObjectId(GetCurrentAction().GetObjectId());
|
|
action.SetUnknown24(GetCurrentAction().GetUnknown24());
|
|
|
|
m_action2.SetAtomId(p_action.GetAtomId());
|
|
m_action2.SetObjectId(p_action.GetObjectId());
|
|
m_action2.SetNotificationObject(this);
|
|
m_action2.SetOrigin(this);
|
|
|
|
MxResult result = Start(&m_action2);
|
|
|
|
GetCurrentAction().SetAtomId(action.GetAtomId());
|
|
GetCurrentAction().SetObjectId(action.GetObjectId());
|
|
GetCurrentAction().SetUnknown24(action.GetUnknown24());
|
|
|
|
if (result == SUCCESS) {
|
|
m_tickleState = p_tickleState;
|
|
m_speed = p_speed;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
return FAILURE;
|
|
}
|
|
|
|
// FUNCTION: BETA10 0x100e92ec
|
|
void MxBackgroundAudioManager::Update(MxS32 p_targetVolume, MxS32 p_speed, MxPresenter::TickleState p_tickleState)
|
|
{
|
|
assert(p_targetVolume >= 0 && p_targetVolume <= 100);
|
|
assert(p_speed > 0);
|
|
|
|
m_tickleState = p_tickleState;
|
|
m_speed = p_speed;
|
|
m_targetVolume = p_targetVolume;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007f470
|
|
// FUNCTION: BETA10 0x100e9388
|
|
void MxBackgroundAudioManager::Stop()
|
|
{
|
|
if (m_action2.GetObjectId() != -1) {
|
|
DeleteObject(m_action2);
|
|
}
|
|
|
|
m_pendingPresenter = NULL;
|
|
m_action2.SetAtomId(MxAtomId());
|
|
m_action2.SetObjectId(-1);
|
|
|
|
if (m_action1.GetObjectId() != -1) {
|
|
DeleteObject(m_action1);
|
|
}
|
|
|
|
m_activePresenter = NULL;
|
|
m_action1.SetAtomId(MxAtomId());
|
|
m_volumeSuppressionAmount = 0;
|
|
m_action1.SetObjectId(-1);
|
|
m_tickleState = MxPresenter::e_idle;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007f570
|
|
// FUNCTION: BETA10 0x100e94e6
|
|
void MxBackgroundAudioManager::LowerVolume()
|
|
{
|
|
if (m_volumeSuppressionAmount == 0) {
|
|
if (m_tickleState == 0) {
|
|
m_tickleState = MxPresenter::e_starting;
|
|
}
|
|
m_speed = 20;
|
|
}
|
|
m_volumeSuppressionAmount++;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007f5b0
|
|
// FUNCTION: BETA10 0x100e9543
|
|
void MxBackgroundAudioManager::RaiseVolume()
|
|
{
|
|
if (m_volumeSuppressionAmount != 0) {
|
|
m_volumeSuppressionAmount--;
|
|
if (m_volumeSuppressionAmount == 0) {
|
|
if (m_tickleState == 0) {
|
|
m_tickleState = MxPresenter::e_starting;
|
|
}
|
|
m_speed = 10;
|
|
}
|
|
}
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007f5f0
|
|
void MxBackgroundAudioManager::Enable(MxBool p_enable)
|
|
{
|
|
if (this->m_enabled != p_enable) {
|
|
this->m_enabled = p_enable;
|
|
|
|
if (!p_enable) {
|
|
Stop();
|
|
}
|
|
}
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007f610
|
|
// FUNCTION: BETA10 0x100e95ee
|
|
MxResult MxBackgroundAudioManager::SetPendingPresenter(
|
|
MxPresenter* p_presenter,
|
|
MxS32 p_speed,
|
|
MxPresenter::TickleState p_tickleState
|
|
)
|
|
|
|
{
|
|
m_pendingPresenter = (MxAudioPresenter*) p_presenter;
|
|
m_targetVolume = ((MxDSSound*) m_pendingPresenter->GetAction())->GetVolume();
|
|
|
|
((MxWavePresenter*) m_pendingPresenter)->SetVolume(0);
|
|
|
|
m_speed = p_speed;
|
|
m_tickleState = p_tickleState;
|
|
return SUCCESS;
|
|
}
|
|
|
|
// FUNCTION: LEGO1 0x1007f650
|
|
// FUNCTION: BETA10 0x100e9663
|
|
void MxBackgroundAudioManager::Init()
|
|
{
|
|
this->m_activePresenter = NULL;
|
|
this->m_tickleState = MxPresenter::e_idle;
|
|
}
|