mirror of
https://github.com/isledecomp/isle-portable.git
synced 2025-02-16 19:50:52 -05:00
Finish Bitmap (#458)
* Finish Bitmap * Add missing vtable annotations * Fixes --------- Co-authored-by: Christian Semmler <mail@csemmler.com>
This commit is contained in:
parent
cecaced797
commit
d5658efe02
6 changed files with 154 additions and 43 deletions
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "decomp.h"
|
#include "decomp.h"
|
||||||
#include "legostate.h"
|
#include "legostate.h"
|
||||||
#include "mxstillpresenter.h";
|
#include "mxstillpresenter.h"
|
||||||
|
|
||||||
// VTABLE: LEGO1 0x100d93a8
|
// VTABLE: LEGO1 0x100d93a8
|
||||||
// SIZE 0x94
|
// SIZE 0x94
|
||||||
|
|
|
@ -44,10 +44,26 @@ public:
|
||||||
__declspec(dllexport) virtual MxLong Read(const char* p_filename); // vtable+24
|
__declspec(dllexport) virtual MxLong Read(const char* p_filename); // vtable+24
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x1004e0d0
|
// FUNCTION: LEGO1 0x1004e0d0
|
||||||
virtual int VTable0x28(int) { return -1; };
|
virtual int VTable0x28(int) { return -1; }; // vtable+28
|
||||||
|
|
||||||
virtual void VTable0x2c(int, int, int, int, int, int, int);
|
virtual void BitBlt(
|
||||||
virtual void VTable0x30(int, int, int, int, int, int, int);
|
MxBitmap* p_src,
|
||||||
|
MxS32 p_left,
|
||||||
|
MxS32 p_top,
|
||||||
|
MxS32 p_right,
|
||||||
|
MxS32 p_bottom,
|
||||||
|
MxS32 p_width,
|
||||||
|
MxS32 p_height
|
||||||
|
); // vtable+2c
|
||||||
|
virtual void BitBltTransparent(
|
||||||
|
MxBitmap* p_src,
|
||||||
|
MxS32 p_left,
|
||||||
|
MxS32 p_top,
|
||||||
|
MxS32 p_right,
|
||||||
|
MxS32 p_bottom,
|
||||||
|
MxS32 p_width,
|
||||||
|
MxS32 p_height
|
||||||
|
); // vtable+30
|
||||||
__declspec(dllexport) virtual MxPalette* CreatePalette(); // vtable+34
|
__declspec(dllexport) virtual MxPalette* CreatePalette(); // vtable+34
|
||||||
virtual void ImportPalette(MxPalette* p_palette); // vtable+38
|
virtual void ImportPalette(MxPalette* p_palette); // vtable+38
|
||||||
virtual MxResult SetBitDepth(MxBool); // vtable+3c
|
virtual MxResult SetBitDepth(MxBool); // vtable+3c
|
||||||
|
@ -92,6 +108,26 @@ public:
|
||||||
return -GetBmiStride();
|
return -GetBmiStride();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline MxLong GetLine(MxS32 p_top)
|
||||||
|
{
|
||||||
|
MxS32 height;
|
||||||
|
if (m_bmiHeader->biCompression == BI_RGB_TOPDOWN || m_bmiHeader->biHeight < 0)
|
||||||
|
height = p_top;
|
||||||
|
else
|
||||||
|
height = GetBmiHeightAbs() - p_top - 1;
|
||||||
|
return GetBmiStride() * height;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MxU8* GetStart(MxS32 p_left, MxS32 p_top)
|
||||||
|
{
|
||||||
|
if (m_bmiHeader->biCompression == BI_RGB)
|
||||||
|
return GetLine(p_top) + m_data + p_left;
|
||||||
|
else if (m_bmiHeader->biCompression == BI_RGB_TOPDOWN)
|
||||||
|
return m_data;
|
||||||
|
else
|
||||||
|
return GetLine(0) + m_data;
|
||||||
|
}
|
||||||
|
|
||||||
// SYNTHETIC: LEGO1 0x100bc9f0
|
// SYNTHETIC: LEGO1 0x100bc9f0
|
||||||
// MxBitmap::`scalar deleting destructor'
|
// MxBitmap::`scalar deleting destructor'
|
||||||
|
|
||||||
|
|
|
@ -56,15 +56,15 @@ inline void GetString(MxU8** p_source, char** p_dest, T* p_obj, void (T::*p_sett
|
||||||
*p_source += strlen(*p_dest) + 1;
|
*p_source += strlen(*p_dest) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
MxBool FUN_100b6e10(
|
MxBool GetRectIntersection(
|
||||||
MxS32 p_bitmapWidth,
|
MxS32 p_rect1Width,
|
||||||
MxS32 p_bitmapHeight,
|
MxS32 p_rect1Height,
|
||||||
MxS32 p_videoParamWidth,
|
MxS32 p_rect2Width,
|
||||||
MxS32 p_videoParamHeight,
|
MxS32 p_rect2Height,
|
||||||
MxS32* p_left,
|
MxS32* p_rect1Left,
|
||||||
MxS32* p_top,
|
MxS32* p_rect1Top,
|
||||||
MxS32* p_right,
|
MxS32* p_rect2Left,
|
||||||
MxS32* p_bottom,
|
MxS32* p_rect2Top,
|
||||||
MxS32* p_width,
|
MxS32* p_width,
|
||||||
MxS32* p_height
|
MxS32* p_height
|
||||||
);
|
);
|
||||||
|
|
|
@ -11,45 +11,45 @@
|
||||||
void (*g_omniUserMessage)(const char*, int);
|
void (*g_omniUserMessage)(const char*, int);
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x100b6e10
|
// FUNCTION: LEGO1 0x100b6e10
|
||||||
MxBool FUN_100b6e10(
|
MxBool GetRectIntersection(
|
||||||
MxS32 p_bitmapWidth,
|
MxS32 p_rect1Width,
|
||||||
MxS32 p_bitmapHeight,
|
MxS32 p_rect1Height,
|
||||||
MxS32 p_videoParamWidth,
|
MxS32 p_rect2Width,
|
||||||
MxS32 p_videoParamHeight,
|
MxS32 p_rect2Height,
|
||||||
MxS32* p_left,
|
MxS32* p_rect1Left,
|
||||||
MxS32* p_top,
|
MxS32* p_rect1Top,
|
||||||
MxS32* p_right,
|
MxS32* p_rect2Left,
|
||||||
MxS32* p_bottom,
|
MxS32* p_rect2Top,
|
||||||
MxS32* p_width,
|
MxS32* p_width,
|
||||||
MxS32* p_height
|
MxS32* p_height
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
MxPoint32 topLeft(*p_left, *p_top);
|
MxPoint32 rect1Origin(*p_rect1Left, *p_rect1Top);
|
||||||
MxRect32 bitmapRect(MxPoint32(0, 0), MxSize32(p_bitmapWidth, p_bitmapHeight));
|
MxRect32 rect1(MxPoint32(0, 0), MxSize32(p_rect1Width, p_rect1Height));
|
||||||
|
|
||||||
MxPoint32 bottomRight(*p_right, *p_bottom);
|
MxPoint32 rect2Origin(*p_rect2Left, *p_rect2Top);
|
||||||
MxRect32 videoParamRect(MxPoint32(0, 0), MxSize32(p_videoParamWidth, p_videoParamHeight));
|
MxRect32 rect2(MxPoint32(0, 0), MxSize32(p_rect2Width, p_rect2Height));
|
||||||
|
|
||||||
MxRect32 rect(0, 0, *p_width, *p_height);
|
MxRect32 rect(0, 0, *p_width, *p_height);
|
||||||
rect.AddPoint(topLeft);
|
rect.AddPoint(rect1Origin);
|
||||||
|
|
||||||
if (!rect.IntersectsWith(bitmapRect))
|
if (!rect.IntersectsWith(rect1))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
rect.Intersect(bitmapRect);
|
rect.Intersect(rect1);
|
||||||
rect.SubtractPoint(topLeft);
|
rect.SubtractPoint(rect1Origin);
|
||||||
rect.AddPoint(bottomRight);
|
rect.AddPoint(rect2Origin);
|
||||||
|
|
||||||
if (!rect.IntersectsWith(videoParamRect))
|
if (!rect.IntersectsWith(rect2))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
rect.Intersect(videoParamRect);
|
rect.Intersect(rect2);
|
||||||
rect.SubtractPoint(bottomRight);
|
rect.SubtractPoint(rect2Origin);
|
||||||
|
|
||||||
*p_left += rect.GetLeft();
|
*p_rect1Left += rect.GetLeft();
|
||||||
*p_top += rect.GetTop();
|
*p_rect1Top += rect.GetTop();
|
||||||
*p_right += rect.GetLeft();
|
*p_rect2Left += rect.GetLeft();
|
||||||
*p_bottom += rect.GetTop();
|
*p_rect2Top += rect.GetTop();
|
||||||
*p_width = rect.GetWidth();
|
*p_width = rect.GetWidth();
|
||||||
*p_height = rect.GetHeight();
|
*p_height = rect.GetHeight();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "mxbitmap.h"
|
#include "mxbitmap.h"
|
||||||
|
|
||||||
#include "decomp.h"
|
#include "decomp.h"
|
||||||
|
#include "mxutil.h"
|
||||||
|
|
||||||
DECOMP_SIZE_ASSERT(MxBitmap, 0x20);
|
DECOMP_SIZE_ASSERT(MxBitmap, 0x20);
|
||||||
DECOMP_SIZE_ASSERT(MxBITMAPINFO, 0x428);
|
DECOMP_SIZE_ASSERT(MxBITMAPINFO, 0x428);
|
||||||
|
@ -207,14 +208,88 @@ MxResult MxBitmap::LoadFile(HANDLE p_handle)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x100bce70
|
// FUNCTION: LEGO1 0x100bce70
|
||||||
void MxBitmap::VTable0x2c(int, int, int, int, int, int, int)
|
void MxBitmap::BitBlt(
|
||||||
|
MxBitmap* p_src,
|
||||||
|
MxS32 p_srcLeft,
|
||||||
|
MxS32 p_srcTop,
|
||||||
|
MxS32 p_dstLeft,
|
||||||
|
MxS32 p_dstTop,
|
||||||
|
MxS32 p_width,
|
||||||
|
MxS32 p_height
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
MxLong dstHeight = GetBmiHeightAbs();
|
||||||
|
MxLong srcHeight = p_src->GetBmiHeightAbs();
|
||||||
|
|
||||||
|
if (GetRectIntersection(
|
||||||
|
p_src->GetBmiWidth(),
|
||||||
|
srcHeight,
|
||||||
|
GetBmiWidth(),
|
||||||
|
dstHeight,
|
||||||
|
&p_srcLeft,
|
||||||
|
&p_srcTop,
|
||||||
|
&p_dstLeft,
|
||||||
|
&p_dstTop,
|
||||||
|
&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();
|
||||||
|
|
||||||
|
while (p_height--) {
|
||||||
|
memcpy(dstStart, srcStart, p_width);
|
||||||
|
dstStart += dstStride;
|
||||||
|
srcStart += srcStride;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x100bd020
|
// FUNCTION: LEGO1 0x100bd020
|
||||||
void MxBitmap::VTable0x30(int, int, int, int, int, int, int)
|
void MxBitmap::BitBltTransparent(
|
||||||
|
MxBitmap* p_src,
|
||||||
|
MxS32 p_srcLeft,
|
||||||
|
MxS32 p_srcTop,
|
||||||
|
MxS32 p_dstLeft,
|
||||||
|
MxS32 p_dstTop,
|
||||||
|
MxS32 p_width,
|
||||||
|
MxS32 p_height
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
MxLong dstHeight = GetBmiHeightAbs();
|
||||||
|
MxLong srcHeight = p_src->GetBmiHeightAbs();
|
||||||
|
|
||||||
|
if (GetRectIntersection(
|
||||||
|
p_src->GetBmiWidth(),
|
||||||
|
srcHeight,
|
||||||
|
GetBmiWidth(),
|
||||||
|
dstHeight,
|
||||||
|
&p_srcLeft,
|
||||||
|
&p_srcTop,
|
||||||
|
&p_dstLeft,
|
||||||
|
&p_dstTop,
|
||||||
|
&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;
|
||||||
|
|
||||||
|
for (MxS32 h = 0; h < p_height; h++) {
|
||||||
|
for (MxS32 w = 0; w < p_width; w++) {
|
||||||
|
if (*srcStart)
|
||||||
|
*dstStart = *srcStart;
|
||||||
|
srcStart++;
|
||||||
|
dstStart++;
|
||||||
|
}
|
||||||
|
|
||||||
|
srcStart += srcStride;
|
||||||
|
dstStart += dstStride;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x100bd1c0
|
// FUNCTION: LEGO1 0x100bd1c0
|
||||||
|
|
|
@ -305,7 +305,7 @@ void MxDisplaySurface::VTable0x28(
|
||||||
MxS32 p_height
|
MxS32 p_height
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (FUN_100b6e10(
|
if (GetRectIntersection(
|
||||||
p_bitmap->GetBmiWidth(),
|
p_bitmap->GetBmiWidth(),
|
||||||
p_bitmap->GetBmiHeightAbs(),
|
p_bitmap->GetBmiHeightAbs(),
|
||||||
m_videoParam.GetRect().GetWidth(),
|
m_videoParam.GetRect().GetWidth(),
|
||||||
|
|
Loading…
Reference in a new issue