Move some classes to LegoOmni (#417)

This commit is contained in:
Christian Semmler
2024-01-08 06:45:07 -05:00
committed by GitHub
parent c47206617d
commit 091ecd5935
27 changed files with 245 additions and 229 deletions

View File

@@ -1,172 +0,0 @@
#include "mxcompositemediapresenter.h"
#include "legoomni.h"
#include "legosoundmanager.h"
#include "legovideomanager.h"
#include "mxautolocker.h"
#include "mxdsmultiaction.h"
#include "mxmediapresenter.h"
#include "mxobjectfactory.h"
#include "mxtimer.h"
DECOMP_SIZE_ASSERT(MxCompositeMediaPresenter, 0x50)
// FUNCTION: LEGO1 0x10073ea0
MxCompositeMediaPresenter::MxCompositeMediaPresenter()
{
m_unk0x4c = 0;
m_unk0x4e = FALSE;
VideoManager()->AddPresenter(*this);
}
// FUNCTION: LEGO1 0x10074020
MxCompositeMediaPresenter::~MxCompositeMediaPresenter()
{
VideoManager()->RemovePresenter(*this);
}
// FUNCTION: LEGO1 0x10074090
MxResult MxCompositeMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action)
{
MxAutoLocker lock(&m_criticalSection);
MxResult result = FAILURE;
MxDSActionList* actions = ((MxDSMultiAction*) p_action)->GetActionList();
MxDSActionListCursor cursor(actions);
MxDSAction* action;
if (MxPresenter::StartAction(p_controller, p_action) == SUCCESS) {
// The usual cursor.Next() loop doesn't match here, even though
// the logic is the same. It does match when "deconstructed" into
// the following Head(), Current() and NextFragment() calls,
// but this seems unlikely to be the original code.
// The alpha debug build also uses Next().
// cursor.Head();
// while (cursor.Current(action)) {
// cursor.NextFragment();
while (cursor.Next(action)) {
MxBool success = FALSE;
action->CopyFlags(m_action->GetFlags());
const char* presenterName = PresenterNameDispatch(*action);
MxPresenter* presenter = (MxPresenter*) ObjectFactory()->Create(presenterName);
if (presenter && presenter->AddToManager() == SUCCESS) {
presenter->SetCompositePresenter(this);
if (presenter->StartAction(p_controller, action) == SUCCESS) {
presenter->SetTickleState(TickleState_Idle);
if (presenter->IsA("MxVideoPresenter"))
VideoManager()->RemovePresenter(*presenter);
else if (presenter->IsA("MxAudioPresenter"))
SoundManager()->RemovePresenter(*presenter);
success = TRUE;
}
}
if (success) {
action->SetOrigin(this);
m_list.push_back(presenter);
}
else if (presenter)
delete presenter;
}
if (!m_compositePresenter) {
SetTickleState(TickleState_Ready);
MxLong time = Timer()->GetTime();
m_action->SetUnknown90(time);
}
result = SUCCESS;
}
return result;
}
// FUNCTION: LEGO1 0x100742e0
void MxCompositeMediaPresenter::StartingTickle()
{
MxAutoLocker lock(&m_criticalSection);
if (!m_unk0x4e) {
for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) {
if ((*it)->GetCurrentTickleState() < TickleState_Streaming) {
(*it)->Tickle();
if ((*it)->GetCurrentTickleState() == TickleState_Streaming ||
((*it)->GetAction() && (*it)->GetAction()->GetStartTime()))
m_unk0x4c++;
}
}
if (m_list.size() == m_unk0x4c) {
m_unk0x4e = TRUE;
m_unk0x4c = 0;
for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) {
if (!(*it)->GetAction()->GetStartTime())
m_unk0x4c++;
}
}
}
else {
for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) {
if (!(*it)->GetAction()->GetStartTime() && ((MxMediaPresenter*) *it)->FUN_100b5650() &&
!((*it)->GetAction()->GetFlags() & MxDSAction::Flag_Bit9)) {
(*it)->Tickle();
(*it)->GetAction()->SetFlags((*it)->GetAction()->GetFlags() | MxDSAction::Flag_Bit9);
m_unk0x4c--;
}
}
if (!m_unk0x4c) {
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
m_currentTickleState = TickleState_Streaming;
MxLong time = Timer()->GetTime();
m_action->SetUnknown90(time);
}
}
}
// FUNCTION: LEGO1 0x10074470
MxResult MxCompositeMediaPresenter::Tickle()
{
MxAutoLocker lock(&m_criticalSection);
switch (m_currentTickleState) {
case TickleState_Ready:
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
m_currentTickleState = TickleState_Starting;
case TickleState_Starting:
StartingTickle();
break;
case TickleState_Streaming:
case TickleState_Repeating:
case TickleState_unk5:
case TickleState_Done: {
for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++)
(*it)->Tickle();
break;
}
default:
break;
}
return SUCCESS;
}
// FUNCTION: LEGO1 0x10074540
MxResult MxCompositeMediaPresenter::PutData()
{
MxAutoLocker lock(&m_criticalSection);
if (m_currentTickleState >= TickleState_Streaming && m_currentTickleState <= TickleState_Done) {
for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++)
(*it)->PutData();
}
return SUCCESS;
}

View File

@@ -2,8 +2,6 @@
#include "decomp.h"
#include "define.h"
#include "legoobjectfactory.h"
#include "legoomni.h"
#include "mxactionnotificationparam.h"
#include "mxautolocker.h"
#include "mxcompositepresenter.h"
@@ -11,8 +9,10 @@
#include "mxdssound.h"
#include "mxentity.h"
#include "mxnotificationmanager.h"
#include "mxobjectfactory.h"
#include "mxparam.h"
#include "mxstreamer.h"
#include "mxutil.h"
#include <string.h>

View File

@@ -0,0 +1,149 @@
#include "mxutil.h"
#include "mxdsfile.h"
#include "mxdsobject.h"
#include "mxrect32.h"
// GLOBAL: LEGO1 0x101020e8
void (*g_omniUserMessage)(const char*, int);
// FUNCTION: LEGO1 0x100b6e10
MxBool FUN_100b6e10(
MxS32 p_bitmapWidth,
MxS32 p_bitmapHeight,
MxS32 p_videoParamWidth,
MxS32 p_videoParamHeight,
MxS32* p_left,
MxS32* p_top,
MxS32* p_right,
MxS32* p_bottom,
MxS32* p_width,
MxS32* p_height
)
{
MxPoint32 topLeft(*p_left, *p_top);
MxRect32 bitmapRect(MxPoint32(0, 0), MxSize32(p_bitmapWidth, p_bitmapHeight));
MxPoint32 bottomRight(*p_right, *p_bottom);
MxRect32 videoParamRect(MxPoint32(0, 0), MxSize32(p_videoParamWidth, p_videoParamHeight));
MxRect32 rect(0, 0, *p_width, *p_height);
rect.AddPoint(topLeft);
if (!rect.IntersectsWith(bitmapRect))
return FALSE;
rect.Intersect(bitmapRect);
rect.SubtractPoint(topLeft);
rect.AddPoint(bottomRight);
if (!rect.IntersectsWith(videoParamRect))
return FALSE;
rect.Intersect(videoParamRect);
rect.SubtractPoint(bottomRight);
*p_left += rect.GetLeft();
*p_top += rect.GetTop();
*p_right += rect.GetLeft();
*p_bottom += rect.GetTop();
*p_width = rect.GetWidth();
*p_height = rect.GetHeight();
return TRUE;
}
// FUNCTION: LEGO1 0x100b6ff0
void MakeSourceName(char* p_output, const char* p_input)
{
const char* cln = strchr(p_input, ':');
if (cln) {
p_input = cln + 1;
}
strcpy(p_output, p_input);
strlwr(p_output);
char* extLoc = strstr(p_output, ".si");
if (extLoc) {
*extLoc = 0;
}
}
// FUNCTION: LEGO1 0x100b7050
MxBool KeyValueStringParse(char* p_outputValue, const char* p_key, const char* p_source)
{
MxBool didMatch = FALSE;
MxS16 len = strlen(p_source);
char* temp = new char[len + 1];
strcpy(temp, p_source);
char* token = strtok(temp, ", \t\r\n:");
while (token) {
len -= (strlen(token) + 1);
if (strcmpi(token, p_key) == 0) {
if (p_outputValue && len > 0) {
char* cur = &token[strlen(p_key)];
cur++;
while (*cur != ',') {
if (*cur == ' ' || *cur == '\0' || *cur == '\t' || *cur == '\n' || *cur == '\r')
break;
*p_outputValue++ = *cur++;
}
*p_outputValue = '\0';
}
didMatch = TRUE;
break;
}
token = strtok(NULL, ", \t\r\n:");
}
delete[] temp;
return didMatch;
}
// FUNCTION: LEGO1 0x100b7210
void SetOmniUserMessage(void (*p_userMsg)(const char*, int))
{
g_omniUserMessage = p_userMsg;
}
// Should probably be somewhere else
// FUNCTION: LEGO1 0x100c0280
MxDSObject* CreateStreamObject(MxDSFile* p_file, MxS16 p_ofs)
{
MxU8* buf;
_MMCKINFO tmpChunk;
if (p_file->Seek(((MxLong*) p_file->GetBuffer())[p_ofs], 0)) {
return NULL;
}
if (p_file->Read((MxU8*) &tmpChunk.ckid, 8) == 0 && tmpChunk.ckid == FOURCC('M', 'x', 'S', 't')) {
if (p_file->Read((MxU8*) &tmpChunk.ckid, 8) == 0 && tmpChunk.ckid == FOURCC('M', 'x', 'O', 'b')) {
buf = new MxU8[tmpChunk.cksize];
if (!buf) {
return NULL;
}
if (p_file->Read(buf, tmpChunk.cksize) != 0) {
return NULL;
}
// Save a copy so we can clean up properly, because
// this function will alter the pointer value.
MxU8* copy = buf;
MxDSObject* obj = DeserializeDSObjectDispatch(&buf, -1);
delete[] copy;
return obj;
}
return NULL;
}
return NULL;
}