99
1010#include < string.h>
1111#include < nstd/String.hpp>
12+ #include < nstd/Array.hpp>
1213
1314#include " math/Vector.h"
1415
1516const int SKY_CLUT_START_Y = 252 ;
1617const int SKY_SIZE_W = 256 / 4 ;
1718const int SKY_SIZE_H = 84 ;
1819
20+ const int BG_SPLICE_W = 64 ;
21+ const int BG_SPLICE_H = 256 ;
22+ const int BG_SPLICE_SIZE = BG_SPLICE_W * 2 * BG_SPLICE_H;
23+
1924void CopyTpageImage (ushort* tp_src, ushort* dst, int x, int y, int dst_w, int dst_h)
2025{
2126 ushort* src = tp_src + x + 128 * y;
@@ -255,7 +260,7 @@ void ConvertBackgroundRaw(const char* filename, const char* extraFilename)
255260
256261 fclose (bgFp);
257262
258- ubyte* imageClut = bgData + 11 * 0x8000 ;
263+ ubyte* imageClut = bgData + 11 * BG_SPLICE_SIZE ;
259264
260265 // convert background image and store
261266 {
@@ -275,7 +280,7 @@ void ConvertBackgroundRaw(const char* filename, const char* extraFilename)
275280
276281 for (int i = 0 ; i < 6 ; i++)
277282 {
278- ubyte* bgImagePiece = bgData + i * 0x8000 ;
283+ ubyte* bgImagePiece = bgData + i * BG_SPLICE_SIZE ;
279284
280285 int rect_y = i / 3 ;
281286 int rect_x = (i - (rect_y & 1 ) * 3 ) * 128 ;
@@ -297,7 +302,7 @@ void ConvertBackgroundRaw(const char* filename, const char* extraFilename)
297302 // check if it's GFX.RAW
298303 // if(str.find("gfx"))
299304 {
300- imageClut = bgData + 0x30000 + 5 * 0x8000 + 128 ;
305+ imageClut = bgData + 0x30000 + 5 * BG_SPLICE_SIZE + 128 ;
301306
302307 // extract font
303308 ubyte* bgImagePiece = bgData + 0x30000 ;
@@ -306,7 +311,7 @@ void ConvertBackgroundRaw(const char* filename, const char* extraFilename)
306311 bgImagePiece, 64 *2 *256 , 0 , 0 , 256 , 256 , imageClut, 1 );
307312
308313 imageClut += 128 ;
309- bgImagePiece += 0x8000 ;
314+ bgImagePiece += BG_SPLICE_SIZE ;
310315
311316 // extract selection texture
312317 SaveTIM_4bit (varargs (" %s_SEL.TIM" , filename),
@@ -318,7 +323,7 @@ void ConvertBackgroundRaw(const char* filename, const char* extraFilename)
318323 // try extract the rest
319324 for (int i = 0 ; i < 6 ; i++)
320325 {
321- ubyte* bgImagePiece = bgData + 0x30000 + i * 0x8000 ;
326+ ubyte* bgImagePiece = bgData + 0x30000 + i * BG_SPLICE_SIZE ;
322327
323328 int rect_y = i / 3 ;
324329 int rect_x = (i - (rect_y & 1 ) * 3 ) * 128 ;
@@ -362,9 +367,9 @@ void ConvertBackgroundRaw(const char* filename, const char* extraFilename)
362367
363368 for (int i = 0 ; i < 16 ; i++)
364369 {
365- ubyte* imageAddr = data + i * 0x8000 ;
370+ ubyte* imageAddr = data + i * BG_SPLICE_SIZE ;
366371
367- if ((i * 0x8000 ) < size)
372+ if ((i * BG_SPLICE_SIZE ) < size)
368373 ExportExtraImage (extraFilename, imageAddr, imageClut, i);
369374 }
370375
@@ -376,15 +381,113 @@ void ConvertBackgroundRaw(const char* filename, const char* extraFilename)
376381 MsgInfo (" Done!\n " );
377382}
378383
379- void ConvertTIMToBackgroundRaw (char ** filenames)
384+ // -----------------------------------------------------
385+
386+ // builds image out of separate TIM slices
387+ bool BuildBackgroundRaw (char * out, const Array<char *>& timFileNames)
380388{
381- FILE* fp = fopen (filenames[0 ], " wb" );
389+ Array<usize> size_cd;
390+ Array<ubyte*> clut_data;
391+
392+ // TODO: check for maximum number of images
393+
394+ clut_data.resize (timFileNames.size ());
395+ size_cd.resize (timFileNames.size ());
396+
397+ FILE* fp = fopen (out, " wb" );
382398
383399 if (!fp)
384400 {
385- MsgError (" Unable to open '%s'\n " , filenames[0 ]);
386- return ;
401+ MsgError (" Unable to open '%s' file\n " , out);
402+ return false ;
403+ }
404+
405+ for (usize i = 0 ; i < timFileNames.size (); i++)
406+ {
407+ FILE* inFp = fopen (timFileNames[i], " rb" );
408+ if (!inFp)
409+ {
410+ MsgError (" Unable to open '%s' file\n " , timFileNames[i]);
411+ return false ;
412+ }
413+
414+ MsgInfo (" Adding file: '%s'\n " , timFileNames[i]);
415+
416+ TIMHDR timHdr;
417+ TIMIMAGEHDR cluthdr;
418+ TIMIMAGEHDR header;
419+ ubyte* image_data;
420+
421+ // Check header
422+ fread (&timHdr, 1 , sizeof (timHdr), inFp);
423+ if (timHdr.magic != 0x10 )
424+ {
425+ MsgError (" Input file is not a TIM file!\n " );
426+ fclose (inFp);
427+ return false ;
428+ }
429+
430+ if (timHdr.flags != 0x08 )
431+ {
432+ MsgError (" Input image must be 4-bit!\n " );
433+ fclose (inFp);
434+ return false ;
435+ }
436+
437+ // FIXME: need to check background image size properties!!!
438+
439+ // Parsing CLUT Header
440+ fread (&cluthdr, 1 , sizeof (cluthdr), inFp);
441+ clut_data[i] = static_cast <ubyte*>(malloc (cluthdr.len - sizeof (cluthdr)));
442+ fread (clut_data[i], 1 , cluthdr.len - sizeof (cluthdr), inFp);
443+
444+ // Parsing image data header
445+ fread (&header, 1 , sizeof (header), inFp);
446+ image_data = static_cast <ubyte*>(malloc (header.len - sizeof (header)));
447+ fread (image_data, 1 , header.len - sizeof (header), inFp);
448+
449+ size_cd[i] = cluthdr.len - sizeof (cluthdr);
450+
451+ fclose (inFp);
452+ MsgInfo (" Writing image data of file '%s' to '%s'\n " , timFileNames[i], out);
453+
454+ ubyte* bgImagePiece = static_cast <ubyte*>(malloc (BG_SPLICE_SIZE));
455+
456+ for (int j = 0 ; j < 6 ; j++)
457+ {
458+ int rect_y = j / 3 ;
459+ int rect_x = (j - (rect_y & 1 ) * 3 ) * (BG_SPLICE_W * 2 );
460+ rect_y *= BG_SPLICE_H;
461+
462+ for (int y = 0 ; y < BG_SPLICE_H; y++)
463+ {
464+ for (int x = 0 ; x < BG_SPLICE_W * 2 ; x++)
465+ {
466+ bgImagePiece[y * BG_SPLICE_W * 2 + x] = image_data[(rect_y + y) * BG_SPLICE_W * 6 + rect_x + x];
467+ }
468+ }
469+
470+ fwrite (bgImagePiece, 1 , BG_SPLICE_SIZE, fp);
471+ }
472+
473+ free (bgImagePiece);
474+ free (image_data);
475+ }
476+
477+ // Set offset to start of CLUT data
478+ fseek (fp, 0x58000 , SEEK_SET);
479+ for (usize i = 0 ; i < timFileNames.size (); i++)
480+ {
481+ MsgInfo (" Writting CLUT data to '%s'\n " , timFileNames[i]);
482+ fwrite (clut_data[i], 1 , size_cd[i], fp);
483+
484+ free (clut_data[i]);
387485 }
486+
487+ fclose (fp);
488+ MsgAccept (" '%s' compiled with success !\n " , out);
489+
490+ return true ;
388491}
389492
390493// -----------------------------------------------------
@@ -395,7 +498,7 @@ void PrintCommandLineArguments()
395498 MsgInfo (" \t DriverImageTool -sky2tim SKY0.RAW\n " );
396499 MsgInfo (" \t DriverImageTool -sky2tga SKY1.RAW\n " );
397500 MsgInfo (" \t DriverImageTool -bg2tim CARBACK.RAW <CCARS.RAW>\n " );
398- MsgInfo (" \t DriverImageTool -tim2raw BG .RAW <FILE.TIM FILE2.TIM ..>\n " );
501+ MsgInfo (" \t DriverImageTool -tim2raw GFX .RAW BG.tim <FontAndSelection.tim Image3.tim ..>\n " );
399502}
400503
401504int main (int argc, char ** argv)
@@ -445,23 +548,27 @@ int main(int argc, char** argv)
445548 ConvertBackgroundRaw (argv[i + 1 ], nullptr );
446549 }
447550 else
448- MsgWarning (" -bg2tim must have an argument!" );
551+ MsgWarning (" -bg2tim must have argument!" );
449552 }
450553 else if (!stricmp (argv[i], " -tim2raw" ))
451554 {
452- int nbFiles = argc - i - 2 ;
453- if (argc > 3 )
555+ if (i + 2 <= argc)
454556 {
455- char ** filenames = (char **)malloc (sizeof (char *)*nbFiles);
456- for (int j = 0 ; j < nbFiles; j++)
557+ Array<char *> filenames;
558+ const char * outputFilename = argv[i + 1 ];
559+
560+ for (int j = i + 2 ; j < argc; j++)
457561 {
458- filenames[j] = argv[i + j + 2 ];
562+ if (*argv[j] == ' -' || *argv[j] == ' +' || *argv[j] == ' /' || *argv[j] == ' \\ ' ) // encountered new option?
563+ break ;
564+
565+ filenames.append (argv[j]);
459566 }
460567
461- SaveRAW_TIM (argv[i + 1 ], filenames, nbFiles );
568+ BuildBackgroundRaw (argv[i + 1 ], filenames);
462569 }
463570 else
464- MsgWarning (" -tim2raw must have at least three arguments!" );
571+ MsgWarning (" -tim2raw must have at least two arguments!" );
465572 }
466573 }
467574
0 commit comments