This commit is contained in:
Christian Semmler 2023-12-30 15:27:07 -05:00
parent bb22b21260
commit eb1c1eb691
2 changed files with 216 additions and 16 deletions

View File

@ -1,6 +1,6 @@
#include "mxdisplaysurface.h" #include "mxdisplaysurface.h"
#include "mxomni.h" #include "legoomni.h"
#include "mxvideomanager.h" #include "mxvideomanager.h"
DECOMP_SIZE_ASSERT(MxDisplaySurface, 0xac); DECOMP_SIZE_ASSERT(MxDisplaySurface, 0xac);
@ -54,7 +54,7 @@ void MxDisplaySurface::FUN_100ba640()
hr = m_ddSurface2->Lock(NULL, &desc, DDLOCK_WAIT, NULL); hr = m_ddSurface2->Lock(NULL, &desc, DDLOCK_WAIT, NULL);
} }
if (hr != S_OK) { if (hr != DD_OK) {
return; return;
} }
@ -68,7 +68,7 @@ void MxDisplaySurface::FUN_100ba640()
m_ddSurface2->Unlock(desc.lpSurface); m_ddSurface2->Unlock(desc.lpSurface);
if (m_videoParam.Flags().GetFlipSurfaces()) { if (m_videoParam.Flags().GetFlipSurfaces()) {
m_ddSurface1->Flip(NULL, 1); m_ddSurface1->Flip(NULL, DDFLIP_WAIT);
} }
} }
} }
@ -223,18 +223,218 @@ void MxDisplaySurface::SetPalette(MxPalette* p_palette)
{ {
} }
// STUB: LEGO1 0x100bacc0 // FUNCTION: LEGO1 0x100bacc0
MxBool MxDisplaySurface::VTable0x28( void MxDisplaySurface::VTable0x28(
MxBitmap* p_bitmap, MxBitmap* p_bitmap, // a2
MxS32 p_left, MxS32 p_left, // a3
MxS32 p_top, MxS32 p_top, // a4
MxS32 p_right, MxS32 p_right, // a5
MxS32 p_bottom, MxS32 p_bottom, // a6
MxS32 p_width, MxS32 p_width, // a7
MxS32 p_height MxS32 p_height // a8
) )
{ {
return 0; if (FUN_100b6e10(
p_bitmap->GetBmiWidth(),
p_bitmap->GetBmiHeightAbs(),
m_videoParam.GetRect().GetWidth(),
m_videoParam.GetRect().GetHeight(),
&p_left,
&p_top,
&p_right,
&p_bottom,
&p_width,
&p_height
)) {
DDSURFACEDESC ddsd;
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
HRESULT hr = m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
if (hr == DDERR_SURFACELOST) {
m_ddSurface2->Restore();
hr = m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
}
if (hr == DD_OK) {
BITMAPINFOHEADER* biHeader = p_bitmap->GetBmiHeader();
MxU8* data;
switch (biHeader->biCompression) {
case BI_RGB: {
MxS32 rowsBeforeTop;
if (p_bitmap->GetBmiHeight() < 0)
rowsBeforeTop = 0;
else
rowsBeforeTop = p_bitmap->GetBmiHeightAbs() - p_top - 1;
data = p_bitmap->GetBitmapData() + p_left + (p_bitmap->GetBmiStride() * rowsBeforeTop);
break;
}
case BI_RGB_TOPDOWN:
data = p_bitmap->GetBitmapData();
break;
default: {
MxS32 rowsBeforeTop;
if (p_bitmap->GetBmiHeight() < 0)
rowsBeforeTop = 0;
else
rowsBeforeTop = p_bitmap->GetBmiHeightAbs() - 1;
data = p_bitmap->GetBitmapData() + (p_bitmap->GetBmiStride() * rowsBeforeTop);
}
}
if (m_videoParam.Flags().GetF1bit3()) {
p_bottom *= 2;
p_right *= 2;
switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) {
case 8: {
OutputDebugStr("Flag, Case 8bit");
MxU8* surface = (MxU8*) ddsd.lpSurface + p_right + (p_bottom * ddsd.lPitch);
MxLong stride;
if (biHeader->biCompression == BI_RGB_TOPDOWN || p_bitmap->GetBmiHeight() < 0)
stride = p_bitmap->GetBmiStride();
else
stride = -p_bitmap->GetBmiStride();
MxLong v22 = stride - p_width;
MxLong v55 = ddsd.lPitch - (2 * p_width);
while (p_height--) {
MxU8* surfaceBefore = surface;
for (MxS32 i = 0; p_width > i; *(surface - 1) = *(data - 1)) {
MxU8 element = *data++;
surface += 2;
++i;
*(surface - 2) = element;
}
data += v22;
MxU8* dest = surface + v55;
memcpy(dest, surfaceBefore, 2 * p_width);
surface = dest + ddsd.lPitch;
}
break;
}
case 16: {
MxU8* surface = (MxU8*) ddsd.lpSurface + (2 * p_right) + (p_bottom * ddsd.lPitch);
MxLong stride;
if (biHeader->biCompression == BI_RGB_TOPDOWN || p_bitmap->GetBmiHeight() < 0)
stride = p_bitmap->GetBmiStride();
else
stride = -p_bitmap->GetBmiStride();
MxLong v31 = 4 * p_width;
MxLong v56 = stride - p_width;
MxS32 v61 = p_width;
MxLong v62 = ddsd.lPitch - (4 * p_width);
MxU16* p16BitPal = m_16bitPal;
if (stride != p_width || v62) {
OutputDebugStr("Flag, Case 16bit A");
while (p_height--) {
MxU8* surfaceBefore = surface;
if (v61 > 0) {
MxS32 v38 = v61;
do {
MxU32 element = *data++;
element = p16BitPal[element];
surface += 4;
*((MxU16*) surface - 2) = element;
--v38;
*((MxU16*) surface - 2) = element;
} while (v38);
}
data += v56;
MxU8* dest = &surface[v62];
memcpy(dest, surfaceBefore, 4 * ((MxU32) (4 * p_width) >> 2));
surface = dest + ddsd.lPitch;
}
}
else {
OutputDebugStr("Flag, Case 16bit B");
while (p_height--) {
MxU8* surfaceBefore = surface;
if (v61 > 0) {
MxS32 v34 = v61;
do {
MxU32 element = *data++;
element = p16BitPal[element];
surface += 4;
*((MxU16*) surface - 2) = element;
--v34;
*((MxU16*) surface - 2) = element;
} while (v34);
}
memcpy(surface, surfaceBefore, v31);
surface += ddsd.lPitch;
}
}
}
}
}
else {
switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) {
case 8: {
OutputDebugStr("No flag, Case 8bit");
MxU8* surface = (MxU8*) ddsd.lpSurface + p_right + (p_bottom * ddsd.lPitch);
MxLong stride;
if (biHeader->biCompression == BI_RGB_TOPDOWN || p_bitmap->GetBmiHeight() < 0)
stride = p_bitmap->GetBmiStride();
else
stride = -p_bitmap->GetBmiStride();
MxLong v57 = ddsd.lPitch;
while (p_height--) {
MxU8* prevData = data;
data += stride;
memcpy(surface, prevData, p_width);
surface += v57;
}
break;
}
case 16: {
OutputDebugStr("No flag, Case 16bit");
MxU8* surface = (MxU8*) ddsd.lpSurface + (2 * p_right) + (p_bottom * ddsd.lPitch);
MxLong stride;
if (biHeader->biCompression == BI_RGB_TOPDOWN || p_bitmap->GetBmiHeight() < 0)
stride = p_bitmap->GetBmiStride();
else
stride = -p_bitmap->GetBmiStride();
MxLong v50 = stride - p_width;
MxLong j = ddsd.lPitch - (2 * p_width);
for (MxU32 v51 = 0; p_height > v51; v51++) {
for (MxU32 k = 0; p_width > k; k++) {
MxU8 v53 = *data++;
surface += 2;
//*(MxU16*) (surface - 2) = *(MxU16*) (*(MxU32*) (&m_16bitPal) + 2 * v53);
*(MxU16*) (surface - 2) = m_16bitPal[v53];
}
data += v50;
surface += j;
}
}
}
}
m_ddSurface2->Unlock(ddsd.lpSurface);
}
}
} }
// STUB: LEGO1 0x100bb1d0 // STUB: LEGO1 0x100bb1d0
@ -269,7 +469,7 @@ void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p
DDSURFACEDESC ddsd; DDSURFACEDESC ddsd;
memset(&ddsd, 0, sizeof(ddsd)); memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd); ddsd.dwSize = sizeof(ddsd);
if (m_ddSurface2->Lock(NULL, &ddsd, 1, NULL) == S_OK) { if (m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) == DD_OK) {
MxU8* surface = (MxU8*) ddsd.lpSurface; MxU8* surface = (MxU8*) ddsd.lpSurface;
MxS32 height = m_videoParam.GetRect().GetHeight(); MxS32 height = m_videoParam.GetRect().GetHeight();
@ -284,7 +484,7 @@ void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p
OutputDebugString("MxDisplaySurface::Display error\n"); OutputDebugString("MxDisplaySurface::Display error\n");
} }
} }
m_ddSurface1->Flip(NULL, 1); m_ddSurface1->Flip(NULL, DDFLIP_WAIT);
} }
else { else {
POINT point = {0, 0}; POINT point = {0, 0};

View File

@ -35,7 +35,7 @@ class MxDisplaySurface : public MxCore {
undefined4, undefined4,
undefined4 undefined4
); // vtable+0x24 ); // vtable+0x24
virtual MxBool VTable0x28( virtual void VTable0x28(
MxBitmap* p_bitmap, MxBitmap* p_bitmap,
MxS32 p_left, MxS32 p_left,
MxS32 p_top, MxS32 p_top,