This commit is contained in:
Anders Jenbo 2025-07-05 07:47:53 +02:00
commit 8f8e9e2487
41 changed files with 476 additions and 281 deletions

View File

@ -455,6 +455,11 @@
<string>Unknown - Broken</string> <string>Unknown - Broken</string>
</property> </property>
</item> </item>
<item>
<property name="text">
<string>Fake Mosaic</string>
</property>
</item>
</widget> </widget>
</item> </item>
<item> <item>

View File

@ -18,5 +18,5 @@ void N3DS_SetupDefaultConfigOverrides(dictionary* p_dictionary)
iniparser_set(p_dictionary, "isle:savepath", "sdmc:/3ds/isle"); iniparser_set(p_dictionary, "isle:savepath", "sdmc:/3ds/isle");
// Use e_noAnimation/cut transition // Use e_noAnimation/cut transition
iniparser_set(p_dictionary, "isle:Transition Type", "1"); iniparser_set(p_dictionary, "isle:Transition Type", "7");
} }

View File

@ -137,11 +137,11 @@ class LegoCarBuild : public LegoWorld {
void FUN_10022f00(); void FUN_10022f00();
void FUN_10022f30(); void FUN_10022f30();
void FUN_10023130(MxLong p_x, MxLong p_y); void FUN_10023130(MxLong p_x, MxLong p_y);
void FUN_100236d0(); void AddSelectedPartToBuild();
undefined4 FUN_10024250(LegoEventNotificationParam* p_param); undefined4 FUN_10024250(LegoEventNotificationParam* p_param);
void FUN_100243a0(); void FUN_100243a0();
undefined4 FUN_10024480(MxActionNotificationParam* p_param); undefined4 FUN_10024480(MxActionNotificationParam* p_param);
undefined4 FUN_100244e0(MxLong p_x, MxLong p_y); undefined4 SelectPartFromMousePosition(MxLong p_x, MxLong p_y);
undefined4 FUN_100246e0(MxLong p_x, MxLong p_y); undefined4 FUN_100246e0(MxLong p_x, MxLong p_y);
MxS32 FUN_10024850(MxLong p_x, MxLong p_y); MxS32 FUN_10024850(MxLong p_x, MxLong p_y);
undefined4 FUN_10024890(MxParam* p_param); undefined4 FUN_10024890(MxParam* p_param);
@ -184,7 +184,7 @@ class LegoCarBuild : public LegoWorld {
MxU8 m_unk0x109; // 0x109 MxU8 m_unk0x109; // 0x109
MxU16 m_unk0x10a; // 0x10a MxU16 m_unk0x10a; // 0x10a
Uint64 m_unk0x10c; // 0x10c Uint64 m_unk0x10c; // 0x10c
LegoROI* m_unk0x110; // 0x110 LegoROI* m_selectedPart; // 0x110
BoundingSphere m_unk0x114; // 0x114 BoundingSphere m_unk0x114; // 0x114
MxMatrix m_unk0x12c; // 0x12c MxMatrix m_unk0x12c; // 0x12c
undefined m_unk0x174; // 0x174 undefined m_unk0x174; // 0x174
@ -202,10 +202,10 @@ class LegoCarBuild : public LegoWorld {
MxS32 m_unk0x290[2]; // 0x290 MxS32 m_unk0x290[2]; // 0x290
MxS32 m_unk0x298[2]; // 0x298 MxS32 m_unk0x298[2]; // 0x298
MxFloat m_unk0x2a0; // 0x2a0 MxFloat m_unk0x2a0; // 0x2a0
Mx4DPointFloat m_unk0x2a4; // 0x2a4 Mx4DPointFloat m_unk0x2a4; // 0x2a4
Mx4DPointFloat m_unk0x2bc; // 0x2bc Mx4DPointFloat m_unk0x2bc; // 0x2bc
MxBool m_unk0x2d4; // 0x2d4 MxBool m_selectedPartIsPlaced; // 0x2d4
// variable names verified by BETA10 0x1006b27a // variable names verified by BETA10 0x1006b27a
MxStillPresenter* m_ColorBook_Bitmap; // 0x2dc MxStillPresenter* m_ColorBook_Bitmap; // 0x2dc

View File

@ -77,11 +77,11 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
void FUN_10079050(MxS16 p_index); void FUN_10079050(MxS16 p_index);
void SwapNodesByName(LegoChar* p_param1, LegoChar* p_param2); void SwapNodesByName(LegoChar* p_param1, LegoChar* p_param2);
void InitBuildPlatform(); void InitBuildPlatform();
void FUN_100795d0(LegoChar* p_param); void HideBuildPartByName(LegoChar* p_param);
void FUN_10079680(LegoChar* p_param); void ShowBuildPartByName(LegoChar* p_param);
LegoAnimNodeData* FindNodeDataByName(LegoTreeNode* p_treeNode, const LegoChar* p_name); LegoAnimNodeData* FindNodeDataByName(LegoTreeNode* p_treeNode, const LegoChar* p_name);
LegoTreeNode* FindNodeByName(LegoTreeNode* p_treeNode, const LegoChar* p_name); LegoTreeNode* FindNodeByName(LegoTreeNode* p_treeNode, const LegoChar* p_name);
void FUN_10079790(const LegoChar* p_name); void AddPartToBuildByName(const LegoChar* p_name);
void RotateAroundYAxis(MxFloat p_angle); void RotateAroundYAxis(MxFloat p_angle);
MxBool FUN_10079c30(const LegoChar* p_name); MxBool FUN_10079c30(const LegoChar* p_name);
MxBool PartIsPlaced(const LegoChar* p_name); MxBool PartIsPlaced(const LegoChar* p_name);

View File

@ -44,21 +44,28 @@ class MxControlPresenter : public MxCompositePresenter {
void EndAction() override; // vtable+0x40 void EndAction() override; // vtable+0x40
MxBool HasTickleStatePassed(TickleState p_tickleState) override; // vtable+0x48 MxBool HasTickleStatePassed(TickleState p_tickleState) override; // vtable+0x48
void Enable(MxBool p_enable) override; // vtable+0x54 void Enable(MxBool p_enable) override; // vtable+0x54
virtual void VTable0x6c(MxS16 p_unk0x4e); // vtable+0x6c virtual void UpdateEnabledChild(MxS16 p_enabledChild); // vtable+0x6c
MxBool FUN_10044480(LegoControlManagerNotificationParam* p_param, MxPresenter* p_presenter); MxBool Notify(LegoControlManagerNotificationParam* p_param, MxPresenter* p_presenter);
MxBool FUN_10044270(MxS32 p_x, MxS32 p_y, MxPresenter* p_presenter); MxBool CheckButtonDown(MxS32 p_x, MxS32 p_y, MxPresenter* p_presenter);
MxS16 GetUnknown0x4e() { return m_unk0x4e; } MxS16 GetEnabledChild() { return m_enabledChild; }
private: private:
MxS16 m_unk0x4c; // 0x4c enum {
MxS16 m_unk0x4e; // 0x4e e_none,
MxBool m_unk0x50; // 0x50 e_toggle,
MxS16 m_unk0x52; // 0x52 e_grid,
MxS16 m_unk0x54; // 0x54 e_map,
MxS16 m_unk0x56; // 0x56 };
MxS16* m_states; // 0x58
MxS16 m_style; // 0x4c
MxS16 m_enabledChild; // 0x4e
MxBool m_unk0x50; // 0x50
MxS16 m_columnsOrRows; // 0x52
MxS16 m_rowsOrColumns; // 0x54
MxS16 m_stateOrCellIndex; // 0x56
MxS16* m_states; // 0x58
}; };
// SYNTHETIC: LEGO1 0x100440f0 // SYNTHETIC: LEGO1 0x100440f0

View File

@ -48,7 +48,8 @@ class MxTransitionManager : public MxCore {
e_mosaic, e_mosaic,
e_wipeDown, e_wipeDown,
e_windows, e_windows,
e_broken // Unknown what this is supposed to be, it locks the game up e_broken, // Unknown what this is supposed to be, it locks the game up
e_fakeMosaic
}; };
MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_doCopy, MxBool p_playMusicInAnim); MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_doCopy, MxBool p_playMusicInAnim);
@ -68,6 +69,7 @@ class MxTransitionManager : public MxCore {
void WipeDownTransition(); void WipeDownTransition();
void WindowsTransition(); void WindowsTransition();
void BrokenTransition(); void BrokenTransition();
void FakeMosaicTransition();
void SubmitCopyRect(LPDDSURFACEDESC p_ddsc); void SubmitCopyRect(LPDDSURFACEDESC p_ddsc);
void SetupCopyRect(LPDDSURFACEDESC p_ddsc); void SetupCopyRect(LPDDSURFACEDESC p_ddsc);

View File

@ -131,7 +131,7 @@ void Radio::Stop()
MxControlPresenter* presenter = (MxControlPresenter*) world->Find(world->GetAtomId(), IsleScript::c_Radio_Ctl); MxControlPresenter* presenter = (MxControlPresenter*) world->Find(world->GetAtomId(), IsleScript::c_Radio_Ctl);
if (presenter) { if (presenter) {
presenter->VTable0x6c(0); presenter->UpdateEnabledChild(0);
} }
BackgroundAudioManager()->Stop(); BackgroundAudioManager()->Stop();

View File

@ -96,9 +96,9 @@ MxS16 LegoCarBuild::g_unk0x100f11cc = -1;
LegoCarBuild::LegoCarBuild() LegoCarBuild::LegoCarBuild()
{ {
m_unk0x100 = 0; m_unk0x100 = 0;
m_unk0x110 = 0; m_selectedPart = 0;
m_unk0xf8 = c_unknownminusone; m_unk0xf8 = c_unknownminusone;
m_unk0x2d4 = FALSE; m_selectedPartIsPlaced = FALSE;
m_animPresenter = NULL; m_animPresenter = NULL;
m_ColorBook_Bitmap = NULL; m_ColorBook_Bitmap = NULL;
m_Yellow_Ctl = NULL; m_Yellow_Ctl = NULL;
@ -138,7 +138,7 @@ LegoCarBuild::LegoCarBuild()
LegoCarBuild::~LegoCarBuild() LegoCarBuild::~LegoCarBuild()
{ {
m_unk0x100 = 0; m_unk0x100 = 0;
m_unk0x110 = NULL; m_selectedPart = NULL;
if (m_animPresenter) { if (m_animPresenter) {
m_animPresenter->SetShelfState(LegoCarBuildAnimPresenter::e_selected); m_animPresenter->SetShelfState(LegoCarBuildAnimPresenter::e_selected);
@ -291,7 +291,7 @@ void LegoCarBuild::InitPresenters()
// FUNCTION: LEGO1 0x10022f00 // FUNCTION: LEGO1 0x10022f00
void LegoCarBuild::FUN_10022f00() void LegoCarBuild::FUN_10022f00()
{ {
if (m_unk0x110) { if (m_selectedPart) {
VTable0x6c(); VTable0x6c();
m_animPresenter->SetShelfState(LegoCarBuildAnimPresenter::e_selected); m_animPresenter->SetShelfState(LegoCarBuildAnimPresenter::e_selected);
m_unk0x100 = 5; m_unk0x100 = 5;
@ -302,18 +302,18 @@ void LegoCarBuild::FUN_10022f00()
// FUNCTION: BETA10 0x1006b835 // FUNCTION: BETA10 0x1006b835
void LegoCarBuild::FUN_10022f30() void LegoCarBuild::FUN_10022f30()
{ {
if (m_unk0x110) { if (m_selectedPart) {
FUN_10024f70(FALSE); FUN_10024f70(FALSE);
FUN_100250e0(FALSE); FUN_100250e0(FALSE);
if (m_animPresenter->PartIsPlaced(m_unk0x110->GetName())) { if (m_animPresenter->PartIsPlaced(m_selectedPart->GetName())) {
m_PlaceBrick_Sound->Enable(FALSE); m_PlaceBrick_Sound->Enable(FALSE);
m_PlaceBrick_Sound->Enable(TRUE); m_PlaceBrick_Sound->Enable(TRUE);
} }
m_animPresenter->SetShelfState(LegoCarBuildAnimPresenter::e_stopped); m_animPresenter->SetShelfState(LegoCarBuildAnimPresenter::e_stopped);
m_animPresenter->PutFrame(); m_animPresenter->PutFrame();
m_unk0x110 = NULL; m_selectedPart = NULL;
m_unk0x100 = 0; m_unk0x100 = 0;
} }
} }
@ -323,8 +323,8 @@ void LegoCarBuild::FUN_10022f30()
void LegoCarBuild::VTable0x6c() void LegoCarBuild::VTable0x6c()
{ {
m_unk0x178 = m_unk0x1c0; m_unk0x178 = m_unk0x1c0;
m_unk0x110->WrappedSetLocal2WorldWithWorldDataUpdate(m_unk0x178); m_selectedPart->WrappedSetLocal2WorldWithWorldDataUpdate(m_unk0x178);
m_unk0x2a4 = Vector4(m_unk0x110->GetWorldPosition()); m_unk0x2a4 = Vector4(m_selectedPart->GetWorldPosition());
VTable0x70(); VTable0x70();
} }
@ -363,7 +363,7 @@ void LegoCarBuild::VTable0x70()
// FUNCTION: BETA10 0x1006bb22 // FUNCTION: BETA10 0x1006bb22
void LegoCarBuild::FUN_10023130(MxLong p_x, MxLong p_y) void LegoCarBuild::FUN_10023130(MxLong p_x, MxLong p_y)
{ {
if (m_unk0x110) { if (m_selectedPart) {
MxFloat pfVar3[2]; MxFloat pfVar3[2];
MxFloat local30[3]; MxFloat local30[3];
MxFloat local84[3]; MxFloat local84[3];
@ -411,7 +411,7 @@ void LegoCarBuild::FUN_10023130(MxLong p_x, MxLong p_y)
local78[3][2] = m_unk0x178[3][2] + local18[2]; local78[3][2] = m_unk0x178[3][2] + local18[2];
local78[3][3] = 1.0; local78[3][3] = 1.0;
m_unk0x110->WrappedSetLocal2WorldWithWorldDataUpdate(local78); m_selectedPart->WrappedSetLocal2WorldWithWorldDataUpdate(local78);
} }
} }
} }
@ -477,15 +477,15 @@ void LegoCarBuild::VTable0x80(MxFloat p_param1[2], MxFloat p_param2[2], MxFloat
// FUNCTION: LEGO1 0x100236d0 // FUNCTION: LEGO1 0x100236d0
// FUNCTION: BETA10 0x1006c076 // FUNCTION: BETA10 0x1006c076
void LegoCarBuild::FUN_100236d0() void LegoCarBuild::AddSelectedPartToBuild()
{ {
MxS32 pLVar2; MxS32 pLVar2;
FUN_10024f70(FALSE); FUN_10024f70(FALSE);
FUN_100250e0(FALSE); FUN_100250e0(FALSE);
m_animPresenter->FUN_10079790(m_unk0x110->GetName()); m_animPresenter->AddPartToBuildByName(m_selectedPart->GetName());
m_animPresenter->SetShelfState(LegoCarBuildAnimPresenter::e_stopped); m_animPresenter->SetShelfState(LegoCarBuildAnimPresenter::e_stopped);
m_unk0x110 = NULL; m_selectedPart = NULL;
m_unk0x100 = 0; m_unk0x100 = 0;
if (m_animPresenter->AllPartsPlaced() && !Lego()->IsVersion10()) { if (m_animPresenter->AllPartsPlaced() && !Lego()->IsVersion10()) {
@ -544,15 +544,15 @@ MxResult LegoCarBuild::Tickle()
FUN_10024f50(); FUN_10024f50();
} }
if (m_unk0x110) { if (m_selectedPart) {
if (m_animPresenter->PartIsPlaced(m_unk0x110->GetName())) { if (m_animPresenter->PartIsPlaced(m_selectedPart->GetName())) {
FUN_10022f30(); FUN_10022f30();
} }
} }
} }
if (m_unk0x100 == 5 && m_unk0x110) { if (m_unk0x100 == 5 && m_selectedPart) {
RotateY(m_unk0x110, g_unk0x100d65a4); RotateY(m_selectedPart, g_unk0x100d65a4);
} }
if (m_unk0x10a) { if (m_unk0x10a) {
@ -690,7 +690,7 @@ MxLong LegoCarBuild::Notify(MxParam& p_param)
if (((m_buildState->m_animationState != 4) && (m_buildState->m_animationState != 6)) && if (((m_buildState->m_animationState != 4) && (m_buildState->m_animationState != 6)) &&
(m_buildState->m_animationState != 2)) { (m_buildState->m_animationState != 2)) {
m_buildState->m_animationState = LegoVehicleBuildState::e_unknown0; m_buildState->m_animationState = LegoVehicleBuildState::e_unknown0;
result = FUN_100244e0( result = SelectPartFromMousePosition(
((LegoEventNotificationParam&) p_param).GetX(), ((LegoEventNotificationParam&) p_param).GetX(),
((LegoEventNotificationParam&) p_param).GetY() ((LegoEventNotificationParam&) p_param).GetY()
); );
@ -820,7 +820,7 @@ undefined4 LegoCarBuild::FUN_10024480(MxActionNotificationParam* p_param)
// FUNCTION: LEGO1 0x100244e0 // FUNCTION: LEGO1 0x100244e0
// FUNCTION: BETA10 0x1006cfb6 // FUNCTION: BETA10 0x1006cfb6
undefined4 LegoCarBuild::FUN_100244e0(MxLong p_x, MxLong p_y) undefined4 LegoCarBuild::SelectPartFromMousePosition(MxLong p_x, MxLong p_y)
{ {
m_unk0x250[0] = p_x; m_unk0x250[0] = p_x;
m_unk0x250[1] = p_y; m_unk0x250[1] = p_y;
@ -831,34 +831,34 @@ undefined4 LegoCarBuild::FUN_100244e0(MxLong p_x, MxLong p_y)
return 0; return 0;
} }
if (m_unk0x110 != roi) { if (m_selectedPart != roi) {
FUN_10022f30(); FUN_10022f30();
m_unk0x110 = roi; m_selectedPart = roi;
FUN_10024f70(TRUE); FUN_10024f70(TRUE);
FUN_100250e0(TRUE); FUN_100250e0(TRUE);
} }
if (m_unk0x100 == 5 && m_animPresenter->PartIsPlaced(m_unk0x110->GetName())) { if (m_unk0x100 == 5 && m_animPresenter->PartIsPlaced(m_selectedPart->GetName())) {
m_unk0x2d4 = TRUE; m_selectedPartIsPlaced = TRUE;
} }
else { else {
m_unk0x2d4 = FALSE; m_selectedPartIsPlaced = FALSE;
} }
FUN_10025450(); FUN_10025450();
VTable0x70(); VTable0x70();
if (m_animPresenter->PartIsPlaced(m_unk0x110->GetName())) { if (m_animPresenter->PartIsPlaced(m_selectedPart->GetName())) {
if (m_unk0x100 != 5) { if (m_unk0x100 != 5) {
m_unk0x250[0] += m_unk0x290[0] - m_unk0x298[0]; m_unk0x250[0] += m_unk0x290[0] - m_unk0x298[0];
m_unk0x250[1] += m_unk0x290[1] - m_unk0x298[1]; m_unk0x250[1] += m_unk0x290[1] - m_unk0x298[1];
} }
if (m_unk0x100 == 0) { if (m_unk0x100 == 0) {
m_unk0x114 = m_unk0x110->GetWorldBoundingSphere(); m_unk0x114 = m_selectedPart->GetWorldBoundingSphere();
} }
} }
else { else {
if (m_animPresenter->FUN_10079c30(m_unk0x110->GetName())) { if (m_animPresenter->FUN_10079c30(m_selectedPart->GetName())) {
m_unk0x114 = m_animPresenter->FUN_10079e20(); m_unk0x114 = m_animPresenter->FUN_10079e20();
} }
} }
@ -895,21 +895,21 @@ undefined4 LegoCarBuild::FUN_100246e0(MxLong p_x, MxLong p_y)
result = 1; result = 1;
break; break;
case 6: case 6:
if (m_animPresenter->PartIsPlaced(m_unk0x110->GetName()) && if (m_animPresenter->PartIsPlaced(m_selectedPart->GetName()) &&
SpheresIntersect(m_unk0x114, m_unk0x110->GetWorldBoundingSphere())) { SpheresIntersect(m_unk0x114, m_selectedPart->GetWorldBoundingSphere())) {
FUN_10024f70(FALSE); FUN_10024f70(FALSE);
FUN_100250e0(FALSE); FUN_100250e0(FALSE);
m_unk0x100 = 0; m_unk0x100 = 0;
m_unk0x110 = NULL; m_selectedPart = NULL;
m_PlaceBrick_Sound->Enable(FALSE); m_PlaceBrick_Sound->Enable(FALSE);
m_PlaceBrick_Sound->Enable(TRUE); m_PlaceBrick_Sound->Enable(TRUE);
m_animPresenter->SetShelfState(LegoCarBuildAnimPresenter::e_stopped); m_animPresenter->SetShelfState(LegoCarBuildAnimPresenter::e_stopped);
} }
else if (m_animPresenter->FUN_10079c30(m_unk0x110->GetName())) { else if (m_animPresenter->FUN_10079c30(m_selectedPart->GetName())) {
if (SpheresIntersect(m_unk0x114, m_unk0x110->GetWorldBoundingSphere())) { if (SpheresIntersect(m_unk0x114, m_selectedPart->GetWorldBoundingSphere())) {
m_PlaceBrick_Sound->Enable(FALSE); m_PlaceBrick_Sound->Enable(FALSE);
m_PlaceBrick_Sound->Enable(TRUE); m_PlaceBrick_Sound->Enable(TRUE);
FUN_100236d0(); AddSelectedPartToBuild();
} }
else { else {
VTable0x6c(); VTable0x6c();
@ -1024,7 +1024,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param)
(m_Decals_Ctl5 && m_Decals_Ctl5->GetAction()->GetObjectId() == param->m_clickedObjectId) || (m_Decals_Ctl5 && m_Decals_Ctl5->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl6 && m_Decals_Ctl6->GetAction()->GetObjectId() == param->m_clickedObjectId) || (m_Decals_Ctl6 && m_Decals_Ctl6->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl7 && m_Decals_Ctl7->GetAction()->GetObjectId() == param->m_clickedObjectId)) { (m_Decals_Ctl7 && m_Decals_Ctl7->GetAction()->GetObjectId() == param->m_clickedObjectId)) {
m_animPresenter->SetPartObjectIdByName(m_unk0x110->GetName(), param->m_clickedObjectId); m_animPresenter->SetPartObjectIdByName(m_selectedPart->GetName(), param->m_clickedObjectId);
m_Decal_Sound->Enable(FALSE); m_Decal_Sound->Enable(FALSE);
m_Decal_Sound->Enable(TRUE); m_Decal_Sound->Enable(TRUE);
} }
@ -1128,7 +1128,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param)
(m_Decals_Ctl5 && m_Decals_Ctl5->GetAction()->GetObjectId() == param->m_clickedObjectId) || (m_Decals_Ctl5 && m_Decals_Ctl5->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl6 && m_Decals_Ctl6->GetAction()->GetObjectId() == param->m_clickedObjectId) || (m_Decals_Ctl6 && m_Decals_Ctl6->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl7 && m_Decals_Ctl7->GetAction()->GetObjectId() == param->m_clickedObjectId)) { (m_Decals_Ctl7 && m_Decals_Ctl7->GetAction()->GetObjectId() == param->m_clickedObjectId)) {
m_animPresenter->SetPartObjectIdByName(m_unk0x110->GetName(), param->m_clickedObjectId); m_animPresenter->SetPartObjectIdByName(m_selectedPart->GetName(), param->m_clickedObjectId);
m_Decal_Sound->Enable(FALSE); m_Decal_Sound->Enable(FALSE);
m_Decal_Sound->Enable(TRUE); m_Decal_Sound->Enable(TRUE);
} }
@ -1271,7 +1271,7 @@ void LegoCarBuild::FUN_10024f30()
// FUNCTION: BETA10 0x1006dfce // FUNCTION: BETA10 0x1006dfce
void LegoCarBuild::FUN_10024f50() void LegoCarBuild::FUN_10024f50()
{ {
m_unk0x2d4 = FALSE; m_selectedPartIsPlaced = FALSE;
m_animPresenter->RotateAroundYAxis(g_rotationAngleStepYAxis); m_animPresenter->RotateAroundYAxis(g_rotationAngleStepYAxis);
} }
@ -1279,7 +1279,7 @@ void LegoCarBuild::FUN_10024f50()
// FUNCTION: BETA10 0x1006e002 // FUNCTION: BETA10 0x1006e002
void LegoCarBuild::FUN_10024f70(MxBool p_enabled) void LegoCarBuild::FUN_10024f70(MxBool p_enabled)
{ {
if (m_animPresenter->StringEndsOnY(m_unk0x110->GetName())) { if (m_animPresenter->StringEndsOnY(m_selectedPart->GetName())) {
SetPresentersEnabled(p_enabled); SetPresentersEnabled(p_enabled);
} }
} }
@ -1314,31 +1314,31 @@ void LegoCarBuild::TogglePresentersEnabled()
// FUNCTION: BETA10 0x1006e124 // FUNCTION: BETA10 0x1006e124
void LegoCarBuild::FUN_100250e0(MxBool p_enabled) void LegoCarBuild::FUN_100250e0(MxBool p_enabled)
{ {
if (m_animPresenter->StringDoesNotEndOnZero(m_unk0x110->GetName()) && m_Decals_Ctl) { if (m_animPresenter->StringDoesNotEndOnZero(m_selectedPart->GetName()) && m_Decals_Ctl) {
if (SDL_strncasecmp(m_unk0x110->GetName(), "JSFRNT", strlen("JSFRNT")) == 0) { if (SDL_strncasecmp(m_selectedPart->GetName(), "JSFRNT", strlen("JSFRNT")) == 0) {
m_Decal_Bitmap->Enable(p_enabled); m_Decal_Bitmap->Enable(p_enabled);
m_Decals_Ctl->Enable(p_enabled); m_Decals_Ctl->Enable(p_enabled);
m_Decals_Ctl1->Enable(p_enabled); m_Decals_Ctl1->Enable(p_enabled);
m_Decals_Ctl2->Enable(p_enabled); m_Decals_Ctl2->Enable(p_enabled);
m_Decals_Ctl3->Enable(p_enabled); m_Decals_Ctl3->Enable(p_enabled);
} }
else if (SDL_strncasecmp(m_unk0x110->GetName(), "JSWNSH", strlen("JSWNSH")) == 0) { else if (SDL_strncasecmp(m_selectedPart->GetName(), "JSWNSH", strlen("JSWNSH")) == 0) {
m_Decal_Bitmap->Enable(p_enabled); m_Decal_Bitmap->Enable(p_enabled);
m_Decals_Ctl4->Enable(p_enabled); m_Decals_Ctl4->Enable(p_enabled);
m_Decals_Ctl5->Enable(p_enabled); m_Decals_Ctl5->Enable(p_enabled);
m_Decals_Ctl6->Enable(p_enabled); m_Decals_Ctl6->Enable(p_enabled);
m_Decals_Ctl7->Enable(p_enabled); m_Decals_Ctl7->Enable(p_enabled);
} }
else if (SDL_strncasecmp(m_unk0x110->GetName(), "RCBACK", strlen("RCBACK")) == 0) { else if (SDL_strncasecmp(m_selectedPart->GetName(), "RCBACK", strlen("RCBACK")) == 0) {
m_Decals_Ctl1->Enable(p_enabled); m_Decals_Ctl1->Enable(p_enabled);
} }
else if (SDL_strncasecmp(m_unk0x110->GetName(), "RCTAIL", strlen("RCTAIL")) == 0) { else if (SDL_strncasecmp(m_selectedPart->GetName(), "RCTAIL", strlen("RCTAIL")) == 0) {
m_Decals_Ctl2->Enable(p_enabled); m_Decals_Ctl2->Enable(p_enabled);
} }
else if (m_Decals_Ctl1 && SDL_strncasecmp(m_unk0x110->GetName(), "chljety", strlen("chljety")) == 0) { else if (m_Decals_Ctl1 && SDL_strncasecmp(m_selectedPart->GetName(), "chljety", strlen("chljety")) == 0) {
m_Decals_Ctl1->Enable(p_enabled); m_Decals_Ctl1->Enable(p_enabled);
} }
else if (m_Decals_Ctl2 && SDL_strncasecmp(m_unk0x110->GetName(), "chrjety", strlen("chrjety")) == 0) { else if (m_Decals_Ctl2 && SDL_strncasecmp(m_selectedPart->GetName(), "chrjety", strlen("chrjety")) == 0) {
m_Decals_Ctl2->Enable(p_enabled); m_Decals_Ctl2->Enable(p_enabled);
} }
else if (m_Decals_Ctl) { else if (m_Decals_Ctl) {
@ -1354,7 +1354,7 @@ void LegoCarBuild::FUN_10025350(MxS32 p_objectId)
const LegoChar* color; const LegoChar* color;
LegoChar buffer[256]; LegoChar buffer[256];
if (!m_unk0x110) { if (!m_selectedPart) {
return; return;
} }
@ -1382,8 +1382,8 @@ void LegoCarBuild::FUN_10025350(MxS32 p_objectId)
m_Paint_Sound->Enable(FALSE); m_Paint_Sound->Enable(FALSE);
m_Paint_Sound->Enable(TRUE); m_Paint_Sound->Enable(TRUE);
m_unk0x110->FUN_100a93b0(color); m_selectedPart->FUN_100a93b0(color);
sprintf(buffer, "c_%s", m_unk0x110->GetName()); sprintf(buffer, "c_%s", m_selectedPart->GetName());
VariableTable()->SetVariable(buffer, color); VariableTable()->SetVariable(buffer, color);
} }
@ -1391,7 +1391,7 @@ void LegoCarBuild::FUN_10025350(MxS32 p_objectId)
// FUNCTION: BETA10 0x1006e599 // FUNCTION: BETA10 0x1006e599
void LegoCarBuild::FUN_10025450() void LegoCarBuild::FUN_10025450()
{ {
m_unk0x12c = m_unk0x110->GetLocal2World(); m_unk0x12c = m_selectedPart->GetLocal2World();
m_unk0x1c0 = m_unk0x12c; m_unk0x1c0 = m_unk0x12c;
Vector3 lastColumnOfUnk0x1c0(m_unk0x1c0[3]); Vector3 lastColumnOfUnk0x1c0(m_unk0x1c0[3]);
@ -1404,10 +1404,10 @@ void LegoCarBuild::FUN_10025450()
MxMatrix* unk0x178 = &m_unk0x178; MxMatrix* unk0x178 = &m_unk0x178;
*unk0x178 = m_unk0x12c; *unk0x178 = m_unk0x12c;
if (m_animPresenter->PartIsPlaced(m_unk0x110->GetName())) { if (m_animPresenter->PartIsPlaced(m_selectedPart->GetName())) {
m_unk0x2a4 = Vector4(m_unk0x110->GetWorldPosition()); m_unk0x2a4 = Vector4(m_selectedPart->GetWorldPosition());
if (!m_unk0x2d4) { if (!m_selectedPartIsPlaced) {
m_unk0x2bc = m_unk0x2a4; m_unk0x2bc = m_unk0x2a4;
m_unk0x208 = m_unk0x12c; m_unk0x208 = m_unk0x12c;
@ -1421,17 +1421,17 @@ void LegoCarBuild::FUN_10025450()
else { else {
const LegoChar* wiredName; const LegoChar* wiredName;
if (!m_animPresenter->FUN_10079c30(m_unk0x110->GetName())) { if (!m_animPresenter->FUN_10079c30(m_selectedPart->GetName())) {
wiredName = m_animPresenter->GetWiredNameByPartName(m_unk0x110->GetName()); wiredName = m_animPresenter->GetWiredNameByPartName(m_selectedPart->GetName());
} }
else { else {
wiredName = m_animPresenter->GetWiredNameOfLastPlacedPart(); wiredName = m_animPresenter->GetWiredNameOfLastPlacedPart();
} }
LegoROI* parentROI = (LegoROI*) m_unk0x110->GetParentROI(); LegoROI* parentROI = (LegoROI*) m_selectedPart->GetParentROI();
m_unk0x208 = parentROI->FindChildROI(wiredName, parentROI)->GetLocal2World(); m_unk0x208 = parentROI->FindChildROI(wiredName, parentROI)->GetLocal2World();
m_unk0x2bc = Vector4(parentROI->FindChildROI(wiredName, parentROI)->GetWorldPosition()); m_unk0x2bc = Vector4(parentROI->FindChildROI(wiredName, parentROI)->GetWorldPosition());
m_unk0x2a4 = Vector4(m_unk0x110->GetWorldPosition()); m_unk0x2a4 = Vector4(m_selectedPart->GetWorldPosition());
m_unk0x2a4[2] += (m_unk0x1c0[3][2] - m_unk0x12c[3][2]); m_unk0x2a4[2] += (m_unk0x1c0[3][2] - m_unk0x12c[3][2]);
m_unk0x178[3][2] = m_unk0x1c0[3][2]; m_unk0x178[3][2] = m_unk0x1c0[3][2];
@ -1653,8 +1653,8 @@ void LegoCarBuild::FUN_10025db0(const char* p_param1, undefined4 p_param2)
} }
} }
else { else {
if (m_unk0x33c->GetUnknown0x4e() != sVar3) { if (m_unk0x33c->GetEnabledChild() != sVar3) {
m_unk0x33c->VTable0x6c(sVar3); m_unk0x33c->UpdateEnabledChild(sVar3);
} }
g_unk0x100f11cc = -1; g_unk0x100f11cc = -1;
@ -1667,7 +1667,7 @@ void LegoCarBuild::FUN_10025e40()
{ {
SetPresentersEnabled(m_presentersEnabled); SetPresentersEnabled(m_presentersEnabled);
if (m_unk0x33c && m_Yellow_Ctl != m_unk0x33c) { if (m_unk0x33c && m_Yellow_Ctl != m_unk0x33c) {
m_unk0x33c->VTable0x6c(0); m_unk0x33c->UpdateEnabledChild(0);
} }
} }

View File

@ -204,15 +204,15 @@ void LegoCarBuildAnimPresenter::StreamingTickle()
for (i = 0; i < m_numberOfParts; i++) { for (i = 0; i < m_numberOfParts; i++) {
if (m_placedPartCount == i) { if (m_placedPartCount == i) {
FUN_10079680(m_parts[i].m_wiredName); ShowBuildPartByName(m_parts[i].m_wiredName);
} }
else { else {
FUN_100795d0(m_parts[i].m_wiredName); HideBuildPartByName(m_parts[i].m_wiredName);
} }
if (i < m_placedPartCount) { if (i < m_placedPartCount) {
FUN_10079050(i); FUN_10079050(i);
FUN_10079680(m_parts[i].m_name); ShowBuildPartByName(m_parts[i].m_name);
} }
LegoChar* name = m_parts[i].m_wiredName; LegoChar* name = m_parts[i].m_wiredName;
@ -321,7 +321,7 @@ MxResult LegoCarBuildAnimPresenter::Serialize(LegoStorage* p_storage)
void LegoCarBuildAnimPresenter::FUN_10079050(MxS16 p_index) void LegoCarBuildAnimPresenter::FUN_10079050(MxS16 p_index)
{ {
SwapNodesByName(m_parts[p_index].m_wiredName, m_parts[p_index].m_name); SwapNodesByName(m_parts[p_index].m_wiredName, m_parts[p_index].m_name);
FUN_100795d0(m_parts[p_index].m_wiredName); HideBuildPartByName(m_parts[p_index].m_wiredName);
} }
// FUNCTION: LEGO1 0x10079090 // FUNCTION: LEGO1 0x10079090
@ -447,7 +447,7 @@ void LegoCarBuildAnimPresenter::InitBuildPlatform()
// FUNCTION: LEGO1 0x100795d0 // FUNCTION: LEGO1 0x100795d0
// FUNCTION: BETA10 0x10071d96 // FUNCTION: BETA10 0x10071d96
void LegoCarBuildAnimPresenter::FUN_100795d0(LegoChar* p_param) void LegoCarBuildAnimPresenter::HideBuildPartByName(LegoChar* p_param)
{ {
LegoAnimNodeData* data = FindNodeDataByName(m_anim->GetRoot(), p_param); LegoAnimNodeData* data = FindNodeDataByName(m_anim->GetRoot(), p_param);
@ -469,7 +469,7 @@ void LegoCarBuildAnimPresenter::FUN_100795d0(LegoChar* p_param)
// FUNCTION: LEGO1 0x10079680 // FUNCTION: LEGO1 0x10079680
// FUNCTION: BETA10 0x10071ec5 // FUNCTION: BETA10 0x10071ec5
void LegoCarBuildAnimPresenter::FUN_10079680(LegoChar* p_param) void LegoCarBuildAnimPresenter::ShowBuildPartByName(LegoChar* p_param)
{ {
LegoAnimNodeData* data = FindNodeDataByName(m_anim->GetRoot(), p_param); LegoAnimNodeData* data = FindNodeDataByName(m_anim->GetRoot(), p_param);
@ -536,7 +536,7 @@ LegoTreeNode* LegoCarBuildAnimPresenter::FindNodeByName(LegoTreeNode* p_treeNode
// FUNCTION: LEGO1 0x10079790 // FUNCTION: LEGO1 0x10079790
// FUNCTION: BETA10 0x100720a3 // FUNCTION: BETA10 0x100720a3
void LegoCarBuildAnimPresenter::FUN_10079790(const LegoChar* p_name) void LegoCarBuildAnimPresenter::AddPartToBuildByName(const LegoChar* p_name)
{ {
MxS16 i; MxS16 i;
LegoChar buffer[40]; LegoChar buffer[40];
@ -559,7 +559,7 @@ void LegoCarBuildAnimPresenter::FUN_10079790(const LegoChar* p_name)
((LegoCarBuild*) m_currentWorld)->SetPlacedPartCount(m_placedPartCount); ((LegoCarBuild*) m_currentWorld)->SetPlacedPartCount(m_placedPartCount);
if (m_placedPartCount < m_numberOfParts) { if (m_placedPartCount < m_numberOfParts) {
FUN_10079680(m_parts[m_placedPartCount].m_wiredName); ShowBuildPartByName(m_parts[m_placedPartCount].m_wiredName);
} }
} }

View File

@ -400,7 +400,7 @@ MxBool LegoAnimMMPresenter::FUN_1004b610(MxLong p_time)
} }
} }
m_action->SetUnknown90(Timer()->GetTime()); m_action->SetTimeStarted(Timer()->GetTime());
if (m_compositePresenter != NULL) { if (m_compositePresenter != NULL) {
m_compositePresenter->VTable0x60(this); m_compositePresenter->VTable0x60(this);

View File

@ -84,7 +84,7 @@ MxResult MxCompositeMediaPresenter::StartAction(MxStreamController* p_controller
if (!m_compositePresenter) { if (!m_compositePresenter) {
SetTickleState(e_ready); SetTickleState(e_ready);
MxLong time = Timer()->GetTime(); MxLong time = Timer()->GetTime();
m_action->SetUnknown90(time); m_action->SetTimeStarted(time);
} }
result = SUCCESS; result = SUCCESS;
@ -134,7 +134,7 @@ void MxCompositeMediaPresenter::StartingTickle()
if (!m_unk0x4c) { if (!m_unk0x4c) {
ProgressTickleState(e_streaming); ProgressTickleState(e_streaming);
MxLong time = Timer()->GetTime(); MxLong time = Timer()->GetTime();
m_action->SetUnknown90(time); m_action->SetTimeStarted(time);
} }
} }
} }

View File

@ -18,12 +18,12 @@ DECOMP_SIZE_ASSERT(MxControlPresenter, 0x5c)
// FUNCTION: LEGO1 0x10043f50 // FUNCTION: LEGO1 0x10043f50
MxControlPresenter::MxControlPresenter() MxControlPresenter::MxControlPresenter()
{ {
m_unk0x4c = 0; m_style = e_none;
m_unk0x4e = -1; m_enabledChild = -1;
m_unk0x50 = FALSE; m_unk0x50 = FALSE;
m_unk0x52 = 0; m_columnsOrRows = 0;
m_states = NULL; m_states = NULL;
m_unk0x54 = 0; m_rowsOrColumns = 0;
} }
// FUNCTION: LEGO1 0x10044110 // FUNCTION: LEGO1 0x10044110
@ -37,7 +37,7 @@ MxControlPresenter::~MxControlPresenter()
// FUNCTION: LEGO1 0x10044180 // FUNCTION: LEGO1 0x10044180
MxResult MxControlPresenter::AddToManager() MxResult MxControlPresenter::AddToManager()
{ {
m_unk0x4e = 0; m_enabledChild = 0;
return SUCCESS; return SUCCESS;
} }
@ -51,11 +51,11 @@ MxResult MxControlPresenter::StartAction(MxStreamController* p_controller, MxDSA
MxS16 i = 0; MxS16 i = 0;
for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) { for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) {
(*it)->Enable((m_unk0x4c != 3 || m_unk0x4e) && IsEnabled() ? m_unk0x4e == i : FALSE); (*it)->Enable((m_style != e_map || m_enabledChild) && IsEnabled() ? m_enabledChild == i : FALSE);
i++; i++;
} }
if (m_unk0x4c == 3) { if (m_style == e_map) {
MxDSAction* action = (*m_list.begin())->GetAction(); MxDSAction* action = (*m_list.begin())->GetAction();
action->SetFlags(action->GetFlags() | MxDSAction::c_bit11); action->SetFlags(action->GetFlags() | MxDSAction::c_bit11);
} }
@ -76,7 +76,7 @@ void MxControlPresenter::EndAction()
// FUNCTION: LEGO1 0x10044270 // FUNCTION: LEGO1 0x10044270
// FUNCTION: BETA10 0x100eae68 // FUNCTION: BETA10 0x100eae68
MxBool MxControlPresenter::FUN_10044270(MxS32 p_x, MxS32 p_y, MxPresenter* p_presenter) MxBool MxControlPresenter::CheckButtonDown(MxS32 p_x, MxS32 p_y, MxPresenter* p_presenter)
{ {
assert(p_presenter); assert(p_presenter);
MxVideoPresenter* presenter = dynamic_cast<MxVideoPresenter*>(p_presenter); MxVideoPresenter* presenter = dynamic_cast<MxVideoPresenter*>(p_presenter);
@ -85,7 +85,7 @@ MxBool MxControlPresenter::FUN_10044270(MxS32 p_x, MxS32 p_y, MxPresenter* p_pre
return FALSE; return FALSE;
} }
if (m_unk0x4c == 3) { if (m_style == e_map) {
MxStillPresenter* map = (MxStillPresenter*) m_list.front(); MxStillPresenter* map = (MxStillPresenter*) m_list.front();
assert(map && map->IsA("MxStillPresenter")); assert(map && map->IsA("MxStillPresenter"));
@ -100,23 +100,23 @@ MxBool MxControlPresenter::FUN_10044270(MxS32 p_x, MxS32 p_y, MxPresenter* p_pre
? NULL ? NULL
: map->GetBitmap()->GetStart(p_x - rect.GetLeft(), p_y - rect.GetTop()); : map->GetBitmap()->GetStart(p_x - rect.GetLeft(), p_y - rect.GetTop());
m_unk0x56 = 0; m_stateOrCellIndex = 0;
if (m_states) { if (m_states) {
for (MxS16 i = 1; i <= *m_states; i++) { for (MxS16 i = 1; i <= *m_states; i++) {
// TODO: Can we match without the cast here? // TODO: Can we match without the cast here?
if (m_states[i] == (MxS16) *start) { if (m_states[i] == (MxS16) *start) {
m_unk0x56 = i; m_stateOrCellIndex = i;
break; break;
} }
} }
} }
else { else {
if (*start != 0) { if (*start != 0) {
m_unk0x56 = 1; m_stateOrCellIndex = 1;
} }
} }
if (m_unk0x56) { if (m_stateOrCellIndex) {
return TRUE; return TRUE;
} }
} }
@ -125,21 +125,21 @@ MxBool MxControlPresenter::FUN_10044270(MxS32 p_x, MxS32 p_y, MxPresenter* p_pre
} }
else { else {
if (ContainsPresenter(m_list, presenter)) { if (ContainsPresenter(m_list, presenter)) {
if (m_unk0x4c == 2) { if (m_style == e_grid) {
MxS32 width = presenter->GetWidth(); MxS32 width = presenter->GetWidth();
MxS32 height = presenter->GetHeight(); MxS32 height = presenter->GetHeight();
if (m_unk0x52 == 2 && m_unk0x54 == 2) { if (m_columnsOrRows == 2 && m_rowsOrColumns == 2) {
if (p_x < presenter->GetX() + width / 2) { if (p_x < presenter->GetX() + width / 2) {
m_unk0x56 = (p_y >= presenter->GetY() + height / 2) ? 3 : 1; m_stateOrCellIndex = (p_y >= presenter->GetY() + height / 2) ? 3 : 1;
} }
else { else {
m_unk0x56 = (p_y >= presenter->GetY() + height / 2) ? 4 : 2; m_stateOrCellIndex = (p_y >= presenter->GetY() + height / 2) ? 4 : 2;
} }
} }
} }
else { else {
m_unk0x56 = -1; m_stateOrCellIndex = -1;
} }
return TRUE; return TRUE;
@ -150,27 +150,27 @@ MxBool MxControlPresenter::FUN_10044270(MxS32 p_x, MxS32 p_y, MxPresenter* p_pre
} }
// FUNCTION: LEGO1 0x10044480 // FUNCTION: LEGO1 0x10044480
MxBool MxControlPresenter::FUN_10044480(LegoControlManagerNotificationParam* p_param, MxPresenter* p_presenter) MxBool MxControlPresenter::Notify(LegoControlManagerNotificationParam* p_param, MxPresenter* p_presenter)
{ {
if (IsEnabled()) { if (IsEnabled()) {
switch (p_param->GetNotification()) { switch (p_param->GetNotification()) {
case c_notificationButtonUp: case c_notificationButtonUp:
if (m_unk0x4c == 0 || m_unk0x4c == 2 || m_unk0x4c == 3) { if (m_style == e_none || m_style == e_grid || m_style == e_map) {
p_param->SetClickedObjectId(m_action->GetObjectId()); p_param->SetClickedObjectId(m_action->GetObjectId());
p_param->SetClickedAtom(m_action->GetAtomId().GetInternal()); p_param->SetClickedAtom(m_action->GetAtomId().GetInternal());
VTable0x6c(0); UpdateEnabledChild(0);
p_param->SetNotification(c_notificationControl); p_param->SetNotification(c_notificationControl);
p_param->SetUnknown0x28(m_unk0x4e); p_param->SetUnknown0x28(m_enabledChild);
return TRUE; return TRUE;
} }
break; break;
case c_notificationButtonDown: case c_notificationButtonDown:
if (FUN_10044270(p_param->GetX(), p_param->GetY(), p_presenter)) { if (CheckButtonDown(p_param->GetX(), p_param->GetY(), p_presenter)) {
p_param->SetClickedObjectId(m_action->GetObjectId()); p_param->SetClickedObjectId(m_action->GetObjectId());
p_param->SetClickedAtom(m_action->GetAtomId().GetInternal()); p_param->SetClickedAtom(m_action->GetAtomId().GetInternal());
VTable0x6c(m_unk0x56); UpdateEnabledChild(m_stateOrCellIndex);
p_param->SetNotification(c_notificationControl); p_param->SetNotification(c_notificationControl);
p_param->SetUnknown0x28(m_unk0x4e); p_param->SetUnknown0x28(m_enabledChild);
return TRUE; return TRUE;
} }
break; break;
@ -181,25 +181,25 @@ MxBool MxControlPresenter::FUN_10044480(LegoControlManagerNotificationParam* p_p
} }
// FUNCTION: LEGO1 0x10044540 // FUNCTION: LEGO1 0x10044540
void MxControlPresenter::VTable0x6c(MxS16 p_unk0x4e) void MxControlPresenter::UpdateEnabledChild(MxS16 p_enabledChild)
{ {
if (p_unk0x4e == -1) { if (p_enabledChild == -1) {
if ((MxS16) ((MxDSMultiAction*) m_action)->GetActionList()->GetNumElements() - m_unk0x4e == 1) { if ((MxS16) ((MxDSMultiAction*) m_action)->GetActionList()->GetNumElements() - m_enabledChild == 1) {
m_unk0x4e = 0; m_enabledChild = 0;
} }
else { else {
m_unk0x4e++; m_enabledChild++;
} }
} }
else { else {
m_unk0x4e = p_unk0x4e; m_enabledChild = p_enabledChild;
} }
m_action->SetUnknown90(Timer()->GetTime()); m_action->SetTimeStarted(Timer()->GetTime());
MxS16 i = 0; MxS16 i = 0;
for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) { for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) {
(*it)->Enable(((m_unk0x4c == 3 && m_unk0x4e == 0) || !IsEnabled()) ? FALSE : m_unk0x4e == i); (*it)->Enable(((m_style == e_map && m_enabledChild == 0) || !IsEnabled()) ? FALSE : m_enabledChild == i);
i++; i++;
} }
} }
@ -230,20 +230,20 @@ void MxControlPresenter::ParseExtra()
char* token = strtok(output, g_parseExtraTokens); char* token = strtok(output, g_parseExtraTokens);
if (!SDL_strcasecmp(token, g_strTOGGLE)) { if (!SDL_strcasecmp(token, g_strTOGGLE)) {
m_unk0x4c = 1; m_style = e_toggle;
} }
else if (!SDL_strcasecmp(token, g_strGRID)) { else if (!SDL_strcasecmp(token, g_strGRID)) {
m_unk0x4c = 2; m_style = e_grid;
token = strtok(NULL, g_parseExtraTokens); token = strtok(NULL, g_parseExtraTokens);
assert(token); assert(token);
m_unk0x52 = atoi(token); m_columnsOrRows = atoi(token);
token = strtok(NULL, g_parseExtraTokens); token = strtok(NULL, g_parseExtraTokens);
assert(token); assert(token);
m_unk0x54 = atoi(token); m_rowsOrColumns = atoi(token);
} }
else if (!SDL_strcasecmp(token, g_strMAP)) { else if (!SDL_strcasecmp(token, g_strMAP)) {
m_unk0x4c = 3; m_style = e_map;
token = strtok(NULL, g_parseExtraTokens); token = strtok(NULL, g_parseExtraTokens);
if (token) { if (token) {
@ -260,7 +260,7 @@ void MxControlPresenter::ParseExtra()
} }
} }
else { else {
m_unk0x4c = 0; m_style = e_none;
} }
} }
@ -280,8 +280,8 @@ void MxControlPresenter::Enable(MxBool p_enable)
MxS16 i = 0; MxS16 i = 0;
for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) { for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) {
if (i == m_unk0x4e) { if (i == m_enabledChild) {
(*it)->Enable((m_unk0x4c != 3 || i != 0) ? p_enable : 0); (*it)->Enable((m_style != e_map || i != 0) ? p_enable : 0);
break; break;
} }
@ -289,7 +289,7 @@ void MxControlPresenter::Enable(MxBool p_enable)
} }
if (!p_enable) { if (!p_enable) {
m_unk0x4e = 0; m_enabledChild = 0;
} }
} }
} }
@ -300,10 +300,10 @@ MxBool MxControlPresenter::HasTickleStatePassed(TickleState p_tickleState)
MxCompositePresenterList::const_iterator it = m_list.begin(); MxCompositePresenterList::const_iterator it = m_list.begin();
#ifdef COMPAT_MODE #ifdef COMPAT_MODE
advance(it, m_unk0x4e); advance(it, m_enabledChild);
#else #else
// Uses forward iterator logic instead of bidrectional for some reason. // Uses forward iterator logic instead of bidrectional for some reason.
_Advance(it, m_unk0x4e, forward_iterator_tag()); _Advance(it, m_enabledChild, forward_iterator_tag());
#endif #endif
return (*it)->HasTickleStatePassed(p_tickleState); return (*it)->HasTickleStatePassed(p_tickleState);

View File

@ -84,6 +84,9 @@ MxResult MxTransitionManager::Tickle()
case e_broken: case e_broken:
BrokenTransition(); BrokenTransition();
break; break;
case e_fakeMosaic:
FakeMosaicTransition();
break;
} }
return SUCCESS; return SUCCESS;
} }
@ -613,3 +616,138 @@ void MxTransitionManager::configureMxTransitionManager(TransitionType p_transiti
{ {
g_transitionManagerConfig = p_transitionManagerConfig; g_transitionManagerConfig = p_transitionManagerConfig;
} }
int g_colorOffset;
int GetColorIndexWithLocality(int p_col, int p_row)
{
int islandX = p_col / 8;
int islandY = p_row / 8; // Dvide screen in 8x6 tiles
int island = islandY * 8 + islandX; // tile id
if (SDL_rand(3) > island / 8) {
return 6 + SDL_rand(2); // emulate sky
}
if (SDL_rand(16) > 2) {
island += SDL_rand(3) - 1 + (SDL_rand(3) - 1) * 8; // blure tiles
}
int hash = (island + g_colorOffset) * 2654435761u;
int scrambled = (hash >> 16) % 32;
int finalIndex = scrambled + SDL_rand(3) - 1;
return abs(finalIndex) % 32;
}
void MxTransitionManager::FakeMosaicTransition()
{
static LPDIRECTDRAWSURFACE g_fakeTranstionSurface = nullptr;
if (m_animationTimer == 16) {
m_animationTimer = 0;
if (g_fakeTranstionSurface) {
g_fakeTranstionSurface->Release();
g_fakeTranstionSurface = nullptr;
}
EndTransition(TRUE);
return;
}
if (m_animationTimer == 0) {
g_colorOffset = SDL_rand(32);
for (MxS32 i = 0; i < 64; i++) {
m_columnOrder[i] = i;
}
for (MxS32 i = 0; i < 64; i++) {
MxS32 swap = SDL_rand(64);
std::swap(m_columnOrder[i], m_columnOrder[swap]);
}
for (MxS32 i = 0; i < 48; i++) {
m_randomShift[i] = SDL_rand(64);
}
}
if (!g_fakeTranstionSurface) {
DDSURFACEDESC mainDesc = {};
mainDesc.dwSize = sizeof(mainDesc);
if (m_ddSurface->GetSurfaceDesc(&mainDesc) != DD_OK) {
return;
}
DDSURFACEDESC tempDesc = {};
tempDesc.dwSize = sizeof(tempDesc);
tempDesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
tempDesc.dwWidth = 64;
tempDesc.dwHeight = 48;
tempDesc.ddpfPixelFormat = mainDesc.ddpfPixelFormat;
tempDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
HRESULT hr = MVideoManager()->GetDirectDraw()->CreateSurface(&tempDesc, &g_fakeTranstionSurface, nullptr);
if (hr != DD_OK || !g_fakeTranstionSurface) {
return;
}
}
DDSURFACEDESC ddsd = {};
ddsd.dwSize = sizeof(ddsd);
HRESULT res = g_fakeTranstionSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
if (res == DDERR_SURFACELOST) {
g_fakeTranstionSurface->Restore();
res = g_fakeTranstionSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
}
if (res == DD_OK) {
SubmitCopyRect(&ddsd);
static const MxU8 g_palette[32][3] = {
{0x00, 0x00, 0x00}, {0x12, 0x1e, 0x50}, {0x00, 0x22, 0x6c}, {0x14, 0x2d, 0x9f}, {0x0e, 0x36, 0xb0},
{0x0e, 0x39, 0xd0}, {0x47, 0x96, 0xe2}, {0x79, 0xaa, 0xca}, {0xff, 0xff, 0xff}, {0xc9, 0xcd, 0xcb},
{0xad, 0xad, 0xab}, {0xa6, 0x91, 0x8e}, {0xaf, 0x59, 0x49}, {0xc0, 0x00, 0x00}, {0xab, 0x18, 0x18},
{0x61, 0x0c, 0x0c}, {0x04, 0x38, 0x12}, {0x2c, 0x67, 0x28}, {0x4a, 0xb4, 0x6b}, {0x94, 0xb7, 0x7c},
{0xb6, 0xb9, 0x87}, {0x52, 0x4a, 0x67}, {0x87, 0x8d, 0x8a}, {0xa6, 0x91, 0x8e}, {0xf8, 0xee, 0xdc},
{0xf4, 0xe2, 0xc3}, {0x87, 0x8d, 0x8a}, {0xba, 0x9f, 0x12}, {0xb5, 0x83, 0x00}, {0x6a, 0x44, 0x27},
{0x36, 0x37, 0x34}, {0x2b, 0x23, 0x0f}
};
MxS32 bytesPerPixel = ddsd.ddpfPixelFormat.dwRGBBitCount / 8;
for (MxS32 col = 0; col < 64; col++) {
if (m_animationTimer * 4 > m_columnOrder[col]) {
continue;
}
if (m_animationTimer * 4 + 3 < m_columnOrder[col]) {
continue;
}
for (MxS32 row = 0; row < 48; row++) {
int paletteIndex = GetColorIndexWithLocality(col, row);
const MxU8* color = g_palette[paletteIndex];
MxS32 xShift = (m_randomShift[row] + col) % 64;
MxU8* dest = (MxU8*) ddsd.lpSurface + row * ddsd.lPitch + xShift * bytesPerPixel;
switch (bytesPerPixel) {
case 1:
*dest = paletteIndex;
break;
case 2:
*((MxU16*) dest) = RGB555_CREATE(color[2], color[1], color[0]);
break;
default:
*((MxU32*) dest) = RGB8888_CREATE(color[2], color[1], color[0], 255);
break;
}
}
}
SetupCopyRect(&ddsd);
g_fakeTranstionSurface->Unlock(ddsd.lpSurface);
RECT srcRect = {0, 0, 64, 48};
m_ddSurface->Blt(&g_fullScreenRect, g_fakeTranstionSurface, &srcRect, DDBLT_WAIT, NULL);
}
m_animationTimer++;
}

View File

@ -131,9 +131,9 @@ void LegoControlManager::FUN_100293c0(MxU32 p_objectId, const char* p_atom, MxS1
MxDSAction* action = control->GetAction(); MxDSAction* action = control->GetAction();
if (action->GetObjectId() == p_objectId && action->GetAtomId().GetInternal() == p_atom) { if (action->GetObjectId() == p_objectId && action->GetAtomId().GetInternal() == p_atom) {
((MxControlPresenter*) control)->VTable0x6c(p_unk0x4e); ((MxControlPresenter*) control)->UpdateEnabledChild(p_unk0x4e);
if (((MxControlPresenter*) control)->GetUnknown0x4e() == 0) { if (((MxControlPresenter*) control)->GetEnabledChild() == 0) {
g_unk0x100f31b0 = -1; g_unk0x100f31b0 = -1;
g_unk0x100f31b4 = NULL; g_unk0x100f31b4 = NULL;
break; break;
@ -154,7 +154,7 @@ MxControlPresenter* LegoControlManager::FUN_100294e0(MxS32 p_x, MxS32 p_y)
if (presenter) { if (presenter) {
while (cursor.Next(control)) { while (cursor.Next(control)) {
if (((MxControlPresenter*) control)->FUN_10044270(p_x, p_y, presenter)) { if (((MxControlPresenter*) control)->CheckButtonDown(p_x, p_y, presenter)) {
return (MxControlPresenter*) control; return (MxControlPresenter*) control;
} }
} }
@ -185,7 +185,7 @@ MxBool LegoControlManager::FUN_10029630()
MxPresenter* presenter; MxPresenter* presenter;
while (cursor.Next(presenter)) { while (cursor.Next(presenter)) {
if (((MxControlPresenter*) presenter)->FUN_10044480(&m_event, m_unk0x14)) { if (((MxControlPresenter*) presenter)->Notify(&m_event, m_unk0x14)) {
g_unk0x100f31b0 = m_event.m_clickedObjectId; g_unk0x100f31b0 = m_event.m_clickedObjectId;
g_unk0x100f31b4 = m_event.GetClickedAtom(); g_unk0x100f31b4 = m_event.GetClickedAtom();
FUN_100292e0(); FUN_100292e0();
@ -206,7 +206,7 @@ MxBool LegoControlManager::FUN_10029750()
while (cursor.Next(presenter)) { while (cursor.Next(presenter)) {
if (presenter->GetAction() && presenter->GetAction()->GetObjectId() == g_unk0x100f31b0 && if (presenter->GetAction() && presenter->GetAction()->GetObjectId() == g_unk0x100f31b0 &&
presenter->GetAction()->GetAtomId().GetInternal() == g_unk0x100f31b4) { presenter->GetAction()->GetAtomId().GetInternal() == g_unk0x100f31b4) {
if (((MxControlPresenter*) presenter)->FUN_10044480(&m_event, m_unk0x14)) { if (((MxControlPresenter*) presenter)->Notify(&m_event, m_unk0x14)) {
FUN_100292e0(); FUN_100292e0();
} }

View File

@ -818,7 +818,7 @@ void LegoAnimPresenter::StartingTickle()
m_compositePresenter->VTable0x60(this); m_compositePresenter->VTable0x60(this);
} }
else { else {
m_action->SetUnknown90(Timer()->GetTime()); m_action->SetTimeStarted(Timer()->GetTime());
} }
ProgressTickleState(e_streaming); ProgressTickleState(e_streaming);

View File

@ -671,14 +671,14 @@ MxLong RegistrationBook::HandlePathStruct(LegoPathStructNotificationParam& p_par
MxBool RegistrationBook::CreateSurface() MxBool RegistrationBook::CreateSurface()
{ {
MxCompositePresenterList* presenters = m_checkmark[0]->GetList(); MxCompositePresenterList* presenters = m_checkmark[0]->GetList();
MxStillPresenter *presenter, *uninitialized; MxStillPresenter* presenter;
if (presenters) { if (presenters) {
if (presenters->begin() != presenters->end()) { if (presenters->begin() != presenters->end()) {
presenter = (MxStillPresenter*) presenters->front(); presenter = (MxStillPresenter*) presenters->front();
} }
else { else {
presenter = uninitialized; // intentionally uninitialized variable presenter = NULL;
} }
if (presenter) { if (presenter) {

View File

@ -12,6 +12,9 @@
#include <ddraw.h> #include <ddraw.h>
#endif #endif
#define RGB555_CREATE(R, G, B) (((R) << 10) | (G) << 5 | (B) << 0)
#define RGB8888_CREATE(R, G, B, A) (((A) << 24) | ((R) << 16) | ((G) << 8) | (B))
class MxBitmap; class MxBitmap;
class MxPalette; class MxPalette;

View File

@ -56,8 +56,8 @@ class MxDSAction : public MxDSObject {
virtual MxDSAction* Clone(); // vtable+0x2c virtual MxDSAction* Clone(); // vtable+0x2c
virtual void MergeFrom(MxDSAction& p_dsAction); // vtable+0x30 virtual void MergeFrom(MxDSAction& p_dsAction); // vtable+0x30
virtual MxBool HasId(MxU32 p_objectId); // vtable+0x34 virtual MxBool HasId(MxU32 p_objectId); // vtable+0x34
virtual void SetUnknown90(MxLong p_unk0x90); // vtable+0x38 virtual void SetTimeStarted(MxLong p_timeStarted); // vtable+0x38
virtual MxLong GetUnknown90(); // vtable+0x3c virtual MxLong GetTimeStarted(); // vtable+0x3c
virtual MxLong GetElapsedTime(); // vtable+0x40 virtual MxLong GetElapsedTime(); // vtable+0x40
void AppendExtra(MxU16 p_extraLength, const char* p_extraData); void AppendExtra(MxU16 p_extraLength, const char* p_extraData);
@ -131,7 +131,7 @@ class MxDSAction : public MxDSObject {
MxCore* m_notificationObject; // 0x84 MxCore* m_notificationObject; // 0x84
undefined4 m_unk0x88; // 0x88 undefined4 m_unk0x88; // 0x88
MxCore* m_origin; // 0x8c MxCore* m_origin; // 0x8c
MxLong m_unk0x90; // 0x90 MxLong m_timeStarted; // 0x90
}; };
#endif // MXDSACTION_H #endif // MXDSACTION_H

View File

@ -38,7 +38,7 @@ class MxDSMultiAction : public MxDSAction {
MxDSAction* Clone() override; // vtable+0x2c MxDSAction* Clone() override; // vtable+0x2c
void MergeFrom(MxDSAction& p_dsAction) override; // vtable+0x30 void MergeFrom(MxDSAction& p_dsAction) override; // vtable+0x30
MxBool HasId(MxU32 p_objectId) override; // vtable+0x34 MxBool HasId(MxU32 p_objectId) override; // vtable+0x34
void SetUnknown90(MxLong p_unk0x90) override; // vtable+0x38 void SetTimeStarted(MxLong p_timeStarted) override; // vtable+0x38
// FUNCTION: BETA10 0x1004e180 // FUNCTION: BETA10 0x1004e180
MxDSActionList* GetActionList() const { return m_actionList; } MxDSActionList* GetActionList() const { return m_actionList; }

View File

@ -31,7 +31,7 @@ MxDSAction::MxDSAction()
m_notificationObject = NULL; m_notificationObject = NULL;
m_unk0x88 = 0; m_unk0x88 = 0;
m_origin = NULL; m_origin = NULL;
m_unk0x90 = INT_MIN; m_timeStarted = INT_MIN;
} }
// FUNCTION: LEGO1 0x100ad940 // FUNCTION: LEGO1 0x100ad940
@ -57,16 +57,16 @@ MxBool MxDSAction::HasId(MxU32 p_objectId)
// FUNCTION: LEGO1 0x100ada40 // FUNCTION: LEGO1 0x100ada40
// FUNCTION: BETA10 0x1012bdf0 // FUNCTION: BETA10 0x1012bdf0
void MxDSAction::SetUnknown90(MxLong p_unk0x90) void MxDSAction::SetTimeStarted(MxLong p_timeStarted)
{ {
m_unk0x90 = p_unk0x90; m_timeStarted = p_timeStarted;
} }
// FUNCTION: LEGO1 0x100ada50 // FUNCTION: LEGO1 0x100ada50
// FUNCTION: BETA10 0x1012be20 // FUNCTION: BETA10 0x1012be20
MxLong MxDSAction::GetUnknown90() MxLong MxDSAction::GetTimeStarted()
{ {
return m_unk0x90; return m_timeStarted;
} }
// FUNCTION: LEGO1 0x100ada80 // FUNCTION: LEGO1 0x100ada80
@ -92,7 +92,7 @@ void MxDSAction::CopyFrom(MxDSAction& p_dsAction)
m_notificationObject = p_dsAction.m_notificationObject; m_notificationObject = p_dsAction.m_notificationObject;
m_unk0x88 = p_dsAction.m_unk0x88; m_unk0x88 = p_dsAction.m_unk0x88;
m_origin = p_dsAction.m_origin; m_origin = p_dsAction.m_origin;
m_unk0x90 = p_dsAction.m_unk0x90; m_timeStarted = p_dsAction.m_timeStarted;
} }
// FUNCTION: BETA10 0x1012b2b3 // FUNCTION: BETA10 0x1012b2b3
@ -158,7 +158,7 @@ MxDSAction* MxDSAction::Clone()
// FUNCTION: BETA10 0x1012b4ca // FUNCTION: BETA10 0x1012b4ca
MxLong MxDSAction::GetElapsedTime() MxLong MxDSAction::GetElapsedTime()
{ {
return Timer()->GetTime() - m_unk0x90; return Timer()->GetTime() - m_timeStarted;
} }
// FUNCTION: LEGO1 0x100add00 // FUNCTION: LEGO1 0x100add00

View File

@ -59,14 +59,14 @@ MxDSMultiAction& MxDSMultiAction::operator=(MxDSMultiAction& p_dsMultiAction)
// FUNCTION: LEGO1 0x100ca290 // FUNCTION: LEGO1 0x100ca290
// FUNCTION: BETA10 0x10159728 // FUNCTION: BETA10 0x10159728
void MxDSMultiAction::SetUnknown90(MxLong p_unk0x90) void MxDSMultiAction::SetTimeStarted(MxLong p_timeStarted)
{ {
m_unk0x90 = p_unk0x90; m_timeStarted = p_timeStarted;
MxDSActionListCursor cursor(m_actionList); MxDSActionListCursor cursor(m_actionList);
MxDSAction* action; MxDSAction* action;
while (cursor.Next(action)) { while (cursor.Next(action)) {
action->SetUnknown90(p_unk0x90); action->SetTimeStarted(p_timeStarted);
} }
} }

View File

@ -252,7 +252,7 @@ void MxMediaPresenter::Enable(MxBool p_enable)
if (p_enable) { if (p_enable) {
MxLong time = Timer()->GetTime(); MxLong time = Timer()->GetTime();
m_action->SetUnknown90(time); m_action->SetTimeStarted(time);
SetTickleState(e_repeating); SetTickleState(e_repeating);
} }
else { else {

View File

@ -210,7 +210,7 @@ MxResult MxDSBuffer::StartPresenterFromAction(
p_objectheader->SetUnknown28(p_action1->GetUnknown28()); p_objectheader->SetUnknown28(p_action1->GetUnknown28());
p_objectheader->SetNotificationObject(p_action1->GetNotificationObject()); p_objectheader->SetNotificationObject(p_action1->GetNotificationObject());
p_objectheader->SetOrigin(p_action1->GetOrigin()); p_objectheader->SetOrigin(p_action1->GetOrigin());
p_objectheader->SetUnknown90(p_action1->GetUnknown90()); p_objectheader->SetTimeStarted(p_action1->GetTimeStarted());
p_objectheader->MergeFrom(*p_action1); p_objectheader->MergeFrom(*p_action1);
m_unk0x30->SetInternalAction(p_objectheader->Clone()); m_unk0x30->SetInternalAction(p_objectheader->Clone());

View File

@ -202,7 +202,7 @@ MxResult MxStreamController::FUN_100c1a00(MxDSAction* p_action, MxU32 p_offset)
streamingAction->SetObjectId(p_action->GetObjectId()); streamingAction->SetObjectId(p_action->GetObjectId());
MxLong time = Timer()->GetTime(); MxLong time = Timer()->GetTime();
streamingAction->SetUnknown90(time); streamingAction->SetTimeStarted(time);
m_unk0x3c.PushBack(streamingAction); m_unk0x3c.PushBack(streamingAction);
return SUCCESS; return SUCCESS;

View File

@ -18,9 +18,6 @@
DECOMP_SIZE_ASSERT(MxDisplaySurface, 0xac); DECOMP_SIZE_ASSERT(MxDisplaySurface, 0xac);
#define RGB555_CREATE(R, G, B) (((R) << 10) | (G) << 5 | (B) << 0)
#define RGB8888_CREATE(R, G, B, A) (((A) << 24) | ((R) << 16) | ((G) << 8) | (B))
// GLOBAL: LEGO1 0x1010215c // GLOBAL: LEGO1 0x1010215c
MxU32 g_unk0x1010215c = 0; MxU32 g_unk0x1010215c = 0;
@ -399,86 +396,88 @@ void MxDisplaySurface::VTable0x28(
DDSURFACEDESC ddsd; DDSURFACEDESC ddsd;
memset(&ddsd, 0, sizeof(ddsd)); memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd); ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
ddsd.dwWidth = p_width;
ddsd.dwHeight = p_height;
ddsd.ddpfPixelFormat = m_surfaceDesc.ddpfPixelFormat;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
HRESULT hr = m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); LPDIRECTDRAWSURFACE tempSurface = nullptr;
LPDIRECTDRAW draw = MVideoManager()->GetDirectDraw();
HRESULT hr = draw->CreateSurface(&ddsd, &tempSurface, nullptr);
if (hr != DD_OK || !tempSurface) {
return;
}
if (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount != 32) {
DDCOLORKEY colorKey;
if (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount == 8) {
colorKey.dwColorSpaceLowValue = colorKey.dwColorSpaceHighValue = 0x10;
}
else {
colorKey.dwColorSpaceLowValue = colorKey.dwColorSpaceHighValue = RGB555_CREATE(0x1f, 0, 0x1f);
}
tempSurface->SetColorKey(DDCKEY_SRCBLT, &colorKey);
}
DDSURFACEDESC tempDesc;
memset(&tempDesc, 0, sizeof(tempDesc));
tempDesc.dwSize = sizeof(tempDesc);
hr = tempSurface->Lock(NULL, &tempDesc, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
if (hr == DDERR_SURFACELOST) { if (hr == DDERR_SURFACELOST) {
m_ddSurface2->Restore(); tempSurface->Restore();
hr = m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); hr = tempSurface->Lock(NULL, &tempDesc, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
} }
if (hr != DD_OK) { if (hr != DD_OK) {
tempSurface->Release();
return; return;
} }
MxU8* data = p_bitmap->GetStart(p_left, p_top); MxU8* data = p_bitmap->GetStart(p_left, p_top);
MxS32 bytesPerPixel = m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount / 8; MxS32 bytesPerPixel = m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount / 8;
if (m_videoParam.Flags().GetF1bit3()) { MxU8* surface = (MxU8*) tempDesc.lpSurface;
p_bottom *= 2;
p_right *= 2;
MxU8* surface = (MxU8*) ddsd.lpSurface + (bytesPerPixel * p_right) + (p_bottom * ddsd.lPitch); MxLong stride = (bytesPerPixel == 1) ? GetAdjustedStride(p_bitmap) : -p_width + GetAdjustedStride(p_bitmap);
MxLong stride = -p_width + GetAdjustedStride(p_bitmap); MxLong length = tempDesc.lPitch - (p_width * bytesPerPixel);
MxS32 copyWidth = p_width * bytesPerPixel * 2;
MxLong length = -(copyWidth) + ddsd.lPitch;
while (p_height--) { for (MxS32 i = 0; i < p_height; i++) {
MxU8* surfaceBefore = surface; if (bytesPerPixel == 1) {
memcpy(surface, data, p_width);
for (MxS32 i = 0; i < p_width; i++) { surface += length + p_width;
if (bytesPerPixel == 1) {
surface[0] = surface[1] = *data;
}
else if (bytesPerPixel == 2) {
((MxU16*) surface)[0] = ((MxU16*) surface)[1] = m_16bitPal[*data];
}
else {
((MxU32*) surface)[0] = ((MxU32*) surface)[1] = m_32bitPal[*data];
}
surface += bytesPerPixel * 2;
data++;
}
if (stride || length != ddsd.lPitch - copyWidth) {
data += stride;
surface += length;
}
memcpy(surface, surfaceBefore, copyWidth);
surface += ddsd.lPitch;
} }
else if (bytesPerPixel == 2) {
for (MxS32 j = 0; j < p_width; j++) {
*(MxU16*) surface = m_16bitPal[*data++];
surface += bytesPerPixel;
}
surface += length;
}
else {
for (MxS32 j = 0; j < p_width; j++) {
*(MxU32*) surface = m_32bitPal[*data++];
surface += bytesPerPixel;
}
surface += length;
}
data += stride;
}
tempSurface->Unlock(NULL);
if (m_videoParam.Flags().GetF1bit3()) {
RECT destRect = {p_right, p_bottom, p_right + p_width * 2, p_bottom + p_height * 2};
m_ddSurface2->Blt(&destRect, tempSurface, NULL, DDBLT_WAIT | DDBLT_KEYSRC, NULL);
} }
else { else {
MxU8* surface = (MxU8*) ddsd.lpSurface + (bytesPerPixel * p_right) + (p_bottom * ddsd.lPitch); m_ddSurface2->BltFast(p_right, p_bottom, tempSurface, NULL, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY);
MxLong stride = (bytesPerPixel == 1) ? GetAdjustedStride(p_bitmap) : -p_width + GetAdjustedStride(p_bitmap);
MxLong length = ddsd.lPitch - (p_width * bytesPerPixel);
for (MxS32 i = 0; i < p_height; i++) {
if (bytesPerPixel == 1) {
memcpy(surface, data, p_width);
surface += length + p_width;
}
else if (bytesPerPixel == 2) {
for (MxS32 j = 0; j < p_width; j++) {
*(MxU16*) surface = m_16bitPal[*data++];
surface += bytesPerPixel;
}
surface += length;
}
else {
for (MxS32 j = 0; j < p_width; j++) {
*(MxU32*) surface = m_32bitPal[*data++];
surface += bytesPerPixel;
}
surface += length;
}
data += stride;
}
} }
m_ddSurface2->Unlock(ddsd.lpSurface); tempSurface->Release();
} }
// FUNCTION: LEGO1 0x100bb1d0 // FUNCTION: LEGO1 0x100bb1d0
@ -511,29 +510,43 @@ void MxDisplaySurface::VTable0x30(
DDSURFACEDESC ddsd; DDSURFACEDESC ddsd;
memset(&ddsd, 0, sizeof(ddsd)); memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd); ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
ddsd.dwWidth = p_width;
ddsd.dwHeight = p_height;
ddsd.ddpfPixelFormat = m_surfaceDesc.ddpfPixelFormat;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
HRESULT hr = m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); LPDIRECTDRAW draw = MVideoManager()->GetDirectDraw();
if (hr == DDERR_SURFACELOST) { LPDIRECTDRAWSURFACE tempSurface = nullptr;
m_ddSurface2->Restore(); if (draw->CreateSurface(&ddsd, &tempSurface, nullptr) != DD_OK || !tempSurface) {
hr = m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); return;
} }
if (hr != DD_OK) { DDCOLORKEY colorKey;
colorKey.dwColorSpaceLowValue = colorKey.dwColorSpaceHighValue = 0;
tempSurface->SetColorKey(DDCKEY_SRCBLT, &colorKey);
DDSURFACEDESC tempDesc;
memset(&tempDesc, 0, sizeof(tempDesc));
tempDesc.dwSize = sizeof(tempDesc);
if (tempSurface->Lock(NULL, &tempDesc, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL) != DD_OK) {
tempSurface->Release();
return; return;
} }
MxU8* data = p_bitmap->GetStart(p_left, p_top); MxU8* data = p_bitmap->GetStart(p_left, p_top);
MxS32 bytesPerPixel = m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount / 8; MxS32 bytesPerPixel = m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount / 8;
MxU8* surface = (MxU8*) ddsd.lpSurface + (bytesPerPixel * p_right) + (p_bottom * ddsd.lPitch); MxU8* surface = (MxU8*) tempDesc.lpSurface;
if (p_RLE) { if (p_RLE) {
MxS32 size = p_bitmap->GetBmiHeader()->biSizeImage; MxS32 size = p_bitmap->GetBmiHeader()->biSizeImage;
DrawTransparentRLE(data, surface, size, p_width, p_height, ddsd.lPitch, bytesPerPixel * 8); DrawTransparentRLE(data, surface, size, p_width, p_height, tempDesc.lPitch, bytesPerPixel * 8);
} }
else { else {
MxLong stride = -p_width + GetAdjustedStride(p_bitmap); MxLong stride = -p_width + GetAdjustedStride(p_bitmap);
MxLong length = -bytesPerPixel * p_width + ddsd.lPitch; MxLong length = -bytesPerPixel * p_width + tempDesc.lPitch;
for (MxS32 i = 0; i < p_height; i++) { for (MxS32 i = 0; i < p_height; i++) {
for (MxS32 j = 0; j < p_width; j++) { for (MxS32 j = 0; j < p_width; j++) {
@ -558,7 +571,11 @@ void MxDisplaySurface::VTable0x30(
} }
} }
m_ddSurface2->Unlock(ddsd.lpSurface); tempSurface->Unlock(NULL);
m_ddSurface2->BltFast(p_right, p_bottom, tempSurface, NULL, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY);
tempSurface->Release();
} }
// FUNCTION: LEGO1 0x100bb500 // FUNCTION: LEGO1 0x100bb500

View File

@ -115,31 +115,34 @@ static int NearestPowerOfTwoClamp(int val)
return 512; return 512;
} }
static SDL_Surface* ConvertAndResizeSurface(SDL_Surface* original, bool isUI, float scale) static SDL_Surface* ConvertAndResizeSurface(SDL_Surface* original, bool isUI, float scaleX, float scaleY)
{ {
SDL_Surface* converted = SDL_ConvertSurface(original, SDL_PIXELFORMAT_RGBA8888);
if (!converted) {
return nullptr;
}
if (!isUI) { if (!isUI) {
return converted; return SDL_ConvertSurface(original, SDL_PIXELFORMAT_RGBA8888);
} }
int scaledW = static_cast<int>(converted->w * scale); scaleX = std::min(scaleX, 1.0f);
int scaledH = static_cast<int>(converted->h * scale); scaleY = std::min(scaleY, 1.0f);
int scaledW = static_cast<int>(original->w * scaleX);
int scaledH = static_cast<int>(original->h * scaleY);
int paddedW = NearestPowerOfTwoClamp(scaledW); int paddedW = NearestPowerOfTwoClamp(scaledW);
int paddedH = NearestPowerOfTwoClamp(scaledH); int paddedH = NearestPowerOfTwoClamp(scaledH);
SDL_Surface* padded = SDL_CreateSurface(paddedW, paddedH, SDL_PIXELFORMAT_RGBA8888); SDL_Surface* padded = SDL_CreateSurface(paddedW, paddedH, SDL_PIXELFORMAT_RGBA8888);
if (!padded) { if (!padded) {
SDL_DestroySurface(converted);
return nullptr; return nullptr;
} }
SDL_Rect dstRect = {0, 0, scaledW, scaledH}; if (scaleX == 1.0f && scaleY == 1.0f) {
SDL_BlitSurfaceScaled(converted, nullptr, padded, &dstRect, SDL_SCALEMODE_LINEAR); SDL_BlitSurface(original, nullptr, padded, nullptr);
SDL_DestroySurface(converted); }
else {
SDL_ScaleMode scaleMode = (scaleX >= 1.0f && scaleY >= 1.0f) ? SDL_SCALEMODE_NEAREST : SDL_SCALEMODE_LINEAR;
SDL_Rect dstRect = {0, 0, scaledW, scaledH};
SDL_BlitSurfaceScaled(original, nullptr, padded, &dstRect, scaleMode);
}
return padded; return padded;
} }
@ -181,9 +184,9 @@ static void EncodeTextureLayout(const u8* src, u8* dst, int width, int height)
} }
} }
static bool ConvertAndUploadTexture(C3D_Tex* tex, SDL_Surface* originalSurface, bool isUI, float scale) static bool ConvertAndUploadTexture(C3D_Tex* tex, SDL_Surface* originalSurface, bool isUI, float scaleX, float scaleY)
{ {
SDL_Surface* resized = ConvertAndResizeSurface(originalSurface, isUI, scale); SDL_Surface* resized = ConvertAndResizeSurface(originalSurface, isUI, scaleX, scaleY);
if (!resized) { if (!resized) {
return false; return false;
} }
@ -198,18 +201,24 @@ static bool ConvertAndUploadTexture(C3D_Tex* tex, SDL_Surface* originalSurface,
params.maxLevel = isUI ? 0 : 4; params.maxLevel = isUI ? 0 : 4;
params.type = GPU_TEX_2D; params.type = GPU_TEX_2D;
if (!C3D_TexInitWithParams(tex, nullptr, params)) { if (!C3D_TexInitWithParams(tex, nullptr, params)) {
SDL_DestroySurface(resized); if (resized != originalSurface) {
SDL_DestroySurface(resized);
}
return false; return false;
} }
uint8_t* tiledData = (uint8_t*) malloc(width * height * 4); uint8_t* tiledData = (uint8_t*) malloc(width * height * 4);
if (!tiledData) { if (!tiledData) {
SDL_DestroySurface(resized); if (resized != originalSurface) {
SDL_DestroySurface(resized);
}
return false; return false;
} }
EncodeTextureLayout((const u8*) resized->pixels, tiledData, width, height); EncodeTextureLayout((const u8*) resized->pixels, tiledData, width, height);
SDL_DestroySurface(resized); if (resized != originalSurface) {
SDL_DestroySurface(resized);
}
C3D_TexUpload(tex, tiledData); C3D_TexUpload(tex, tiledData);
free(tiledData); free(tiledData);
@ -228,7 +237,7 @@ static bool ConvertAndUploadTexture(C3D_Tex* tex, SDL_Surface* originalSurface,
return true; return true;
} }
Uint32 Citro3DRenderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi) Uint32 Citro3DRenderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUI, float scaleX, float scaleY)
{ {
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture); auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface); auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface);
@ -242,7 +251,13 @@ Uint32 Citro3DRenderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi)
if (tex.texture == texture) { if (tex.texture == texture) {
if (tex.version != texture->m_version) { if (tex.version != texture->m_version) {
C3D_TexDelete(&tex.c3dTex); C3D_TexDelete(&tex.c3dTex);
if (!ConvertAndUploadTexture(&tex.c3dTex, originalSurface, isUi, m_viewportTransform.scale)) { if (!ConvertAndUploadTexture(
&tex.c3dTex,
originalSurface,
isUI,
scaleX * m_viewportTransform.scale,
scaleY * m_viewportTransform.scale
)) {
return NO_TEXTURE_ID; return NO_TEXTURE_ID;
} }
@ -260,7 +275,13 @@ Uint32 Citro3DRenderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi)
entry.width = NearestPowerOfTwoClamp(originalW * m_viewportTransform.scale); entry.width = NearestPowerOfTwoClamp(originalW * m_viewportTransform.scale);
entry.height = NearestPowerOfTwoClamp(originalH * m_viewportTransform.scale); entry.height = NearestPowerOfTwoClamp(originalH * m_viewportTransform.scale);
if (!ConvertAndUploadTexture(&entry.c3dTex, originalSurface, isUi, m_viewportTransform.scale)) { if (!ConvertAndUploadTexture(
&entry.c3dTex,
originalSurface,
isUI,
scaleX * m_viewportTransform.scale,
scaleY * m_viewportTransform.scale
)) {
return NO_TEXTURE_ID; return NO_TEXTURE_ID;
} }

View File

@ -76,7 +76,7 @@ void DirectX9Renderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture*
); );
} }
Uint32 DirectX9Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi) Uint32 DirectX9Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUI, float scaleX, float scaleY)
{ {
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture); auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface); auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface);

View File

@ -49,12 +49,12 @@ int GL11_GetMaxTextureSize()
return maxTextureSize; return maxTextureSize;
} }
GLuint GL11_UploadTextureData(void* pixels, int width, int height, bool isUi) GLuint GL11_UploadTextureData(void* pixels, int width, int height, bool isUI, float scaleX, float scaleY)
{ {
GLuint texId; GLuint texId;
glGenTextures(1, &texId); glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId); glBindTexture(GL_TEXTURE_2D, texId);
if (isUi) { if (isUI) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

View File

@ -65,7 +65,7 @@ void GL11_InitState();
void GL11_LoadExtensions(); void GL11_LoadExtensions();
void GL11_DestroyTexture(GLuint texId); void GL11_DestroyTexture(GLuint texId);
int GL11_GetMaxTextureSize(); int GL11_GetMaxTextureSize();
GLuint GL11_UploadTextureData(void* pixels, int width, int height, bool isUI); GLuint GL11_UploadTextureData(void* pixels, int width, int height, bool isUI, float scaleX, float scaleY);
void GL11_UploadMesh(GLMeshCacheEntry& cache, bool hasTexture); void GL11_UploadMesh(GLMeshCacheEntry& cache, bool hasTexture);
void GL11_DestroyMesh(GLMeshCacheEntry& cache); void GL11_DestroyMesh(GLMeshCacheEntry& cache);
void GL11_BeginFrame(const Matrix4x4* projection); void GL11_BeginFrame(const Matrix4x4* projection);

View File

@ -121,7 +121,7 @@ static int NextPowerOfTwo(int v)
return power; return power;
} }
static Uint32 UploadTextureData(SDL_Surface* src, bool useNPOT, bool isUi) static Uint32 UploadTextureData(SDL_Surface* src, bool useNPOT, bool isUI, float scaleX, float scaleY)
{ {
SDL_Surface* working = src; SDL_Surface* working = src;
if (src->format != SDL_PIXELFORMAT_RGBA32) { if (src->format != SDL_PIXELFORMAT_RGBA32) {
@ -168,14 +168,14 @@ static Uint32 UploadTextureData(SDL_Surface* src, bool useNPOT, bool isUi)
finalSurface = resized; finalSurface = resized;
} }
Uint32 texId = GL11_UploadTextureData(finalSurface->pixels, finalSurface->w, finalSurface->h, isUi); Uint32 texId = GL11_UploadTextureData(finalSurface->pixels, finalSurface->w, finalSurface->h, isUI, scaleX, scaleY);
if (finalSurface != src) { if (finalSurface != src) {
SDL_DestroySurface(finalSurface); SDL_DestroySurface(finalSurface);
} }
return texId; return texId;
} }
Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi) Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUI, float scaleX, float scaleY)
{ {
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture); auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface); auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface);
@ -185,7 +185,7 @@ Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi)
if (tex.texture == texture) { if (tex.texture == texture) {
if (tex.version != texture->m_version) { if (tex.version != texture->m_version) {
GL11_DestroyTexture(tex.glTextureId); GL11_DestroyTexture(tex.glTextureId);
tex.glTextureId = UploadTextureData(surface->m_surface, m_useNPOT, isUi); tex.glTextureId = UploadTextureData(surface->m_surface, m_useNPOT, isUI, scaleX, scaleY);
tex.version = texture->m_version; tex.version = texture->m_version;
tex.width = surface->m_surface->w; tex.width = surface->m_surface->w;
tex.height = surface->m_surface->h; tex.height = surface->m_surface->h;
@ -194,7 +194,7 @@ Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi)
} }
} }
GLuint texId = UploadTextureData(surface->m_surface, m_useNPOT, isUi); GLuint texId = UploadTextureData(surface->m_surface, m_useNPOT, isUI, scaleX, scaleY);
for (Uint32 i = 0; i < m_textures.size(); ++i) { for (Uint32 i = 0; i < m_textures.size(); ++i) {
auto& tex = m_textures[i]; auto& tex = m_textures[i];

View File

@ -321,7 +321,7 @@ void OpenGLES2Renderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture*
); );
} }
bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUi) bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUI)
{ {
SDL_Surface* surf = source; SDL_Surface* surf = source;
if (source->format != SDL_PIXELFORMAT_RGBA32) { if (source->format != SDL_PIXELFORMAT_RGBA32) {
@ -335,7 +335,7 @@ bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUi)
glBindTexture(GL_TEXTURE_2D, outTexId); glBindTexture(GL_TEXTURE_2D, outTexId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surf->w, surf->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surf->w, surf->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels);
if (isUi) { if (isUI) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@ -362,7 +362,7 @@ bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUi)
return true; return true;
} }
Uint32 OpenGLES2Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi) Uint32 OpenGLES2Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUI, float scaleX, float scaleY)
{ {
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture); auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface); auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface);
@ -372,7 +372,7 @@ Uint32 OpenGLES2Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi)
if (tex.texture == texture) { if (tex.texture == texture) {
if (tex.version != texture->m_version) { if (tex.version != texture->m_version) {
glDeleteTextures(1, &tex.glTextureId); glDeleteTextures(1, &tex.glTextureId);
if (UploadTexture(surface->m_surface, tex.glTextureId, isUi)) { if (UploadTexture(surface->m_surface, tex.glTextureId, isUI)) {
tex.version = texture->m_version; tex.version = texture->m_version;
} }
} }
@ -381,7 +381,7 @@ Uint32 OpenGLES2Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi)
} }
GLuint texId; GLuint texId;
if (!UploadTexture(surface->m_surface, texId, isUi)) { if (!UploadTexture(surface->m_surface, texId, isUI)) {
return NO_TEXTURE_ID; return NO_TEXTURE_ID;
} }

View File

@ -499,7 +499,7 @@ SDL_GPUTexture* Direct3DRMSDL3GPURenderer::CreateTextureFromSurface(SDL_Surface*
return texptr; return texptr;
} }
Uint32 Direct3DRMSDL3GPURenderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi) Uint32 Direct3DRMSDL3GPURenderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUI, float scaleX, float scaleY)
{ {
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture); auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface); auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface);

View File

@ -554,7 +554,7 @@ void Direct3DRMSoftwareRenderer::AddTextureDestroyCallback(Uint32 id, IDirect3DR
); );
} }
Uint32 Direct3DRMSoftwareRenderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi) Uint32 Direct3DRMSoftwareRenderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUI, float scaleX, float scaleY)
{ {
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture); auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface); auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface);

View File

@ -78,11 +78,13 @@ HRESULT FrameBufferImpl::Blt(
if (!surface) { if (!surface) {
return DDERR_GENERIC; return DDERR_GENERIC;
} }
Uint32 textureId = DDRenderer->GetTextureId(surface->ToTexture(), true);
SDL_Rect srcRect = SDL_Rect srcRect =
lpSrcRect ? ConvertRect(lpSrcRect) : SDL_Rect{0, 0, surface->m_surface->w, surface->m_surface->h}; lpSrcRect ? ConvertRect(lpSrcRect) : SDL_Rect{0, 0, surface->m_surface->w, surface->m_surface->h};
SDL_Rect dstRect = SDL_Rect dstRect =
lpDestRect ? ConvertRect(lpDestRect) : SDL_Rect{0, 0, (int) m_virtualWidth, (int) m_virtualHeight}; lpDestRect ? ConvertRect(lpDestRect) : SDL_Rect{0, 0, (int) m_virtualWidth, (int) m_virtualHeight};
float scaleX = (float) dstRect.w / (float) srcRect.w;
float scaleY = (float) dstRect.h / (float) srcRect.h;
Uint32 textureId = DDRenderer->GetTextureId(surface->ToTexture(), true, scaleX, scaleY);
DDRenderer->Draw2DImage(textureId, srcRect, dstRect, {1.0f, 1.0f, 1.0f, 1.0f}); DDRenderer->Draw2DImage(textureId, srcRect, dstRect, {1.0f, 1.0f, 1.0f, 1.0f});
return DD_OK; return DD_OK;

View File

@ -31,7 +31,7 @@ class Direct3DRMRenderer : public IDirect3DDevice2 {
virtual void PushLights(const SceneLight* vertices, size_t count) = 0; virtual void PushLights(const SceneLight* vertices, size_t count) = 0;
virtual void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) = 0; virtual void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) = 0;
virtual void SetFrustumPlanes(const Plane* frustumPlanes) = 0; virtual void SetFrustumPlanes(const Plane* frustumPlanes) = 0;
virtual Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUi = false) = 0; virtual Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUI = false, float scaleX = 0, float scaleY = 0) = 0;
virtual Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) = 0; virtual Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) = 0;
int GetWidth() { return m_width; } int GetWidth() { return m_width; }
int GetHeight() { return m_height; } int GetHeight() { return m_height; }

View File

@ -32,7 +32,7 @@ class Citro3DRenderer : public Direct3DRMRenderer {
void PushLights(const SceneLight* lightsArray, size_t count) override; void PushLights(const SceneLight* lightsArray, size_t count) override;
void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override; void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override;
void SetFrustumPlanes(const Plane* frustumPlanes) override; void SetFrustumPlanes(const Plane* frustumPlanes) override;
Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUi) override; Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUI, float scaleX, float scaleY) override;
Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override; Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override;
HRESULT BeginFrame() override; HRESULT BeginFrame() override;
void EnableTransparency() override; void EnableTransparency() override;

View File

@ -18,7 +18,7 @@ class DirectX9Renderer : public Direct3DRMRenderer {
void PushLights(const SceneLight* lightsArray, size_t count) override; void PushLights(const SceneLight* lightsArray, size_t count) override;
void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override; void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override;
void SetFrustumPlanes(const Plane* frustumPlanes) override; void SetFrustumPlanes(const Plane* frustumPlanes) override;
Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUi) override; Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUI, float scaleX, float scaleY) override;
Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override; Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override;
HRESULT BeginFrame() override; HRESULT BeginFrame() override;
void EnableTransparency() override; void EnableTransparency() override;

View File

@ -18,7 +18,7 @@ class OpenGL1Renderer : public Direct3DRMRenderer {
void PushLights(const SceneLight* lightsArray, size_t count) override; void PushLights(const SceneLight* lightsArray, size_t count) override;
void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override; void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override;
void SetFrustumPlanes(const Plane* frustumPlanes) override; void SetFrustumPlanes(const Plane* frustumPlanes) override;
Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUi) override; Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUI, float scaleX, float scaleY) override;
Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override; Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override;
HRESULT BeginFrame() override; HRESULT BeginFrame() override;
void EnableTransparency() override; void EnableTransparency() override;

View File

@ -39,7 +39,7 @@ class OpenGLES2Renderer : public Direct3DRMRenderer {
void PushLights(const SceneLight* lightsArray, size_t count) override; void PushLights(const SceneLight* lightsArray, size_t count) override;
void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override; void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override;
void SetFrustumPlanes(const Plane* frustumPlanes) override; void SetFrustumPlanes(const Plane* frustumPlanes) override;
Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUi) override; Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUI, float scaleX, float scaleY) override;
Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override; Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override;
HRESULT BeginFrame() override; HRESULT BeginFrame() override;
void EnableTransparency() override; void EnableTransparency() override;

View File

@ -47,7 +47,7 @@ class Direct3DRMSDL3GPURenderer : public Direct3DRMRenderer {
static Direct3DRMRenderer* Create(DWORD width, DWORD height); static Direct3DRMRenderer* Create(DWORD width, DWORD height);
~Direct3DRMSDL3GPURenderer() override; ~Direct3DRMSDL3GPURenderer() override;
void PushLights(const SceneLight* vertices, size_t count) override; void PushLights(const SceneLight* vertices, size_t count) override;
Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUi) override; Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUI, float scaleX, float scaleY) override;
Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override; Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override;
void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override; void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override;
void SetFrustumPlanes(const Plane* frustumPlanes) override; void SetFrustumPlanes(const Plane* frustumPlanes) override;

View File

@ -29,7 +29,7 @@ class Direct3DRMSoftwareRenderer : public Direct3DRMRenderer {
Direct3DRMSoftwareRenderer(DWORD width, DWORD height); Direct3DRMSoftwareRenderer(DWORD width, DWORD height);
~Direct3DRMSoftwareRenderer() override; ~Direct3DRMSoftwareRenderer() override;
void PushLights(const SceneLight* vertices, size_t count) override; void PushLights(const SceneLight* vertices, size_t count) override;
Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUi) override; Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUI, float scaleX, float scaleY) override;
Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override; Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override;
void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override; void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override;
void SetFrustumPlanes(const Plane* frustumPlanes) override; void SetFrustumPlanes(const Plane* frustumPlanes) override;