11#define PROGRAM_NAME "make_patch"
2- #define USAGE_OPTS "values.sym patched.gbc original.gbc vc.patch.template vc.patch"
2+ #define USAGE_OPTS "[--ignore addr:size] values.sym patched.gbc original.gbc vc.patch.template vc.patch"
33
44#include "common.h"
55
@@ -127,7 +127,7 @@ struct Symbol *parse_symbols(const char *filename) {
127127 if (c == EOF || c == '\n' || c == '\r' || c == ';' || (state == SYM_NAME && (c == ' ' || c == '\t' ))) {
128128 if (state == SYM_NAME ) {
129129 // The symbol name has ended; append the buffered symbol
130- buffer_append (buffer , & (char [] ){'\0' });
130+ buffer_append (buffer , & (char ){'\0' });
131131 symbol_append (& symbols , buffer -> data , bank , address );
132132 }
133133 // Skip to the next line, ignoring anything after the symbol value and name
@@ -143,7 +143,7 @@ struct Symbol *parse_symbols(const char *filename) {
143143 // The symbol value or name has started; buffer its contents
144144 if (++ state == SYM_NAME ) {
145145 // The symbol name has started; parse the buffered value
146- buffer_append (buffer , & (char [] ){'\0' });
146+ buffer_append (buffer , & (char ){'\0' });
147147 parse_symbol_value (buffer -> data , & bank , & address );
148148 }
149149 buffer -> size = 0 ;
@@ -349,7 +349,15 @@ void skip_to_next_line(FILE *restrict input, FILE *restrict output) {
349349 }
350350}
351351
352- struct Buffer * process_template (const char * template_filename , const char * patch_filename , FILE * restrict new_rom , FILE * restrict orig_rom , const struct Symbol * symbols ) {
352+ struct Buffer * process_template (
353+ const char * template_filename ,
354+ const char * patch_filename ,
355+ FILE * restrict new_rom ,
356+ FILE * restrict orig_rom ,
357+ const struct Symbol * symbols ,
358+ unsigned int ignore_addr ,
359+ unsigned int ignore_size
360+ ) {
353361 FILE * input = xfopen (template_filename , 'r' );
354362 FILE * output = xfopen (patch_filename , 'w' );
355363
@@ -358,11 +366,10 @@ struct Buffer *process_template(const char *template_filename, const char *patch
358366
359367 // The ROM checksum will always differ
360368 buffer_append (patches , & (struct Patch ){0x14e , 2 });
361- // The Stadium data (see stadium.c) will always differ
369+ // The ignored data will always differ
362370 unsigned int rom_size = (unsigned int )xfsize ("" , orig_rom );
363- if (rom_size == 128 * 0x4000 ) {
364- unsigned int stadium_size = 24 + 6 + 2 + 128 * 2 * 2 ;
365- buffer_append (patches , & (struct Patch ){rom_size - stadium_size , stadium_size });
371+ if (ignore_size > 0 && ignore_size <= rom_size && ignore_addr <= rom_size - ignore_size ) {
372+ buffer_append (patches , & (struct Patch ){ignore_addr , ignore_size });
366373 }
367374
368375 // Fill in the template
@@ -381,7 +388,7 @@ struct Buffer *process_template(const char *template_filename, const char *patch
381388 for (c = getc (input ); c != EOF && c != '}' ; c = getc (input )) {
382389 buffer_append (buffer , & c );
383390 }
384- buffer_append (buffer , & (char [] ){'\0' });
391+ buffer_append (buffer , & (char ){'\0' });
385392 // Interpret the command in the context of the current patch
386393 interpret_command (buffer -> data , current_hook , symbols , patches , new_rom , orig_rom , output );
387394 break ;
@@ -410,7 +417,7 @@ struct Buffer *process_template(const char *template_filename, const char *patch
410417 buffer_append (buffer , & c );
411418 }
412419 }
413- buffer_append (buffer , & (char [] ){'\0' });
420+ buffer_append (buffer , & (char ){'\0' });
414421 // The current patch should have a corresponding ".VC_" label
415422 current_hook = symbol_find_cat (symbols , ".VC_" , buffer -> data );
416423 skip_to_next_line (input , output );
@@ -464,19 +471,53 @@ bool verify_completeness(FILE *restrict orig_rom, FILE *restrict new_rom, struct
464471 }
465472}
466473
474+ void parse_args (int argc , char * argv [], unsigned int * ignore_addr , unsigned int * ignore_size ) {
475+ struct option long_options [] = {
476+ {"ignore" , required_argument , 0 , 'i' },
477+ {"help" , no_argument , 0 , 'h' },
478+ {0 }
479+ };
480+ for (int opt ; (opt = getopt_long (argc , argv , "h" , long_options )) != -1 ;) {
481+ switch (opt ) {
482+ case 'i' : {
483+ char * colon = strchr (optarg , ':' );
484+ if (colon ) {
485+ * colon ++ = '\0' ;
486+ * ignore_addr = strtoul (optarg , NULL , 0 );
487+ * ignore_size = strtoul (colon , NULL , 0 );
488+ } else {
489+ error_exit ("Error: Invalid argument for '--ignore': \"%s\"\n" , optarg );
490+ }
491+ break ;
492+ }
493+ case 'h' :
494+ usage_exit (0 );
495+ break ;
496+ default :
497+ usage_exit (1 );
498+ }
499+ }
500+ }
501+
467502int main (int argc , char * argv []) {
468- if (argc != 6 ) {
503+ unsigned int ignore_addr = 0 , ignore_size = 0 ;
504+
505+ parse_args (argc , argv , & ignore_addr , & ignore_size );
506+
507+ argc -= optind ;
508+ argv += optind ;
509+ if (argc != 5 ) {
469510 usage_exit (1 );
470511 }
471512
472- struct Symbol * symbols = parse_symbols (argv [1 ]);
513+ struct Symbol * symbols = parse_symbols (argv [0 ]);
473514
474- FILE * new_rom = xfopen (argv [2 ], 'r' );
475- FILE * orig_rom = xfopen (argv [3 ], 'r' );
476- struct Buffer * patches = process_template (argv [4 ], argv [5 ], new_rom , orig_rom , symbols );
515+ FILE * new_rom = xfopen (argv [1 ], 'r' );
516+ FILE * orig_rom = xfopen (argv [2 ], 'r' );
517+ struct Buffer * patches = process_template (argv [3 ], argv [4 ], new_rom , orig_rom , symbols , ignore_addr , ignore_size );
477518
478519 if (!verify_completeness (orig_rom , new_rom , patches )) {
479- fprintf (stderr , PROGRAM_NAME ": Warning: Not all ROM differences are defined by \"%s\"\n" , argv [5 ]);
520+ fprintf (stderr , PROGRAM_NAME ": Warning: Not all ROM differences are defined by \"%s\"\n" , argv [4 ]);
480521 }
481522
482523 symbol_free (symbols );
0 commit comments