diff --git a/LEGO1/lego/legoomni/include/legopathboundary.h b/LEGO1/lego/legoomni/include/legopathboundary.h index 3499c24d..a2a2d6ba 100644 --- a/LEGO1/lego/legoomni/include/legopathboundary.h +++ b/LEGO1/lego/legoomni/include/legopathboundary.h @@ -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; } diff --git a/LEGO1/lego/legoomni/include/mxcontrolpresenter.h b/LEGO1/lego/legoomni/include/mxcontrolpresenter.h index 8fcfecc7..8ecfeacf 100644 --- a/LEGO1/lego/legoomni/include/mxcontrolpresenter.h +++ b/LEGO1/lego/legoomni/include/mxcontrolpresenter.h @@ -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 diff --git a/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp b/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp index 49b4c28d..d89f5cd4 100644 --- a/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp @@ -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); diff --git a/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp b/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp index c1188ccd..667ce45f 100644 --- a/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp @@ -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); } diff --git a/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp b/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp index 3a47f2da..8dd094f9 100644 --- a/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp +++ b/LEGO1/lego/legoomni/src/control/legocontrolmanager.cpp @@ -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)) { diff --git a/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp index 0aef42bd..64a06a08 100644 --- a/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp @@ -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); } } diff --git a/LEGO1/lego/sources/anim/legoanim.h b/LEGO1/lego/sources/anim/legoanim.h index 00cbafdb..0df350a9 100644 --- a/LEGO1/lego/sources/anim/legoanim.h +++ b/LEGO1/lego/sources/anim/legoanim.h @@ -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( diff --git a/LEGO1/lego/sources/geom/legowegedge.h b/LEGO1/lego/sources/geom/legowegedge.h index af32c3ea..7ff23c10 100644 --- a/LEGO1/lego/sources/geom/legowegedge.h +++ b/LEGO1/lego/sources/geom/legowegedge.h @@ -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) { diff --git a/LEGO1/mxdirectx/mxdirect3d.cpp b/LEGO1/mxdirectx/mxdirect3d.cpp index 3e2974bc..b153ff3e 100644 --- a/LEGO1/mxdirectx/mxdirect3d.cpp +++ b/LEGO1/mxdirectx/mxdirect3d.cpp @@ -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; } diff --git a/LEGO1/mxdirectx/mxdirect3d.h b/LEGO1/mxdirectx/mxdirect3d.h index 04621791..f37c2c17 100644 --- a/LEGO1/mxdirectx/mxdirect3d.h +++ b/LEGO1/mxdirectx/mxdirect3d.h @@ -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 diff --git a/LEGO1/mxdirectx/mxdirectdraw.cpp b/LEGO1/mxdirectx/mxdirectdraw.cpp index c79d48de..8ef07e3a 100644 --- a/LEGO1/mxdirectx/mxdirectdraw.cpp +++ b/LEGO1/mxdirectx/mxdirectdraw.cpp @@ -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) { diff --git a/LEGO1/mxdirectx/mxdirectdraw.h b/LEGO1/mxdirectx/mxdirectdraw.h index f346744d..27497b94 100644 --- a/LEGO1/mxdirectx/mxdirectdraw.h +++ b/LEGO1/mxdirectx/mxdirectdraw.h @@ -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 }; diff --git a/LEGO1/mxdirectx/mxdirectxinfo.h b/LEGO1/mxdirectx/mxdirectxinfo.h index 0371b276..ac68af79 100644 --- a/LEGO1/mxdirectx/mxdirectxinfo.h +++ b/LEGO1/mxdirectx/mxdirectxinfo.h @@ -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)); diff --git a/LEGO1/omni/include/mxbitmap.h b/LEGO1/omni/include/mxbitmap.h index b73c52a5..d01a4050 100644 --- a/LEGO1/omni/include/mxbitmap.h +++ b/LEGO1/omni/include/mxbitmap.h @@ -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 + diff --git a/LEGO1/omni/include/mxgeometry.h b/LEGO1/omni/include/mxgeometry.h index 073b5471..99a6e420 100644 --- a/LEGO1/omni/include/mxgeometry.h +++ b/LEGO1/omni/include/mxgeometry.h @@ -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 diff --git a/LEGO1/omni/src/common/mxutilities.cpp b/LEGO1/omni/src/common/mxutilities.cpp index 73b492cf..4d71062d 100644 --- a/LEGO1/omni/src/common/mxutilities.cpp +++ b/LEGO1/omni/src/common/mxutilities.cpp @@ -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()); diff --git a/LEGO1/omni/src/event/mxeventpresenter.cpp b/LEGO1/omni/src/event/mxeventpresenter.cpp index 05c94de0..f819b68c 100644 --- a/LEGO1/omni/src/event/mxeventpresenter.cpp +++ b/LEGO1/omni/src/event/mxeventpresenter.cpp @@ -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) { diff --git a/LEGO1/omni/src/stream/mxstreamcontroller.cpp b/LEGO1/omni/src/stream/mxstreamcontroller.cpp index 958fa371..dadd03ca 100644 --- a/LEGO1/omni/src/stream/mxstreamcontroller.cpp +++ b/LEGO1/omni/src/stream/mxstreamcontroller.cpp @@ -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 diff --git a/LEGO1/omni/src/video/mxvideopresenter.cpp b/LEGO1/omni/src/video/mxvideopresenter.cpp index 7e7c9822..93a886a5 100644 --- a/LEGO1/omni/src/video/mxvideopresenter.cpp +++ b/LEGO1/omni/src/video/mxvideopresenter.cpp @@ -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;