Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdarg.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <gctypes.h>
- extern "C"
- {
- #include "wpad.h"
- #include "video.h"
- };
- #define DEBUG_PRINT
- #ifdef DEBUG_PRINT
- FILE * debugfile;
- #endif
- void debug_print(const char * format, ...)
- {
- char * tmp = 0;
- va_list va;
- va_start(va, format);
- if((vasprintf(&tmp, format, va)>=0) && tmp)
- {
- printf(tmp);
- #ifdef DEBUG_PRINT
- fprintf(debugfile, tmp);
- #endif
- free(tmp);
- }
- va_end(va);
- }
- struct IMD5Header
- {
- u32 fcc;
- u32 filesize;
- u8 zeroes[8];
- u8 crypto[16];
- } __attribute__((packed));
- struct IMETHeader
- {
- u8 zeroes[64];
- u32 fcc;
- u8 unk[8];
- u32 iconSize;
- u32 bannerSize;
- u32 soundSize;
- u32 flag1;
- u8 names[7][84];
- u8 zeroes_2[0x348];
- u8 crypto[16];
- } __attribute__((packed));
- struct U8Header
- {
- u32 fcc;
- u32 rootNodeOffset;
- u32 headerSize;
- u32 dataOffset;
- u8 zeroes[16];
- } __attribute__((packed));
- struct U8Entry
- {
- struct
- {
- u32 fileType : 8;
- u32 nameOffset : 24;
- };
- u32 fileOffset;
- union
- {
- u32 fileLength;
- u32 numEntries;
- };
- } __attribute__((packed));
- struct LZ77Info
- {
- u16 length : 4;
- u16 offset : 12;
- } __attribute__((packed));
- typedef struct
- {
- u32 fcc; // "RLYT" in ASCII
- u32 version; // Always 0xFE 0xFF 0x 00 0x08.
- u32 filesize; // Size of whole file, including the header.
- u32 num; // number of sections
- } BRLYT_Header;
- typedef struct
- {
- u32 fcc; // "lyt1" in ASCII.
- u32 size_header;
- u8 layout_centered; // 1 if layout is drawn from center
- u8 pad[3];
- float width;
- float height;
- } LYT1_Header;
- typedef struct
- {
- u32 fcc; // "txl1" in ASCII.
- u32 size_section; // Size of the whole section.
- u16 num_textures; // Number of textures in list.
- u16 offset_to_next_section; // Should be 0
- } TXL1_Header;
- typedef struct
- {
- u32 offset_filename; // Offset to a null-terminated ASCII string containing the filename.
- u32 pad; // Always zero
- } TXL1_Offset;
- typedef struct
- {
- u32 fcc; // "mat1" in ASCII.
- u32 size_section; // // Size of the whole section.
- u16 num_materials; //
- u16 size_header; // Offset to list start. Always zero
- } MAT1_Header;
- typedef struct
- {
- u32 offset; // Offset from beginning of mat1-section.
- } MAT1_Offset;
- typedef struct
- {
- char name[20];
- s16 fore_color[4];
- s16 back_color[4];
- s16 tevREG3_color[4];
- u32 tev_kcolor[4];
- u32 flags;
- } MAT1_Material;
- typedef struct
- {
- u16 text_offset; //texture # in the txl1 list
- u8 wrap_modes[2];
- } MAT1_TexRef;
- typedef struct
- {
- u32 fcc; // "pic1" in ASCII.
- u32 size_section;
- u8 visibility;
- u8 pane_origin;
- u8 alpha1;
- u8 alpha2;
- char name[0x18];
- float x;
- float y;
- float z;
- float xFlip;
- float yFlip;
- float angle;
- float xMag;
- float yMag;
- float width;
- float height;
- } PIC1_Header;
- typedef struct
- {
- u32 fcc; // "pan1" in ASCII.
- u32 size_section;
- u8 visibility;
- u8 pane_origin;
- u8 alpha1;
- u8 padding;
- char pane_name [0x10]; // Pane name in ASCII.
- char user_data [0x08]; // User data
- float xTranslate;
- float yTranslate;
- float zTranslate;
- float xRotate;
- float yRotate;
- float zRotate;
- float xScale;
- float yScale;
- float width;
- float height;
- } PAN1_Header;
- static char *u8Filename(const U8Entry *fst, int i)
- {
- return (char *)(fst + fst[0].numEntries) + fst[i].nameOffset;
- }
- inline u32 le32(u32 i)
- {
- return ((i & 0xFF) << 24) | ((i & 0xFF00) << 8) | ((i & 0xFF0000) >> 8) | ((i & 0xFF000000) >> 24);
- }
- inline u16 le16(u16 i)
- {
- return ((i & 0xFF) << 8) | ((i & 0xFF00) >> 8);
- }
- static u8 *uncompressLZ77(const u8 *inBuf, u32 inLength, u32 &size)
- {
- u8 *buffer = NULL;
- if (inLength <= 0x8 || *((const u32 *)inBuf) != 0x4C5A3737 /*"LZ77"*/ || inBuf[4] != 0x10)
- return NULL;
- u32 uncSize = le32(((const u32 *)inBuf)[1] << 8);
- const u8 *inBufEnd = inBuf + inLength;
- inBuf += 8;
- buffer = new u8[uncSize];
- if (!buffer)
- return buffer;
- u8 *bufCur = buffer;
- u8 *bufEnd = buffer + uncSize;
- while (bufCur < bufEnd && inBuf < inBufEnd)
- {
- u8 flags = *inBuf;
- ++inBuf;
- for (int i = 0; i < 8 && bufCur < bufEnd && inBuf < inBufEnd; ++i)
- {
- if ((flags & 0x80) != 0)
- {
- const LZ77Info &info = *(const LZ77Info *)inBuf;
- inBuf += sizeof (LZ77Info);
- int length = info.length + 3;
- if (bufCur - info.offset - 1 < buffer || bufCur + length > bufEnd)
- return buffer;
- memcpy(bufCur, bufCur - info.offset - 1, length);
- bufCur += length;
- }
- else
- {
- *bufCur = *inBuf;
- ++inBuf;
- ++bufCur;
- }
- flags <<= 1;
- }
- }
- size = uncSize;
- return buffer;
- }
- const u8 *LoadBannerBin(const u8 *opening_bnr, u32 *size)
- {
- const IMETHeader *imetHdr = (IMETHeader *)opening_bnr;
- if ( imetHdr->fcc != 0x494D4554 /*"IMET"*/ )
- {
- debug_print("IMET Header wrong: %08X\n", imetHdr->fcc);
- debug_print("IMET Header wrong: %s\n", (char*) &imetHdr->fcc);
- return NULL;
- }
- const U8Header *bnrArcHdr = (U8Header *)(imetHdr + 1);
- const U8Entry *fst = (const U8Entry *)( ((const u8 *)bnrArcHdr) + bnrArcHdr->rootNodeOffset);
- u32 i;
- for (i = 1; i < fst[0].numEntries; ++i)
- if (fst[i].fileType == 0 && strcasecmp(u8Filename(fst, i), "banner.bin") == 0)
- break;
- if (i >= fst[0].numEntries)
- {
- /* Not all games have a sound.bin and this message is annoying **/
- debug_print("banner.bin not found.\n");
- return 0;
- }
- const u8 *banner_bin = ((const u8 *)bnrArcHdr) + fst[i].fileOffset;
- if ( ((IMD5Header *)banner_bin)->fcc != 0x494D4435 /*"IMD5"*/ )
- {
- debug_print("IMD5 error: %08X\n", ((IMD5Header *)banner_bin)->fcc);
- debug_print("IMD5: %s\n", (char*) &((IMD5Header *)banner_bin)->fcc);
- return 0;
- }
- *size = ((IMD5Header *)banner_bin)->filesize;
- return banner_bin;
- }
- const u8 *LoadBRLYT(const u8 *bannerbin, u32 * outsize)
- {
- u32 size = ((IMD5Header *)bannerbin)->filesize;
- const IMD5Header *IMD5Hdr = (IMD5Header *)bannerbin;
- const u8 * binfile = (const u8 *)(IMD5Hdr+1);
- const u8 * unpackedbin = binfile;
- u32 uncSize = size;
- if(*((u32*)binfile) == 0x4C5A3737 /* LZ77 */)
- {
- unpackedbin = uncompressLZ77(binfile, size-sizeof(IMD5Header), uncSize);
- }
- const U8Header * binHdr = (const U8Header *) unpackedbin;
- if(binHdr->fcc != 0x55AA382D)
- {
- debug_print("Wrong u8 tag: %08X\n", binHdr->fcc);
- return 0;
- }
- const U8Entry *fst = (const U8Entry *)( ((const u8 *)binHdr) + binHdr->rootNodeOffset);
- u32 i;
- for (i = 1; i < fst[0].numEntries; ++i)
- {
- //debug_print("%s\n", u8Filename(fst, i));
- if (fst[i].fileType == 0 && strstr(u8Filename(fst, i), ".brlyt") != 0)
- break;
- }
- if (i >= fst[0].numEntries)
- {
- /* Not all games have a sound.bin and this message is annoying **/
- debug_print("brlyt not found.\n");
- return 0;
- }
- const u8 * banner_brlyt = ((const u8 *)binHdr) + fst[i].fileOffset;
- if ( ((BRLYT_Header *)banner_brlyt)->fcc != 0x524C5954 /*"RLYT"*/ )
- {
- debug_print("BRLYT error: %08X\n", ((BRLYT_Header *)banner_brlyt)->fcc);
- debug_print("BRLYT: %s\n", (char*) &((BRLYT_Header *)banner_brlyt)->fcc);
- return 0;
- }
- *outsize = ((BRLYT_Header *)banner_brlyt)->filesize;
- return banner_brlyt;
- }
- const u8 *LoadBRLYT_Info(const u8 *brlytfile)
- {
- const BRLYT_Header * brlytHeader = (const BRLYT_Header *) brlytfile;
- if(brlytHeader->fcc != 0x524C5954 /*"RLYT"*/)
- {
- debug_print("BRLYT_Header error: %s\n", (char*) &((BRLYT_Header *)brlytHeader)->fcc);
- return 0;
- }
- u32 filesize = brlytHeader->filesize;
- const LYT1_Header * lyt1 = (const LYT1_Header *) (brlytHeader+1);
- if(lyt1->fcc != 0x6C797431 /*"lyt1"*/)
- {
- debug_print("LYT1_Header error: %s\n", (char*) &((LYT1_Header *)lyt1)->fcc);
- return 0;
- }
- debug_print("\n");
- debug_print("LYT1_Header: %s\n", (char*) &((LYT1_Header *)lyt1)->fcc);
- debug_print("size_header: %d\n", lyt1->size_header);
- debug_print("layout_centered: %d\n", lyt1->layout_centered);
- debug_print("width: %0.2f\n", lyt1->width);
- debug_print("height: %0.2f\n", lyt1->height);
- debug_print("\n");
- const TXL1_Header * txl1 = (const TXL1_Header *) (lyt1+1);
- if(txl1->fcc != 0x74786C31 /*"txl1"*/)
- {
- debug_print("TXL1_Header error: %s\n", (char*) &((TXL1_Header *)txl1)->fcc);
- return 0;
- }
- const TXL1_Offset * txl1_off = (TXL1_Offset *) (txl1+1);
- for(u16 i = 0; i < txl1->num_textures; i++)
- {
- debug_print("%d: %s\n", i, (const char*) ((const u8*)(txl1+1)+txl1_off->offset_filename));
- txl1_off++;
- }
- const u8 * ptr = (u8 *) txl1_off;
- while(!(*((u32*)ptr) == 0x6D617431 /* mat1 */))
- {
- ptr++;
- }
- const MAT1_Header * mat1 = (MAT1_Header *) ptr;
- const MAT1_Offset * mat1_off = (MAT1_Offset *) (mat1+1);
- for(u16 n = 0; n < mat1->num_materials; n++)
- {
- const MAT1_Material * mat1Material = (MAT1_Material *) ((const u8*)(ptr)+mat1_off->offset);
- debug_print("\n");
- debug_print("%d: %s\n", n, mat1Material->name);
- for(int i = 0; i < 4; i++)
- debug_print("fore_color[%d]: %d\n", i, mat1Material->fore_color[i]);
- for(int i = 0; i < 4; i++)
- debug_print("back_color[%d]: %d\n", i, mat1Material->back_color[i]);
- for(int i = 0; i < 4; i++)
- debug_print("tevREG3_color[%d]: %d\n", i, mat1Material->tevREG3_color[i]);
- for(int i = 0; i < 4; i++)
- debug_print("tev_kcolor[%d]: %d\n", i, mat1Material->tev_kcolor[i]);
- debug_print("%d flags: %d\n", n, mat1Material->flags);
- const MAT1_TexRef * matTextRef = (MAT1_TexRef*) (mat1Material+1);
- txl1_off = ((TXL1_Offset *) (txl1+1)) + matTextRef->text_offset;
- const char* tex_filename = (char*) ((const u8*)(txl1+1)+txl1_off->offset_filename);
- debug_print("RefTex: %s\n", tex_filename);
- mat1_off++;
- }
- u32 i = 0;
- ptr = brlytfile;
- while(i < filesize)
- {
- if (*((u32*)ptr) == 0x70696331 /*"pic1"*/)
- {
- const PIC1_Header * pic1 = (const PIC1_Header *) ptr;
- debug_print("\n");
- debug_print("PIC1_Header: %s\n", (char*) &((PIC1_Header *)pic1)->fcc);
- debug_print("size_section: %d\n", pic1->size_section);
- debug_print("visibility: %d\n", pic1->visibility);
- debug_print("pane_origin: %d\n", pic1->pane_origin);
- debug_print("alpha1: %d\n", pic1->alpha1);
- debug_print("alpha2: %d\n", pic1->alpha2);
- debug_print("Name: %s\n", pic1->name); //seems to be the equivalent to mat1 names
- debug_print("X: %0.2f\n", pic1->x);
- debug_print("Y: %0.2f\n", pic1->y);
- debug_print("Z: %0.2f\n", pic1->z);
- debug_print("X-FLIP: %0.2f\n", pic1->xFlip);
- debug_print("Y-FLIP: %0.2f\n", pic1->yFlip);
- debug_print("angle: %0.2f\n", pic1->angle);
- debug_print("X-MAG: %0.2f\n", pic1->xMag);
- debug_print("Y-MAG: %0.2f\n", pic1->yMag);
- debug_print("width: %0.2f\n", pic1->width);
- debug_print("height: %0.2f\n", pic1->height);
- }
- else if (*((u32*)ptr) == 0x70616E31 /*"pan1"*/)
- {
- const PAN1_Header * pan1 = (const PAN1_Header *) ptr;
- debug_print("\n");
- debug_print("PAN1_Header: %s\n", (char*) &((PAN1_Header *)pan1)->fcc);
- debug_print("size_section: %d\n", pan1->size_section);
- debug_print("visibility: %d\n", pan1->visibility);
- debug_print("pane_origin: %d\n", pan1->pane_origin);
- debug_print("alpha1: %d\n", pan1->alpha1);
- debug_print("padding: %d\n", pan1->padding);
- debug_print("Name: %s\n", pan1->pane_name);
- debug_print("user_data: %s\n", pan1->user_data);
- debug_print("xTranslate: %0.2f\n", pan1->xTranslate);
- debug_print("yTranslate: %0.2f\n", pan1->yTranslate);
- debug_print("zTranslate: %0.2f\n", pan1->zTranslate);
- debug_print("xRotate: %0.2f\n", pan1->xRotate);
- debug_print("yRotate: %0.2f\n", pan1->yRotate);
- debug_print("zRotate: %0.2f\n", pan1->zRotate);
- debug_print("xScale: %0.2f\n", pan1->xScale);
- debug_print("yScale: %0.2f\n", pan1->yScale);
- debug_print("width: %0.2f\n", pan1->width);
- debug_print("height: %0.2f\n", pan1->height);
- }
- ptr++;
- i++;
- }
- return 0;
- }
- int Test()
- {
- FILE * f = fopen("SD:/opening.bnr", "rb");
- if(!f)
- return 1;
- fseek(f, 0, SEEK_END);
- u32 filesize = ftell(f);
- rewind(f);
- u8 * openingbnr = (u8*) malloc(filesize);
- if(!openingbnr)
- return 2;
- fread(openingbnr, 1, filesize, f);
- fclose(f);
- #ifdef DEBUG_PRINT
- debugfile = fopen("SD:/debug.txt", "wb");
- #endif
- u32 bannerbinsize = 0;
- const u8 * bannerbin = LoadBannerBin(openingbnr, &bannerbinsize);
- if(!bannerbin)
- debug_print("No banner.bin\n");
- u32 brlytsize = 0;
- const u8 * brlyt = LoadBRLYT(bannerbin, &brlytsize);
- if(!brlyt)
- debug_print("No .brlyt\n");
- LoadBRLYT_Info(brlyt);
- free(openingbnr);
- #ifdef DEBUG_PRINT
- fclose(debugfile);
- #endif
- return 0;
- }
Add Comment
Please, Sign In to add comment