mirror of
https://github.com/isledecomp/isle.git
synced 2024-11-26 09:38:14 -05:00
Implement MxDisplaySurface::VTable0x44 (#467)
* Update mxdisplaysurface.cpp * add arguments to header * Fix glitched bitmaps * WIP fixes * Match * Fix * Changes * Fixes --------- Co-authored-by: Christian Semmler <mail@csemmler.com>
This commit is contained in:
parent
961282e3c6
commit
ea5f9b4886
2 changed files with 145 additions and 31 deletions
|
@ -80,10 +80,15 @@ class MxDisplaySurface : public MxCore {
|
||||||
MxS32 p_top2,
|
MxS32 p_top2,
|
||||||
MxS32 p_width,
|
MxS32 p_width,
|
||||||
MxS32 p_height
|
MxS32 p_height
|
||||||
); // vtable+0x38
|
); // vtable+0x38
|
||||||
virtual void GetDC(HDC* p_hdc); // vtable+0x3c
|
virtual void GetDC(HDC* p_hdc); // vtable+0x3c
|
||||||
virtual void ReleaseDC(HDC p_hdc); // vtable+0x40
|
virtual void ReleaseDC(HDC p_hdc); // vtable+0x40
|
||||||
virtual LPDIRECTDRAWSURFACE VTable0x44(MxBitmap*, undefined4*, undefined4, undefined4); // vtable+0x44
|
virtual LPDIRECTDRAWSURFACE VTable0x44(
|
||||||
|
MxBitmap* p_bitmap,
|
||||||
|
undefined4* p_ret,
|
||||||
|
undefined4 p_doNotWriteToSurface,
|
||||||
|
undefined4 p_transparent
|
||||||
|
); // vtable+0x44
|
||||||
|
|
||||||
void ClearScreen();
|
void ClearScreen();
|
||||||
static LPDIRECTDRAWSURFACE FUN_100bc070();
|
static LPDIRECTDRAWSURFACE FUN_100bc070();
|
||||||
|
|
|
@ -328,30 +328,7 @@ void MxDisplaySurface::VTable0x28(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hr == DD_OK) {
|
if (hr == DD_OK) {
|
||||||
MxU8* data;
|
MxU8* data = p_bitmap->GetStart(p_left, p_top);
|
||||||
|
|
||||||
switch (p_bitmap->GetBmiHeader()->biCompression) {
|
|
||||||
case BI_RGB: {
|
|
||||||
MxS32 rowsBeforeTop;
|
|
||||||
if (p_bitmap->GetBmiHeight() < 0)
|
|
||||||
rowsBeforeTop = p_top;
|
|
||||||
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()) {
|
if (m_videoParam.Flags().GetF1bit3()) {
|
||||||
p_bottom *= 2;
|
p_bottom *= 2;
|
||||||
|
@ -564,10 +541,142 @@ void MxDisplaySurface::ReleaseDC(HDC p_hdc)
|
||||||
this->m_ddSurface2->ReleaseDC(p_hdc);
|
this->m_ddSurface2->ReleaseDC(p_hdc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x100bbc60
|
// FUNCTION: LEGO1 0x100bbc60
|
||||||
LPDIRECTDRAWSURFACE MxDisplaySurface::VTable0x44(MxBitmap*, undefined4*, undefined4, undefined4)
|
LPDIRECTDRAWSURFACE MxDisplaySurface::VTable0x44(
|
||||||
|
MxBitmap* p_bitmap,
|
||||||
|
undefined4* p_ret,
|
||||||
|
undefined4 p_doNotWriteToSurface,
|
||||||
|
undefined4 p_transparent
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return NULL;
|
LPDIRECTDRAWSURFACE surface = NULL;
|
||||||
|
LPDIRECTDRAW draw = MVideoManager()->GetDirectDraw();
|
||||||
|
MVideoManager();
|
||||||
|
|
||||||
|
DDSURFACEDESC ddsd;
|
||||||
|
memset(&ddsd, 0, sizeof(ddsd));
|
||||||
|
ddsd.dwSize = sizeof(ddsd);
|
||||||
|
|
||||||
|
if (draw->GetDisplayMode(&ddsd))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
|
||||||
|
ddsd.dwWidth = p_bitmap->GetBmiWidth();
|
||||||
|
ddsd.dwHeight = p_bitmap->GetBmiHeightAbs();
|
||||||
|
|
||||||
|
*p_ret = 0;
|
||||||
|
ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
|
||||||
|
|
||||||
|
if (draw->CreateSurface(&ddsd, &surface, NULL) != S_OK) {
|
||||||
|
if (*p_ret) {
|
||||||
|
*p_ret = 0;
|
||||||
|
|
||||||
|
// Try creating bitmap surface in vram if system ram ran out
|
||||||
|
ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
|
||||||
|
ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
|
||||||
|
|
||||||
|
if (draw->CreateSurface(&ddsd, &surface, NULL) != S_OK) {
|
||||||
|
surface = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (surface) {
|
||||||
|
memset(&ddsd, 0, sizeof(ddsd));
|
||||||
|
ddsd.dwSize = sizeof(ddsd);
|
||||||
|
|
||||||
|
if (surface->Lock(NULL, &ddsd, DDLOCK_WAIT, 0) != S_OK) {
|
||||||
|
surface->Release();
|
||||||
|
surface = NULL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_doNotWriteToSurface) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
MxU8* bitmapSrcPtr = p_bitmap->GetStart(0, 0);
|
||||||
|
MxU16* surfaceData = (MxU16*) ddsd.lpSurface;
|
||||||
|
MxLong widthNormal = p_bitmap->GetBmiWidth();
|
||||||
|
MxLong heightAbs = p_bitmap->GetBmiHeightAbs();
|
||||||
|
|
||||||
|
// TODO: Probably p_bitmap->GetAdjustedStride()
|
||||||
|
MxS32 rowSeek = p_bitmap->GetBmiStride();
|
||||||
|
if (p_bitmap->GetBmiHeader()->biCompression != BI_RGB_TOPDOWN && p_bitmap->GetBmiHeight() >= 0)
|
||||||
|
rowSeek = -rowSeek;
|
||||||
|
|
||||||
|
MxLong newPitch = ddsd.lPitch;
|
||||||
|
switch (ddsd.ddpfPixelFormat.dwRGBBitCount) {
|
||||||
|
case 8: {
|
||||||
|
for (MxS32 y = heightAbs; y > 0; y--) {
|
||||||
|
memcpy(surfaceData, bitmapSrcPtr, p_bitmap->GetBmiHeight());
|
||||||
|
bitmapSrcPtr += rowSeek;
|
||||||
|
surfaceData = (MxU16*) ((MxU8*) surfaceData + newPitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
surface->Unlock(ddsd.lpSurface);
|
||||||
|
|
||||||
|
if (p_transparent && surface) {
|
||||||
|
DDCOLORKEY key;
|
||||||
|
key.dwColorSpaceHighValue = 0;
|
||||||
|
key.dwColorSpaceLowValue = 0;
|
||||||
|
surface->SetColorKey(DDCKEY_SRCBLT, &key);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 16:
|
||||||
|
if (m_16bitPal == NULL) {
|
||||||
|
if (surface) {
|
||||||
|
surface->Release();
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rowSeek -= p_bitmap->GetBmiWidth();
|
||||||
|
newPitch -= 2 * p_bitmap->GetBmiWidth();
|
||||||
|
|
||||||
|
if (p_transparent) {
|
||||||
|
for (MxS32 y = heightAbs; y > 0; y--) {
|
||||||
|
for (MxS32 x = widthNormal; x > 0; x--) {
|
||||||
|
if (*bitmapSrcPtr) {
|
||||||
|
*surfaceData = m_16bitPal[*bitmapSrcPtr];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*surfaceData = 31775;
|
||||||
|
}
|
||||||
|
bitmapSrcPtr++;
|
||||||
|
surfaceData++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmapSrcPtr += rowSeek;
|
||||||
|
surfaceData = (MxU16*) ((MxU8*) surfaceData + newPitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
DDCOLORKEY key;
|
||||||
|
key.dwColorSpaceHighValue = 31775;
|
||||||
|
key.dwColorSpaceLowValue = 31775;
|
||||||
|
surface->SetColorKey(DDCKEY_SRCBLT, &key);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (MxS32 y = heightAbs; y > 0; y--) {
|
||||||
|
for (MxS32 x = widthNormal; x > 0; x--) {
|
||||||
|
*surfaceData++ = m_16bitPal[*bitmapSrcPtr++];
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmapSrcPtr += rowSeek;
|
||||||
|
surfaceData = (MxU16*) ((MxU8*) surfaceData + newPitch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
surface->Unlock(ddsd.lpSurface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x100bc070
|
// STUB: LEGO1 0x100bc070
|
||||||
|
|
Loading…
Reference in a new issue