diff --git a/CMakeLists.txt b/CMakeLists.txt index b7c93768..2206c199 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -221,8 +221,11 @@ add_library(lego1 SHARED LEGO1/omni/src/system/mxsemaphore.cpp LEGO1/omni/src/system/mxthread.cpp LEGO1/omni/src/video/mxbitmap.cpp + LEGO1/omni/src/video/mxcolor.cpp LEGO1/omni/src/video/mxdisplaysurface.cpp LEGO1/omni/src/video/mxflcpresenter.cpp + LEGO1/omni/src/video/mximage.cpp + LEGO1/omni/src/video/mximageptr.cpp LEGO1/omni/src/video/mxloopingflcpresenter.cpp LEGO1/omni/src/video/mxloopingsmkpresenter.cpp LEGO1/omni/src/video/mxpalette.cpp diff --git a/LEGO1/lego/legoomni/src/common/legostream.cpp b/LEGO1/lego/legoomni/src/common/legostream.cpp index f54d5982..08214b31 100644 --- a/LEGO1/lego/legoomni/src/common/legostream.cpp +++ b/LEGO1/lego/legoomni/src/common/legostream.cpp @@ -179,9 +179,9 @@ MxResult LegoFileStream::Open(const char* p_filename, OpenFlags p_mode) } if ((p_mode & c_binaryBit) != 0) - strcat(modeString, "b"); - else strcat(modeString, "t"); + else + strcat(modeString, "b"); return (m_hFile = fopen(p_filename, modeString)) ? SUCCESS : FAILURE; } diff --git a/LEGO1/omni/include/mxcolor.h b/LEGO1/omni/include/mxcolor.h new file mode 100644 index 00000000..abdd1e4e --- /dev/null +++ b/LEGO1/omni/include/mxcolor.h @@ -0,0 +1,15 @@ +#ifndef MXCOLOR_H +#define MXCOLOR_H +#include "legostream.h" + +class MxColor { +public: + MxColor(); + MxResult Read(LegoStream* p_stream); + MxResult Write(LegoStream* p_stream); + +private: + MxU8 m_color[3]; +}; + +#endif // MXCOLOR_H diff --git a/LEGO1/omni/include/mximage.h b/LEGO1/omni/include/mximage.h new file mode 100644 index 00000000..ad2f146a --- /dev/null +++ b/LEGO1/omni/include/mximage.h @@ -0,0 +1,22 @@ +#ifndef MXIMAGE_H +#define MXIMAGE_H +#include "legostream.h" +#include "mxcolor.h" + +class MxImage { +public: + MxImage(); + MxImage(MxU32 p_width, MxU32 p_height); + ~MxImage(); + MxResult Read(LegoStream* p_stream, MxU32 p_square); + MxResult Write(LegoStream* p_stream); + +private: + MxU32 m_width; + MxU32 m_height; + MxU32 m_colors; + MxColor m_palette[256]; + MxU8* m_image; +}; + +#endif // MXIMAGE_H diff --git a/LEGO1/omni/include/mximageptr.h b/LEGO1/omni/include/mximageptr.h new file mode 100644 index 00000000..85e158d1 --- /dev/null +++ b/LEGO1/omni/include/mximageptr.h @@ -0,0 +1,16 @@ +#ifndef MXIMAGEPTR_H +#define MXIMAGEPTR_H + +#include "mximage.h" + +class MxImagePtr { + MxImagePtr(); + ~MxImagePtr(); + MxResult Read(LegoStream* p_stream, MxU32 p_square); + MxResult Write(LegoStream* p_stream); + +private: + MxImage* m_pImage; +}; + +#endif // MXIMAGEPTR_H diff --git a/LEGO1/omni/src/video/mxcolor.cpp b/LEGO1/omni/src/video/mxcolor.cpp new file mode 100644 index 00000000..c845d8bd --- /dev/null +++ b/LEGO1/omni/src/video/mxcolor.cpp @@ -0,0 +1,33 @@ +#include "mxcolor.h" + +DECOMP_SIZE_ASSERT(MxColor, 0x3) + +// FUNCTION: LEGO1 0x100994c0 +MxColor::MxColor() +{ + m_color[0] = 0; + m_color[1] = 0; + m_color[2] = 0; +} + +// FUNCTION: LEGO1 0x100994d0 +MxResult MxColor::Read(LegoStream* p_stream) +{ + MxResult result; + if ((result = p_stream->Read(m_color, 1)) != SUCCESS) + return result; + if ((result = p_stream->Read(m_color + 1, 1)) != SUCCESS) + return result; + return (result = p_stream->Read(m_color + 2, 1)) != SUCCESS ? result : SUCCESS; +} + +// FUNCTION: LEGO1 0x10099520 +MxResult MxColor::Write(LegoStream* p_stream) +{ + MxResult result; + if ((result = p_stream->Write(m_color, 1)) != SUCCESS) + return result; + if ((result = p_stream->Write(m_color + 1, 1)) != SUCCESS) + return result; + return (result = p_stream->Write(m_color + 2, 1)) != SUCCESS ? result : SUCCESS; +} diff --git a/LEGO1/omni/src/video/mximage.cpp b/LEGO1/omni/src/video/mximage.cpp new file mode 100644 index 00000000..a82a11e9 --- /dev/null +++ b/LEGO1/omni/src/video/mximage.cpp @@ -0,0 +1,105 @@ +#include "mximage.h" + +DECOMP_SIZE_ASSERT(MxImage, 0x310) + +// FUNCTION: LEGO1 0x10099570 +MxImage::MxImage() +{ + m_width = 0; + m_height = 0; + m_colors = 0; + m_image = NULL; +} + +// FUNCTION: LEGO1 0x100995a0 +MxImage::MxImage(MxU32 p_width, MxU32 p_height) +{ + m_width = p_width; + m_height = p_height; + m_colors = 0; + m_image = new MxU8[p_width * p_height]; +} + +// FUNCTION: LEGO1 0x100995f0 +MxImage::~MxImage() +{ + if (m_image) + delete m_image; +} + +// FUNCTION: LEGO1 0x10099610 +MxResult MxImage::Read(LegoStream* p_stream, MxU32 p_square) +{ + MxResult result; + if ((result = p_stream->Read(&m_width, 4)) != SUCCESS) + return result; + if ((result = p_stream->Read(&m_height, 4)) != SUCCESS) + return result; + if ((result = p_stream->Read(&m_colors, 4)) != SUCCESS) + return result; + for (int i = 0; i < m_colors; i++) { + if ((result = m_palette[i].Read(p_stream)) != SUCCESS) + return result; + } + if (m_image) + delete m_image; + m_image = new MxU8[m_width * m_height]; + if ((result = p_stream->Read(m_image, m_width * m_height)) != SUCCESS) + return result; + if (p_square && m_width != m_height) { + MxU8* newImage; + if (m_height < m_width) { + MxU32 aspect = m_width / m_height; + newImage = new MxU8[m_width * m_width]; + MxU8* src = m_image; + MxU8* dst = newImage; + for (MxU32 row = 0; row < m_height; row++) { + for (MxU32 dup = aspect; dup; dup--) { + memcpy(dst, src, m_width); + dst += m_width; + } + src += m_width; + } + m_height = m_width; + } + else { + MxU32 aspect = m_height / m_width; + newImage = new MxU8[m_height * m_height]; + MxU8* src = m_image; + MxU8* dst = newImage; + for (MxU32 row = 0; row < m_height; row++) { + for (MxU32 col = 0; col < m_width; col++) { + for (MxU32 dup = aspect; dup; dup--) { + *dst = *src; + dst++; + } + src++; + } + } + m_width = m_height; + } + delete m_image; + m_image = newImage; + } + return SUCCESS; +} + +// FUNCTION: LEGO1 0x100997e0 +MxResult MxImage::Write(LegoStream* p_stream) +{ + MxResult result; + if ((result = p_stream->Write(&m_width, 4)) != SUCCESS) + return result; + if ((result = p_stream->Write(&m_height, 4)) != SUCCESS) + return result; + if ((result = p_stream->Write(&m_colors, 4)) != SUCCESS) + return result; + for (int i = 0; i < m_colors; i++) { + if ((result = m_palette[i].Write(p_stream)) != SUCCESS) + return result; + } + if (m_image) + if ((result = p_stream->Write(m_image, m_width * m_height)) != SUCCESS) + return result; + return SUCCESS; +} diff --git a/LEGO1/omni/src/video/mximageptr.cpp b/LEGO1/omni/src/video/mximageptr.cpp new file mode 100644 index 00000000..1667a709 --- /dev/null +++ b/LEGO1/omni/src/video/mximageptr.cpp @@ -0,0 +1,25 @@ +#include "mximageptr.h" + +DECOMP_SIZE_ASSERT(MxImagePtr, 0x4) + +// FUNCTION: LEGO1 0x10098fb0 +MxImagePtr::MxImagePtr() +{ + m_pImage = new MxImage(); +} +// FUNCTION: LEGO1 0x10099030 +MxImagePtr::~MxImagePtr() +{ + if (m_pImage) + delete m_pImage; +} +// FUNCTION: LEGO1 0x10099050 +MxResult MxImagePtr::Read(LegoStream* p_stream, MxU32 p_square) +{ + return m_pImage->Read(p_stream, p_square); +} +// FUNCTION: LEGO1 0x10099070 +MxResult MxImagePtr::Write(LegoStream* p_stream) +{ + return m_pImage->Write(p_stream); +}