@@ -40,6 +40,8 @@ typedef struct
4040 unsigned int alignment ;
4141 char compress ;
4242 char dump ;
43+ char fix_f3d ;
44+ char fix_geo ;
4345} compress_config ;
4446
4547// default configuration
@@ -49,7 +51,9 @@ static const compress_config default_config =
4951 NULL , // output filename
5052 16 , // MIO0 alignment
5153 0 , // compress all MIO0 blocks
52- 0 , // TODO: dump
54+ 0 , // dump
55+ 0 , // f3d
56+ 0 , // geo
5357};
5458
5559static void print_usage (void )
@@ -61,6 +65,8 @@ static void print_usage(void)
6165 "Optional arguments:\n"
6266 " -a ALIGNMENT byte boundary to align MIO0 blocks (default: %d)\n"
6367 " -c compress all blocks using MIO0\n"
68+ " -f fix F3D combine blending parameters\n"
69+ " -g fix geo layout display list layers\n"
6470 " -v verbose progress output\n"
6571 "\n"
6672 "File arguments:\n"
@@ -98,6 +104,12 @@ static void parse_arguments(int argc, char *argv[], compress_config *config)
98104 case 'd' :
99105 config -> dump = 1 ;
100106 break ;
107+ case 'f' :
108+ config -> fix_f3d = 1 ;
109+ break ;
110+ case 'g' :
111+ config -> fix_geo = 1 ;
112+ break ;
101113 case 'v' :
102114 g_verbosity = 1 ;
103115 break ;
@@ -290,18 +302,25 @@ static int find_some_block(block *blocks, int block_count, unsigned char *buf)
290302 return block_count + 1 ;
291303}
292304
293- static void fix_f3d_geo (unsigned char * buf , int len )
305+ // set different parameters for G_SETCOMBINE blending parameters
306+ static void fix_f3d (unsigned char * buf , int len )
294307{
295- // set different parameters for G_SETCOMBINE blending parameters
296308 static const unsigned char f3d_combine_old [] = {0xFC , 0x12 , 0x7F , 0xFF , 0xFF , 0xFF , 0xF8 , 0x38 };
297309 static const unsigned char f3d_combine_new [] = {0xFC , 0x12 , 0x18 , 0x24 , 0xFF , 0x33 , 0xFF , 0xFF };
298- // set geo layout drawing layer from 6 to 4
299- static const unsigned char geo_dl_old [] = {0x15 , 0x06 , 0x00 , 0x00 , 0x0E };
300- static const unsigned char geo_dl_new [] = {0x15 , 0x04 , 0x00 , 0x00 , 0x0E };
301310 for (int i = 0 ; i < len ; i ++ ) {
302311 if (!memcmp (& buf [i ], f3d_combine_old , sizeof (f3d_combine_old ))) {
303312 memcpy (& buf [i ], f3d_combine_new , sizeof (f3d_combine_new ));
304- } else if (!memcmp (& buf [i ], geo_dl_old , sizeof (geo_dl_old ))) {
313+ }
314+ }
315+ }
316+
317+ // set geo layout drawing layer from 6 to 4
318+ static void fix_geo (unsigned char * buf , int len )
319+ {
320+ static const unsigned char geo_dl_old [] = {0x15 , 0x06 , 0x00 , 0x00 , 0x0E };
321+ static const unsigned char geo_dl_new [] = {0x15 , 0x04 , 0x00 , 0x00 , 0x0E };
322+ for (int i = 0 ; i < len ; i ++ ) {
323+ if (!memcmp (& buf [i ], geo_dl_old , sizeof (geo_dl_old ))) {
305324 memcpy (& buf [i ], geo_dl_new , sizeof (geo_dl_new ));
306325 }
307326 }
@@ -343,11 +362,11 @@ static int sm64_compress_mio0(const compress_config *config,
343362 block_count = walk_scripts (block_table , block_count , in_buf , in_length , ENTRY_SCRIPT , ENTRY_SCRIPT + 0x30 );
344363 // find sequence bank block (usually 0x02F00000 or 0x03E00000)
345364 block_count = find_sequence_bank (block_table , block_count , in_buf );
346- // find sequence bank block (usually 0x01200000)
365+ // some block (usually ROM 0x01200000) is DMAd to 0x80400000
347366 block_count = find_some_block (block_table , block_count , in_buf );
348367 printf ("count: %d\n" , block_count );
349368
350- // sort the addresses
369+ // sort the blocks
351370 qsort (block_table , block_count , sizeof (block_table [0 ]), compare_block );
352371
353372 // debug table
@@ -377,8 +396,15 @@ static int sm64_compress_mio0(const compress_config *config,
377396 blk -> new_end = blk -> old_end ;
378397 } else {
379398 int src_len ;
380- // fix F3D commands
381- fix_f3d_geo (& in_buf [blk -> old ], blk -> old_end - blk -> old );
399+ // implement fixes
400+ // TODO: this is liberally applied to all data
401+ // TODO: this assumes fake MIO0 headers
402+ if (config -> fix_f3d ) {
403+ fix_f3d (& in_buf [blk -> old ], blk -> old_end - blk -> old );
404+ }
405+ if (config -> fix_geo ) {
406+ fix_geo (& in_buf [blk -> old ], blk -> old_end - blk -> old );
407+ }
382408 if (config -> compress && blk -> type == BLOCK_MIO0 ) {
383409 // TODO: this decompression step may be unnecesary if it is a fake header
384410 int raw_len = mio0_decode (& in_buf [blk -> old ], tmp_raw , NULL );
@@ -519,7 +545,9 @@ static int sm64_compress_mio0(const compress_config *config,
519545 free (tmp_raw );
520546 free (tmp_cmp );
521547 }
522- out_length = cur_offset ;
548+
549+ // align output length to nearest MB
550+ out_length = ALIGN (cur_offset , 1 * MB );
523551
524552 return out_length ;
525553}
0 commit comments