mirror of
https://github.com/isledecomp/isle.git
synced 2026-01-21 07:11:16 +00:00
A few things for MxBitmap
* new struct MxBITMAPINFO * vtable18 and ImportPalette 100% * ImportColorsToPalette improvement
This commit is contained in:
parent
95bb105817
commit
9184b284d1
@ -1,4 +1,7 @@
|
|||||||
#include "mxbitmap.h"
|
#include "mxbitmap.h"
|
||||||
|
#include "decomp.h"
|
||||||
|
|
||||||
|
DECOMP_SIZE_ASSERT(MxBITMAPINFO, 1064);
|
||||||
|
|
||||||
// The way that the BITMAPFILEHEADER structure ensures the file type is by ensuring it is "BM", which is literally just 0x424d.
|
// The way that the BITMAPFILEHEADER structure ensures the file type is by ensuring it is "BM", which is literally just 0x424d.
|
||||||
// Sources: https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapfileheader, DirectX Complete (1998)
|
// Sources: https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapfileheader, DirectX Complete (1998)
|
||||||
@ -34,17 +37,19 @@ int MxBitmap::vtable14(int)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x100bcba0
|
// OFFSET: LEGO1 0x100bcba0
|
||||||
MxResult MxBitmap::vtable18(BITMAPINFOHEADER *p_bmiHeader)
|
MxResult MxBitmap::vtable18(MxBITMAPINFO *p_info)
|
||||||
{
|
{
|
||||||
MxResult result = FAILURE;
|
MxResult result = FAILURE;
|
||||||
MxU32 width = p_bmiHeader->biWidth;
|
MxLong width = p_info->bmiHeader.biWidth;
|
||||||
MxU32 height = p_bmiHeader->biHeight;
|
MxLong height = p_info->bmiHeader.biHeight;
|
||||||
|
// ((width + 3) & -4) clamps width to nearest 4-byte boundary
|
||||||
|
MxLong size = ((width + 3) & -4) * height;
|
||||||
|
|
||||||
this->m_info = new BITMAPINFO;
|
this->m_info = new MxBITMAPINFO;
|
||||||
if (this->m_info) {
|
if (this->m_info) {
|
||||||
this->m_data = (LPVOID*) malloc((sizeof(width + 3U & -4) * height));
|
this->m_data = (LPVOID*) new MxU8[size];
|
||||||
if(this->m_data) {
|
if(this->m_data) {
|
||||||
memcpy(&this->m_info->bmiHeader, p_bmiHeader, sizeof(BITMAPINFO));
|
memcpy(this->m_info, p_info, sizeof(MxBITMAPINFO));
|
||||||
this->m_bmiHeader = &this->m_info->bmiHeader;
|
this->m_bmiHeader = &this->m_info->bmiHeader;
|
||||||
this->m_paletteData = this->m_info->bmiColors;
|
this->m_paletteData = this->m_info->bmiColors;
|
||||||
result = SUCCESS;
|
result = SUCCESS;
|
||||||
@ -53,9 +58,11 @@ MxResult MxBitmap::vtable18(BITMAPINFOHEADER *p_bmiHeader)
|
|||||||
if (result != SUCCESS) {
|
if (result != SUCCESS) {
|
||||||
if (this->m_info) {
|
if (this->m_info) {
|
||||||
delete this->m_info;
|
delete this->m_info;
|
||||||
|
this->m_info = NULL;
|
||||||
}
|
}
|
||||||
if (this->m_data) {
|
if (this->m_data) {
|
||||||
delete this->m_data;
|
delete this->m_data;
|
||||||
|
this->m_data = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -63,26 +70,27 @@ MxResult MxBitmap::vtable18(BITMAPINFOHEADER *p_bmiHeader)
|
|||||||
|
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x100bd450
|
// OFFSET: LEGO1 0x100bd450
|
||||||
MxResult ImportColorsToPalette(RGBQUAD* p_rgbquad, MxPalette* p_palette)
|
MxResult MxBitmap::ImportColorsToPalette(RGBQUAD* p_rgbquad, MxPalette* p_palette)
|
||||||
{
|
{
|
||||||
MxPalette* local_pal;
|
|
||||||
MxResult ret = FAILURE;
|
MxResult ret = FAILURE;
|
||||||
PALETTEENTRY entries[256];
|
PALETTEENTRY entries[256];
|
||||||
MxResult opret;
|
|
||||||
|
|
||||||
if(p_palette == NULL) {
|
if (p_palette) {
|
||||||
local_pal = new MxPalette;
|
if (p_palette->GetEntries(entries))
|
||||||
opret = local_pal->GetEntries(entries);
|
|
||||||
if(opret != 0) {
|
|
||||||
delete local_pal;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
opret = p_palette->GetEntries(entries);
|
MxPalette local_pal;
|
||||||
if(opret != 0) return ret;
|
if (local_pal.GetEntries(entries))
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
p_rgbquad[i].rgbRed = entries[i].peRed;
|
||||||
|
p_rgbquad[i].rgbGreen = entries[i].peGreen;
|
||||||
|
p_rgbquad[i].rgbBlue = entries[i].peBlue;
|
||||||
|
p_rgbquad[i].rgbReserved = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME/TODO: the loop here, possibly memcpy
|
|
||||||
ret = SUCCESS;
|
ret = SUCCESS;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -105,14 +113,14 @@ MxResult MxBitmap::LoadFile(HANDLE p_handle)
|
|||||||
|
|
||||||
ret = ReadFile(p_handle, &hdr, sizeof(hdr), &bytesRead, NULL);
|
ret = ReadFile(p_handle, &hdr, sizeof(hdr), &bytesRead, NULL);
|
||||||
if (ret && (hdr.bfType == g_bitmapSignature)) {
|
if (ret && (hdr.bfType == g_bitmapSignature)) {
|
||||||
this->m_info = new BITMAPINFO;
|
this->m_info = new MxBITMAPINFO;
|
||||||
if(this->m_info) {
|
if(this->m_info) {
|
||||||
ret = ReadFile(p_handle, this->m_info, 1064, &bytesRead, NULL);
|
ret = ReadFile(p_handle, this->m_info, sizeof(MxBITMAPINFO), &bytesRead, NULL);
|
||||||
if (ret && ((this->m_info->bmiHeader).biBitCount == 8)) {
|
if (ret && ((this->m_info->bmiHeader).biBitCount == 8)) {
|
||||||
lpBuffer = (LPVOID*) malloc(hdr.bfSize - 1078);
|
lpBuffer = (LPVOID*) malloc(hdr.bfSize - (sizeof(MxBITMAPINFO) + sizeof(BITMAPFILEHEADER)));
|
||||||
this->m_data = lpBuffer;
|
this->m_data = lpBuffer;
|
||||||
if (this->m_data) {
|
if (this->m_data) {
|
||||||
ret = ReadFile(p_handle, lpBuffer, hdr.bfSize - 1078, &bytesRead, NULL);
|
ret = ReadFile(p_handle, lpBuffer, hdr.bfSize - (sizeof(MxBITMAPINFO) + sizeof(BITMAPFILEHEADER)), &bytesRead, NULL);
|
||||||
if(ret != 0) {
|
if(ret != 0) {
|
||||||
this->m_bmiHeader = &this->m_info->bmiHeader;
|
this->m_bmiHeader = &this->m_info->bmiHeader;
|
||||||
this->m_paletteData = this->m_info->bmiColors;
|
this->m_paletteData = this->m_info->bmiColors;
|
||||||
@ -211,13 +219,20 @@ MxPalette *MxBitmap::CreatePalette()
|
|||||||
// OFFSET: LEGO1 0x100bd280
|
// OFFSET: LEGO1 0x100bd280
|
||||||
void MxBitmap::ImportPalette(MxPalette* p_palette)
|
void MxBitmap::ImportPalette(MxPalette* p_palette)
|
||||||
{
|
{
|
||||||
if (this->m_bmiColorsProvided) {
|
// This is weird but it matches. Maybe m_bmiColorsProvided had more
|
||||||
ImportColorsToPalette(this->m_paletteData, p_palette);
|
// potential values than just true/false at some point?
|
||||||
|
switch (this->m_bmiColorsProvided) {
|
||||||
|
case FALSE:
|
||||||
|
ImportColorsToPalette(this->m_paletteData, p_palette);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TRUE:
|
||||||
|
if (this->m_palette) {
|
||||||
|
delete this->m_palette;
|
||||||
|
}
|
||||||
|
this->m_palette = p_palette->Clone();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (this->m_palette) {
|
|
||||||
delete this->m_palette;
|
|
||||||
}
|
|
||||||
this->m_palette = p_palette->Clone();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x100bd2d0 STUB
|
// OFFSET: LEGO1 0x100bd2d0 STUB
|
||||||
@ -234,5 +249,5 @@ MxResult MxBitmap::CopyColorData(HDC p_hdc, int p_xSrc, int p_ySrc, int p_xDest,
|
|||||||
p_ySrc = (this->m_bmiHeader->biHeight - p_destHeight) - p_ySrc;
|
p_ySrc = (this->m_bmiHeader->biHeight - p_destHeight) - p_ySrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return StretchDIBits(p_hdc, p_xDest, p_yDest, p_destWidth, p_destHeight, p_xSrc, p_ySrc, p_destWidth, p_destHeight, this->m_data, this->m_info, this->m_bmiColorsProvided, SRCCOPY);
|
return StretchDIBits(p_hdc, p_xDest, p_yDest, p_destWidth, p_destHeight, p_xSrc, p_ySrc, p_destWidth, p_destHeight, this->m_data, (BITMAPINFO*)this->m_info, this->m_bmiColorsProvided, SRCCOPY);
|
||||||
}
|
}
|
||||||
@ -7,6 +7,20 @@
|
|||||||
#include "mxpalette.h"
|
#include "mxpalette.h"
|
||||||
#include "mxtypes.h"
|
#include "mxtypes.h"
|
||||||
|
|
||||||
|
// The stock BITMAPINFO struct from wingdi.h only makes room for one color
|
||||||
|
// in the palette. It seems like the expectation (if you use the struct)
|
||||||
|
// is to malloc as much as you actually need, and then index into the array
|
||||||
|
// anyway even though its stated size is [1].
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfo
|
||||||
|
// In our case, the size 0x428 is used frequently, which matches
|
||||||
|
// a 40-byte header plus 256 colors, so just use that as our template.
|
||||||
|
|
||||||
|
// SIZE 0x428
|
||||||
|
struct MxBITMAPINFO {
|
||||||
|
BITMAPINFOHEADER bmiHeader;
|
||||||
|
RGBQUAD bmiColors[256];
|
||||||
|
};
|
||||||
|
|
||||||
class MxBitmap : public MxCore
|
class MxBitmap : public MxCore
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -14,7 +28,7 @@ class MxBitmap : public MxCore
|
|||||||
__declspec(dllexport) virtual ~MxBitmap(); // vtable+00
|
__declspec(dllexport) virtual ~MxBitmap(); // vtable+00
|
||||||
|
|
||||||
virtual int vtable14(int);
|
virtual int vtable14(int);
|
||||||
virtual MxResult vtable18(BITMAPINFOHEADER *p_bmiHeader);
|
virtual MxResult vtable18(MxBITMAPINFO *p_info);
|
||||||
virtual int vtable1c(int p_width, int p_height, MxPalette *p_palette, int);
|
virtual int vtable1c(int p_width, int p_height, MxPalette *p_palette, int);
|
||||||
virtual MxResult LoadFile(HANDLE p_handle);
|
virtual MxResult LoadFile(HANDLE p_handle);
|
||||||
__declspec(dllexport) virtual MxLong Read(const char *p_filename); // vtable+24
|
__declspec(dllexport) virtual MxLong Read(const char *p_filename); // vtable+24
|
||||||
@ -27,7 +41,9 @@ class MxBitmap : public MxCore
|
|||||||
virtual MxResult CopyColorData(HDC p_hdc, int p_xSrc, int p_ySrc, int p_xDest, int p_yDest, int p_destWidth, int p_destHeight); // vtable+40
|
virtual MxResult CopyColorData(HDC p_hdc, int p_xSrc, int p_ySrc, int p_xDest, int p_yDest, int p_destWidth, int p_destHeight); // vtable+40
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BITMAPINFO *m_info; // 0x8
|
MxResult ImportColorsToPalette(RGBQUAD*, MxPalette*);
|
||||||
|
|
||||||
|
MxBITMAPINFO *m_info; // 0x8
|
||||||
BITMAPINFOHEADER *m_bmiHeader; // 0xc
|
BITMAPINFOHEADER *m_bmiHeader; // 0xc
|
||||||
RGBQUAD *m_paletteData; // 0x10
|
RGBQUAD *m_paletteData; // 0x10
|
||||||
LPVOID *m_data; // 0x14
|
LPVOID *m_data; // 0x14
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user