Guest User

Untitled

a guest
Jul 23rd, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.44 KB | None | 0 0
  1. #include <stdarg.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <gctypes.h>
  7.  
  8. extern "C"
  9. {
  10. #include "wpad.h"
  11. #include "video.h"
  12. };
  13.  
  14. #define DEBUG_PRINT
  15.  
  16. #ifdef DEBUG_PRINT
  17. FILE * debugfile;
  18. #endif
  19.  
  20. void debug_print(const char * format, ...)
  21. {
  22. char * tmp = 0;
  23. va_list va;
  24. va_start(va, format);
  25. if((vasprintf(&tmp, format, va)>=0) && tmp)
  26. {
  27. printf(tmp);
  28. #ifdef DEBUG_PRINT
  29. fprintf(debugfile, tmp);
  30. #endif
  31. free(tmp);
  32. }
  33. va_end(va);
  34. }
  35.  
  36. struct IMD5Header
  37. {
  38. u32 fcc;
  39. u32 filesize;
  40. u8 zeroes[8];
  41. u8 crypto[16];
  42. } __attribute__((packed));
  43.  
  44. struct IMETHeader
  45. {
  46. u8 zeroes[64];
  47. u32 fcc;
  48. u8 unk[8];
  49. u32 iconSize;
  50. u32 bannerSize;
  51. u32 soundSize;
  52. u32 flag1;
  53. u8 names[7][84];
  54. u8 zeroes_2[0x348];
  55. u8 crypto[16];
  56. } __attribute__((packed));
  57.  
  58. struct U8Header
  59. {
  60. u32 fcc;
  61. u32 rootNodeOffset;
  62. u32 headerSize;
  63. u32 dataOffset;
  64. u8 zeroes[16];
  65. } __attribute__((packed));
  66.  
  67. struct U8Entry
  68. {
  69. struct
  70. {
  71. u32 fileType : 8;
  72. u32 nameOffset : 24;
  73. };
  74. u32 fileOffset;
  75. union
  76. {
  77. u32 fileLength;
  78. u32 numEntries;
  79. };
  80. } __attribute__((packed));
  81.  
  82. struct LZ77Info
  83. {
  84. u16 length : 4;
  85. u16 offset : 12;
  86. } __attribute__((packed));
  87.  
  88. typedef struct
  89. {
  90. u32 fcc; // "RLYT" in ASCII
  91. u32 version; // Always 0xFE 0xFF 0x 00 0x08.
  92. u32 filesize; // Size of whole file, including the header.
  93. u32 num; // number of sections
  94. } BRLYT_Header;
  95.  
  96. typedef struct
  97. {
  98. u32 fcc; // "lyt1" in ASCII.
  99. u32 size_header;
  100. u8 layout_centered; // 1 if layout is drawn from center
  101. u8 pad[3];
  102. float width;
  103. float height;
  104. } LYT1_Header;
  105.  
  106. typedef struct
  107. {
  108. u32 fcc; // "txl1" in ASCII.
  109. u32 size_section; // Size of the whole section.
  110. u16 num_textures; // Number of textures in list.
  111. u16 offset_to_next_section; // Should be 0
  112. } TXL1_Header;
  113.  
  114. typedef struct
  115. {
  116. u32 offset_filename; // Offset to a null-terminated ASCII string containing the filename.
  117. u32 pad; // Always zero
  118. } TXL1_Offset;
  119.  
  120. typedef struct
  121. {
  122. u32 fcc; // "mat1" in ASCII.
  123. u32 size_section; // // Size of the whole section.
  124. u16 num_materials; //
  125. u16 size_header; // Offset to list start. Always zero
  126. } MAT1_Header;
  127.  
  128. typedef struct
  129. {
  130. u32 offset; // Offset from beginning of mat1-section.
  131. } MAT1_Offset;
  132.  
  133. typedef struct
  134. {
  135. char name[20];
  136. s16 fore_color[4];
  137. s16 back_color[4];
  138. s16 tevREG3_color[4];
  139. u32 tev_kcolor[4];
  140. u32 flags;
  141. } MAT1_Material;
  142.  
  143. typedef struct
  144. {
  145. u16 text_offset; //texture # in the txl1 list
  146. u8 wrap_modes[2];
  147. } MAT1_TexRef;
  148.  
  149. typedef struct
  150. {
  151. u32 fcc; // "pic1" in ASCII.
  152. u32 size_section;
  153. u8 visibility;
  154. u8 pane_origin;
  155. u8 alpha1;
  156. u8 alpha2;
  157. char name[0x18];
  158. float x;
  159. float y;
  160. float z;
  161. float xFlip;
  162. float yFlip;
  163. float angle;
  164. float xMag;
  165. float yMag;
  166. float width;
  167. float height;
  168. } PIC1_Header;
  169.  
  170. typedef struct
  171. {
  172. u32 fcc; // "pan1" in ASCII.
  173. u32 size_section;
  174. u8 visibility;
  175. u8 pane_origin;
  176. u8 alpha1;
  177. u8 padding;
  178. char pane_name [0x10]; // Pane name in ASCII.
  179. char user_data [0x08]; // User data
  180. float xTranslate;
  181. float yTranslate;
  182. float zTranslate;
  183. float xRotate;
  184. float yRotate;
  185. float zRotate;
  186. float xScale;
  187. float yScale;
  188. float width;
  189. float height;
  190. } PAN1_Header;
  191.  
  192.  
  193. static char *u8Filename(const U8Entry *fst, int i)
  194. {
  195. return (char *)(fst + fst[0].numEntries) + fst[i].nameOffset;
  196. }
  197.  
  198. inline u32 le32(u32 i)
  199. {
  200. return ((i & 0xFF) << 24) | ((i & 0xFF00) << 8) | ((i & 0xFF0000) >> 8) | ((i & 0xFF000000) >> 24);
  201. }
  202.  
  203. inline u16 le16(u16 i)
  204. {
  205. return ((i & 0xFF) << 8) | ((i & 0xFF00) >> 8);
  206. }
  207.  
  208. static u8 *uncompressLZ77(const u8 *inBuf, u32 inLength, u32 &size)
  209. {
  210. u8 *buffer = NULL;
  211. if (inLength <= 0x8 || *((const u32 *)inBuf) != 0x4C5A3737 /*"LZ77"*/ || inBuf[4] != 0x10)
  212. return NULL;
  213. u32 uncSize = le32(((const u32 *)inBuf)[1] << 8);
  214.  
  215. const u8 *inBufEnd = inBuf + inLength;
  216. inBuf += 8;
  217. buffer = new u8[uncSize];
  218. if (!buffer)
  219. return buffer;
  220.  
  221. u8 *bufCur = buffer;
  222. u8 *bufEnd = buffer + uncSize;
  223.  
  224. while (bufCur < bufEnd && inBuf < inBufEnd)
  225. {
  226. u8 flags = *inBuf;
  227. ++inBuf;
  228. for (int i = 0; i < 8 && bufCur < bufEnd && inBuf < inBufEnd; ++i)
  229. {
  230. if ((flags & 0x80) != 0)
  231. {
  232. const LZ77Info &info = *(const LZ77Info *)inBuf;
  233. inBuf += sizeof (LZ77Info);
  234. int length = info.length + 3;
  235. if (bufCur - info.offset - 1 < buffer || bufCur + length > bufEnd)
  236. return buffer;
  237. memcpy(bufCur, bufCur - info.offset - 1, length);
  238. bufCur += length;
  239. }
  240. else
  241. {
  242. *bufCur = *inBuf;
  243. ++inBuf;
  244. ++bufCur;
  245. }
  246. flags <<= 1;
  247. }
  248. }
  249. size = uncSize;
  250. return buffer;
  251. }
  252.  
  253. const u8 *LoadBannerBin(const u8 *opening_bnr, u32 *size)
  254. {
  255. const IMETHeader *imetHdr = (IMETHeader *)opening_bnr;
  256. if ( imetHdr->fcc != 0x494D4554 /*"IMET"*/ )
  257. {
  258. debug_print("IMET Header wrong: %08X\n", imetHdr->fcc);
  259. debug_print("IMET Header wrong: %s\n", (char*) &imetHdr->fcc);
  260. return NULL;
  261. }
  262. const U8Header *bnrArcHdr = (U8Header *)(imetHdr + 1);
  263.  
  264. const U8Entry *fst = (const U8Entry *)( ((const u8 *)bnrArcHdr) + bnrArcHdr->rootNodeOffset);
  265. u32 i;
  266. for (i = 1; i < fst[0].numEntries; ++i)
  267. if (fst[i].fileType == 0 && strcasecmp(u8Filename(fst, i), "banner.bin") == 0)
  268. break;
  269. if (i >= fst[0].numEntries)
  270. {
  271. /* Not all games have a sound.bin and this message is annoying **/
  272. debug_print("banner.bin not found.\n");
  273. return 0;
  274. }
  275. const u8 *banner_bin = ((const u8 *)bnrArcHdr) + fst[i].fileOffset;
  276. if ( ((IMD5Header *)banner_bin)->fcc != 0x494D4435 /*"IMD5"*/ )
  277. {
  278. debug_print("IMD5 error: %08X\n", ((IMD5Header *)banner_bin)->fcc);
  279. debug_print("IMD5: %s\n", (char*) &((IMD5Header *)banner_bin)->fcc);
  280. return 0;
  281. }
  282.  
  283. *size = ((IMD5Header *)banner_bin)->filesize;
  284. return banner_bin;
  285. }
  286.  
  287. const u8 *LoadBRLYT(const u8 *bannerbin, u32 * outsize)
  288. {
  289. u32 size = ((IMD5Header *)bannerbin)->filesize;
  290.  
  291. const IMD5Header *IMD5Hdr = (IMD5Header *)bannerbin;
  292. const u8 * binfile = (const u8 *)(IMD5Hdr+1);
  293. const u8 * unpackedbin = binfile;
  294. u32 uncSize = size;
  295.  
  296. if(*((u32*)binfile) == 0x4C5A3737 /* LZ77 */)
  297. {
  298. unpackedbin = uncompressLZ77(binfile, size-sizeof(IMD5Header), uncSize);
  299. }
  300.  
  301. const U8Header * binHdr = (const U8Header *) unpackedbin;
  302. if(binHdr->fcc != 0x55AA382D)
  303. {
  304. debug_print("Wrong u8 tag: %08X\n", binHdr->fcc);
  305. return 0;
  306. }
  307.  
  308. const U8Entry *fst = (const U8Entry *)( ((const u8 *)binHdr) + binHdr->rootNodeOffset);
  309. u32 i;
  310. for (i = 1; i < fst[0].numEntries; ++i)
  311. {
  312. //debug_print("%s\n", u8Filename(fst, i));
  313. if (fst[i].fileType == 0 && strstr(u8Filename(fst, i), ".brlyt") != 0)
  314. break;
  315. }
  316.  
  317. if (i >= fst[0].numEntries)
  318. {
  319. /* Not all games have a sound.bin and this message is annoying **/
  320. debug_print("brlyt not found.\n");
  321. return 0;
  322. }
  323.  
  324. const u8 * banner_brlyt = ((const u8 *)binHdr) + fst[i].fileOffset;
  325. if ( ((BRLYT_Header *)banner_brlyt)->fcc != 0x524C5954 /*"RLYT"*/ )
  326. {
  327. debug_print("BRLYT error: %08X\n", ((BRLYT_Header *)banner_brlyt)->fcc);
  328. debug_print("BRLYT: %s\n", (char*) &((BRLYT_Header *)banner_brlyt)->fcc);
  329. return 0;
  330. }
  331.  
  332. *outsize = ((BRLYT_Header *)banner_brlyt)->filesize;
  333. return banner_brlyt;
  334. }
  335.  
  336. const u8 *LoadBRLYT_Info(const u8 *brlytfile)
  337. {
  338. const BRLYT_Header * brlytHeader = (const BRLYT_Header *) brlytfile;
  339. if(brlytHeader->fcc != 0x524C5954 /*"RLYT"*/)
  340. {
  341. debug_print("BRLYT_Header error: %s\n", (char*) &((BRLYT_Header *)brlytHeader)->fcc);
  342. return 0;
  343. }
  344.  
  345. u32 filesize = brlytHeader->filesize;
  346.  
  347. const LYT1_Header * lyt1 = (const LYT1_Header *) (brlytHeader+1);
  348. if(lyt1->fcc != 0x6C797431 /*"lyt1"*/)
  349. {
  350. debug_print("LYT1_Header error: %s\n", (char*) &((LYT1_Header *)lyt1)->fcc);
  351. return 0;
  352. }
  353.  
  354. debug_print("\n");
  355. debug_print("LYT1_Header: %s\n", (char*) &((LYT1_Header *)lyt1)->fcc);
  356. debug_print("size_header: %d\n", lyt1->size_header);
  357. debug_print("layout_centered: %d\n", lyt1->layout_centered);
  358. debug_print("width: %0.2f\n", lyt1->width);
  359. debug_print("height: %0.2f\n", lyt1->height);
  360. debug_print("\n");
  361.  
  362. const TXL1_Header * txl1 = (const TXL1_Header *) (lyt1+1);
  363. if(txl1->fcc != 0x74786C31 /*"txl1"*/)
  364. {
  365. debug_print("TXL1_Header error: %s\n", (char*) &((TXL1_Header *)txl1)->fcc);
  366. return 0;
  367. }
  368.  
  369. const TXL1_Offset * txl1_off = (TXL1_Offset *) (txl1+1);
  370. for(u16 i = 0; i < txl1->num_textures; i++)
  371. {
  372. debug_print("%d: %s\n", i, (const char*) ((const u8*)(txl1+1)+txl1_off->offset_filename));
  373. txl1_off++;
  374. }
  375.  
  376. const u8 * ptr = (u8 *) txl1_off;
  377. while(!(*((u32*)ptr) == 0x6D617431 /* mat1 */))
  378. {
  379. ptr++;
  380. }
  381.  
  382. const MAT1_Header * mat1 = (MAT1_Header *) ptr;
  383. const MAT1_Offset * mat1_off = (MAT1_Offset *) (mat1+1);
  384. for(u16 n = 0; n < mat1->num_materials; n++)
  385. {
  386. const MAT1_Material * mat1Material = (MAT1_Material *) ((const u8*)(ptr)+mat1_off->offset);
  387.  
  388. debug_print("\n");
  389. debug_print("%d: %s\n", n, mat1Material->name);
  390. for(int i = 0; i < 4; i++)
  391. debug_print("fore_color[%d]: %d\n", i, mat1Material->fore_color[i]);
  392. for(int i = 0; i < 4; i++)
  393. debug_print("back_color[%d]: %d\n", i, mat1Material->back_color[i]);
  394. for(int i = 0; i < 4; i++)
  395. debug_print("tevREG3_color[%d]: %d\n", i, mat1Material->tevREG3_color[i]);
  396. for(int i = 0; i < 4; i++)
  397. debug_print("tev_kcolor[%d]: %d\n", i, mat1Material->tev_kcolor[i]);
  398. debug_print("%d flags: %d\n", n, mat1Material->flags);
  399.  
  400. const MAT1_TexRef * matTextRef = (MAT1_TexRef*) (mat1Material+1);
  401. txl1_off = ((TXL1_Offset *) (txl1+1)) + matTextRef->text_offset;
  402. const char* tex_filename = (char*) ((const u8*)(txl1+1)+txl1_off->offset_filename);
  403.  
  404. debug_print("RefTex: %s\n", tex_filename);
  405.  
  406. mat1_off++;
  407. }
  408.  
  409. u32 i = 0;
  410. ptr = brlytfile;
  411. while(i < filesize)
  412. {
  413. if (*((u32*)ptr) == 0x70696331 /*"pic1"*/)
  414. {
  415. const PIC1_Header * pic1 = (const PIC1_Header *) ptr;
  416.  
  417. debug_print("\n");
  418. debug_print("PIC1_Header: %s\n", (char*) &((PIC1_Header *)pic1)->fcc);
  419. debug_print("size_section: %d\n", pic1->size_section);
  420. debug_print("visibility: %d\n", pic1->visibility);
  421. debug_print("pane_origin: %d\n", pic1->pane_origin);
  422. debug_print("alpha1: %d\n", pic1->alpha1);
  423. debug_print("alpha2: %d\n", pic1->alpha2);
  424. debug_print("Name: %s\n", pic1->name); //seems to be the equivalent to mat1 names
  425. debug_print("X: %0.2f\n", pic1->x);
  426. debug_print("Y: %0.2f\n", pic1->y);
  427. debug_print("Z: %0.2f\n", pic1->z);
  428. debug_print("X-FLIP: %0.2f\n", pic1->xFlip);
  429. debug_print("Y-FLIP: %0.2f\n", pic1->yFlip);
  430. debug_print("angle: %0.2f\n", pic1->angle);
  431. debug_print("X-MAG: %0.2f\n", pic1->xMag);
  432. debug_print("Y-MAG: %0.2f\n", pic1->yMag);
  433. debug_print("width: %0.2f\n", pic1->width);
  434. debug_print("height: %0.2f\n", pic1->height);
  435. }
  436.  
  437. else if (*((u32*)ptr) == 0x70616E31 /*"pan1"*/)
  438. {
  439. const PAN1_Header * pan1 = (const PAN1_Header *) ptr;
  440.  
  441. debug_print("\n");
  442. debug_print("PAN1_Header: %s\n", (char*) &((PAN1_Header *)pan1)->fcc);
  443. debug_print("size_section: %d\n", pan1->size_section);
  444. debug_print("visibility: %d\n", pan1->visibility);
  445. debug_print("pane_origin: %d\n", pan1->pane_origin);
  446. debug_print("alpha1: %d\n", pan1->alpha1);
  447. debug_print("padding: %d\n", pan1->padding);
  448. debug_print("Name: %s\n", pan1->pane_name);
  449. debug_print("user_data: %s\n", pan1->user_data);
  450. debug_print("xTranslate: %0.2f\n", pan1->xTranslate);
  451. debug_print("yTranslate: %0.2f\n", pan1->yTranslate);
  452. debug_print("zTranslate: %0.2f\n", pan1->zTranslate);
  453. debug_print("xRotate: %0.2f\n", pan1->xRotate);
  454. debug_print("yRotate: %0.2f\n", pan1->yRotate);
  455. debug_print("zRotate: %0.2f\n", pan1->zRotate);
  456. debug_print("xScale: %0.2f\n", pan1->xScale);
  457. debug_print("yScale: %0.2f\n", pan1->yScale);
  458. debug_print("width: %0.2f\n", pan1->width);
  459. debug_print("height: %0.2f\n", pan1->height);
  460. }
  461.  
  462. ptr++;
  463. i++;
  464. }
  465.  
  466. return 0;
  467. }
  468.  
  469.  
  470.  
  471. int Test()
  472. {
  473. FILE * f = fopen("SD:/opening.bnr", "rb");
  474. if(!f)
  475. return 1;
  476.  
  477. fseek(f, 0, SEEK_END);
  478. u32 filesize = ftell(f);
  479. rewind(f);
  480.  
  481. u8 * openingbnr = (u8*) malloc(filesize);
  482. if(!openingbnr)
  483. return 2;
  484.  
  485. fread(openingbnr, 1, filesize, f);
  486. fclose(f);
  487.  
  488. #ifdef DEBUG_PRINT
  489. debugfile = fopen("SD:/debug.txt", "wb");
  490. #endif
  491.  
  492. u32 bannerbinsize = 0;
  493.  
  494. const u8 * bannerbin = LoadBannerBin(openingbnr, &bannerbinsize);
  495.  
  496. if(!bannerbin)
  497. debug_print("No banner.bin\n");
  498.  
  499. u32 brlytsize = 0;
  500.  
  501. const u8 * brlyt = LoadBRLYT(bannerbin, &brlytsize);
  502.  
  503. if(!brlyt)
  504. debug_print("No .brlyt\n");
  505.  
  506.  
  507. LoadBRLYT_Info(brlyt);
  508.  
  509.  
  510. free(openingbnr);
  511.  
  512. #ifdef DEBUG_PRINT
  513. fclose(debugfile);
  514. #endif
  515.  
  516. return 0;
  517. }
Add Comment
Please, Sign In to add comment