From 267e3a0753876d3f38d46878d23fea2f559c59ba Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Thu, 18 Jan 2024 18:38:27 -0500 Subject: [PATCH] WIP --- 3rdparty/flic/flic.h | 61 +++++++++++------- 3rdparty/flic/flic.lib | Bin 0 -> 2880 bytes CMakeLists.txt | 3 +- LEGO1/omni/include/mxflcpresenter.h | 3 +- LEGO1/omni/src/video/mxflcpresenter.cpp | 45 +++++++++++-- .../omni/src/video/mxloopingflcpresenter.cpp | 2 +- 6 files changed, 80 insertions(+), 34 deletions(-) create mode 100644 3rdparty/flic/flic.lib diff --git a/3rdparty/flic/flic.h b/3rdparty/flic/flic.h index 42969e5c..c828b2f4 100644 --- a/3rdparty/flic/flic.h +++ b/3rdparty/flic/flic.h @@ -6,31 +6,42 @@ // A basic FLIC header structure from the "EGI" documentation. Source: https://www.compuphase.com/flic.htm#FLICHEADER // This also goes over the FLIC structures: https://github.com/thinkbeforecoding/nomemalloc.handson/blob/master/flic.txt typedef struct { - DWORD size; /* Size of FLIC including this header */ - WORD type; /* File type 0xAF11, 0xAF12, 0xAF30, 0xAF44, ... */ - WORD frames; /* Number of frames in first segment */ - WORD width; /* FLIC width in pixels */ - WORD height; /* FLIC height in pixels */ - WORD depth; /* Bits per pixel (usually 8) */ - WORD flags; /* Set to zero or to three */ - DWORD speed; /* Delay between frames */ - WORD reserved1; /* Set to zero */ - DWORD created; /* Date of FLIC creation (FLC only) */ - DWORD creator; /* Serial number or compiler id (FLC only) */ - DWORD updated; /* Date of FLIC update (FLC only) */ - DWORD updater; /* Serial number (FLC only), see creator */ - WORD aspect_dx; /* Width of square rectangle (FLC only) */ - WORD aspect_dy; /* Height of square rectangle (FLC only) */ - WORD ext_flags; /* EGI: flags for specific EGI extensions */ - WORD keyframes; /* EGI: key-image frequency */ - WORD totalframes; /* EGI: total number of frames (segments) */ - DWORD req_memory; /* EGI: maximum chunk size (uncompressed) */ - WORD max_regions; /* EGI: max. number of regions in a CHK_REGION chunk */ - WORD transp_num; /* EGI: number of transparent levels */ - BYTE reserved2[24]; /* Set to zero */ - DWORD oframe1; /* Offset to frame 1 (FLC only) */ - DWORD oframe2; /* Offset to frame 2 (FLC only) */ - BYTE reserved3[40]; /* Set to zero */ + DWORD size; /* Size of FLIC including this header */ + WORD type; /* File type 0xAF11, 0xAF12, 0xAF30, 0xAF44, ... */ + WORD frames; /* Number of frames in first segment */ + WORD width; /* FLIC width in pixels */ + WORD height; /* FLIC height in pixels */ + WORD depth; /* Bits per pixel (usually 8) */ + WORD flags; /* Set to zero or to three */ + DWORD speed; /* Delay between frames */ + WORD reserved1; /* Set to zero */ + DWORD created; /* Date of FLIC creation (FLC only) */ + DWORD creator; /* Serial number or compiler id (FLC only) */ + DWORD updated; /* Date of FLIC update (FLC only) */ + DWORD updater; /* Serial number (FLC only), see creator */ + WORD aspect_dx; /* Width of square rectangle (FLC only) */ + WORD aspect_dy; /* Height of square rectangle (FLC only) */ + WORD ext_flags; /* EGI: flags for specific EGI extensions */ + WORD keyframes; /* EGI: key-image frequency */ + WORD totalframes; /* EGI: total number of frames (segments) */ + DWORD req_memory; /* EGI: maximum chunk size (uncompressed) */ + WORD max_regions; /* EGI: max. number of regions in a CHK_REGION chunk */ + WORD transp_num; /* EGI: number of transparent levels */ + BYTE reserved2[24]; /* Set to zero */ + DWORD oframe1; /* Offset to frame 1 (FLC only) */ + DWORD oframe2; /* Offset to frame 2 (FLC only) */ + BYTE reserved3[40]; /* Set to zero */ } FLIC_HEADER; +extern "C" +{ + void DecodeFLCFrame( + LPBITMAPINFOHEADER bitmapHeader, + void* pixelData, + FLIC_HEADER* flcHeader, + void* flcFrame, + unsigned char* decodedColorMap + ); +} + #endif // FLIC_H diff --git a/3rdparty/flic/flic.lib b/3rdparty/flic/flic.lib new file mode 100644 index 0000000000000000000000000000000000000000..5d3c86c2d1217796ca9737cb5baf5e97e5b4b202 GIT binary patch literal 2880 zcmb7Ge{2(V6#uq&bhQ-jtko3LkQ&c8ota}D`vF8doU^zwuIqXwalj_q6A%QkOWLH2 z=&jiGEc&l8F(#r3e<=PVAx3S><|YF)+drBRqZl>Sfu+s;to2~;zJB(9eR|8zJv}zv;Z4UTw$wB1-MzDV|I>TQ5z1)mo64w+_nMlT`ucj0 zr?%ePXlQzD?Iw;LKXJT&%F37%BhXbH>5oPX@n4@FCihhL^+tOC)xwzYF*#e^_4wAV z1$N(8F!lS{-D++*@euEc935`J?IuPxu%WQ zL8m&#rP?L8`qQj%;tCg$#H77p$M%u*F^N2;-_V~el1l*%C&OvDA2WAS=FR{S(W&I2R4N&ndnqxe*1?x^>ykvuZG!fJ%RvbV zj;=(ST}i7?AH|BdDBi@#e~|nu2&+yVwT>}UVOx;YVI}_qMk}-%Hd~SV1vX7(8_&gw;+jNY^plSj}Wr|yecY86%`d`j;~l|Id|?Hdb6T4 zUJm4M$90%SxipOLgXXb5@f-0L!_XE=N6pcC5KdO$z2Ago_QVsAxIDnaC(MMl&X5uY z?hiRneL~25hDDUN`?zb+7MsxPjy76UgiO06<}RAaJ7-PTSwTAuPh#aq?n9M5WmU&` zHOnPC=2HH-WXFw^zm)8l1#NNezoJ+B>eLo!UJ1iI4(J&eM08+Fs1|EQZrW6;JTElc_IqkcEbq0g!-RH}~H+eF9$!pr@@ zj`fO*oJhORra+Y`4E_)x8b|th9<*jN_-Q0YqlhlGx^?J6dFw2F-LAsDsCJ{Fi_CD+5mMxEpfjJpUMdNh^Jv2T z2HcIgvqKjK-qbPELyRR2;QUB>6Qk|a`Q3L{*RRbDf2Cv+HKRNN^h z9DNT<$>vM3@qAtn7oE9JAe*7G8O)f&OqMwr_L_435jRv+gt?p z)j#J-rTKmDlc+Bk{P~eTWXPg~y=Ri`(h4loT{aX%*c=T}KXlM3<)A+GI;cOHs!mVN zP{Sg|by^XGCw%s7=ETDila;2tI``H#>ehh0-=F81SmZ5Uod+9d)8FUI)m zzYW}j3!UkJD0fmE;>|?`6p%afK?Cxck;B*(>9n`7BPiXbOCIcv%XLXY$*xP4D6PSdfs7s9~QERiX4JbKusTy|g?MI2Oxe{Z~nDqan-WT>6I(qtc?%#Ky zdUxNf$AJeGW89*D9y(4rdMvpX{_i0Cf3{ihuY-`#hW>Ua=UdmKJ8IXiX{u$Exo*P@ zjhFcrYZ_}=3IlP>gST$e=w)v$(bTc`muS|q(IuLCHnl|4z`k3eX=J}H)-=_y8}k}M Tj|Ua|0J9-HX8mt*>7VFd10q_6 literal 0 HcmV?d00001 diff --git a/CMakeLists.txt b/CMakeLists.txt index 61a8d165..34b67e0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -278,9 +278,10 @@ if (ISLE_USE_DX5) endif() target_link_directories(lego1 PRIVATE "${CMAKE_SOURCE_DIR}/3rdparty/smacker") +target_link_directories(lego1 PRIVATE "${CMAKE_SOURCE_DIR}/3rdparty/flic") # Link libraries -target_link_libraries(lego1 PRIVATE ddraw dsound dinput dxguid winmm d3drm smack) +target_link_libraries(lego1 PRIVATE ddraw dsound dinput dxguid winmm d3drm smack flic) # Make sure filenames are ALL CAPS set_property(TARGET lego1 PROPERTY OUTPUT_NAME LEGO1) diff --git a/LEGO1/omni/include/mxflcpresenter.h b/LEGO1/omni/include/mxflcpresenter.h index d883d106..c8f9854d 100644 --- a/LEGO1/omni/include/mxflcpresenter.h +++ b/LEGO1/omni/include/mxflcpresenter.h @@ -28,13 +28,14 @@ class MxFlcPresenter : public MxVideoPresenter { virtual void LoadHeader(MxStreamChunk* p_chunk) override; // vtable+0x5c virtual void CreateBitmap() override; // vtable+0x60 + virtual void LoadFrame(MxStreamChunk* p_chunk) override; // vtable+0x68 virtual void RealizePalette() override; // vtable+0x70 // SYNTHETIC: LEGO1 0x100b3400 // MxFlcPresenter::`scalar deleting destructor' protected: - FLIC_HEADER* m_flicHeader; + FLIC_HEADER* m_flcHeader; // 0x64 }; #endif // MXFLCPRESENTER_H diff --git a/LEGO1/omni/src/video/mxflcpresenter.cpp b/LEGO1/omni/src/video/mxflcpresenter.cpp index de334852..b61c04a0 100644 --- a/LEGO1/omni/src/video/mxflcpresenter.cpp +++ b/LEGO1/omni/src/video/mxflcpresenter.cpp @@ -2,6 +2,7 @@ #include "decomp.h" #include "mxbitmap.h" +#include "mxdsmediaaction.h" #include "mxomni.h" #include "mxpalette.h" #include "mxvideomanager.h" @@ -11,7 +12,7 @@ DECOMP_SIZE_ASSERT(MxFlcPresenter, 0x68); // FUNCTION: LEGO1 0x100b3310 MxFlcPresenter::MxFlcPresenter() { - this->m_flicHeader = NULL; + this->m_flcHeader = NULL; this->m_flags &= ~c_bit2; this->m_flags &= ~c_bit3; } @@ -19,16 +20,16 @@ MxFlcPresenter::MxFlcPresenter() // FUNCTION: LEGO1 0x100b3420 MxFlcPresenter::~MxFlcPresenter() { - if (this->m_flicHeader) { - delete this->m_flicHeader; + if (this->m_flcHeader) { + delete this->m_flcHeader; } } // FUNCTION: LEGO1 0x100b3490 void MxFlcPresenter::LoadHeader(MxStreamChunk* p_chunk) { - m_flicHeader = (FLIC_HEADER*) new MxU8[p_chunk->GetLength()]; - memcpy(m_flicHeader, p_chunk->GetData(), p_chunk->GetLength()); + m_flcHeader = (FLIC_HEADER*) new MxU8[p_chunk->GetLength()]; + memcpy(m_flcHeader, p_chunk->GetData(), p_chunk->GetLength()); } // FUNCTION: LEGO1 0x100b34d0 @@ -38,7 +39,39 @@ void MxFlcPresenter::CreateBitmap() delete m_bitmap; m_bitmap = new MxBitmap; - m_bitmap->SetSize(m_flicHeader->width, m_flicHeader->height, NULL, FALSE); + m_bitmap->SetSize(m_flcHeader->width, m_flcHeader->height, NULL, FALSE); +} + +// FUNCTION: LEGO1 0x100b3570 +void MxFlcPresenter::LoadFrame(MxStreamChunk* p_chunk) +{ + MxU32* dat = (MxU32*) p_chunk->GetData() + 4; + MxU32 offset = *(MxU32*) p_chunk->GetData(); + MxBool decodedColorMap; + + DecodeFLCFrame( + &m_bitmap->GetBitmapInfo()->m_bmiHeader, + m_bitmap->GetBitmapData(), + m_flcHeader, + &dat[offset], + //&(p_chunk->GetData() + 4)[*(MxU32*) p_chunk->GetData()], + &decodedColorMap + ); + + if (((MxDSMediaAction*) m_action)->GetPaletteManagement() && decodedColorMap) + RealizePalette(); + + while (offset > 0) { + dat += 4; + MxRect32 rect( + dat[-4] + m_location.GetX(), + dat[-3] + m_location.GetY(), + dat[-2] + m_location.GetX(), + dat[-1] + m_location.GetY() + ); + MVideoManager()->InvalidateRect(rect); + offset--; + } } // FUNCTION: LEGO1 0x100b3620 diff --git a/LEGO1/omni/src/video/mxloopingflcpresenter.cpp b/LEGO1/omni/src/video/mxloopingflcpresenter.cpp index dcdeba96..b8d9bd45 100644 --- a/LEGO1/omni/src/video/mxloopingflcpresenter.cpp +++ b/LEGO1/omni/src/video/mxloopingflcpresenter.cpp @@ -45,7 +45,7 @@ void MxLoopingFlcPresenter::NextFrame() else { LoadFrame(chunk); LoopChunk(chunk); - m_unk0x68 += m_flicHeader->speed; + m_unk0x68 += m_flcHeader->speed; } m_subscriber->DestroyChunk(chunk);