diff --git a/LEGO1/omni/include/mxbitmap.h b/LEGO1/omni/include/mxbitmap.h index e0056957..e2fbaf59 100644 --- a/LEGO1/omni/include/mxbitmap.h +++ b/LEGO1/omni/include/mxbitmap.h @@ -94,6 +94,7 @@ class MxBitmap : public MxCore { // FUNCTION: BETA10 0x1002c690 static MxLong HeightAbs(MxLong p_value) { return p_value > 0 ? p_value : -p_value; } + // FUNCTION: BETA10 0x10142030 inline BITMAPINFOHEADER* GetBmiHeader() const { return m_bmiHeader; } // FUNCTION: BETA10 0x1002c440 @@ -124,15 +125,9 @@ class MxBitmap : public MxCore { } } - inline MxLong GetAdjustedStride() - { - if (m_bmiHeader->biCompression == BI_RGB_TOPDOWN || m_bmiHeader->biHeight < 0) { - return GetBmiStride(); - } - else { - return -GetBmiStride(); - } - } +#define GetAdjustedStride(p_bitmap) \ + (p_bitmap->IsTopDown() ? p_bitmap->AlignToFourByte(p_bitmap->GetBmiWidth()) \ + : -p_bitmap->AlignToFourByte(p_bitmap->GetBmiWidth())) // FUNCTION: BETA10 0x1002c320 inline MxU8* GetStart(MxS32 p_left, MxS32 p_top) diff --git a/LEGO1/omni/include/mxdisplaysurface.h b/LEGO1/omni/include/mxdisplaysurface.h index 2ec14784..92e23cb2 100644 --- a/LEGO1/omni/include/mxdisplaysurface.h +++ b/LEGO1/omni/include/mxdisplaysurface.h @@ -95,11 +95,11 @@ class MxDisplaySurface : public MxCore { static LPDIRECTDRAWSURFACE CreateCursorSurface(); static LPDIRECTDRAWSURFACE CopySurface(LPDIRECTDRAWSURFACE p_src); - inline LPDIRECTDRAWSURFACE GetDirectDrawSurface1() { return this->m_ddSurface1; } - inline LPDIRECTDRAWSURFACE GetDirectDrawSurface2() { return this->m_ddSurface2; } - inline MxVideoParam& GetVideoParam() { return this->m_videoParam; } + inline LPDIRECTDRAWSURFACE GetDirectDrawSurface1() { return m_ddSurface1; } + inline LPDIRECTDRAWSURFACE GetDirectDrawSurface2() { return m_ddSurface2; } + inline MxVideoParam& GetVideoParam() { return m_videoParam; } - static void FUN_100bb500( + void FUN_100bb500( MxU8** p_bitmapData, MxU8** p_surfaceData, MxU32 p_bitmapSize, diff --git a/LEGO1/omni/src/video/mxbitmap.cpp b/LEGO1/omni/src/video/mxbitmap.cpp index 88295b21..d914d7fa 100644 --- a/LEGO1/omni/src/video/mxbitmap.cpp +++ b/LEGO1/omni/src/video/mxbitmap.cpp @@ -274,14 +274,11 @@ void MxBitmap::BitBlt( MxS32 p_height ) { - MxLong dstHeight = GetBmiHeightAbs(); - MxLong srcHeight = p_src->GetBmiHeightAbs(); - - if (GetRectIntersection( + if (!GetRectIntersection( p_src->GetBmiWidth(), - srcHeight, + p_src->GetBmiHeightAbs(), GetBmiWidth(), - dstHeight, + GetBmiHeightAbs(), &p_srcLeft, &p_srcTop, &p_dstLeft, @@ -289,16 +286,18 @@ void MxBitmap::BitBlt( &p_width, &p_height )) { - MxU8* srcStart = p_src->GetStart(p_srcLeft, p_srcTop); - MxU8* dstStart = GetStart(p_dstLeft, p_dstTop); - MxLong srcStride = p_src->GetAdjustedStride(); - MxLong dstStride = GetAdjustedStride(); + return; + } - while (p_height--) { - memcpy(dstStart, srcStart, p_width); - dstStart += dstStride; - srcStart += srcStride; - } + MxU8* srcStart = p_src->GetStart(p_srcLeft, p_srcTop); + MxU8* dstStart = GetStart(p_dstLeft, p_dstTop); + MxLong srcStride = GetAdjustedStride(p_src); + MxLong dstStride = GetAdjustedStride(this); + + while (p_height--) { + memcpy(dstStart, srcStart, p_width); + dstStart += dstStride; + srcStart += srcStride; } } @@ -314,14 +313,11 @@ void MxBitmap::BitBltTransparent( MxS32 p_height ) { - MxLong dstHeight = GetBmiHeightAbs(); - MxLong srcHeight = p_src->GetBmiHeightAbs(); - - if (GetRectIntersection( + if (!GetRectIntersection( p_src->GetBmiWidth(), - srcHeight, + p_src->GetBmiHeightAbs(), GetBmiWidth(), - dstHeight, + GetBmiHeightAbs(), &p_srcLeft, &p_srcTop, &p_dstLeft, @@ -329,23 +325,25 @@ void MxBitmap::BitBltTransparent( &p_width, &p_height )) { - MxU8* srcStart = p_src->GetStart(p_srcLeft, p_srcTop); - MxU8* dstStart = GetStart(p_dstLeft, p_dstTop); - MxLong srcStride = p_src->GetAdjustedStride() - p_width; - MxLong dstStride = GetAdjustedStride() - p_width; + return; + } - for (MxS32 h = 0; h < p_height; h++) { - for (MxS32 w = 0; w < p_width; w++) { - if (*srcStart) { - *dstStart = *srcStart; - } - srcStart++; - dstStart++; + MxU8* srcStart = p_src->GetStart(p_srcLeft, p_srcTop); + MxU8* dstStart = GetStart(p_dstLeft, p_dstTop); + MxLong srcStride = -p_width + GetAdjustedStride(p_src); + MxLong dstStride = -p_width + GetAdjustedStride(this); + + for (MxS32 h = 0; h < p_height; h++) { + for (MxS32 w = 0; w < p_width; w++) { + if (*srcStart) { + *dstStart = *srcStart; } - - srcStart += srcStride; - dstStart += dstStride; + srcStart++; + dstStart++; } + + srcStart += srcStride; + dstStart += dstStride; } } diff --git a/LEGO1/omni/src/video/mxdisplaysurface.cpp b/LEGO1/omni/src/video/mxdisplaysurface.cpp index 6f3fbe0e..de78aadb 100644 --- a/LEGO1/omni/src/video/mxdisplaysurface.cpp +++ b/LEGO1/omni/src/video/mxdisplaysurface.cpp @@ -7,6 +7,7 @@ #include "mxutilities.h" #include "mxvideomanager.h" +#include #include DECOMP_SIZE_ASSERT(MxDisplaySurface, 0xac); @@ -17,24 +18,24 @@ MxU32 g_unk0x1010215c = 0; // FUNCTION: LEGO1 0x100ba500 MxDisplaySurface::MxDisplaySurface() { - this->Init(); + Init(); } // FUNCTION: LEGO1 0x100ba5a0 MxDisplaySurface::~MxDisplaySurface() { - this->Destroy(); + Destroy(); } // FUNCTION: LEGO1 0x100ba610 void MxDisplaySurface::Init() { - this->m_ddSurface1 = NULL; - this->m_ddSurface2 = NULL; - this->m_ddClipper = NULL; - this->m_16bitPal = NULL; - this->m_initialized = FALSE; - memset(&this->m_surfaceDesc, 0, sizeof(this->m_surfaceDesc)); + m_ddSurface1 = NULL; + m_ddSurface2 = NULL; + m_ddClipper = NULL; + m_16bitPal = NULL; + m_initialized = FALSE; + memset(&m_surfaceDesc, 0, sizeof(m_surfaceDesc)); } // FUNCTION: LEGO1 0x100ba640 @@ -114,16 +115,16 @@ MxResult MxDisplaySurface::Init( { MxResult result = SUCCESS; - this->m_videoParam = p_videoParam; - this->m_ddSurface1 = p_ddSurface1; - this->m_ddSurface2 = p_ddSurface2; - this->m_ddClipper = p_ddClipper; - this->m_initialized = FALSE; + m_videoParam = p_videoParam; + m_ddSurface1 = p_ddSurface1; + m_ddSurface2 = p_ddSurface2; + m_ddClipper = p_ddClipper; + m_initialized = FALSE; - memset(&this->m_surfaceDesc, 0, sizeof(this->m_surfaceDesc)); - this->m_surfaceDesc.dwSize = sizeof(this->m_surfaceDesc); + memset(&m_surfaceDesc, 0, sizeof(m_surfaceDesc)); + m_surfaceDesc.dwSize = sizeof(m_surfaceDesc); - if (this->m_ddSurface2->GetSurfaceDesc(&this->m_surfaceDesc)) { + if (m_ddSurface2->GetSurfaceDesc(&m_surfaceDesc)) { result = FAILURE; } @@ -138,32 +139,32 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam) LPDIRECTDRAW lpDirectDraw = MVideoManager()->GetDirectDraw(); HWND hWnd = MxOmni::GetInstance()->GetWindowHandle(); - this->m_initialized = TRUE; - this->m_videoParam = p_videoParam; + m_initialized = TRUE; + m_videoParam = p_videoParam; - if (!this->m_videoParam.Flags().GetFullScreen()) { - this->m_videoParam.Flags().SetFlipSurfaces(FALSE); + if (!m_videoParam.Flags().GetFullScreen()) { + m_videoParam.Flags().SetFlipSurfaces(FALSE); } - if (!this->m_videoParam.Flags().GetFlipSurfaces()) { - this->m_videoParam.SetBackBuffers(1); + if (!m_videoParam.Flags().GetFlipSurfaces()) { + m_videoParam.SetBackBuffers(1); } else { - MxU32 backBuffers = this->m_videoParam.GetBackBuffers(); + MxU32 backBuffers = m_videoParam.GetBackBuffers(); if (backBuffers < 1) { - this->m_videoParam.SetBackBuffers(1); + m_videoParam.SetBackBuffers(1); } else if (backBuffers > 2) { - this->m_videoParam.SetBackBuffers(2); + m_videoParam.SetBackBuffers(2); } - this->m_videoParam.Flags().SetBackBuffers(TRUE); + m_videoParam.Flags().SetBackBuffers(TRUE); } - if (this->m_videoParam.Flags().GetFullScreen()) { - MxS32 width = this->m_videoParam.GetRect().GetWidth(); - MxS32 height = this->m_videoParam.GetRect().GetHeight(); + if (m_videoParam.Flags().GetFullScreen()) { + MxS32 width = m_videoParam.GetRect().GetWidth(); + MxS32 height = m_videoParam.GetRect().GetHeight(); if (lpDirectDraw->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN)) { goto done; @@ -176,7 +177,7 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam) goto done; } - MxS32 bitdepth = !this->m_videoParam.Flags().Get16Bit() ? 8 : 16; + MxS32 bitdepth = !m_videoParam.Flags().Get16Bit() ? 8 : 16; if (ddsd.dwWidth != width || ddsd.dwHeight != height || ddsd.ddpfPixelFormat.dwRGBBitCount != bitdepth) { if (lpDirectDraw->SetDisplayMode(width, height, bitdepth)) { @@ -185,20 +186,20 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam) } } - if (this->m_videoParam.Flags().GetFlipSurfaces()) { + if (m_videoParam.Flags().GetFlipSurfaces()) { memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); - ddsd.dwBackBufferCount = this->m_videoParam.GetBackBuffers(); + ddsd.dwBackBufferCount = m_videoParam.GetBackBuffers(); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; - if (lpDirectDraw->CreateSurface(&ddsd, &this->m_ddSurface1, NULL)) { + if (lpDirectDraw->CreateSurface(&ddsd, &m_ddSurface1, NULL)) { goto done; } ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; - if (this->m_ddSurface1->GetAttachedSurface(&ddsd.ddsCaps, &this->m_ddSurface2)) { + if (m_ddSurface1->GetAttachedSurface(&ddsd.ddsCaps, &m_ddSurface2)) { goto done; } } @@ -208,32 +209,32 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam) ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - if (lpDirectDraw->CreateSurface(&ddsd, &this->m_ddSurface1, NULL)) { + if (lpDirectDraw->CreateSurface(&ddsd, &m_ddSurface1, NULL)) { goto done; } memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS; - ddsd.dwWidth = this->m_videoParam.GetRect().GetWidth(); - ddsd.dwHeight = this->m_videoParam.GetRect().GetHeight(); + ddsd.dwWidth = m_videoParam.GetRect().GetWidth(); + ddsd.dwHeight = m_videoParam.GetRect().GetHeight(); ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN; - if (!this->m_videoParam.Flags().GetBackBuffers()) { + if (!m_videoParam.Flags().GetBackBuffers()) { ddsd.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN; } - if (lpDirectDraw->CreateSurface(&ddsd, &this->m_ddSurface2, NULL)) { + if (lpDirectDraw->CreateSurface(&ddsd, &m_ddSurface2, NULL)) { goto done; } } - memset(&this->m_surfaceDesc, 0, sizeof(this->m_surfaceDesc)); - this->m_surfaceDesc.dwSize = sizeof(this->m_surfaceDesc); + memset(&m_surfaceDesc, 0, sizeof(m_surfaceDesc)); + m_surfaceDesc.dwSize = sizeof(m_surfaceDesc); - if (!this->m_ddSurface2->GetSurfaceDesc(&this->m_surfaceDesc)) { - if (!lpDirectDraw->CreateClipper(0, &this->m_ddClipper, NULL) && !this->m_ddClipper->SetHWnd(0, hWnd) && - !this->m_ddSurface1->SetClipper(this->m_ddClipper)) { + if (!m_ddSurface2->GetSurfaceDesc(&m_surfaceDesc)) { + if (!lpDirectDraw->CreateClipper(0, &m_ddClipper, NULL) && !m_ddClipper->SetHWnd(0, hWnd) && + !m_ddSurface1->SetClipper(m_ddClipper)) { result = SUCCESS; } } @@ -245,25 +246,25 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam) // FUNCTION: LEGO1 0x100baa90 void MxDisplaySurface::Destroy() { - if (this->m_initialized) { - if (this->m_ddSurface2) { - this->m_ddSurface2->Release(); + if (m_initialized) { + if (m_ddSurface2) { + m_ddSurface2->Release(); } - if (this->m_ddSurface1) { - this->m_ddSurface1->Release(); + if (m_ddSurface1) { + m_ddSurface1->Release(); } - if (this->m_ddClipper) { - this->m_ddClipper->Release(); + if (m_ddClipper) { + m_ddClipper->Release(); } } - if (this->m_16bitPal) { - delete[] this->m_16bitPal; + if (m_16bitPal) { + delete[] m_16bitPal; } - this->Init(); + Init(); } // FUNCTION: LEGO1 0x100baae0 @@ -319,6 +320,7 @@ void MxDisplaySurface::SetPalette(MxPalette* p_palette) } // FUNCTION: LEGO1 0x100bacc0 +// FUNCTION: BETA10 0x1014012b void MxDisplaySurface::VTable0x28( MxBitmap* p_bitmap, MxS32 p_left, @@ -329,7 +331,7 @@ void MxDisplaySurface::VTable0x28( MxS32 p_height ) { - if (GetRectIntersection( + if (!GetRectIntersection( p_bitmap->GetBmiWidth(), p_bitmap->GetBmiHeightAbs(), m_videoParam.GetRect().GetWidth(), @@ -341,138 +343,146 @@ void MxDisplaySurface::VTable0x28( &p_width, &p_height )) { - DDSURFACEDESC ddsd; - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); + return; + } + 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); + 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) { + return; + } + + MxU8* data = p_bitmap->GetStart(p_left, p_top); + + if (m_videoParam.Flags().GetF1bit3()) { + p_bottom *= 2; + p_right *= 2; + + switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) { + case 8: { + MxU8* surface = (MxU8*) ddsd.lpSurface + p_right + (p_bottom * ddsd.lPitch); + MxLong stride = -p_width + GetAdjustedStride(p_bitmap); + + MxLong length = -2 * p_width + ddsd.lPitch; + while (p_height--) { + MxU8* surfaceBefore = surface; + + for (MxS32 i = 0; p_width > i; i++) { + *surface++ = *data; + *surface++ = *data++; + } + + data += stride; + surface += length; + + memcpy(surface, surfaceBefore, 2 * p_width); + surface += ddsd.lPitch; + } + break; } + case 16: { + MxU8* surface = (MxU8*) ddsd.lpSurface + (2 * p_right) + (p_bottom * ddsd.lPitch); + MxLong stride = -p_width + GetAdjustedStride(p_bitmap); - if (hr == DD_OK) { - MxU8* data = p_bitmap->GetStart(p_left, p_top); + MxS32 length = -4 * p_width + ddsd.lPitch; + MxS32 height = p_height; + MxS32 width = p_width; + MxS32 copyWidth = width * 4; + MxU16* p16bitPal = m_16bitPal; - if (m_videoParam.Flags().GetF1bit3()) { - p_bottom *= 2; - p_right *= 2; + MxS32 i; + if (stride || length) { + while (height--) { + MxU8* surfaceBefore = surface; - switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) { - case 8: { - MxU8* surface = (MxU8*) ddsd.lpSurface + p_right + (p_bottom * ddsd.lPitch); - MxLong stride = p_bitmap->GetAdjustedStride(); + for (i = 0; i < width; i++) { + MxU16 element = p16bitPal[*data]; + *(MxU16*) surface = element; + surface += 2; + *(MxU16*) surface = element; - MxLong v22 = stride - p_width; - MxLong length = ddsd.lPitch - (2 * p_width); - while (p_height--) { - MxU8* surfaceBefore = surface; - - for (MxS32 i = 0; p_width > i; i++) { - MxU8 element = *data; - *surface++ = element; - data++; - *surface++ = *(data - 1); - } - - data += v22; - surface += length; - - memcpy(surface, surfaceBefore, 2 * p_width); - surface += ddsd.lPitch; + data++; + surface += 2; } - break; - } - case 16: { - MxU8* surface = (MxU8*) ddsd.lpSurface + (2 * p_right) + (p_bottom * ddsd.lPitch); - MxLong stride = p_bitmap->GetAdjustedStride(); - // TODO: Match - stride -= p_width; - MxS32 length = p_width * 4; - MxLong v62 = ddsd.lPitch - length; - MxS32 height = p_height; - MxS32 width = p_width; - MxU16* p16BitPal = m_16bitPal; - - if (stride || v62) { - while (height--) { - MxU8* surfaceBefore = surface; - - for (MxS32 i = width; i > 0; i--) { - MxU16 element = p16BitPal[*data++]; - *(MxU16*) surface = element; - surface += 2; - *(MxU16*) surface = element; - surface += 2; - } - - data += stride; - surface += v62; - - // Odd expression for the length? - memcpy(surface, surfaceBefore, 4 * ((MxU32) (4 * p_width) / 4)); - surface += ddsd.lPitch; - } - } - else { - while (height--) { - MxU8* surfaceBefore = surface; - - for (MxS32 i = width; i > 0; i--) { - MxU16 element = p16BitPal[*data++]; - *(MxU16*) surface = element; - surface += 2; - *(MxU16*) surface = element; - surface += 2; - } - - memcpy(surface, surfaceBefore, length); - surface += ddsd.lPitch; - } - } - } + memcpy(surface, surfaceBefore, copyWidth); + surface += ddsd.lPitch; } } else { - switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) { - case 8: { - MxU8* surface = (MxU8*) ddsd.lpSurface + p_right + (p_bottom * ddsd.lPitch); - MxLong stride = p_bitmap->GetAdjustedStride(); + while (height--) { + MxU8* surfaceBefore = surface; - MxLong length = ddsd.lPitch; - while (p_height--) { - memcpy(surface, data, p_width); - data += stride; - surface += length; + for (i = 0; i < width; i++) { + MxU16 element = p16bitPal[*data]; + *(MxU16*) surface = element; + surface += 2; + *(MxU16*) surface = element; + + data++; + surface += 2; } - break; - } - case 16: { - MxU8* surface = (MxU8*) ddsd.lpSurface + (2 * p_right) + (p_bottom * ddsd.lPitch); - MxLong stride = p_bitmap->GetAdjustedStride(); - MxLong v50 = stride - p_width; - MxLong length = ddsd.lPitch - (2 * p_width); - for (MxS32 i = 0; p_height > i; i++) { - for (MxS32 j = 0; p_width > j; j++) { - *(MxU16*) surface = m_16bitPal[*data++]; - surface += 2; - } + data += stride; + surface += length; - data += v50; - surface += length; - } - } + memcpy(surface, surfaceBefore, p_width * 4); + surface += ddsd.lPitch; } } - - m_ddSurface2->Unlock(ddsd.lpSurface); + break; + } + default: + break; } } + else { + switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) { + case 8: { + MxU8* surface = (MxU8*) ddsd.lpSurface + p_right + (p_bottom * ddsd.lPitch); + MxLong stride = GetAdjustedStride(p_bitmap); + + MxLong length = ddsd.lPitch; + while (p_height--) { + memcpy(surface, data, p_width); + data += stride; + surface += length; + } + break; + } + case 16: { + MxU8* surface = (MxU8*) ddsd.lpSurface + (2 * p_right) + (p_bottom * ddsd.lPitch); + MxLong stride = -p_width + GetAdjustedStride(p_bitmap); + + MxLong length = -2 * p_width + ddsd.lPitch; + for (MxS32 i = 0; i < p_height; i++) { + for (MxS32 j = 0; j < p_width; j++) { + *(MxU16*) surface = m_16bitPal[*data++]; + surface += 2; + } + + data += stride; + surface += length; + } + break; + } + default: + break; + } + } + + m_ddSurface2->Unlock(ddsd.lpSurface); } // FUNCTION: LEGO1 0x100bb1d0 +// FUNCTION: BETA10 0x1014088e void MxDisplaySurface::VTable0x30( MxBitmap* p_bitmap, MxS32 p_left, @@ -484,7 +494,7 @@ void MxDisplaySurface::VTable0x30( MxBool p_und ) { - if (GetRectIntersection( + if (!GetRectIntersection( p_bitmap->GetBmiWidth(), p_bitmap->GetBmiHeightAbs(), m_videoParam.GetRect().GetWidth(), @@ -496,92 +506,86 @@ void MxDisplaySurface::VTable0x30( &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) { - MxU8* data = p_bitmap->GetStart(p_left, p_top); - - switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) { - case 8: { - MxU8* surface = (MxU8*) ddsd.lpSurface + p_right + (p_bottom * ddsd.lPitch); - if (p_und) { - FUN_100bb500( - &data, - &surface, - p_bitmap->GetBmiHeader()->biSizeImage, - p_width, - p_height, - ddsd.lPitch, - 8 - ); - } - else { - MxLong stride = p_bitmap->GetAdjustedStride(); - - MxLong length = ddsd.lPitch; - for (MxS32 i = 0; p_height > i; i++) { - for (MxS32 j = 0; p_width > j; j++) { - if (*data != 0) { - *(MxU8*) surface = *data; - } - data++; - surface++; - } - - data += stride; - surface += length; - } - } - break; - } - case 16: { - MxU8* surface = (MxU8*) ddsd.lpSurface + (2 * p_right) + (p_bottom * ddsd.lPitch); - if (p_und) { - FUN_100bb500( - &data, - &surface, - p_bitmap->GetBmiHeader()->biSizeImage, - p_width, - p_height, - ddsd.lPitch, - 16 - ); - } - else { - MxLong stride = p_bitmap->GetAdjustedStride(); - - MxLong v50 = stride - p_width; - MxLong length = ddsd.lPitch - (2 * p_width); - for (MxS32 i = 0; p_height > i; i++) { - for (MxS32 j = 0; p_width > j; j++) { - if (*data != 0) { - *(MxU16*) surface = m_16bitPal[*data]; - } - data++; - surface += 2; - } - - data += v50; - surface += length; - } - } - } - } - - m_ddSurface2->Unlock(ddsd.lpSurface); - } + return; } + 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) { + return; + } + + MxU8* data = p_bitmap->GetStart(p_left, p_top); + + switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) { + case 8: { + MxU8* surface = (MxU8*) ddsd.lpSurface + p_right + (p_bottom * ddsd.lPitch); + if (p_und) { + MxS32 size = p_bitmap->GetBmiHeader()->biSizeImage; + FUN_100bb500(&data, &surface, size, p_width, p_height, ddsd.lPitch, 8); + } + else { + MxLong stride = -p_width + GetAdjustedStride(p_bitmap); + + MxLong length = -p_width + ddsd.lPitch; + for (MxS32 i = 0; i < p_height; i++) { + for (MxS32 j = 0; j < p_width; j++) { + if (*data != 0) { + *surface = *data; + } + + data++; + surface++; + } + + data += stride; + surface += length; + } + } + break; + } + case 16: { + MxU8* surface = (MxU8*) ddsd.lpSurface + (2 * p_right) + (p_bottom * ddsd.lPitch); + if (p_und) { + MxS32 size = p_bitmap->GetBmiHeader()->biSizeImage; + FUN_100bb500(&data, &surface, size, p_width, p_height, ddsd.lPitch, 16); + } + else { + MxLong stride = -p_width + GetAdjustedStride(p_bitmap); + + MxLong length = -2 * p_width + ddsd.lPitch; + for (MxS32 i = 0; i < p_height; i++) { + for (MxS32 j = 0; j < p_width; j++) { + if (*data != 0) { + *(MxU16*) surface = m_16bitPal[*data]; + } + + data++; + surface += 2; + } + + data += stride; + surface += length; + } + } + break; + } + default: + break; + } + + m_ddSurface2->Unlock(ddsd.lpSurface); } // STUB: LEGO1 0x100bb500 +// STUB: BETA10 0x10140cd6 void MxDisplaySurface::FUN_100bb500( MxU8** p_bitmapData, MxU8** p_surfaceData, @@ -655,7 +659,7 @@ void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p // FUNCTION: LEGO1 0x100bbc10 void MxDisplaySurface::GetDC(HDC* p_hdc) { - if (this->m_ddSurface2 && !this->m_ddSurface2->GetDC(p_hdc)) { + if (m_ddSurface2 && !m_ddSurface2->GetDC(p_hdc)) { return; } @@ -665,12 +669,13 @@ void MxDisplaySurface::GetDC(HDC* p_hdc) // FUNCTION: LEGO1 0x100bbc40 void MxDisplaySurface::ReleaseDC(HDC p_hdc) { - if (this->m_ddSurface2 && p_hdc) { - this->m_ddSurface2->ReleaseDC(p_hdc); + if (m_ddSurface2 && p_hdc) { + m_ddSurface2->ReleaseDC(p_hdc); } } // FUNCTION: LEGO1 0x100bbc60 +// FUNCTION: BETA10 0x10141745 LPDIRECTDRAWSURFACE MxDisplaySurface::VTable0x44( MxBitmap* p_bitmap, undefined4* p_ret, @@ -680,7 +685,7 @@ LPDIRECTDRAWSURFACE MxDisplaySurface::VTable0x44( { LPDIRECTDRAWSURFACE surface = NULL; LPDIRECTDRAW draw = MVideoManager()->GetDirectDraw(); - MVideoManager(); + MxVideoParamFlags& flags = MVideoManager()->GetVideoParam().Flags(); DDSURFACEDESC ddsd; memset(&ddsd, 0, sizeof(ddsd)); @@ -693,9 +698,9 @@ LPDIRECTDRAWSURFACE MxDisplaySurface::VTable0x44( ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; ddsd.dwWidth = p_bitmap->GetBmiWidth(); ddsd.dwHeight = p_bitmap->GetBmiHeightAbs(); - + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; *p_ret = 0; - ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN; + ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; if (draw->CreateSurface(&ddsd, &surface, NULL) != DD_OK) { if (*p_ret) { @@ -721,63 +726,57 @@ LPDIRECTDRAWSURFACE MxDisplaySurface::VTable0x44( if (surface->Lock(NULL, &ddsd, DDLOCK_WAIT, 0) != DD_OK) { surface->Release(); surface = NULL; - goto done; } - - if (p_doNotWriteToSurface) { - goto done; + else if (p_doNotWriteToSurface) { + assert(0); } + else { + MxU8* bitmapSrcPtr = p_bitmap->GetStart(0, 0); + MxU16* surfaceData = (MxU16*) ddsd.lpSurface; + MxLong widthNormal = p_bitmap->GetBmiWidth(); + MxLong heightAbs = p_bitmap->GetBmiHeightAbs(); - 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); + MxLong newPitch = ddsd.lPitch; + MxS32 rowSeek = p_bitmap->AlignToFourByte(p_bitmap->GetBmiWidth()); + if (!p_bitmap->IsTopDown()) { + rowSeek *= -1; } - 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(); + switch (ddsd.ddpfPixelFormat.dwRGBBitCount) { + case 8: { + for (MxS32 y = 0; y < heightAbs; y++) { + memcpy(surfaceData, bitmapSrcPtr, widthNormal); + bitmapSrcPtr += rowSeek; + surfaceData = (MxU16*) ((MxU8*) surfaceData + newPitch); } - return NULL; + + surface->Unlock(ddsd.lpSurface); + + if (p_transparent && surface) { + DDCOLORKEY key; + key.dwColorSpaceLowValue = key.dwColorSpaceHighValue = 0; + surface->SetColorKey(DDCKEY_SRCBLT, &key); + } + break; } - else { - rowSeek -= p_bitmap->GetBmiWidth(); - newPitch -= 2 * p_bitmap->GetBmiWidth(); + case 16: { + if (m_16bitPal == NULL) { + goto error; + } + + rowSeek -= widthNormal; + newPitch -= 2 * widthNormal; if (p_transparent) { - for (MxS32 y = heightAbs; y > 0; y--) { - for (MxS32 x = widthNormal; x > 0; x--) { - if (*bitmapSrcPtr) { - *surfaceData = m_16bitPal[*bitmapSrcPtr]; - } - else { + for (MxS32 y = 0; y < heightAbs; y++) { + for (MxS32 x = 0; x < widthNormal; x++) { + if (*bitmapSrcPtr == NULL) { *surfaceData = 31775; } + else { + *surfaceData = m_16bitPal[*bitmapSrcPtr]; + } + bitmapSrcPtr++; surfaceData++; } @@ -787,13 +786,12 @@ LPDIRECTDRAWSURFACE MxDisplaySurface::VTable0x44( } DDCOLORKEY key; - key.dwColorSpaceHighValue = 31775; - key.dwColorSpaceLowValue = 31775; + key.dwColorSpaceLowValue = key.dwColorSpaceHighValue = 31775; surface->SetColorKey(DDCKEY_SRCBLT, &key); } else { - for (MxS32 y = heightAbs; y > 0; y--) { - for (MxS32 x = widthNormal; x > 0; x--) { + for (MxS32 y = 0; y < heightAbs; y++) { + for (MxS32 x = 0; x < widthNormal; x++) { *surfaceData++ = m_16bitPal[*bitmapSrcPtr++]; } @@ -803,12 +801,20 @@ LPDIRECTDRAWSURFACE MxDisplaySurface::VTable0x44( } surface->Unlock(ddsd.lpSurface); + break; + } } } } -done: return surface; + +error: + if (surface) { + surface->Release(); + } + + return NULL; } // FUNCTION: LEGO1 0x100bbfb0