Skip to content

Commit

Permalink
Load8BitBMP2
Browse files Browse the repository at this point in the history
With tests
  • Loading branch information
krystalgamer committed Oct 3, 2024
1 parent 2998e9e commit ff36d82
Show file tree
Hide file tree
Showing 10 changed files with 723 additions and 14 deletions.
211 changes: 207 additions & 4 deletions Image.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#include "Image.h"
#include "validate.h"
#include "dcshellutils.h"
#include "PCTex.h"
#include "dcfileio.h"
#include "mem.h"

#include "validate.h"


u16 gSlicedImageRelated[16];
u16 gSlicedImageRelated[256];

// @Ok
void SlicedImage2::pack(void)
Expand Down Expand Up @@ -208,7 +209,7 @@ i32 LoadNBitBMP_(
}
else
{
Load8BitBMP2(reinterpret_cast<char*>(pBmp), a2, a3, a4, a5, 0);
Load8BitBMP_2(reinterpret_cast<char*>(pBmp), a2, a3, a4, a5);
}

Mem_Delete(pBmp);
Expand Down Expand Up @@ -247,12 +248,141 @@ int SlicedImage2::screenHeight(void)
}

// @Ok
int Load8BitBMP_2(char *a1, char **a2, int *a3, int *a4, unsigned __int16 *a5)
INLINE i32 Load8BitBMP_2(char *a1, char **a2, int *a3, int *a4, unsigned __int16 *a5)
{
Load8BitBMP2(a1, a2, a3, a4, a5, false);
return 1;
}

// @Ok
// @Validated
i32 Load8BitBMP2(
char *pData,
char **data,
i32 *ww,
i32 *hh,
u16 *clut,
bool a6)
{
*data = 0;

BMPHeader *pBmp = reinterpret_cast<BMPHeader*>(pData);
u16 height_px = pBmp->height_px;
u16 width_px = pBmp->width_px;
u16 bits_per_pixel = pBmp->bits_per_pixel;

if ((bits_per_pixel != 16) & (bits_per_pixel != 8))
{
error("\nNot 8 bits per pixel, is %d bits per pixel", bits_per_pixel);
return 0;
}

u16 num_colors = pBmp->num_colors;
if (!num_colors)
num_colors = 256;


u16* pClut = PCTex_CreateClut(256);

u8* pPalette = reinterpret_cast<u8*>(&pBmp[1]);
char v18;

for (i32 i = 0; i < num_colors; i++)
{
u16 v22[3];

if (bits_per_pixel == 8)
{
v22[0] = pPalette[0];
v22[1] = pPalette[1];
v22[2] = pPalette[2];
}
else
{
char* pCPalette = reinterpret_cast<char*>(pPalette);
v22[0] = pCPalette[0];
v22[1] = pCPalette[1];
v22[2] = pCPalette[2];
}

if( v22[0] <= 0xF7 || v22[1] || v22[2] <= 0xF7)
{
i8 v25 = 0;
if (v22[0] < 8u && v22[1] < 8u && v22[2] < 8u && (v22[0] || v22[1] || v22[2]) )
v25 = 1;

i16 v26[3];
if ( v25 )
{
v26[0] = 1;
v26[1] = 1;
v26[2] = 1;
}
else
{
v26[0] = v22[0] >> 3;
v26[1] = v22[1] >> 3;
v26[2] = v22[2] >> 3;
}
if ( v26[0] || v26[1] || v26[2] )
pClut[i] = v26[0] + 32 * (v26[1] + 32 * (v26[2] + 32));
else
pClut[i] = 0x8000;
}
else
{
pClut[i] = 0;
v18 = i;
}

pPalette += 4;
}

for (i32 j = 0; j < 256; j++)
{
gSlicedImageRelated[j] = pClut[j];
}

i32 v19 = width_px % 4;
if (v19 > 0)
v19 = 4 - v19;

i32 rounded_width = v19 + width_px;

char *dstData = reinterpret_cast<char*>(DCMem_New(rounded_width * height_px, 1, 1, 0, 1));
//char *dstData = reinterpret_cast<char*>(malloc(rounded_width * height_px));;
*data = dstData;
char* pPixel = reinterpret_cast<char*>(&reinterpret_cast<i32*>(&pBmp[1])[num_colors]);

char* pRow = &dstData[(height_px - 1) * rounded_width];

for (i32 k = 0; k < height_px; k++)
{
for (i32 m = 0; m < rounded_width - v19; m++)
{
*pRow++ = *pPixel++;
}

for (i32 l = 0; l < v19; l++)
{
*pRow++ = v18;
pPixel++;
}

pRow -= 2 * rounded_width;
}


if (a6)
Mem_Delete(pData);

*ww = rounded_width;
*hh = height_px;
*clut = -1;
return 1;
}


void validate_SlicedImage2(void)
{
VALIDATE_SIZE(SlicedImage2, 0x20);
Expand Down Expand Up @@ -283,3 +413,76 @@ void validate_Image(void)
VALIDATE(Image, field_B, 0xB);
VALIDATE(Image, field_C, 0xC);
}

void validate_BmpHeader(void)
{
VALIDATE_SIZE(BMPHeader, 0x36);

VALIDATE(BMPHeader, type, 0x0);
VALIDATE(BMPHeader, size, 0x2);

VALIDATE(BMPHeader, width_px, 0x12);
VALIDATE(BMPHeader, height_px, 0x16);
VALIDATE(BMPHeader, num_planes, 0x1A);
VALIDATE(BMPHeader, bits_per_pixel, 0x1C);
VALIDATE(BMPHeader, image_size_bytes, 0x22);

VALIDATE(BMPHeader, num_colors, 0x2E);

}
void validate_Load8BitBMP2(void)
{
return;

FILE *bmpFp = fopen("LegalPC.bmp", "rb");

if (!bmpFp)
{
puts("Couldnt open LegalPC.bmp");
return;
}

char legalpc[0x1E436];
if(!fread(legalpc, 0x1E436, 1, bmpFp))
{
puts("Couldnt read LegalPC.bmp");
fclose(bmpFp);
return;
}

fclose(bmpFp);

char* data = 0;
i32 width = 0;
i32 height = 0;
u16 clut = 0;
i32 ret = Load8BitBMP2(legalpc, &data, &width, &height, &clut, false);

VALIDATE_I32(ret, 1);
VALIDATE_I32(width, 0x200);
VALIDATE_I32(height, 0xF0);
VALIDATE_I32(clut, 0xFFFF);

puts("Finished basics");

u16 gSlicedExpected[0x100];
if (read_into("legalbmpgsliced.bin", gSlicedExpected, 0x200))
return;

if (compare_buffs("gsliced", gSlicedImageRelated, gSlicedExpected, 0x200))
return;

u8 expectedBmpData[0x1E000];

if (read_into("legalbmpdata.bin", expectedBmpData, sizeof(expectedBmpData)))
return;

if (compare_buffs("bmpdata", expectedBmpData, data, sizeof(expectedBmpData)))
{
FILE *fp = fopen("mylegal.bin", "wb");

fwrite(data, sizeof(expectedBmpData), 1, fp);
fclose(fp);
return;
}
}
29 changes: 27 additions & 2 deletions Image.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,28 @@
#include "export.h"
#include "main.h"

#pragma pack(push, 1)
struct BMPHeader
{
u16 type; // Magic identifier: 0x4d42
u32 size; // File size in bytes
u16 reserved1; // Not used
u16 reserved2; // Not used
u32 offset; // Offset to image data in bytes from beginning of file (54 bytes)
u32 dib_header_size; // DIB Header size in bytes (40 bytes)
i32 width_px; // Width of the image
i32 height_px; // Height of image
u16 num_planes; // Number of color planes
u16 bits_per_pixel; // Bits per pixel
u32 compression; // Compression type
u32 image_size_bytes; // Image size in bytes
i32 x_resolution_ppm; // Pixels per meter
i32 y_resolution_ppm; // Pixels per meter
u32 num_colors; // Number of colors
u32 important_colors; // Important colors
};
#pragma pack(pop)

class Image : public CClass
{
public:
Expand Down Expand Up @@ -49,13 +71,16 @@ class SlicedImage2 : public Image
u16 field_1E;
};

EXPORT int Load8BitBMP_2(char *, char **, i32 *, i32 *, u16*);
EXPORT i32 Load8BitBMP_2(char *, char **, i32 *, i32 *, u16*);
EXPORT i32 Load8BitBMP2(char *, char **, i32 *, i32 *, u16*, bool);
EXPORT i32 GetBMPBitDepth(char *);
EXPORT void Load4BitBMP_2(char *,char **,i32 *,i32 *,u16 *);
EXPORT i32 LoadNBitBMP_(const char *,char **,i32 *,i32 *,u16 *,i32 *);

EXPORT extern u16 gSlicedImageRelated[16];
EXPORT extern u16 gSlicedImageRelated[256];

void validate_Image(void);
void validate_SlicedImage2(void);
void validate_BmpHeader(void);
void validate_Load8BitBMP2(void);
#endif
7 changes: 0 additions & 7 deletions dcshellutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,6 @@ Sprite2::Sprite2(
}
}

// @BIGTODO
void Load8BitBMP2(char *a1, char **a2, int *a3, int *a4, unsigned __int16 *a5, bool a6)
{

printf("void Load8BitBMP2(char *a1, char **a2, int *a3, int *a4, unsigned __int16 *a5, bool a6)");
}

// @Ok
// @Test
// @Validate
Expand Down
1 change: 0 additions & 1 deletion dcshellutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ class Sprite2 : public SlicedImage2
u8* field_20;
};

EXPORT void Load8BitBMP2(char *, char **, int *, int *, unsigned __int16 *, bool);
EXPORT void DCSpriteDraw(i32, i32, i32, float, u32, u32, u32, i32, u32, float);

void validate_Sprite2(void);
Expand Down
2 changes: 2 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,8 @@ i32 validate(void)
validate_SButton();
validate_DDPIXELFORMAT();
validate_ConvertPSXPaletteToPC();
validate_BmpHeader();
validate_Load8BitBMP2();

puts("[*] Validation done!");

Expand Down
Binary file added tests/bmp/LegalPC.bmp
Binary file not shown.
440 changes: 440 additions & 0 deletions tests/bmp/legalbmpdata.bin

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions tests/bmp/legalbmpgsliced.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
!�A�����%�d�����a�����Ǡ����&���
�J���ɘ�.�̌���͠
�*���M��-�L�L��.�O�N��� �*�����M�M�������!�aѢɡ�F�fц�����J�hժɩ�m����ժ�������!����E������
�)��-֏ޏ�I����M�n���
��-��2���5���s�ҠV�ըװ0�Q������ѝ����ҕ�u���0�0�p�p��r�r�p������Щ����ӥҩ��u�U�����ԥԩ����֥��չ8�9�����<�^�ݸx�����y�9������ݥ��������{���>Ž���2���U���2������T�U���V�v�5��U�U���V�V������9���]���:�9������>��������>�2�SғΓ�5�U֖ζ�p�p�����������T���X�yҹ���]�^���������;��>�>۟�9�{���^�|����
Expand Down
39 changes: 39 additions & 0 deletions validate.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "validate.h"
#include <cstdarg>

#include <cstring>

int FAIL_VALIDATION = 0;

void validate_i32(int cur, int expected, const char *name, int line)
Expand Down Expand Up @@ -82,3 +84,40 @@ void validate_vtable_index(
fflush(stdout);
#endif
}

i32 read_into(const char* fileName, void* dst, u32 size)
{
FILE *fp = fopen(fileName, "rb");
if (!fp)
{
printf("Couldnt open ");
printf(fileName);
return 1;
}

if (!fread(dst, size, 1, fp))
{
printf("Couldnt read ");
printf(fileName);
puts("");

fclose(fp);
return 1;
}

fclose(fp);
return 0;
}

i32 compare_buffs(const char* name, void* src, void* dst, u32 size)
{
if(!memcmp(src, dst, 0x200))
{
return 0;
}

printf("Failed comparing buffer ");
printf(name);
puts("");
return 1;
}
3 changes: 3 additions & 0 deletions validate.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,8 @@ void validate_vtable_index(
validate_vtable_index(expected, get_thunk_address(0, &cls::member), #cls, #member);\
}

i32 read_into(const char* fileName, void* dst, u32 size);

i32 compare_buffs(const char*, void*, void*, u32 size);

#endif

0 comments on commit ff36d82

Please sign in to comment.