Merge remote-tracking branch 'isle/master' into mergeisle4

This commit is contained in:
Christian Semmler 2025-04-06 08:36:09 -07:00
commit 9d01f67abb
19 changed files with 319 additions and 269 deletions

View file

@ -21,7 +21,7 @@ struct LegoPathActorSetCompare {
};
struct LegoAnimPresenterSetCompare {
MxBool operator()(const LegoAnimPresenter* p_lhs, const LegoAnimPresenter* p_rhs) const
MxU32 operator()(const LegoAnimPresenter* p_lhs, const LegoAnimPresenter* p_rhs) const
{
return (COMPARE_POINTER_TYPE) p_lhs < (COMPARE_POINTER_TYPE) p_rhs;
}

View file

@ -5,7 +5,6 @@
#include "mxcompositepresenter.h"
class LegoControlManagerNotificationParam;
class MxVideoPresenter;
// VTABLE: LEGO1 0x100d7b88
// VTABLE: BETA10 0x101bf5d0
@ -48,18 +47,18 @@ public:
virtual void VTable0x6c(MxS16 p_unk0x4e); // vtable+0x6c
MxBool FUN_10044480(LegoControlManagerNotificationParam* p_param, MxPresenter* p_presenter);
MxBool FUN_10044270(MxS32 p_x, MxS32 p_y, MxVideoPresenter* p_presenter);
MxBool FUN_10044270(MxS32 p_x, MxS32 p_y, MxPresenter* p_presenter);
MxS16 GetUnknown0x4e() { return m_unk0x4e; }
private:
undefined2 m_unk0x4c; // 0x4c
MxS16 m_unk0x4e; // 0x4e
MxBool m_unk0x50; // 0x50
undefined2 m_unk0x52; // 0x52
undefined2 m_unk0x54; // 0x54
undefined2 m_unk0x56; // 0x56
MxS16* m_unk0x58; // 0x58
MxS16 m_unk0x4c; // 0x4c
MxS16 m_unk0x4e; // 0x4e
MxBool m_unk0x50; // 0x50
MxS16 m_unk0x52; // 0x52
MxS16 m_unk0x54; // 0x54
MxS16 m_unk0x56; // 0x56
MxS16* m_states; // 0x58
};
// SYNTHETIC: LEGO1 0x100440f0

View file

@ -163,6 +163,7 @@ void MxBackgroundAudioManager::FUN_1007ef40()
}
// FUNCTION: LEGO1 0x1007f0e0
// FUNCTION: BETA10 0x100e8d8d
void MxBackgroundAudioManager::FadeInOrFadeOut()
{
MxS32 volume, compare;
@ -178,12 +179,10 @@ void MxBackgroundAudioManager::FadeInOrFadeOut()
}
if (volume < compare) {
volume = Min(volume + m_speed, compare);
m_unk0xa0->SetVolume(volume);
m_unk0xa0->SetVolume(volume + m_speed < compare ? volume + m_speed : compare);
}
else if (compare < volume) {
volume = Max(volume - m_speed, compare);
m_unk0xa0->SetVolume(volume);
m_unk0xa0->SetVolume(volume - m_speed > compare ? volume - m_speed : compare);
}
else {
m_unk0xa0->SetVolume(volume);

View file

@ -4,12 +4,13 @@
#include "legocontrolmanager.h"
#include "mxdsmultiaction.h"
#include "mxmisc.h"
#include "mxstillpresenter.h"
#include "mxticklemanager.h"
#include "mxtimer.h"
#include "mxutilities.h"
#include "mxvideopresenter.h"
#include <SDL3/SDL_stdinc.h>
#include <assert.h>
DECOMP_SIZE_ASSERT(MxControlPresenter, 0x5c)
@ -20,15 +21,15 @@ MxControlPresenter::MxControlPresenter()
m_unk0x4e = -1;
m_unk0x50 = FALSE;
m_unk0x52 = 0;
m_unk0x58 = 0;
m_states = NULL;
m_unk0x54 = 0;
}
// FUNCTION: LEGO1 0x10044110
MxControlPresenter::~MxControlPresenter()
{
if (m_unk0x58) {
delete m_unk0x58;
if (m_states) {
delete m_states;
}
}
@ -74,46 +75,41 @@ void MxControlPresenter::EndAction()
// FUNCTION: LEGO1 0x10044270
// FUNCTION: BETA10 0x100eae68
MxBool MxControlPresenter::FUN_10044270(MxS32 p_x, MxS32 p_y, MxVideoPresenter* p_presenter)
MxBool MxControlPresenter::FUN_10044270(MxS32 p_x, MxS32 p_y, MxPresenter* p_presenter)
{
assert(p_presenter);
MxStillPresenter* presenter = (MxStillPresenter*) p_presenter;
if (m_unk0x4c == 3) {
MxVideoPresenter* frontPresenter = (MxVideoPresenter*) m_list.front();
MxStillPresenter* map = (MxStillPresenter*) m_list.front();
assert(map && map->IsA("MxStillPresenter"));
if (p_presenter == frontPresenter || frontPresenter->GetDisplayZ() < p_presenter->GetDisplayZ()) {
if (p_presenter->VTable0x7c()) {
MxS32 height = frontPresenter->GetHeight();
MxS32 width = frontPresenter->GetWidth();
if (presenter == map || map->GetDisplayZ() < presenter->GetDisplayZ()) {
if (map->VTable0x7c()) {
MxRect32 rect(0, 0, map->GetWidth() - 1, map->GetHeight() - 1);
rect += map->GetLocation();
if (frontPresenter->GetLocation().GetX() <= p_x &&
p_x < width - 1 + frontPresenter->GetLocation().GetX() &&
frontPresenter->GetLocation().GetY() <= p_y &&
p_y < height - 1 + frontPresenter->GetLocation().GetY()) {
MxU8* start;
if (frontPresenter->GetAlphaMask() == NULL) {
start = frontPresenter->GetBitmap()->GetStart(
p_x - frontPresenter->GetLocation().GetX(),
p_y - frontPresenter->GetLocation().GetY()
);
}
else {
start = NULL;
}
if (rect.GetLeft() <= p_x && p_x < rect.GetRight() && rect.GetTop() <= p_y && p_y < rect.GetBottom()) {
// DECOMP: Beta uses GetBitmapStart() here, but that causes more diffs for retail.
MxU8* start = map->GetAlphaMask()
? NULL
: map->GetBitmap()->GetStart(p_x - rect.GetLeft(), p_y - rect.GetTop());
m_unk0x56 = 0;
if (m_unk0x58 == NULL) {
if (*start != 0) {
m_unk0x56 = 1;
}
}
else {
for (MxS16 i = 1; i <= *m_unk0x58; i++) {
if (m_unk0x58[i] == *start) {
if (m_states) {
for (MxS16 i = 1; i <= *m_states; i++) {
// TODO: Can we match without the cast here?
if (m_states[i] == (MxS16) *start) {
m_unk0x56 = i;
break;
}
}
}
else {
if (*start != 0) {
m_unk0x56 = 1;
}
}
if (m_unk0x56) {
return TRUE;
@ -123,29 +119,18 @@ MxBool MxControlPresenter::FUN_10044270(MxS32 p_x, MxS32 p_y, MxVideoPresenter*
}
}
else {
if (ContainsPresenter(m_list, p_presenter)) {
if (ContainsPresenter(m_list, presenter)) {
if (m_unk0x4c == 2) {
MxS32 width = p_presenter->GetWidth();
MxS32 height = p_presenter->GetHeight();
MxS32 width = presenter->GetWidth();
MxS32 height = presenter->GetHeight();
if (m_unk0x52 == 2 && m_unk0x54 == 2) {
MxS16 val;
if (p_x < p_presenter->GetLocation().GetX() + width / 2) {
val = 3;
if (p_y < p_presenter->GetLocation().GetY() + height / 2) {
val = 1;
}
m_unk0x56 = val;
return TRUE;
if (p_x < presenter->GetX() + width / 2) {
m_unk0x56 = (p_y >= presenter->GetY() + height / 2) ? 3 : 1;
}
val = 4;
if (p_y < p_presenter->GetLocation().GetY() + height / 2) {
val = 2;
else {
m_unk0x56 = (p_y >= presenter->GetY() + height / 2) ? 4 : 2;
}
m_unk0x56 = val;
return TRUE;
}
}
else {
@ -175,7 +160,7 @@ MxBool MxControlPresenter::FUN_10044480(LegoControlManagerNotificationParam* p_p
}
break;
case c_notificationButtonDown:
if (FUN_10044270(p_param->GetX(), p_param->GetY(), (MxVideoPresenter*) p_presenter)) {
if (FUN_10044270(p_param->GetX(), p_param->GetY(), p_presenter)) {
p_param->SetClickedObjectId(m_action->GetObjectId());
p_param->SetClickedAtom(m_action->GetAtomId().GetInternal());
VTable0x6c(m_unk0x56);
@ -223,6 +208,7 @@ void MxControlPresenter::ReadyTickle()
}
// FUNCTION: LEGO1 0x10044640
// FUNCTION: BETA10 0x100eb5e3
void MxControlPresenter::ParseExtra()
{
MxU16 extraLength;
@ -236,27 +222,35 @@ void MxControlPresenter::ParseExtra()
char output[256];
if (KeyValueStringParse(output, g_strSTYLE, extraCopy)) {
char* str = strtok(output, g_parseExtraTokens);
char* token = strtok(output, g_parseExtraTokens);
if (!SDL_strcasecmp(str, g_strTOGGLE)) {
if (!SDL_strcasecmp(token, g_strTOGGLE)) {
m_unk0x4c = 1;
}
else if (!SDL_strcasecmp(str, g_strGRID)) {
else if (!SDL_strcasecmp(token, g_strGRID)) {
m_unk0x4c = 2;
m_unk0x52 = atoi(strtok(NULL, g_parseExtraTokens));
m_unk0x54 = atoi(strtok(NULL, g_parseExtraTokens));
token = strtok(NULL, g_parseExtraTokens);
assert(token);
m_unk0x52 = atoi(token);
token = strtok(NULL, g_parseExtraTokens);
assert(token);
m_unk0x54 = atoi(token);
}
else if (!SDL_strcasecmp(str, g_strMAP)) {
else if (!SDL_strcasecmp(token, g_strMAP)) {
m_unk0x4c = 3;
str = strtok(NULL, g_parseExtraTokens);
token = strtok(NULL, g_parseExtraTokens);
if (str) {
MxS16 count = atoi(str);
m_unk0x58 = new MxS16[count + 1];
*m_unk0x58 = count;
if (token) {
MxS16 numStates = atoi(token);
m_states = new MxS16[numStates + 1];
assert(numStates);
*m_states = numStates;
for (MxS16 i = 1; i <= count; i++) {
m_unk0x58[i] = atoi(strtok(NULL, g_parseExtraTokens));
for (MxS16 i = 1; i <= numStates; i++) {
token = strtok(NULL, g_parseExtraTokens);
assert(token);
m_states[i] = atoi(token);
}
}
}
@ -298,9 +292,14 @@ void MxControlPresenter::Enable(MxBool p_enable)
// FUNCTION: LEGO1 0x100448a0
MxBool MxControlPresenter::HasTickleStatePassed(TickleState p_tickleState)
{
MxCompositePresenterList::iterator it = m_list.begin();
for (MxS16 i = m_unk0x4e; i > 0; i--, it++) {
}
MxCompositePresenterList::const_iterator it = m_list.begin();
#ifdef COMPAT_MODE
advance(it, m_unk0x4e);
#else
// Uses forward iterator logic instead of bidrectional for some reason.
_Advance(it, m_unk0x4e, forward_iterator_tag());
#endif
return (*it)->HasTickleStatePassed(p_tickleState);
}

View file

@ -144,12 +144,13 @@ void LegoControlManager::FUN_100293c0(MxU32 p_objectId, const char* p_atom, MxS1
}
// FUNCTION: LEGO1 0x100294e0
// FUNCTION: BETA10 0x1007c92f
MxControlPresenter* LegoControlManager::FUN_100294e0(MxS32 p_x, MxS32 p_y)
{
if (m_presenterList) {
MxPresenterListCursor cursor(m_presenterList);
MxPresenter* control;
MxVideoPresenter* presenter = (MxVideoPresenter*) VideoManager()->GetPresenterAt(p_x, p_y);
MxPresenter* presenter = VideoManager()->GetPresenterAt(p_x, p_y);
if (presenter) {
while (cursor.Next(control)) {

View file

@ -118,8 +118,7 @@ void LegoHideAnimPresenter::FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time)
if (boundary != NULL) {
newB = data->FUN_100a0990(p_time);
boundary->GetFlag0x10();
// TODO: Match
previousB = boundary->GetFlag0x10();
boundary->SetFlag0x10(newB);
}
}

View file

@ -189,6 +189,7 @@ public:
// FUNCTION: BETA10 0x1005abc0
LegoU16 GetUnknown0x20() { return m_unk0x20; }
// FUNCTION: BETA10 0x1005d5c0
LegoU16 GetUnknown0x22() { return m_unk0x22; }
// FUNCTION: BETA10 0x10073b80
@ -222,6 +223,8 @@ public:
{
return CreateLocalTransform((LegoFloat) p_time, p_matrix);
}
// FUNCTION: BETA10 0x1005d580
LegoBool FUN_100a0990(LegoTime p_time) { return FUN_100a0990((LegoFloat) p_time); }
inline static void GetTranslation(

View file

@ -45,7 +45,15 @@ public:
LegoS32 VTable0x04() override; // vtable+0x04
// FUNCTION: BETA10 0x100270c0
LegoU32 GetFlag0x10() { return m_flags & c_bit5 ? FALSE : TRUE; }
LegoU32 GetFlag0x10()
{
if (m_flags & c_bit5) {
return FALSE;
}
else {
return TRUE;
}
}
// TODO: Other BETA10 reference at 0x1001c9e0, not sure what is going on
// FUNCTION: BETA10 0x1001ff80
@ -57,6 +65,7 @@ public:
// FUNCTION: BETA10 0x1001c9b0
const LegoChar* GetName() { return m_name; }
// FUNCTION: BETA10 0x1005d5f0
void SetFlag0x10(LegoU32 p_disable)
{
if (p_disable) {

View file

@ -13,21 +13,24 @@ DECOMP_SIZE_ASSERT(MxDirect3D, 0x894)
}
// FUNCTION: LEGO1 0x1009b0a0
// FUNCTION: BETA10 0x1011b220
MxDirect3D::MxDirect3D()
{
this->m_pDirect3d = NULL;
this->m_pDirect3dDevice = NULL;
this->m_bTexturesDisabled = FALSE;
this->m_assignedDevice = NULL;
m_pDirect3d = NULL;
m_pDirect3dDevice = NULL;
m_bTexturesDisabled = FALSE;
m_currentDeviceInfo = NULL;
}
// FUNCTION: LEGO1 0x1009b140
// FUNCTION: BETA10 0x1011b2c3
MxDirect3D::~MxDirect3D()
{
Destroy();
}
// FUNCTION: LEGO1 0x1009b1a0
// FUNCTION: BETA10 0x1011b333
BOOL MxDirect3D::Create(
HWND hWnd,
BOOL fullscreen_1,
@ -41,29 +44,33 @@ BOOL MxDirect3D::Create(
)
{
BOOL success = FALSE;
BOOL ret = MxDirectDraw::Create(
hWnd,
fullscreen_1,
surface_fullscreen,
onlySystemMemory,
width,
height,
bpp,
pPaletteEntries,
paletteEntryCount
);
assert(m_currentDeviceInfo);
if (!ret) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MxDirectDraw::Create failed");
if (!MxDirectDraw::Create(
hWnd,
fullscreen_1,
surface_fullscreen,
onlySystemMemory,
width,
height,
bpp,
pPaletteEntries,
paletteEntryCount
)) {
goto done;
}
if (ret && D3DCreate() && D3DSetMode()) {
success = TRUE;
}
else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "D3DCreate()/D3DSetMode failed");
if (!D3DCreate()) {
goto done;
}
if (!D3DSetMode()) {
goto done;
}
success = TRUE;
done:
if (!success) {
FUN_1009d920();
}
@ -72,24 +79,26 @@ BOOL MxDirect3D::Create(
}
// FUNCTION: LEGO1 0x1009b210
// FUNCTION: BETA10 0x1011b41d
void MxDirect3D::Destroy()
{
RELEASE(m_pDirect3dDevice);
RELEASE(m_pDirect3d);
if (this->m_assignedDevice) {
delete m_assignedDevice;
this->m_assignedDevice = NULL;
if (m_currentDeviceInfo) {
delete m_currentDeviceInfo;
m_currentDeviceInfo = NULL;
}
if (m_pCurrentDeviceModesList) {
m_pCurrentDeviceModesList = NULL;
if (m_currentDevInfo) {
m_currentDevInfo = NULL;
}
MxDirectDraw::Destroy();
}
// FUNCTION: LEGO1 0x1009b290
// FUNCTION: BETA10 0x1011b50a
void MxDirect3D::DestroyButNotDirectDraw()
{
RELEASE(m_pDirect3dDevice);
@ -98,6 +107,7 @@ void MxDirect3D::DestroyButNotDirectDraw()
}
// FUNCTION: LEGO1 0x1009b2d0
// FUNCTION: BETA10 0x1011b592
BOOL MxDirect3D::D3DCreate()
{
HRESULT result;
@ -111,46 +121,50 @@ BOOL MxDirect3D::D3DCreate()
}
// FUNCTION: LEGO1 0x1009b310
// FUNCTION: BETA10 0x1011b617
BOOL MxDirect3D::D3DSetMode()
{
if (m_assignedDevice->m_flags & MxAssignedDevice::c_hardwareMode) {
assert(m_currentDeviceInfo);
if (m_currentDeviceInfo->m_flags & MxAssignedDevice::c_hardwareMode) {
if (m_bOnlySoftRender) {
Error("Failed to place vital surfaces in video memory for hardware driver", DDERR_GENERIC);
return FALSE;
}
if (m_assignedDevice->m_desc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) {
if (m_currentDeviceInfo->m_desc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) {
m_bTexturesDisabled = FALSE;
}
else {
m_bTexturesDisabled = TRUE;
}
if (!CreateZBuffer(DDSCAPS_VIDEOMEMORY, ZBufferDepth(m_assignedDevice))) {
if (!CreateZBuffer(DDSCAPS_VIDEOMEMORY, ZBufferDepth(m_currentDeviceInfo))) {
return FALSE;
}
}
else {
if (m_assignedDevice->m_desc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) {
if (m_currentDeviceInfo->m_desc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) {
m_bTexturesDisabled = FALSE;
}
else {
m_bTexturesDisabled = TRUE;
}
if (!CreateZBuffer(DDSCAPS_SYSTEMMEMORY, ZBufferDepth(m_assignedDevice))) {
if (!CreateZBuffer(DDSCAPS_SYSTEMMEMORY, ZBufferDepth(m_currentDeviceInfo))) {
return FALSE;
}
}
HRESULT result = m_pDirect3d->CreateDevice(m_assignedDevice->m_guid, m_pBackBuffer, &m_pDirect3dDevice);
LPDIRECTDRAWSURFACE backBuf = BackBuffer();
HRESULT result = m_pDirect3d->CreateDevice(m_currentDeviceInfo->m_guid, backBuf, &m_pDirect3dDevice);
if (result != DD_OK) {
Error("Create D3D device failed", result);
return FALSE;
}
DeviceModesInfo::Mode mode = m_currentMode;
DeviceModesInfo::Mode mode = *CurrentMode();
if (IsFullScreen()) {
if (!IsSupportedMode(mode.width, mode.height, mode.bitsPerPixel)) {
@ -159,8 +173,8 @@ BOOL MxDirect3D::D3DSetMode()
}
}
LPDIRECTDRAWSURFACE frontBuffer = m_pFrontBuffer;
LPDIRECTDRAWSURFACE backBuffer = m_pBackBuffer;
LPDIRECTDRAWSURFACE frontBuffer = FrontBuffer();
LPDIRECTDRAWSURFACE backBuffer = BackBuffer();
DDSURFACEDESC desc;
memset(&desc, 0, sizeof(desc));
@ -169,7 +183,7 @@ BOOL MxDirect3D::D3DSetMode()
if (backBuffer->Lock(NULL, &desc, DDLOCK_WAIT, NULL) == DD_OK) {
unsigned char* surface = (unsigned char*) desc.lpSurface;
for (int i = mode.height; i > 0; i--) {
for (int i = 0; i < mode.height; i++) {
memset(surface, 0, mode.width * desc.ddpfPixelFormat.dwRGBBitCount / 8);
surface += desc.lPitch;
}
@ -180,14 +194,14 @@ BOOL MxDirect3D::D3DSetMode()
SDL_Log("MxDirect3D::D3DSetMode() back lock failed\n");
}
if (m_bFullScreen) {
if (IsFullScreen()) {
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
if (frontBuffer->Lock(NULL, &desc, DDLOCK_WAIT, NULL) == DD_OK) {
unsigned char* surface = (unsigned char*) desc.lpSurface;
for (int i = mode.height; i > 0; i--) {
for (int i = 0; i < mode.height; i++) {
memset(surface, 0, mode.width * desc.ddpfPixelFormat.dwRGBBitCount / 8);
surface += desc.lPitch;
}
@ -203,6 +217,7 @@ BOOL MxDirect3D::D3DSetMode()
}
// FUNCTION: LEGO1 0x1009b5a0
// FUNCTION: BETA10 0x1011babb
int MxDirect3D::ZBufferDepth(MxAssignedDevice* p_assignedDevice)
{
int depth;
@ -238,10 +253,10 @@ int MxDirect3D::ZBufferDepth(MxAssignedDevice* p_assignedDevice)
// FUNCTION: BETA10 0x1011bbca
BOOL MxDirect3D::SetDevice(MxDeviceEnumerate& p_deviceEnumerate, MxDriver* p_driver, Direct3DDeviceInfo* p_device)
{
if (m_assignedDevice) {
delete m_assignedDevice;
m_assignedDevice = NULL;
m_pCurrentDeviceModesList = NULL;
if (m_currentDeviceInfo) {
delete m_currentDeviceInfo;
m_currentDeviceInfo = NULL;
m_currentDevInfo = NULL;
}
MxAssignedDevice* d = new MxAssignedDevice;
@ -295,15 +310,15 @@ BOOL MxDirect3D::SetDevice(MxDeviceEnumerate& p_deviceEnumerate, MxDriver* p_dri
d->m_desc = device.m_HELDesc;
}
m_assignedDevice = d;
m_pCurrentDeviceModesList = d->m_deviceInfo;
m_currentDeviceInfo = d;
m_currentDevInfo = d->m_deviceInfo;
break;
}
}
}
}
if (!m_assignedDevice) {
if (!m_currentDeviceInfo) {
delete d;
return FALSE;
}

View file

@ -9,6 +9,7 @@
#include <d3d.h>
// VTABLE: LEGO1 0x100db800
// VTABLE: BETA10 0x101c1af8
// SIZE 0x894
class MxDirect3D : public MxDirectDraw {
public:
@ -29,9 +30,13 @@ public:
void Destroy() override; // vtable+0x08
void DestroyButNotDirectDraw() override; // vtable+0x0c
MxAssignedDevice* AssignedDevice() { return this->m_assignedDevice; }
IDirect3D2* Direct3D() { return this->m_pDirect3d; }
IDirect3DDevice2* Direct3DDevice() { return this->m_pDirect3dDevice; }
MxAssignedDevice* AssignedDevice() { return m_currentDeviceInfo; }
// FUNCTION: BETA10 0x100d8b40
IDirect3D2* Direct3D() { return m_pDirect3d; }
// FUNCTION: BETA10 0x100d8b70
IDirect3DDevice2* Direct3DDevice() { return m_pDirect3dDevice; }
BOOL SetDevice(MxDeviceEnumerate& p_deviceEnumerate, MxDriver* p_driver, Direct3DDeviceInfo* p_device);
@ -42,14 +47,19 @@ protected:
int ZBufferDepth(MxAssignedDevice* p_assignedDevice);
// SYNTHETIC: LEGO1 0x1009b120
// SYNTHETIC: BETA10 0x1011c0f0
// MxDirect3D::`scalar deleting destructor'
private:
MxAssignedDevice* m_assignedDevice; // 0x880
IDirect3D2* m_pDirect3d; // 0x884
IDirect3DDevice2* m_pDirect3dDevice; // 0x888
BOOL m_bTexturesDisabled; // 0x88c
undefined4 m_unk0x890; // 0x890
MxAssignedDevice* m_currentDeviceInfo; // 0x880
IDirect3D2* m_pDirect3d; // 0x884
IDirect3DDevice2* m_pDirect3dDevice; // 0x888
BOOL m_bTexturesDisabled; // 0x88c
undefined4 m_unk0x890; // 0x890
};
// GLOBAL: LEGO1 0x100dd1b0
// GLOBAL: BETA10 0x101c2de8
// IID_IDirect3D2
#endif // MXDIRECT3D_H

View file

@ -3,6 +3,7 @@
#include "decomp.h"
#include <SDL3/SDL_log.h>
#include <assert.h>
DECOMP_SIZE_ASSERT(MxDirectDraw, 0x880)
@ -17,9 +18,11 @@ DECOMP_SIZE_ASSERT(MxDirectDraw, 0x880)
#endif
// GLOBAL: LEGO1 0x10100c68
// GLOBAL: BETA10 0x101ff1c4
BOOL g_isPaletteIndexed8 = 0;
// FUNCTION: LEGO1 0x1009d490
// FUNCTION: BETA10 0x1012036a
MxDirectDraw::MxDirectDraw()
{
m_pFrontBuffer = NULL;
@ -28,6 +31,7 @@ MxDirectDraw::MxDirectDraw()
m_pClipper = NULL;
m_pPalette = NULL;
m_pDirectDraw = NULL;
m_bIsOnPrimaryDevice = TRUE;
m_pText1Surface = NULL;
m_pText2Surface = NULL;
m_hWndMain = NULL;
@ -41,32 +45,31 @@ MxDirectDraw::MxDirectDraw()
m_pFatalErrorHandler = NULL;
m_pErrorHandlerArg = NULL;
m_pFatalErrorHandlerArg = NULL;
m_pCurrentDeviceModesList = NULL;
m_bIsOnPrimaryDevice = TRUE;
m_currentDevInfo = NULL;
m_hFont = NULL;
}
// FUNCTION: LEGO1 0x1009d530
// FUNCTION: BETA10 0x1012048f
MxDirectDraw::~MxDirectDraw()
{
Destroy();
if (m_pCurrentDeviceModesList != NULL) {
delete m_pCurrentDeviceModesList;
m_pCurrentDeviceModesList = NULL;
if (m_currentDevInfo != NULL) {
delete m_currentDevInfo;
m_currentDevInfo = NULL;
}
}
// FUNCTION: LEGO1 0x1009d570
// FUNCTION: BETA10 0x101204fe
int MxDirectDraw::GetPrimaryBitDepth()
{
DWORD dwRGBBitCount;
DWORD dwRGBBitCount = 8;
LPDIRECTDRAW pDDraw;
DDSURFACEDESC ddsd;
HRESULT result = DirectDrawCreate(NULL, &pDDraw, NULL);
dwRGBBitCount = 8;
if (!result) {
if (!DirectDrawCreate(NULL, &pDDraw, NULL)) {
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
@ -80,6 +83,7 @@ int MxDirectDraw::GetPrimaryBitDepth()
}
// FUNCTION: LEGO1 0x1009d5e0
// FUNCTION: BETA10 0x1012058c
BOOL MxDirectDraw::Create(
HWND hWnd,
BOOL fullscreen,
@ -92,17 +96,19 @@ BOOL MxDirectDraw::Create(
int paletteEntryCount
)
{
assert(m_currentDevInfo);
m_hWndMain = hWnd;
CacheOriginalPaletteEntries();
if (!RecreateDirectDraw(&m_pCurrentDeviceModesList->m_guid)) {
if (!RecreateDirectDraw(&m_currentDevInfo->m_guid)) {
return FALSE;
}
m_bFlipSurfaces = surface_fullscreen;
m_bOnlySystemMemory = onlySystemMemory;
m_bIsOnPrimaryDevice = !m_pCurrentDeviceModesList->m_guid;
m_bIsOnPrimaryDevice = m_currentDevInfo->m_guid ? FALSE : TRUE;
if (!m_bIsOnPrimaryDevice) {
fullscreen = TRUE;
@ -124,6 +130,7 @@ BOOL MxDirectDraw::Create(
}
// FUNCTION: LEGO1 0x1009d690
// FUNCTION: BETA10 0x101206ca
BOOL MxDirectDraw::RecreateDirectDraw(GUID** ppGUID)
{
RELEASE(m_pDirectDraw);
@ -131,6 +138,7 @@ BOOL MxDirectDraw::RecreateDirectDraw(GUID** ppGUID)
}
// FUNCTION: LEGO1 0x1009d6c0
// FUNCTION: BETA10 0x10120733
BOOL MxDirectDraw::CacheOriginalPaletteEntries()
{
HDC hdc;
@ -144,11 +152,9 @@ BOOL MxDirectDraw::CacheOriginalPaletteEntries()
}
// FUNCTION: LEGO1 0x1009d700
// FUNCTION: BETA10 0x1012078c
BOOL MxDirectDraw::SetPaletteEntries(const PALETTEENTRY* pPaletteEntries, int paletteEntryCount, BOOL fullscreen)
{
int reservedLowEntryCount = 10;
int reservedHighEntryCount = 10;
int arraySize = sizeOfArray(m_paletteEntries);
HDC hdc;
int i;
@ -158,24 +164,26 @@ BOOL MxDirectDraw::SetPaletteEntries(const PALETTEENTRY* pPaletteEntries, int pa
ReleaseDC(NULL, hdc);
}
for (i = 0; i < reservedLowEntryCount; i++) {
for (i = 0; i < 10; i++) {
m_paletteEntries[i].peFlags = 0x80;
}
for (i = reservedLowEntryCount; i < 142; i++) {
for (; i < 142; i++) {
m_paletteEntries[i].peFlags = 0x44;
}
for (i = 142; i < arraySize - reservedHighEntryCount; i++) {
for (; i < 246; i++) {
m_paletteEntries[i].peFlags = 0x84;
}
for (i = 256 - reservedHighEntryCount; i < 256; i++) {
for (; i < 256; i++) {
m_paletteEntries[i].peFlags = 0x80;
}
if (paletteEntryCount != 0) {
for (i = reservedLowEntryCount; (i < paletteEntryCount) && (i < 256 - reservedHighEntryCount); i++) {
assert(paletteEntryCount <= (sizeof(m_paletteEntries) / sizeof(m_paletteEntries[0])));
for (i = 10; (i < paletteEntryCount) && (i < 246); i++) {
m_paletteEntries[i].peRed = pPaletteEntries[i].peRed;
m_paletteEntries[i].peGreen = pPaletteEntries[i].peGreen;
m_paletteEntries[i].peBlue = pPaletteEntries[i].peBlue;
@ -196,6 +204,7 @@ BOOL MxDirectDraw::SetPaletteEntries(const PALETTEENTRY* pPaletteEntries, int pa
}
// FUNCTION: LEGO1 0x1009d800
// FUNCTION: BETA10 0x10120971
void MxDirectDraw::Destroy()
{
DestroyButNotDirectDraw();
@ -206,13 +215,14 @@ void MxDirectDraw::Destroy()
m_bIsOnPrimaryDevice = TRUE;
if (m_pCurrentDeviceModesList != NULL) {
delete m_pCurrentDeviceModesList;
m_pCurrentDeviceModesList = NULL;
if (m_currentDevInfo != NULL) {
delete m_currentDevInfo;
m_currentDevInfo = NULL;
}
}
// FUNCTION: LEGO1 0x1009d860
// FUNCTION: BETA10 0x10120a18
void MxDirectDraw::DestroyButNotDirectDraw()
{
RestoreOriginalPaletteEntries();
@ -234,6 +244,7 @@ void MxDirectDraw::DestroyButNotDirectDraw()
}
// FUNCTION: LEGO1 0x1009d920
// FUNCTION: BETA10 0x10120b9e
void MxDirectDraw::FUN_1009d920()
{
RestoreOriginalPaletteEntries();
@ -246,8 +257,11 @@ void MxDirectDraw::FUN_1009d920()
}
// FUNCTION: LEGO1 0x1009d960
// FUNCTION: BETA10 0x10120d61
BOOL MxDirectDraw::DDInit(BOOL fullscreen)
{
assert(m_pDirectDraw);
HRESULT result;
if (fullscreen) {
@ -270,12 +284,15 @@ BOOL MxDirectDraw::DDInit(BOOL fullscreen)
}
// FUNCTION: LEGO1 0x1009d9d0
// FUNCTION: BETA10 0x10120e45
BOOL MxDirectDraw::IsSupportedMode(int width, int height, int bpp)
{
DeviceModesInfo::Mode mode = {width, height, bpp};
for (int i = 0; i < m_pCurrentDeviceModesList->m_count; i++) {
if (m_pCurrentDeviceModesList->m_modeArray[i] == mode) {
assert(m_currentDevInfo);
for (int i = 0; i < m_currentDevInfo->m_count; i++) {
if (m_currentDevInfo->m_modeArray[i] == mode) {
return TRUE;
}
}
@ -284,6 +301,7 @@ BOOL MxDirectDraw::IsSupportedMode(int width, int height, int bpp)
}
// FUNCTION: LEGO1 0x1009da20
// FUNCTION: BETA10 0x10120efb
void EnableResizing(HWND p_hwnd, BOOL p_flag)
{
static DWORD g_dwStyle;
@ -300,17 +318,17 @@ void EnableResizing(HWND p_hwnd, BOOL p_flag)
}
// FUNCTION: LEGO1 0x1009da80
// FUNCTION: BETA10 0x10120f68
BOOL MxDirectDraw::DDSetMode(int width, int height, int bpp)
{
HRESULT result;
if (m_bFullScreen) {
LPDIRECTDRAW lpDD;
EnableResizing(m_hWndMain, FALSE);
#ifndef BETA10
if (!m_bIsOnPrimaryDevice) {
lpDD = NULL;
LPDIRECTDRAW lpDD = NULL;
result = DirectDrawCreate(0, &lpDD, 0);
if (result == DD_OK) {
result = lpDD->SetCooperativeLevel(m_hWndMain, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT);
@ -319,11 +337,12 @@ BOOL MxDirectDraw::DDSetMode(int width, int height, int bpp)
}
}
}
#endif
if (!IsSupportedMode(width, height, bpp)) {
width = m_pCurrentDeviceModesList->m_modeArray[0].width;
height = m_pCurrentDeviceModesList->m_modeArray[0].height;
bpp = m_pCurrentDeviceModesList->m_modeArray[0].bitsPerPixel;
width = m_currentDevInfo->m_modeArray[0].width;
height = m_currentDevInfo->m_modeArray[0].height;
bpp = m_currentDevInfo->m_modeArray[0].bitsPerPixel;
}
m_bIgnoreWMSIZE = TRUE;
@ -414,20 +433,29 @@ BOOL MxDirectDraw::DDSetMode(int width, int height, int bpp)
}
// create debug text only in windowed mode?
return m_bFullScreen || CreateTextSurfaces();
if (!m_bFullScreen) {
if (!CreateTextSurfaces()) {
return FALSE;
}
}
return TRUE;
}
// FUNCTION: LEGO1 0x1009dd80
// FUNCTION: BETA10 0x1012137f
HRESULT MxDirectDraw::CreateDDSurface(
LPDDSURFACEDESC p_lpDDSurfDesc,
LPDIRECTDRAWSURFACE FAR* p_lpDDSurface,
IUnknown FAR* p_pUnkOuter
)
{
return m_pDirectDraw->CreateSurface(p_lpDDSurfDesc, p_lpDDSurface, p_pUnkOuter);
HRESULT res = m_pDirectDraw->CreateSurface(p_lpDDSurfDesc, p_lpDDSurface, p_pUnkOuter);
return res;
}
// FUNCTION: LEGO1 0x1009dda0
// FUNCTION: BETA10 0x101213bb
BOOL MxDirectDraw::GetDDSurfaceDesc(LPDDSURFACEDESC lpDDSurfDesc, LPDIRECTDRAWSURFACE lpDDSurf)
{
HRESULT result;
@ -443,6 +471,7 @@ BOOL MxDirectDraw::GetDDSurfaceDesc(LPDDSURFACEDESC lpDDSurfDesc, LPDIRECTDRAWSU
}
// FUNCTION: LEGO1 0x1009ddf0
// FUNCTION: BETA10 0x10121430
BOOL MxDirectDraw::DDCreateSurfaces()
{
HRESULT result;
@ -520,13 +549,14 @@ BOOL MxDirectDraw::DDCreateSurfaces()
}
// FUNCTION: LEGO1 0x1009e020
// FUNCTION: BETA10 0x10121700
void MxDirectDraw::FUN_1009e020()
{
HRESULT result;
byte* line;
DDSURFACEDESC ddsd;
int j;
int count = m_bFlipSurfaces ? 2 : 1;
int value = 0;
for (int i = 0; i < count; i++) {
memset(&ddsd, 0, sizeof(ddsd));
@ -545,8 +575,8 @@ void MxDirectDraw::FUN_1009e020()
// clear backBuffer
line = (byte*) ddsd.lpSurface;
for (j = ddsd.dwHeight; j--;) {
memset(line, 0, ddsd.dwWidth);
for (int j = ddsd.dwHeight; j--;) {
memset(line, value, ddsd.dwWidth);
line += ddsd.lPitch;
}
@ -559,6 +589,7 @@ void MxDirectDraw::FUN_1009e020()
}
// FUNCTION: LEGO1 0x1009e110
// FUNCTION: BETA10 0x101219de
BOOL MxDirectDraw::TextToTextSurface(const char* text, IDirectDrawSurface* pSurface, SIZE& textSizeOnSurface)
{
HRESULT result;
@ -591,18 +622,21 @@ BOOL MxDirectDraw::TextToTextSurface(const char* text, IDirectDrawSurface* pSurf
}
// FUNCTION: LEGO1 0x1009e210
// FUNCTION: BETA10 0x10121aea
BOOL MxDirectDraw::TextToTextSurface1(const char* text)
{
return TextToTextSurface(text, m_pText1Surface, m_text1SizeOnSurface);
}
// FUNCTION: LEGO1 0x1009e230
// FUNCTION: BETA10 0x10121b1e
BOOL MxDirectDraw::TextToTextSurface2(const char* text)
{
return TextToTextSurface(text, m_pText2Surface, m_text2SizeOnSurface);
}
// FUNCTION: LEGO1 0x1009e250
// FUNCTION: BETA10 0x10121b52
BOOL MxDirectDraw::CreateTextSurfaces()
{
HRESULT result;
@ -682,6 +716,7 @@ BOOL MxDirectDraw::CreateTextSurfaces()
}
// FUNCTION: LEGO1 0x1009e4d0
// FUNCTION: BETA10 0x10121e87
BOOL MxDirectDraw::RestoreSurfaces()
{
HRESULT result;
@ -740,6 +775,7 @@ BOOL MxDirectDraw::RestoreSurfaces()
}
// FUNCTION: LEGO1 0x1009e5e0
// FUNCTION: BETA10 0x10122087
BOOL MxDirectDraw::CreateZBuffer(DWORD memorytype, DWORD depth)
{
HRESULT result; // eax
@ -771,6 +807,7 @@ BOOL MxDirectDraw::CreateZBuffer(DWORD memorytype, DWORD depth)
}
// FUNCTION: LEGO1 0x1009e6a0
// FUNCTION: BETA10 0x10122166
int MxDirectDraw::Pause(BOOL p_pause)
{
if (p_pause) {
@ -813,6 +850,7 @@ int MxDirectDraw::Pause(BOOL p_pause)
}
// FUNCTION: LEGO1 0x1009e750
// FUNCTION: BETA10 0x101223c9
BOOL MxDirectDraw::RestorePaletteEntries()
{
@ -833,6 +871,7 @@ BOOL MxDirectDraw::RestorePaletteEntries()
}
// FUNCTION: LEGO1 0x1009e7a0
// FUNCTION: BETA10 0x10122458
BOOL MxDirectDraw::RestoreOriginalPaletteEntries()
{
if (m_bPrimaryPalettized) {
@ -856,6 +895,7 @@ BOOL MxDirectDraw::RestoreOriginalPaletteEntries()
}
// FUNCTION: LEGO1 0x1009e7f0
// FUNCTION: BETA10 0x101224d9
int MxDirectDraw::FlipToGDISurface()
{
@ -873,23 +913,28 @@ int MxDirectDraw::FlipToGDISurface()
}
// FUNCTION: LEGO1 0x1009e830
// FUNCTION: BETA10 0x101225b9
void MxDirectDraw::Error(const char* p_message, int p_error)
{
// at LEGO1 0x10100c70, needs no annotation
// ~GLOBAL: LEGO1 0x10100c70
// ~GLOBAL: BETA10 0x101ff1cc
static BOOL g_isInsideError = FALSE;
if (!g_isInsideError) {
g_isInsideError = TRUE;
Destroy();
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MxDirectDraw error: [0x%08x] %s", p_error, p_message);
if (m_pErrorHandler) {
m_pErrorHandler(p_message, p_error, m_pErrorHandlerArg);
}
g_isInsideError = FALSE;
if (g_isInsideError) {
return;
}
g_isInsideError = TRUE;
Destroy();
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MxDirectDraw error: [0x%08x] %s", p_error, p_message);
if (m_pErrorHandler) {
m_pErrorHandler(p_message, p_error, m_pErrorHandlerArg);
}
g_isInsideError = FALSE;
}
// FUNCTION: LEGO1 0x1009e880
// FUNCTION: BETA10 0x10122630
const char* MxDirectDraw::ErrorToString(HRESULT p_error)
{
switch (p_error) {

View file

@ -8,6 +8,7 @@
#include <windows.h>
// VTABLE: LEGO1 0x100db818
// VTABLE: BETA10 0x101c1b10
// SIZE 0x880
class MxDirectDraw {
public:
@ -33,10 +34,20 @@ public:
virtual void DestroyButNotDirectDraw(); // vtable+0x0c
IDirectDraw* DirectDraw() { return m_pDirectDraw; }
// FUNCTION: BETA10 0x100d8ab0
IDirectDrawSurface* FrontBuffer() { return m_pFrontBuffer; }
// FUNCTION: BETA10 0x100d8ae0
IDirectDrawSurface* BackBuffer() { return m_pBackBuffer; }
// FUNCTION: BETA10 0x100d8b10
IDirectDrawClipper* Clipper() { return m_pClipper; }
// FUNCTION: BETA10 0x1011c190
DeviceModesInfo::Mode* CurrentMode() { return &m_currentMode; }
// FUNCTION: BETA10 0x1011c170
BOOL IsFullScreen() { return m_bFullScreen; }
BOOL IsSupportedMode(int width, int height, int bpp);
@ -73,6 +84,7 @@ protected:
void FUN_1009d920();
// SYNTHETIC: LEGO1 0x1009d510
// SYNTHETIC: BETA10 0x10122f80
// MxDirectDraw::`scalar deleting destructor'
protected:
@ -103,7 +115,7 @@ protected:
void* m_pErrorHandlerArg; // 0x864
void* m_pFatalErrorHandlerArg; // 0x868
int m_pauseCount; // 0x86c
DeviceModesInfo* m_pCurrentDeviceModesList; // 0x870
DeviceModesInfo* m_currentDevInfo; // 0x870
DeviceModesInfo::Mode m_currentMode; // 0x874
};

View file

@ -10,6 +10,7 @@
struct DeviceModesInfo {
// SIZE 0x0c
struct Mode {
// FUNCTION: BETA10 0x10122fc0
int operator==(const Mode& p_mode) const
{
return ((width == p_mode.width) && (height == p_mode.height) && (bitsPerPixel == p_mode.bitsPerPixel));

View file

@ -116,7 +116,7 @@ public:
MxLong GetDataSize() const { return AlignToFourByte(m_bmiHeader->biWidth) * GetBmiHeightAbs(); }
// FUNCTION: BETA10 0x1002c4b0
MxBool IsTopDown()
MxBool IsTopDown() const
{
if (m_bmiHeader->biCompression == BI_RGB_TOPDOWN) {
return TRUE;
@ -131,7 +131,7 @@ public:
: -p_bitmap->AlignToFourByte(p_bitmap->GetBmiWidth()))
// FUNCTION: BETA10 0x1002c320
MxU8* GetStart(MxS32 p_left, MxS32 p_top)
MxU8* GetStart(MxS32 p_left, MxS32 p_top) const
{
if (m_bmiHeader->biCompression == BI_RGB) {
return m_data + p_left +

View file

@ -369,7 +369,6 @@ public:
MxRect32(MxS32 p_l, MxS32 p_t, MxS32 p_r, MxS32 p_b) : MxRect<MxS32>(p_l, p_t, p_r, p_b) {}
#ifndef COMPAT_MODE
// FUNCTION: LEGO1 0x100b6fc0
// FUNCTION: BETA10 0x10137060
MxRect32(MxPoint32& p_p, MxSize32& p_s) : MxRect<MxS32>(p_p, p_s) {}
#else
@ -406,6 +405,7 @@ public:
// TEMPLATE: BETA10 0x10031800
// ??0?$MxRect@H@@QAE@XZ
// TEMPLATE: LEGO1 0x100b6fc0
// TEMPLATE: BETA10 0x10031860
// ??0?$MxRect@H@@QAE@ABV?$MxPoint@H@@ABV?$MxSize@H@@@Z

View file

@ -82,6 +82,7 @@ void MakeSourceName(char* p_output, const char* p_input)
}
// FUNCTION: LEGO1 0x100b7050
// FUNCTION: BETA10 0x10136c19
MxBool KeyValueStringParse(char* p_output, const char* p_command, const char* p_string)
{
MxBool didMatch = FALSE;
@ -93,7 +94,8 @@ MxBool KeyValueStringParse(char* p_output, const char* p_command, const char* p_
assert(string);
strcpy(string, p_string);
for (char* token = strtok(string, ", \t\r\n:"); token; token = strtok(NULL, ", \t\r\n:")) {
const char* delim = ", \t\r\n:";
for (char* token = strtok(string, delim); token; token = strtok(NULL, delim)) {
len -= (strlen(token) + 1);
if (SDL_strcasecmp(token, p_command) == 0) {
@ -117,6 +119,7 @@ MxBool KeyValueStringParse(char* p_output, const char* p_command, const char* p_
}
// FUNCTION: LEGO1 0x100b7170
// FUNCTION: BETA10 0x10136e12
MxBool ContainsPresenter(MxCompositePresenterList& p_presenterList, MxPresenter* p_presenter)
{
for (MxCompositePresenterList::iterator it = p_presenterList.begin(); it != p_presenterList.end(); it++) {
@ -147,9 +150,20 @@ void SetOmniUserMessage(void (*p_omniUserMessage)(const char*, MxS32))
}
// FUNCTION: LEGO1 0x100b7220
// FUNCTION: BETA10 0x10136f37
void FUN_100b7220(MxDSAction* p_action, MxU32 p_newFlags, MxBool p_setFlags)
{
p_action->SetFlags(!p_setFlags ? p_action->GetFlags() & ~p_newFlags : p_action->GetFlags() | p_newFlags);
MxU32 oldFlags = p_action->GetFlags();
MxU32 newFlags;
if (p_setFlags) {
newFlags = oldFlags | p_newFlags;
}
else {
newFlags = oldFlags & ~p_newFlags;
}
p_action->SetFlags(newFlags);
if (p_action->IsA("MxDSMultiAction")) {
MxDSActionListCursor cursor(((MxDSMultiAction*) p_action)->GetActionList());

View file

@ -8,6 +8,8 @@
#include "mxmisc.h"
#include "mxvariabletable.h"
#include <assert.h>
DECOMP_SIZE_ASSERT(MxEventPresenter, 0x54);
// FUNCTION: LEGO1 0x100c2b70
@ -90,6 +92,7 @@ void MxEventPresenter::StartingTickle()
}
// FUNCTION: LEGO1 0x100c2ef0
// FUNCTION: BETA10 0x10152d26
MxResult MxEventPresenter::PutData()
{
AUTOLOCK(m_criticalSection);
@ -102,10 +105,15 @@ MxResult MxEventPresenter::PutData()
const char* data = (const char*) m_currentChunk->GetData();
MxVariableTable* variableTable = VariableTable();
const char* key = data;
const char* value = &data[strlen(data) + 1];
strlen(value);
variableTable->SetVariable(key, value);
const char* name = data;
assert(name);
data += strlen(data) + 1;
const char* value = data;
assert(value);
data += strlen(data) + 1;
variableTable->SetVariable(name, value);
}
if (m_currentTickleState == e_streaming) {

View file

@ -87,7 +87,7 @@ void MxStreamController::AddSubscriber(MxDSSubscriber* p_subscriber)
// FUNCTION: BETA10 0x1014e7b4
void MxStreamController::RemoveSubscriber(MxDSSubscriber* p_subscriber)
{
m_subscribers.Remove(p_subscriber);
m_subscribers.remove(p_subscriber);
}
// FUNCTION: LEGO1 0x100c1690

View file

@ -15,17 +15,12 @@ DECOMP_SIZE_ASSERT(MxVideoPresenter::AlphaMask, 0x0c);
MxVideoPresenter::AlphaMask::AlphaMask(const MxBitmap& p_bitmap)
{
m_width = p_bitmap.GetBmiWidth();
// DECOMP: ECX becomes word-sized if these are not two separate actions.
MxLong height = p_bitmap.GetBmiHeightAbs();
m_height = height;
m_height = p_bitmap.GetBmiHeightAbs();
MxS32 size = ((m_width * m_height) / 8) + 1;
m_bitmask = new MxU8[size];
memset(m_bitmask, 0, size);
MxU32 rowsBeforeTop;
MxU8* bitmapSrcPtr;
// The goal here is to enable us to walk through the bitmap's rows
// in order, regardless of the orientation. We want to end up at the
// start of the first row, which is either at position 0, or at
@ -34,37 +29,13 @@ MxVideoPresenter::AlphaMask::AlphaMask(const MxBitmap& p_bitmap)
// Reminder: Negative biHeight means this is a top-down DIB.
// Otherwise it is bottom-up.
switch (p_bitmap.GetBmiHeader()->biCompression) {
case BI_RGB: {
if (p_bitmap.GetBmiHeight() < 0) {
rowsBeforeTop = 0;
}
else {
rowsBeforeTop = p_bitmap.GetBmiHeightAbs() - 1;
}
bitmapSrcPtr = p_bitmap.GetImage() + (p_bitmap.GetBmiStride() * rowsBeforeTop);
break;
}
case BI_RGB_TOPDOWN:
bitmapSrcPtr = p_bitmap.GetImage();
break;
default: {
if (p_bitmap.GetBmiHeight() < 0) {
rowsBeforeTop = 0;
}
else {
rowsBeforeTop = p_bitmap.GetBmiHeightAbs() - 1;
}
bitmapSrcPtr = p_bitmap.GetImage() + (p_bitmap.GetBmiStride() * rowsBeforeTop);
}
}
MxU8* bitmapSrcPtr = p_bitmap.GetStart(0, 0);
// How many bytes are there for each row of the bitmap?
// (i.e. the image stride)
// If this is a bottom-up DIB, we will walk it in reverse.
// TODO: Same rounding trick as in MxBitmap
MxS32 rowSeek = ((m_width + 3) & -4);
if (p_bitmap.GetBmiHeader()->biCompression != BI_RGB_TOPDOWN && p_bitmap.GetBmiHeight() > 0) {
MxS32 rowSeek = p_bitmap.AlignToFourByte(m_width);
if (p_bitmap.GetBmiHeader()->biCompression != BI_RGB_TOPDOWN && p_bitmap.GetBmiHeight() >= 0) {
rowSeek = -rowSeek;
}
@ -76,9 +47,7 @@ MxVideoPresenter::AlphaMask::AlphaMask(const MxBitmap& p_bitmap)
MxU8* tPtr = bitmapSrcPtr;
for (MxS32 i = 0; i < m_width; i++) {
if (*tPtr) {
// TODO: Second CDQ instruction for abs() should not be there.
MxU32 shift = abs(offset) & 7;
m_bitmask[offset / 8] |= (1 << abs((MxS32) shift));
m_bitmask[offset / 8] |= (1 << (offset % 8));
}
tPtr++;
offset++;
@ -116,7 +85,7 @@ MxS32 MxVideoPresenter::AlphaMask::IsHit(MxU32 p_x, MxU32 p_y)
}
MxS32 pos = p_y * m_width + p_x;
return m_bitmask[pos / 8] & (1 << abs(abs(pos) & 7)) ? 1 : 0;
return m_bitmask[pos / 8] & (1 << (pos % 8)) ? 1 : 0;
}
// FUNCTION: LEGO1 0x100b2760
@ -205,47 +174,14 @@ MxBool MxVideoPresenter::IsHit(MxS32 p_x, MxS32 p_y)
return m_alpha->IsHit(p_x - m_location.GetX(), p_y - m_location.GetY());
}
MxLong heightAbs = m_frameBitmap->GetBmiHeightAbs();
MxRect32 rect(0, 0, m_frameBitmap->GetBmiWidth(), m_frameBitmap->GetBmiHeightAbs());
rect += GetLocation();
MxLong minX = m_location.GetX();
MxLong minY = m_location.GetY();
MxLong maxY = minY + heightAbs;
MxLong maxX = minX + m_frameBitmap->GetBmiWidth();
if (p_x < minX || p_x >= maxX || p_y < minY || p_y >= maxY) {
if (p_x < rect.GetLeft() || p_x >= rect.GetRight() || p_y < rect.GetTop() || p_y >= rect.GetBottom()) {
return FALSE;
}
MxU8* pixel;
MxLong biCompression = m_frameBitmap->GetBmiHeader()->biCompression;
MxLong height = m_frameBitmap->GetBmiHeight();
MxLong seekRow;
// DECOMP: Same basic layout as AlphaMask constructor
// The idea here is to again seek to the correct place in the bitmap's
// m_data buffer. The x,y args are (most likely) screen x and y, so we
// need to shift that to coordinates local to the bitmap by removing
// the MxPresenter location x and y coordinates.
if (biCompression == BI_RGB) {
if (biCompression == BI_RGB_TOPDOWN || height < 0) {
seekRow = p_y - m_location.GetY();
}
else {
height = height > 0 ? height : -height;
seekRow = height - p_y - 1 + m_location.GetY();
}
pixel = m_frameBitmap->GetBmiStride() * seekRow + m_frameBitmap->GetImage() - m_location.GetX() + p_x;
}
else if (biCompression == BI_RGB_TOPDOWN) {
pixel = m_frameBitmap->GetImage();
}
else {
height = height > 0 ? height : -height;
height--;
pixel = m_frameBitmap->GetBmiStride() * height + m_frameBitmap->GetImage();
}
MxU8* pixel = m_frameBitmap->GetStart(p_x - rect.GetLeft(), p_y - rect.GetTop());
if (GetBit4()) {
return (MxBool) *pixel;