mirror of
https://github.com/isledecomp/isle-portable.git
synced 2024-11-26 17:36:12 -05:00
74329d681b
* implement/match CalcLocalTransform * fix odd build error * address feedback move vec.h to thirdparty folder update vec.h move all realtime code to realtime folder move calclocaltransform out of legoutil and into realtime cast shift to MxS32 add additional unroll hack to CalcLocalTransform to prevent msvc entropy
239 lines
5.5 KiB
C++
239 lines
5.5 KiB
C++
#include "mxvideopresenter.h"
|
|
#include "mxvideomanager.h"
|
|
|
|
DECOMP_SIZE_ASSERT(MxVideoPresenter, 0x64);
|
|
DECOMP_SIZE_ASSERT(MxVideoPresenter::AlphaMask, 0xc);
|
|
|
|
// OFFSET: LEGO1 0x1000c700
|
|
void MxVideoPresenter::VTable0x5c(undefined4 p_unknown1)
|
|
{
|
|
// Empty
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x1000c710
|
|
void MxVideoPresenter::VTable0x60()
|
|
{
|
|
// Empty
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x1000c720
|
|
void MxVideoPresenter::VTable0x68(undefined4 p_unknown1)
|
|
{
|
|
// Empty
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x1000c730
|
|
void MxVideoPresenter::VTable0x70()
|
|
{
|
|
// Empty
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x1000c740
|
|
MxVideoPresenter::~MxVideoPresenter()
|
|
{
|
|
Destroy(TRUE);
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x1000c7a0
|
|
void MxVideoPresenter::Destroy()
|
|
{
|
|
Destroy(FALSE);
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x1000c7b0
|
|
LPDIRECTDRAWSURFACE MxVideoPresenter::VTable0x78()
|
|
{
|
|
return m_unk58;
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x1000c7c0
|
|
MxBool MxVideoPresenter::VTable0x7c()
|
|
{
|
|
return (m_bitmap != NULL) || (m_alpha != NULL);
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x1000c7e0
|
|
MxS32 MxVideoPresenter::GetWidth()
|
|
{
|
|
return m_alpha ? m_alpha->m_width
|
|
: m_bitmap->GetBmiHeader()->biWidth;
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x1000c800
|
|
MxS32 MxVideoPresenter::GetHeight()
|
|
{
|
|
return m_alpha ? m_alpha->m_height
|
|
: m_bitmap->GetBmiHeader()->biHeight;
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x100b24f0
|
|
MxVideoPresenter::AlphaMask::AlphaMask(const MxBitmap &p_bitmap)
|
|
{
|
|
m_width = p_bitmap.GetBmiWidth();
|
|
// DECOMP: ECX becomes word-sized if these are not two separate actions.
|
|
MxLong _height = p_bitmap.GetBmiHeightAbs();
|
|
m_height = _height;
|
|
|
|
MxS32 size = ((m_width * m_height) / 8) + 1;
|
|
m_bitmask = new MxU8[size];
|
|
memset(m_bitmask, 0, size);
|
|
|
|
MxU32 biCompression = p_bitmap.GetBmiHeader()->biCompression;
|
|
MxU32 rows_before_top;
|
|
MxU8 *bitmap_src_ptr;
|
|
|
|
// The goal here is to enable us to walk through the bitmap's rows
|
|
// in order, regardless of the orientation. We want to end up at the
|
|
// start of the first row, which is either at position 0, or at
|
|
// (image_stride * biHeight) - 1.
|
|
|
|
// Reminder: Negative biHeight means this is a top-down DIB.
|
|
// Otherwise it is bottom-up.
|
|
|
|
if (biCompression == BI_RGB) {
|
|
// DECOMP: I think this must be an OR. If not, the check for
|
|
// biCompression == 16 gets optimized away.
|
|
if (biCompression == BI_RGB_TOPDOWN || p_bitmap.GetBmiHeight() < 0) {
|
|
rows_before_top = 0;
|
|
} else {
|
|
rows_before_top = p_bitmap.GetBmiHeightAbs();
|
|
rows_before_top--;
|
|
}
|
|
|
|
goto seek_to_last_row;
|
|
} else if (biCompression == BI_RGB_TOPDOWN) {
|
|
// DECOMP: This is the only condition where we skip the
|
|
// calculation below.
|
|
bitmap_src_ptr = p_bitmap.GetBitmapData();
|
|
} else {
|
|
if (p_bitmap.GetBmiHeight() < 0) {
|
|
rows_before_top = 0;
|
|
} else {
|
|
rows_before_top = p_bitmap.GetBmiHeightAbs();
|
|
rows_before_top--;
|
|
}
|
|
|
|
// TODO: would prefer not to use goto if we can figure this structure out
|
|
seek_to_last_row:
|
|
bitmap_src_ptr = ((p_bitmap.GetBmiWidth()+3)&-4) * rows_before_top + p_bitmap.GetBitmapData();
|
|
}
|
|
|
|
// How many bytes are there for each row of the bitmap?
|
|
// (i.e. the image stride)
|
|
// If this is a bottom-up DIB, we will walk it in reverse.
|
|
// TODO: Same rounding trick as in MxBitmap
|
|
MxS32 row_seek = ((m_height+3)&-4);
|
|
if (p_bitmap.GetBmiHeight() < 0)
|
|
row_seek = -row_seek;
|
|
|
|
// The actual offset into the m_bitmask array. The two for-loops
|
|
// are just for counting the pixels.
|
|
MxS32 offset = 0;
|
|
|
|
MxU8 *t_ptr = bitmap_src_ptr;
|
|
for (MxS32 j = 0; j < m_height; j++) {
|
|
for (MxS32 i = 0; i < m_width; i++) {
|
|
if (*t_ptr) {
|
|
// TODO: Second CDQ instruction for abs() should not be there.
|
|
MxU32 shift = abs(offset) & 7;
|
|
m_bitmask[offset / 8] |= (1 << abs((MxS32)shift));
|
|
}
|
|
t_ptr++;
|
|
offset++;
|
|
}
|
|
// Seek to the start of the next row
|
|
bitmap_src_ptr += row_seek;
|
|
t_ptr = bitmap_src_ptr;
|
|
}
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x100b2670
|
|
MxVideoPresenter::AlphaMask::AlphaMask(const MxVideoPresenter::AlphaMask &p_alpha)
|
|
{
|
|
m_width = p_alpha.m_width;
|
|
m_height = p_alpha.m_height;
|
|
|
|
MxS32 size = ((m_width * m_height) / 8) + 1;
|
|
m_bitmask = new MxU8[size];
|
|
memcpy(m_bitmask, p_alpha.m_bitmask, size);
|
|
}
|
|
|
|
|
|
// OFFSET: LEGO1 0x100b26d0
|
|
MxVideoPresenter::AlphaMask::~AlphaMask()
|
|
{
|
|
if (m_bitmask)
|
|
delete[] m_bitmask;
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x100b2760
|
|
void MxVideoPresenter::Init()
|
|
{
|
|
m_bitmap = NULL;
|
|
m_alpha = NULL;
|
|
m_unk5c = 1;
|
|
m_unk58 = NULL;
|
|
m_unk60 = -1;
|
|
m_flags = m_flags & 0xfe;
|
|
|
|
if (MVideoManager() != NULL) {
|
|
MVideoManager();
|
|
m_flags = m_flags | 2;
|
|
m_flags = m_flags & 0xfb;
|
|
}
|
|
|
|
m_flags = m_flags & 0xf7;
|
|
m_flags = m_flags & 0xef;
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x100b27b0
|
|
void MxVideoPresenter::Destroy(MxBool p_fromDestructor)
|
|
{
|
|
if (MVideoManager() != NULL)
|
|
MVideoManager()->RemovePresenter(*this);
|
|
|
|
if (m_unk58) {
|
|
m_unk58->Release();
|
|
m_unk58 = NULL;
|
|
m_flags = m_flags & 0xfd;
|
|
m_flags = m_flags & 0xfb;
|
|
}
|
|
|
|
if (MVideoManager() && (m_alpha || m_bitmap)) {
|
|
MxS32 height = GetHeight();
|
|
MxS32 width = GetWidth();
|
|
|
|
MxS32 x = GetLocationX();
|
|
MxS32 y = GetLocationY();
|
|
MxRect32 rect(x, y, x + width, y + height);
|
|
|
|
MVideoManager()->InvalidateRect(rect);
|
|
MVideoManager()->vtable0x34(rect.m_left, rect.m_top, rect.GetWidth(), rect.GetHeight());
|
|
}
|
|
|
|
delete m_bitmap;
|
|
delete m_alpha;
|
|
|
|
Init();
|
|
|
|
if (!p_fromDestructor)
|
|
MxMediaPresenter::Destroy(FALSE);
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x100b28b0 STUB
|
|
void MxVideoPresenter::VTable0x64()
|
|
{
|
|
// TODO
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x100b2a70 STUB
|
|
void MxVideoPresenter::VTable0x6c()
|
|
{
|
|
// TODO
|
|
}
|
|
|
|
// OFFSET: LEGO1 0x100b3300
|
|
undefined MxVideoPresenter::VTable0x74()
|
|
{
|
|
return 0;
|
|
}
|