2626#define STATUS_TEXT_RGBA MAKE_RGBA(255, 0, 0, 255)
2727#define STATUS_TEXT_TIMEOUT 120 /* Frames */
2828
29- // TODO: make these configurable?
30- #define AUDIO_FREQUENCY 44100
31- #define AUDIO_FRAMES 2048 /* ~46ms of latency at 44.1kHz */
32- #define REWIND_FRAMES_PER_BASE_STATE 45
33- #define REWIND_BUFFER_CAPACITY MEGABYTES(32)
34- #define REWIND_CYCLES_PER_FRAME (70224 * 3 / 2) /* Rewind at 1.5x */
35-
3629typedef enum Layer {
3730 LAYER_BG ,
3831 LAYER_WINDOW ,
@@ -69,6 +62,12 @@ static Bool s_force_dmg;
6962static Bool s_use_sgb_border ;
7063static u32 s_render_scale = 4 ;
7164
65+ static u32 s_audio_frequency = 44100 ;
66+ static u32 s_audio_frames = 2048 ; /* ~46ms of latency at 44.1kHz */
67+ static u32 s_rewind_frames_per_base_state = 45 ;
68+ static u32 s_rewind_buffer_capacity_megabytes = 32 ;
69+ static f32 s_rewind_scale = 1.5f ;
70+
7271static Overlay s_overlay ;
7372static StatusText s_status_text ;
7473
@@ -413,9 +412,68 @@ void parse_arguments(int argc, char** argv) {
413412 exit (1 );
414413}
415414
415+ void read_ini_file (void ) {
416+ FILE * file = fopen ("binjgb.ini" , "r" );
417+ if (!file ) {
418+ return ;
419+ }
420+ while (1 ) {
421+ char buffer [1024 ], * value , * equals , * newline ;
422+ if (!fgets (buffer , sizeof (buffer ), file )) {
423+ break ;
424+ }
425+
426+ if (buffer [0 ] == '#' || buffer [0 ] == '\n' ) {
427+ continue ;
428+ }
429+
430+ equals = strchr (buffer , '=' );
431+ if (!equals ) {
432+ fprintf (stderr , "warning: bad ini line: %s\n" , buffer );
433+ continue ;
434+ }
435+ * equals = 0 ;
436+ value = equals + 1 ;
437+
438+ newline = strchr (value , '\n' );
439+ if (newline ) {
440+ * newline = 0 ;
441+ }
442+
443+ if (strcmp (buffer , "autoload" ) == 0 ) {
444+ s_rom_filename = xstrdup (value );
445+ } else if (strcmp (buffer , "audio-frequency" ) == 0 ) {
446+ s_audio_frequency = atoi (value );
447+ } else if (strcmp (buffer , "audio-frames" ) == 0 ) {
448+ s_audio_frames = atoi (value );
449+ } else if (strcmp (buffer , "builtin-palette" ) == 0 ) {
450+ s_builtin_palette = atoi (value );
451+ } else if (strcmp (buffer , "force-dmg" ) == 0 ) {
452+ s_force_dmg = atoi (value );
453+ } else if (strcmp (buffer , "rewind-frames-per-base-state" ) == 0 ) {
454+ s_rewind_frames_per_base_state = atoi (value );
455+ } else if (strcmp (buffer , "rewind-buffer-capacity-megabytes" ) == 0 ) {
456+ s_rewind_buffer_capacity_megabytes = atoi (value );
457+ } else if (strcmp (buffer , "rewind-scale" ) == 0 ) {
458+ s_rewind_scale = atof (value );
459+ } else if (strcmp (buffer , "render-scale" ) == 0 ) {
460+ s_render_scale = atoi (value );
461+ } else if (strcmp (buffer , "random-seed" ) == 0 ) {
462+ s_random_seed = atoi (value );
463+ } else if (strcmp (buffer , "sgb-border" ) == 0 ) {
464+ s_use_sgb_border = atoi (value );
465+ } else {
466+ fprintf (stderr , "warning: unknown ini key: %s\n" , buffer );
467+ }
468+ }
469+ fclose (file );
470+ }
471+
416472int main (int argc , char * * argv ) {
417473 int result = 1 ;
418474
475+ read_ini_file ();
476+
419477 parse_arguments (argc , argv );
420478
421479 FileData rom ;
@@ -424,8 +482,8 @@ int main(int argc, char** argv) {
424482 EmulatorInit emulator_init ;
425483 ZERO_MEMORY (emulator_init );
426484 emulator_init .rom = rom ;
427- emulator_init .audio_frequency = AUDIO_FREQUENCY ;
428- emulator_init .audio_frames = AUDIO_FRAMES ;
485+ emulator_init .audio_frequency = s_audio_frequency ;
486+ emulator_init .audio_frames = s_audio_frames ;
429487 emulator_init .random_seed = s_random_seed ;
430488 emulator_init .builtin_palette = s_builtin_palette ;
431489 emulator_init .force_dmg = s_force_dmg ;
@@ -437,11 +495,11 @@ int main(int argc, char** argv) {
437495 host_init .hooks .key_down = key_down ;
438496 host_init .hooks .key_up = key_up ;
439497 host_init .render_scale = s_render_scale ;
440- host_init .audio_frequency = AUDIO_FREQUENCY ;
441- host_init .audio_frames = AUDIO_FRAMES ;
498+ host_init .audio_frequency = s_audio_frequency ;
499+ host_init .audio_frames = s_audio_frames ;
442500 host_init .audio_volume = s_audio_volume ;
443- host_init .rewind .frames_per_base_state = REWIND_FRAMES_PER_BASE_STATE ;
444- host_init .rewind .buffer_capacity = REWIND_BUFFER_CAPACITY ;
501+ host_init .rewind .frames_per_base_state = s_rewind_frames_per_base_state ;
502+ host_init .rewind .buffer_capacity = s_rewind_buffer_capacity_megabytes * MEGABYTES ( 1 ) ;
445503 host_init .joypad_filename = s_read_joypad_filename ;
446504 host_init .use_sgb_border = s_use_sgb_border ;
447505 host = host_new (& host_init , e );
@@ -458,7 +516,7 @@ int main(int argc, char** argv) {
458516 f64 refresh_ms = host_get_monitor_refresh_ms (host );
459517 while (s_running && host_poll_events (host )) {
460518 if (s_rewinding ) {
461- rewind_by (REWIND_CYCLES_PER_FRAME );
519+ rewind_by (( Ticks )( PPU_FRAME_TICKS * s_rewind_scale ) );
462520 } else if (!s_paused ) {
463521 EmulatorEvent event = host_run_ms (host , refresh_ms );
464522 if (event & EMULATOR_EVENT_INVALID_OPCODE ) {
0 commit comments