#include "legoimage.h" #include "decomp.h" #include "legostorage.h" #include "memory.h" DECOMP_SIZE_ASSERT(LegoPaletteEntry, 0x03); DECOMP_SIZE_ASSERT(LegoImage, 0x310); // FUNCTION: LEGO1 0x100994c0 LegoPaletteEntry::LegoPaletteEntry() { m_color.r = 0; m_color.g = 0; m_color.b = 0; m_color.a = MORTAR_ALPHA_OPAQUE; } // FUNCTION: LEGO1 0x100994d0 LegoResult LegoPaletteEntry::Read(LegoStorage* p_storage) { LegoResult result; if ((result = p_storage->Read(&m_color.r, sizeof(uint8_t))) != SUCCESS) { return result; } if ((result = p_storage->Read(&m_color.g, sizeof(uint8_t))) != SUCCESS) { return result; } if ((result = p_storage->Read(&m_color.b, sizeof(uint8_t))) != SUCCESS) { return result; } return SUCCESS; } // FUNCTION: LEGO1 0x10099520 LegoResult LegoPaletteEntry::Write(LegoStorage* p_storage) const { LegoResult result; if ((result = p_storage->Write(&m_color.r, sizeof(uint8_t))) != SUCCESS) { return result; } if ((result = p_storage->Write(&m_color.g, sizeof(uint8_t))) != SUCCESS) { return result; } if ((result = p_storage->Write(&m_color.b, sizeof(uint8_t))) != SUCCESS) { return result; } return SUCCESS; } // FUNCTION: LEGO1 0x10099570 LegoImage::LegoImage() { m_surface = NULL; m_palette = NULL; } // FUNCTION: LEGO1 0x100995a0 LegoImage::LegoImage(LegoU32 p_width, LegoU32 p_height) { m_surface = MORTAR_CreateSurface(p_width, p_height, MORTAR_PIXELFORMAT_INDEX8); m_palette = NULL; } // FUNCTION: LEGO1 0x100995f0 LegoImage::~LegoImage() { MORTAR_DestroySurface(m_surface); MORTAR_DestroyPalette(m_palette); } // FUNCTION: LEGO1 0x10099610 LegoResult LegoImage::Read(LegoStorage* p_storage, LegoU32 p_square) { LegoResult result; LegoU32 width, height, count; if ((result = p_storage->Read(&width, sizeof(LegoU32))) != SUCCESS) { return result; } if ((result = p_storage->Read(&height, sizeof(LegoU32))) != SUCCESS) { return result; } if ((result = p_storage->Read(&count, sizeof(LegoU32))) != SUCCESS) { return result; } if (m_palette) { MORTAR_DestroyPalette(m_palette); } m_palette = MORTAR_CreatePalette(count); for (LegoU32 i = 0; i < count; i++) { LegoPaletteEntry paletteEntry; if ((result = paletteEntry.Read(p_storage)) != SUCCESS) { return result; } m_palette->colors[i] = paletteEntry.GetColor(); } if (m_surface) { MORTAR_DestroySurface(m_surface); } m_surface = MORTAR_CreateSurface(width, height, MORTAR_PIXELFORMAT_INDEX8); if ((result = p_storage->Read(m_surface->pixels, width * height)) != SUCCESS) { return result; } if (p_square && width != height) { MORTAR_Surface* newSurface; if (height < width) { LegoU32 aspect = width / height; newSurface = MORTAR_CreateSurface(width, width, MORTAR_PIXELFORMAT_INDEX8); LegoU8* src = (LegoU8*) m_surface->pixels; LegoU8* dst = (LegoU8*) newSurface->pixels; for (LegoU32 row = 0; row < height; row++) { if (aspect) { for (LegoU32 dup = aspect; dup; dup--) { memcpy(dst, src, width); dst += width; } } src += width; } height = width; } else { LegoU32 aspect = height / width; newSurface = MORTAR_CreateSurface(height, height, MORTAR_PIXELFORMAT_INDEX8); LegoU8* src = (LegoU8*) m_surface->pixels; LegoU8* dst = (LegoU8*) newSurface->pixels; for (LegoU32 row = 0; row < height; row++) { for (LegoU32 col = 0; col < width; col++) { if (aspect) { for (LegoU32 dup = aspect; dup; dup--) { *dst = *src; dst++; } } src++; } } width = height; } MORTAR_DestroySurface(m_surface); m_surface = newSurface; } return SUCCESS; } // FUNCTION: LEGO1 0x100997e0 LegoResult LegoImage::Write(LegoStorage* p_storage) { LegoResult result; if ((result = p_storage->Write(&m_surface->w, sizeof(int))) != SUCCESS) { return result; } if ((result = p_storage->Write(&m_surface->h, sizeof(int))) != SUCCESS) { return result; } if ((result = p_storage->Write(&m_palette->ncolors, sizeof(int))) != SUCCESS) { return result; } if (m_palette) { LegoPaletteEntry paletteEntry; for (LegoU32 i = 0; i < m_palette->ncolors; i++) { paletteEntry.SetColor(m_palette->colors[i]); if ((result = paletteEntry.Write(p_storage)) != SUCCESS) { return result; } } if ((result = p_storage->Write(m_surface->pixels, m_surface->w * m_surface->h)) != SUCCESS) { return result; } } return SUCCESS; }