Implement/match most of MxVideoPresenter (#280)

* Bootstrap MxMediaPresenter

* Implement/match MxMediaPresenter::Tickle and related

* Implement AppendChunk and Enable

* Implement/match most of MxVideoPresenter

* Add missing offset
This commit is contained in:
Christian Semmler 2023-11-14 15:25:14 -05:00 committed by GitHub
parent c626f18b03
commit d8bf4aebf4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 232 additions and 46 deletions

View file

@ -70,27 +70,21 @@ public:
inline MxBool IsLooping() const { return m_flags & Flag_Looping; }
inline MxBool IsBit3() const { return m_flags & Flag_Bit3; }
private:
MxU32 m_sizeOnDisk;
MxU32 m_flags;
MxLong m_startTime;
protected:
MxLong m_duration;
MxS32 m_loopCount;
private:
MxVector3Data m_location;
MxVector3Data m_direction;
MxVector3Data m_up;
char* m_extraData;
MxU16 m_extraLength;
MxCore* m_unk84;
undefined4 m_unk88;
MxCore* m_unk8c;
protected:
MxLong m_unkTimingField; // 0x90
MxU32 m_sizeOnDisk; // 0x2c
MxU32 m_flags; // 0x30
MxLong m_startTime; // 0x34
MxLong m_duration; // 0x38
MxS32 m_loopCount; // 0x3c
MxVector3Data m_location; // 0x40
MxVector3Data m_direction; // 0x54
MxVector3Data m_up; // 0x68
char* m_extraData; // 0x7c
MxU16 m_extraLength; // 0x80
MxCore* m_unk84; // 0x84
undefined4 m_unk88; // 0x88
MxCore* m_unk8c; // 0x8c
MxLong m_unkTimingField; // 0x90
};
#endif // MXDSACTION_H

View file

@ -37,17 +37,17 @@ public:
inline MxLong GetSustainTime() const { return this->m_sustainTime; }
private:
MxU32 m_sizeOnDisk;
char* m_mediaSrcPath;
MxU32 m_sizeOnDisk; // 0x94
char* m_mediaSrcPath; // 0x98
struct {
undefined4 m_unk00;
undefined4 m_unk04;
} m_unk9c;
MxS32 m_framesPerSecond;
MxS32 m_mediaFormat;
MxS32 m_paletteManagement;
MxLong m_sustainTime;
undefined4 m_unkb4;
} m_unk9c; // 0x9c
MxS32 m_framesPerSecond; // 0xa4
MxS32 m_mediaFormat; // 0xa8
MxS32 m_paletteManagement; // 0xac
MxLong m_sustainTime; // 0xb0
undefined4 m_unkb4; // 0xb4
};
#endif // MXDSMEDIAACTION_H

View file

@ -129,7 +129,7 @@ void MxMediaPresenter::StreamingTickle()
else if (m_action->GetFlags() & MxDSAction::Flag_Looping) {
AppendChunk(m_currentChunk);
if (!MxPresenter::IsEnabled()) {
if (!IsEnabled()) {
m_subscriber->FUN_100b8390(m_currentChunk);
m_currentChunk = NULL;
}
@ -141,7 +141,7 @@ void MxMediaPresenter::StreamingTickle()
// OFFSET: LEGO1 0x100b5e10
void MxMediaPresenter::RepeatingTickle()
{
if (MxPresenter::IsEnabled() && !m_currentChunk) {
if (IsEnabled() && !m_currentChunk) {
if (m_cursor)
if (!m_cursor->Next(m_currentChunk))
m_cursor->Next(m_currentChunk);
@ -173,7 +173,7 @@ void MxMediaPresenter::DoneTickle()
// OFFSET: LEGO1 0x100b6030
void MxMediaPresenter::Enable(MxBool p_enable)
{
if (MxPresenter::IsEnabled() != p_enable) {
if (IsEnabled() != p_enable) {
MxPresenter::Enable(p_enable);
if (p_enable) {

View file

@ -1,12 +1,14 @@
#include "mxvideopresenter.h"
#include "mxautolocker.h"
#include "mxdsmediaaction.h"
#include "mxvideomanager.h"
DECOMP_SIZE_ASSERT(MxVideoPresenter, 0x64);
DECOMP_SIZE_ASSERT(MxVideoPresenter::AlphaMask, 0xc);
// OFFSET: LEGO1 0x1000c700
void MxVideoPresenter::VTable0x5c(undefined4 p_unknown1)
void MxVideoPresenter::VTable0x5c(MxStreamChunk* p_chunk)
{
// Empty
}
@ -18,7 +20,7 @@ void MxVideoPresenter::VTable0x60()
}
// OFFSET: LEGO1 0x1000c720
void MxVideoPresenter::VTable0x68(undefined4 p_unknown1)
void MxVideoPresenter::VTable0x68(MxStreamChunk* p_chunk)
{
// Empty
}
@ -232,10 +234,20 @@ void MxVideoPresenter::Destroy(MxBool p_fromDestructor)
MxMediaPresenter::Destroy(FALSE);
}
// OFFSET: LEGO1 0x100b28b0 STUB
// OFFSET: LEGO1 0x100b28b0
void MxVideoPresenter::VTable0x64()
{
// TODO
MxStreamChunk* chunk = NextChunk();
if (chunk->GetFlags() & MxStreamChunk::Flag_Bit2) {
m_subscriber->FUN_100b8390(chunk);
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
m_currentTickleState = TickleState_Repeating;
}
else {
VTable0x68(chunk);
m_subscriber->FUN_100b8390(chunk);
}
}
// OFFSET: LEGO1 0x100b2900
@ -306,6 +318,175 @@ void MxVideoPresenter::VTable0x6c()
// TODO
}
// OFFSET: LEGO1 0x100b2f60
void MxVideoPresenter::ReadyTickle()
{
MxStreamChunk* chunk = NextChunk();
if (chunk) {
VTable0x5c(chunk);
m_subscriber->FUN_100b8390(chunk);
ParseExtra();
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
m_currentTickleState = TickleState_Starting;
}
}
// OFFSET: LEGO1 0x100b2fa0
void MxVideoPresenter::StartingTickle()
{
MxStreamChunk* chunk = FUN_100b5650();
if (chunk && m_action->GetElapsedTime() >= chunk->GetTime()) {
VTable0x60();
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
m_currentTickleState = TickleState_Streaming;
}
}
// OFFSET: LEGO1 0x100b2fe0
void MxVideoPresenter::StreamingTickle()
{
if (m_action->GetFlags() & MxDSAction::Flag_Bit9) {
if (!m_currentChunk)
MxMediaPresenter::StreamingTickle();
if (m_currentChunk) {
VTable0x68(m_currentChunk);
m_currentChunk = NULL;
}
}
else {
for (MxS16 i = 0; i < m_unk5c; i++) {
if (!m_currentChunk) {
MxMediaPresenter::StreamingTickle();
if (!m_currentChunk)
break;
}
if (m_action->GetElapsedTime() < m_currentChunk->GetTime())
break;
VTable0x68(m_currentChunk);
m_subscriber->FUN_100b8390(m_currentChunk);
m_currentChunk = NULL;
m_flags |= Flag_Bit1;
if (m_currentTickleState != TickleState_Streaming)
break;
}
if (m_flags & Flag_Bit1)
m_unk5c = 5;
}
}
// OFFSET: LEGO1 0x100b3080
void MxVideoPresenter::RepeatingTickle()
{
if (IsEnabled()) {
if (m_action->GetFlags() & MxDSAction::Flag_Bit9) {
if (!m_currentChunk)
MxMediaPresenter::RepeatingTickle();
if (m_currentChunk) {
VTable0x68(m_currentChunk);
m_currentChunk = NULL;
}
}
else {
for (MxS16 i = 0; i < m_unk5c; i++) {
if (!m_currentChunk) {
MxMediaPresenter::RepeatingTickle();
if (!m_currentChunk)
break;
}
if (m_action->GetElapsedTime() % m_action->GetLoopCount() < m_currentChunk->GetTime())
break;
VTable0x68(m_currentChunk);
m_currentChunk = NULL;
m_flags |= Flag_Bit1;
if (m_currentTickleState != TickleState_Repeating)
break;
}
if (m_flags & Flag_Bit1)
m_unk5c = 5;
}
}
}
// OFFSET: LEGO1 0x100b3130
void MxVideoPresenter::Unk5Tickle()
{
MxLong sustainTime = ((MxDSMediaAction*) m_action)->GetSustainTime();
if (sustainTime != -1) {
if (sustainTime) {
if (m_unk60 == -1)
m_unk60 = m_action->GetElapsedTime();
if (m_action->GetElapsedTime() >= m_unk60 + ((MxDSMediaAction*) m_action)->GetSustainTime()) {
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
m_currentTickleState = TickleState_Done;
}
}
else {
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
m_currentTickleState = TickleState_Done;
}
}
}
// OFFSET: LEGO1 0x100b31a0
MxResult MxVideoPresenter::AddToManager()
{
MxResult result = FAILURE;
if (MVideoManager()) {
result = SUCCESS;
MVideoManager()->AddPresenter(*this);
}
return result;
}
// OFFSET: LEGO1 0x100b31d0
void MxVideoPresenter::EndAction()
{
if (m_action) {
MxMediaPresenter::EndAction();
MxAutoLocker lock(&m_criticalSection);
if (m_bitmap) {
MxLong height = m_bitmap->GetBmiHeightAbs();
MxLong width = m_bitmap->GetBmiWidth();
MxS32 x = m_location.m_x;
MxS32 y = m_location.m_y;
MxRect32 rect(x, y, x + width, y + height);
MVideoManager()->InvalidateRect(rect);
}
}
}
// OFFSET: LEGO1 0x100b3280
undefined4 MxVideoPresenter::PutData()
{
MxAutoLocker lock(&m_criticalSection);
if (IsEnabled() && m_currentTickleState >= TickleState_Streaming && m_currentTickleState <= TickleState_unk5)
VTable0x6c();
return 0;
}
// OFFSET: LEGO1 0x100b3300
undefined MxVideoPresenter::VTable0x74()
{

View file

@ -6,10 +6,14 @@
#include "mxmediapresenter.h"
// VTABLE 0x100d4be8
// SIZE 0x64
class MxVideoPresenter : public MxMediaPresenter {
public:
MxVideoPresenter() { Init(); }
enum {
Flag_Bit1 = 0x01,
};
MxVideoPresenter() { Init(); }
virtual ~MxVideoPresenter() override; // vtable+0x0
// OFFSET: LEGO1 0x1000c820
@ -28,13 +32,20 @@ public:
void Init();
void Destroy(MxBool p_fromDestructor);
virtual void Destroy() override; // vtable+0x38
virtual void ReadyTickle() override; // vtable+0x18
virtual void StartingTickle() override; // vtable+0x1c
virtual void StreamingTickle() override; // vtable+0x20
virtual void RepeatingTickle() override; // vtable+0x24
virtual void Unk5Tickle() override; // vtable+0x28
virtual MxResult AddToManager() override; // vtable+0x34
virtual void Destroy() override; // vtable+0x38
virtual void EndAction() override; // vtable+0x40
virtual undefined4 PutData() override; // vtable+0x4c
virtual MxBool IsHit(MxS32 p_x, MxS32 p_y) override; // vtable+0x50
virtual void VTable0x5c(undefined4 p_unknown1); // vtable+0x5c
virtual void VTable0x5c(MxStreamChunk* p_chunk); // vtable+0x5c
virtual void VTable0x60(); // vtable+0x60
virtual void VTable0x64(); // vtable+0x64
virtual void VTable0x68(undefined4 p_unknown1); // vtable+0x68
virtual void VTable0x68(MxStreamChunk* p_chunk); // vtable+0x68
virtual void VTable0x6c(); // vtable+0x6c
virtual void VTable0x70(); // vtable+0x70
virtual undefined VTable0x74(); // vtable+0x74
@ -56,12 +67,12 @@ public:
MxS32 IsHit(MxU32 p_x, MxU32 p_y);
};
MxBitmap* m_bitmap;
AlphaMask* m_alpha;
LPDIRECTDRAWSURFACE m_unk58;
undefined2 m_unk5c;
unsigned char m_flags; // 0x5e
MxLong m_unk60;
MxBitmap* m_bitmap; // 0x50
AlphaMask* m_alpha; // 0x54
LPDIRECTDRAWSURFACE m_unk58; // 0x58
MxS16 m_unk5c; // 0x5c
MxU8 m_flags; // 0x5e
MxLong m_unk60; // 0x60
};
#endif // MXVIDEOPRESENTER_H