Merge branch 'master' into window-and-broken-transition

This commit is contained in:
Ramen2X 2023-10-14 20:50:56 -04:00 committed by GitHub
commit adb7f5a7b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 295 additions and 140 deletions

View File

@ -159,6 +159,7 @@ add_library(lego1 SHARED
LEGO1/mxpresenterlist.cpp LEGO1/mxpresenterlist.cpp
LEGO1/mxramstreamcontroller.cpp LEGO1/mxramstreamcontroller.cpp
LEGO1/mxramstreamprovider.cpp LEGO1/mxramstreamprovider.cpp
LEGO1/mxregion.cpp
LEGO1/mxscheduler.cpp LEGO1/mxscheduler.cpp
LEGO1/mxsemaphore.cpp LEGO1/mxsemaphore.cpp
LEGO1/mxsmkpresenter.cpp LEGO1/mxsmkpresenter.cpp

View File

@ -37,29 +37,28 @@ void MxEventManager::Destroy(MxBool p_fromDestructor)
} }
// OFFSET: LEGO1 0x100c04a0 // OFFSET: LEGO1 0x100c04a0
MxResult MxEventManager::CreateEventThread(MxU32 p_frequencyMS, MxBool p_noRegister) MxResult MxEventManager::Create(MxU32 p_frequencyMS, MxBool p_createThread)
{ {
MxResult status = FAILURE; MxResult status = FAILURE;
MxBool locked = FALSE; MxBool locked = FALSE;
MxResult result = MxMediaManager::InitPresenters(); MxResult result = MxMediaManager::InitPresenters();
if (result == SUCCESS) { if (result == SUCCESS) {
if (p_noRegister) { if (p_createThread) {
this->m_criticalSection.Enter(); this->m_criticalSection.Enter();
locked = TRUE; locked = TRUE;
this->m_thread = new MxTickleThread(this, p_frequencyMS); this->m_thread = new MxTickleThread(this, p_frequencyMS);
if (this->m_thread) { if (!this->m_thread || this->m_thread->Start(0, 0) != SUCCESS)
if (this->m_thread->Start(0, 0) == SUCCESS) goto done;
status = SUCCESS;
}
} }
else { else
TickleManager()->RegisterClient(this, p_frequencyMS); TickleManager()->RegisterClient(this, p_frequencyMS);
status = SUCCESS;
} status = SUCCESS;
} }
done:
if (status != SUCCESS) if (status != SUCCESS)
Destroy(); Destroy();

View File

@ -13,7 +13,7 @@ class MxEventManager : public MxMediaManager
virtual ~MxEventManager() override; virtual ~MxEventManager() override;
virtual void Destroy() override; // vtable+18 virtual void Destroy() override; // vtable+18
virtual MxResult CreateEventThread(MxU32 p_frequencyMS, MxBool p_noRegister); // vtable+28 virtual MxResult Create(MxU32 p_frequencyMS, MxBool p_createThread); // vtable+28
private: private:
void Init(); void Init();

View File

@ -120,44 +120,32 @@ void MxMusicManager::SetVolume(MxS32 p_volume)
} }
// OFFSET: LEGO1 0x100c0840 // OFFSET: LEGO1 0x100c0840
MxResult MxMusicManager::StartMIDIThread(MxU32 p_frequencyMS, MxBool p_noRegister) MxResult MxMusicManager::Create(MxU32 p_frequencyMS, MxBool p_createThread)
{ {
MxResult status = FAILURE; MxResult status = FAILURE;
MxBool locked = FALSE; MxBool locked = FALSE;
MxResult result = MxAudioManager::InitPresenters(); if (MxAudioManager::InitPresenters() == SUCCESS) {
if (result == SUCCESS) if (p_createThread) {
{
if (p_noRegister)
{
m_criticalSection.Enter(); m_criticalSection.Enter();
locked = TRUE; locked = TRUE;
m_thread = new MxTickleThread(this, p_frequencyMS); m_thread = new MxTickleThread(this, p_frequencyMS);
if (m_thread) if (!m_thread || m_thread->Start(0, 0) != SUCCESS)
{ goto done;
if (m_thread->Start(0, 0) == SUCCESS)
{
status = SUCCESS;
}
}
} }
else else
{
TickleManager()->RegisterClient(this, p_frequencyMS); TickleManager()->RegisterClient(this, p_frequencyMS);
status = SUCCESS;
} status = SUCCESS;
} }
done:
if (status != SUCCESS) if (status != SUCCESS)
{
Destroy(); Destroy();
}
if (locked) if (locked)
{
m_criticalSection.Leave(); m_criticalSection.Leave();
}
return status; return status;
} }

View File

@ -14,7 +14,7 @@ class MxMusicManager : public MxAudioManager
virtual void Destroy() override; // vtable+18 virtual void Destroy() override; // vtable+18
virtual void SetVolume(MxS32 p_volume) override; // vtable+2c virtual void SetVolume(MxS32 p_volume) override; // vtable+2c
virtual MxResult StartMIDIThread(MxU32 p_frequencyMS, MxU8 p_noRegister); // vtable+30 virtual MxResult Create(MxU32 p_frequencyMS, MxBool p_createThread); // vtable+30
inline MxBool GetMIDIInitialized() { return m_MIDIInitialized; } inline MxBool GetMIDIInitialized() { return m_MIDIInitialized; }

View File

@ -72,7 +72,7 @@ MxResult MxNotificationManager::Tickle()
} }
// OFFSET: LEGO1 0x100ac600 // OFFSET: LEGO1 0x100ac600
MxResult MxNotificationManager::Create(MxS32 p_unk1, MxS32 p_unk2) MxResult MxNotificationManager::Create(MxU32 p_frequencyMS, MxBool p_createThread)
{ {
MxResult result = SUCCESS; MxResult result = SUCCESS;
m_queue = new MxNotificationPtrList(); m_queue = new MxNotificationPtrList();

View File

@ -45,7 +45,7 @@ class MxNotificationManager : public MxCore
virtual MxResult Tickle(); // vtable+0x8 virtual MxResult Tickle(); // vtable+0x8
// TODO: Where does this method come from? // TODO: Where does this method come from?
virtual MxResult Create(MxS32 p_unk1, MxS32 p_unk2); // vtable+0x14 virtual MxResult Create(MxU32 p_frequencyMS, MxBool p_createThread); // vtable+0x14
void Register(MxCore *p_listener); void Register(MxCore *p_listener);
void Unregister(MxCore *p_listener); void Unregister(MxCore *p_listener);
MxResult Send(MxCore *p_listener, MxNotificationParam *p_param); MxResult Send(MxCore *p_listener, MxNotificationParam *p_param);

View File

@ -189,119 +189,87 @@ void MxOmni::SetInstance(MxOmni *instance)
MxResult MxOmni::Create(MxOmniCreateParam &p) MxResult MxOmni::Create(MxOmniCreateParam &p)
{ {
MxResult result = FAILURE; MxResult result = FAILURE;
m_atomIdCounterSet = new MxAtomIdCounterSet();
if (m_atomIdCounterSet == NULL) if (!(m_atomIdCounterSet = new MxAtomIdCounterSet()))
{ goto done;
goto failure;
}
m_mediaPath = p.GetMediaPath(); m_mediaPath = p.GetMediaPath();
m_windowHandle = p.GetWindowHandle(); m_windowHandle = p.GetWindowHandle();
if (p.CreateFlags().CreateObjectFactory())
{
MxObjectFactory *objectFactory = new MxObjectFactory();
this->m_objectFactory = objectFactory;
if (objectFactory == NULL) if (p.CreateFlags().CreateObjectFactory()) {
goto failure; if (!(m_objectFactory = new MxObjectFactory()))
goto done;
} }
if (p.CreateFlags().CreateVariableTable()) if (p.CreateFlags().CreateVariableTable()) {
{ if (!(m_variableTable = new MxVariableTable()))
MxVariableTable *variableTable = new MxVariableTable(); goto done;
this->m_variableTable = variableTable;
if (variableTable == NULL)
goto failure;
} }
if (p.CreateFlags().CreateTimer()) if (p.CreateFlags().CreateTimer()) {
{ if (!(m_timer = new MxTimer()))
MxTimer *timer = new MxTimer(); goto done;
this->m_timer = timer;
if (timer == NULL)
return FAILURE;
} }
if (p.CreateFlags().CreateTickleManager()) if (p.CreateFlags().CreateTickleManager()) {
{ if (!(m_tickleManager = new MxTickleManager()))
this->m_tickleManager = new MxTickleManager(); goto done;
if (m_tickleManager == NULL)
goto failure;
} }
if (p.CreateFlags().CreateNotificationManager()) if (p.CreateFlags().CreateNotificationManager()) {
{ if (m_notificationManager = new MxNotificationManager()) {
MxNotificationManager *notificationManager = new MxNotificationManager(); if (m_notificationManager->Create(100, 0) != SUCCESS)
this->m_notificationManager = notificationManager; goto done;
}
if (notificationManager == NULL || notificationManager->Create(100, 0) != SUCCESS) else
goto failure; goto done;
} }
if (p.CreateFlags().CreateStreamer()) if (p.CreateFlags().CreateStreamer()) {
{ if (!(m_streamer = new MxStreamer()) || m_streamer->Create() != SUCCESS)
MxStreamer *streamer = new MxStreamer(); goto done;
this->m_streamer = streamer;
if (streamer == NULL || streamer->Init() != SUCCESS)
goto failure;
} }
if (p.CreateFlags().CreateVideoManager()) if (p.CreateFlags().CreateVideoManager()) {
{ if (m_videoManager = new MxVideoManager()) {
MxVideoManager *videoManager = new MxVideoManager(); if (m_videoManager->Create(p.GetVideoParam(), 100, 0) != SUCCESS) {
this->m_videoManager = videoManager; delete m_videoManager;
m_videoManager = NULL;
if (videoManager != NULL && videoManager->vtable0x2c(p.GetVideoParam(), 100, 0) != SUCCESS) }
{
delete m_videoManager;
m_videoManager = NULL;
} }
} }
if (p.CreateFlags().CreateSoundManager()) if (p.CreateFlags().CreateSoundManager()) {
{ if (m_soundManager = new MxSoundManager()) {
MxSoundManager *soundManager = new MxSoundManager(); if (m_soundManager->Create(10, 0) != SUCCESS) {
this->m_soundManager = soundManager; delete m_soundManager;
m_soundManager = NULL;
//TODO }
if (soundManager != NULL && soundManager->StartDirectSound(10, 0) != SUCCESS)
{
delete m_soundManager;
m_soundManager = NULL;
} }
} }
if (p.CreateFlags().CreateMusicManager()) if (p.CreateFlags().CreateMusicManager()) {
{ if (m_musicManager = new MxMusicManager()) {
MxMusicManager *musicManager = new MxMusicManager(); if (m_musicManager->Create(50, 0) != SUCCESS) {
this->m_musicManager = musicManager; delete m_musicManager;
if (musicManager != NULL && musicManager->StartMIDIThread(50, 0) != SUCCESS) m_musicManager = NULL;
{ }
delete m_musicManager;
m_musicManager = NULL;
} }
} }
if (p.CreateFlags().CreateEventManager()) if (p.CreateFlags().CreateEventManager()) {
{ if (m_eventManager = new MxEventManager()) {
MxEventManager *eventManager = new MxEventManager(); if (m_eventManager->Create(50, 0) != SUCCESS) {
this->m_eventManager = eventManager; delete m_eventManager;
if (m_eventManager != NULL && m_eventManager->CreateEventThread(50, 0) != SUCCESS) m_eventManager = NULL;
{ }
delete m_eventManager;
m_eventManager = NULL;
} }
} }
result = SUCCESS; result = SUCCESS;
failure: done:
if (result != SUCCESS) if (result != SUCCESS)
{
Destroy(); Destroy();
}
return result; return result;
} }

View File

@ -14,7 +14,7 @@ class MxOmniCreateParam : public MxParam
__declspec(dllexport) MxOmniCreateParam(const char *mediaPath, struct HWND__ *windowHandle, MxVideoParam &vparam, MxOmniCreateFlags flags); __declspec(dllexport) MxOmniCreateParam(const char *mediaPath, struct HWND__ *windowHandle, MxVideoParam &vparam, MxOmniCreateFlags flags);
const MxOmniCreateFlags& CreateFlags() const { return this->m_createFlags; } const MxOmniCreateFlags& CreateFlags() const { return this->m_createFlags; }
const MxString GetMediaPath() const { return m_mediaPath; } const MxString& GetMediaPath() const { return m_mediaPath; }
const HWND GetWindowHandle() const { return m_windowHandle; } const HWND GetWindowHandle() const { return m_windowHandle; }
MxVideoParam& GetVideoParam() { return m_videoParam; } MxVideoParam& GetVideoParam() { return m_videoParam; }

39
LEGO1/mxregion.cpp Normal file
View File

@ -0,0 +1,39 @@
#include "mxregion.h"
DECOMP_SIZE_ASSERT(MxRegion, 0x1c);
// OFFSET: LEGO1 0x100c31c0 STUB
MxRegion::MxRegion()
{
// TODO
}
// OFFSET: LEGO1 0x100c3690 STUB
MxRegion::~MxRegion()
{
// TODO
}
// OFFSET: LEGO1 0x100c3700 STUB
void MxRegion::Reset()
{
// TODO
}
// OFFSET: LEGO1 0x100c3750 STUB
void MxRegion::vtable18()
{
// TODO
}
// OFFSET: LEGO1 0x100c3e20 STUB
void MxRegion::vtable1c()
{
// TODO
}
// OFFSET: LEGO1 0x100c3660 STUB
void MxRegion::vtable20()
{
// TODO
}

View File

@ -2,6 +2,7 @@
#define MXREGION_H #define MXREGION_H
#include "mxcore.h" #include "mxcore.h"
#include "decomp.h"
// VTABLE 0x100dcae8 // VTABLE 0x100dcae8
// SIZE 0x1c // SIZE 0x1c
@ -21,6 +22,7 @@ class MxRegion : public MxCore
// MxList<MxRect32> *m_rects; // MxList<MxRect32> *m_rects;
// 4 coordinates (could be MxRect32) // 4 coordinates (could be MxRect32)
// MxS32 left, top, right, bottom; // MxS32 left, top, right, bottom;
undefined pad[0x14];
}; };
#endif // MXREGION_H #endif // MXREGION_H

View File

@ -49,9 +49,9 @@ void MxSoundManager::Destroy(MxBool p_fromDestructor)
} }
// OFFSET: LEGO1 0x100ae8b0 STUB // OFFSET: LEGO1 0x100ae8b0 STUB
MxResult MxSoundManager::StartDirectSound(undefined4 p_unknown1, MxBool p_unknown2) MxResult MxSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread)
{ {
// TODO STUB // TODO
return FAILURE; return FAILURE;
} }

View File

@ -14,7 +14,7 @@ class MxSoundManager : public MxAudioManager
MxSoundManager(); MxSoundManager();
virtual ~MxSoundManager() override; // vtable+0x0 virtual ~MxSoundManager() override; // vtable+0x0
virtual MxResult StartDirectSound(undefined4 p_unknown1, MxBool p_unknown2); //vtable+0x30 virtual MxResult Create(MxU32 p_frequencyMS, MxBool p_createThread); //vtable+0x30
virtual void vtable0x34(); // vtable+0x34 virtual void vtable0x34(); // vtable+0x34
virtual void vtable0x38(); // vtable+0x38 virtual void vtable0x38(); // vtable+0x38

View File

@ -16,7 +16,7 @@ MxStreamer::MxStreamer()
} }
// OFFSET: LEGO1 0x100b9190 // OFFSET: LEGO1 0x100b9190
MxResult MxStreamer::Init() MxResult MxStreamer::Create()
{ {
undefined *b = new undefined[m_subclass1.GetSize() * 0x5800]; undefined *b = new undefined[m_subclass1.GetSize() * 0x5800];
m_subclass1.SetBuffer(b); m_subclass1.SetBuffer(b);

View File

@ -90,7 +90,7 @@ class MxStreamer : public MxCore
return !strcmp(p_name, MxStreamer::ClassName()) || MxCore::IsA(p_name); return !strcmp(p_name, MxStreamer::ClassName()) || MxCore::IsA(p_name);
} }
virtual MxResult Init(); // vtable+0x14 virtual MxResult Create(); // vtable+0x14
MxStreamController *GetOpenStream(const char *p_name); MxStreamController *GetOpenStream(const char *p_name);

View File

@ -56,7 +56,7 @@ void MxString::ToLowerCase()
} }
// OFFSET: LEGO1 0x100ae4b0 // OFFSET: LEGO1 0x100ae4b0
MxString &MxString::operator=(MxString &param) MxString &MxString::operator=(const MxString &param)
{ {
if (this->m_data != param.m_data) if (this->m_data != param.m_data)
{ {

View File

@ -15,7 +15,7 @@ class MxString : public MxCore
MxString(const char *); MxString(const char *);
void ToUpperCase(); void ToUpperCase();
void ToLowerCase(); void ToLowerCase();
MxString& operator=(MxString &); MxString& operator=(const MxString &);
MxString operator+(const char *); MxString operator+(const char *);
MxString& operator+=(const char *); MxString& operator+=(const char *);

View File

@ -53,14 +53,13 @@ class MxTickleClient
MxU16 m_flags; // 0xc MxU16 m_flags; // 0xc
}; };
class MxTickleClientPtrList : public list<MxTickleClient *> typedef list<MxTickleClient*> MxTickleClientPtrList;
{};
// VTABLE 0x100d86d8 // VTABLE 0x100d86d8
class MxTickleManager : public MxCore class MxTickleManager : public MxCore
{ {
public: public:
inline MxTickleManager() : MxCore(), m_clients() {} inline MxTickleManager() {}
virtual ~MxTickleManager(); // vtable+0x0 (scalar deleting destructor) virtual ~MxTickleManager(); // vtable+0x0 (scalar deleting destructor)
virtual MxResult Tickle(); // vtable+0x8 virtual MxResult Tickle(); // vtable+0x8

View File

@ -347,7 +347,6 @@ void MxTransitionManager::Transition_Pixelation()
} }
// OFFSET: LEGO1 0x1004c270 // OFFSET: LEGO1 0x1004c270
void MxTransitionManager::Transition_Windows() void MxTransitionManager::Transition_Windows()
{ {
@ -395,10 +394,29 @@ void MxTransitionManager::Transition_Windows()
} }
} }
// OFFSET: LEGO1 0x1004c3e0 STUB // OFFSET: LEGO1 0x1004c3e0
void MxTransitionManager::Transition_Broken() void MxTransitionManager::Transition_Broken()
{ {
// TODO // This function has no actual animation logic.
// It also never calls EndTransition to
// properly terminate the transition, so
// the game just hangs forever.
DDSURFACEDESC ddsd;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
HRESULT res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
if (res == DDERR_SURFACELOST) {
m_ddSurface->Restore();
res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
}
if (res == DD_OK) {
SubmitCopyRect(&ddsd);
SetupCopyRect(&ddsd);
m_ddSurface->Unlock(ddsd.lpSurface);
}
} }
// OFFSET: LEGO1 0x1004c170 // OFFSET: LEGO1 0x1004c170

View File

@ -139,7 +139,7 @@ void MxVideoManager::InvalidateRect(MxRect32 &p_rect)
} }
// OFFSET: LEGO1 0x100bebe0 // OFFSET: LEGO1 0x100bebe0
MxLong MxVideoManager::RealizePalette(MxPalette *p_palette) MxResult MxVideoManager::RealizePalette(MxPalette *p_palette)
{ {
PALETTEENTRY paletteEntries[256]; PALETTEENTRY paletteEntries[256];
@ -152,17 +152,149 @@ MxLong MxVideoManager::RealizePalette(MxPalette *p_palette)
} }
this->m_criticalSection.Leave(); this->m_criticalSection.Leave();
return 0; return SUCCESS;
} }
// OFFSET: LEGO1 0x100be600 STUB // OFFSET: LEGO1 0x100be600
void MxVideoManager::vtable0x28() MxResult MxVideoManager::vtable0x28(
MxVideoParam &p_videoParam,
LPDIRECTDRAW p_pDirectDraw,
LPDIRECTDRAWSURFACE p_pDDSurface,
LPDIRECTDRAWSURFACE p_ddSurface1,
LPDIRECTDRAWSURFACE p_ddSurface2,
LPDIRECTDRAWCLIPPER p_ddClipper,
MxU32 p_frequencyMS,
MxBool p_createThread)
{ {
MxBool locked = FALSE;
MxResult status = FAILURE;
m_unk60 = FALSE;
if (MxMediaManager::InitPresenters() != SUCCESS)
goto done;
m_criticalSection.Enter();
locked = TRUE;
m_videoParam = p_videoParam;
m_region = new MxRegion();
if (!m_region)
goto done;
m_pDirectDraw = p_pDirectDraw;
m_pDDSurface = p_pDDSurface;
MxPalette *palette;
if (p_videoParam.GetPalette() == NULL) {
palette = new MxPalette();
m_videoParam.SetPalette(palette);
if (!palette)
goto done;
}
else {
palette = p_videoParam.GetPalette()->Clone();
m_videoParam.SetPalette(palette);
if (!palette)
goto done;
}
m_displaySurface = new MxDisplaySurface();
if (m_displaySurface && m_displaySurface->Init(m_videoParam, p_ddSurface1, p_ddSurface2, p_ddClipper) == SUCCESS) {
m_displaySurface->SetPalette(m_videoParam.GetPalette());
if (p_createThread) {
m_thread = new MxTickleThread(this, p_frequencyMS);
if (!m_thread || m_thread->Start(0, 0) != SUCCESS)
goto done;
}
else
TickleManager()->RegisterClient(this, p_frequencyMS);
status = SUCCESS;
}
done:
if (status != SUCCESS)
Destroy();
if (locked)
m_criticalSection.Leave();
return status;
} }
// OFFSET: LEGO1 0x100bebe0 STUB // OFFSET: LEGO1 0x100be820
MxResult MxVideoManager::vtable0x2c(MxVideoParam& p_videoParam, undefined4 p_unknown1, MxU8 p_unknown2) MxResult MxVideoManager::Create(
MxVideoParam &p_videoParam,
MxU32 p_frequencyMS,
MxBool p_createThread)
{ {
return FAILURE; MxBool locked = FALSE;
MxResult status = FAILURE;
m_unk60 = TRUE;
if (MxMediaManager::InitPresenters() != SUCCESS)
goto done;
m_criticalSection.Enter();
locked = TRUE;
m_videoParam = p_videoParam;
m_region = new MxRegion();
if (!m_region)
goto done;
if (DirectDrawCreate(NULL, &m_pDirectDraw, NULL) != DD_OK)
goto done;
if (m_pDirectDraw->SetCooperativeLevel(MxOmni::GetInstance()->GetWindowHandle(), DDSCL_NORMAL) != DD_OK)
goto done;
MxPalette *palette;
if (p_videoParam.GetPalette() == NULL) {
palette = new MxPalette();
m_videoParam.SetPalette(palette);
if (!palette)
goto done;
}
else {
palette = p_videoParam.GetPalette()->Clone();
m_videoParam.SetPalette(palette);
if (!palette)
goto done;
}
m_displaySurface = new MxDisplaySurface();
if (m_displaySurface && m_displaySurface->Create(m_videoParam) == SUCCESS) {
m_displaySurface->SetPalette(m_videoParam.GetPalette());
if (p_createThread) {
m_thread = new MxTickleThread(this, p_frequencyMS);
if (!m_thread || m_thread->Start(0, 0) != SUCCESS)
goto done;
}
else
TickleManager()->RegisterClient(this, p_frequencyMS);
status = SUCCESS;
}
done:
if (status != SUCCESS)
Destroy();
if (locked)
m_criticalSection.Leave();
return status;
} }

View File

@ -15,11 +15,20 @@ class MxVideoManager : public MxMediaManager
virtual MxResult Tickle() override; // vtable+0x8 virtual MxResult Tickle() override; // vtable+0x8
virtual void Destroy() override; // vtable+0x18 virtual void Destroy() override; // vtable+0x18
virtual void vtable0x28(); // vtable+0x28 (TODO ARGUMENTS) virtual MxResult vtable0x28(
virtual MxResult vtable0x2c(MxVideoParam& p_videoParam, undefined4 p_unknown1, MxU8 p_unknown2); // vtable+0x2c MxVideoParam& p_videoParam,
LPDIRECTDRAW p_pDirectDraw,
LPDIRECTDRAWSURFACE p_pDDSurface,
LPDIRECTDRAWSURFACE p_ddSurface1,
LPDIRECTDRAWSURFACE p_ddSurface2,
LPDIRECTDRAWCLIPPER p_ddClipper,
MxU32 p_frequencyMS,
MxBool p_createThread
); // vtable+0x28
virtual MxResult Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS, MxBool p_createThread); // vtable+0x2c
__declspec(dllexport) void InvalidateRect(MxRect32 &); __declspec(dllexport) void InvalidateRect(MxRect32 &);
__declspec(dllexport) virtual MxLong RealizePalette(MxPalette *); // vtable+0x30 __declspec(dllexport) virtual MxResult RealizePalette(MxPalette *); // vtable+0x30
MxVideoManager(); MxVideoManager();