diff --git a/src/input.h b/src/input.h index e954f34..ba5156d 100644 --- a/src/input.h +++ b/src/input.h @@ -14,6 +14,7 @@ typedef enum { input_Result_Reset = 2, input_Result_Save = 3, input_Result_Load = 4, + input_Result_Cancel = 5, } nes_Input_Result; #define nes_controller_num_buttons (8U) diff --git a/src/nese.c b/src/nese.c index b282abf..0069d15 100644 --- a/src/nese.c +++ b/src/nese.c @@ -24,6 +24,66 @@ extern nes_Audio_Stream sdl_audio; static nes sys = {0}; +typedef struct { + Overlay* overlay; + int timer; + int id; + int mode; +} loadsave_state; + +void loadsave_start(loadsave_state* loadsave, int mode) { + if (0 != loadsave->mode) { + // We can't do two things at once. + overlay_clear_message(loadsave->overlay, loadsave->id); + loadsave->mode = 0; + + } else { + loadsave->mode = mode; + loadsave->timer = 60 * 1; + const char* op = NULL; + if (input_Result_Load == mode) op = "Restoring"; + else if (input_Result_Save == mode) op = "Saving"; + if (NULL != op) { + char msg[100]; + snprintf(msg, sizeof(msg), "%s game state ...", op); + loadsave->id = overlay_add_message( + loadsave->overlay, msg, 60 * 1 + ); + } + } +} + +int loadsave_tick(loadsave_state* loadsave) { + int action = 0; + + if (loadsave->mode != 0 && --loadsave->timer <= 0) { + const char *op = NULL; + + if (input_Result_Load == loadsave->mode) { + //load_state(&sys, cart_filename); + op = "restored"; + + } else if (input_Result_Save == loadsave->mode) { + //save_state(&sys, cart_filename); + op = "saved"; + } + + if (NULL != op) { + char msg[100]; + snprintf(msg, sizeof(msg), "Game state %s", op); + overlay_add_message(loadsave->overlay, msg, 60 * 3); + } + + overlay_clear_message(loadsave->overlay, loadsave->id); + + action = loadsave->mode; + loadsave->mode = 0; + } + + return action; +} + + int main(int argc, char* argv[]) { int status = 0; @@ -70,6 +130,10 @@ int main(int argc, char* argv[]) { } if (status == 0) { + loadsave_state loadsave = { + .overlay = &rend->overlay, + }; + nes_reset(&sys); nes_render(rend, &sys.ppu); @@ -88,6 +152,14 @@ int main(int argc, char* argv[]) { status = nes_render(rend, &sys.ppu); if (status > 0) { + // Load/Save Operations + int action = loadsave_tick(&loadsave); + if (input_Result_Load == action) { + load_state(&sys, cart_filename); + } else if (input_Result_Save == action) { + save_state(&sys, cart_filename); + } + // Sleep to catch up to master clock uint64_t elapsed_cycles = total_cycles - cycle_last_frame; @@ -111,15 +183,26 @@ int main(int argc, char* argv[]) { status = nes_input_update(input, &sys.input); if (input_Result_Reset == status) { + overlay_add_message( + &rend->overlay, + "Game reset", + 60 * 3 + ); nes_reset(&sys); status = 0; } else if (input_Result_Load == status) { - load_state(&sys, cart_filename); + loadsave_start(&loadsave, status); status = 0; } else if (input_Result_Save == status) { - save_state(&sys, cart_filename); + loadsave_start(&loadsave, status); + status = 0; + + } else if (input_Result_Cancel == status) { + overlay_clear_message(loadsave.overlay, + loadsave.id); + loadsave.mode = 0; status = 0; } diff --git a/src/sdl_input.c b/src/sdl_input.c index d852b94..7a235bd 100644 --- a/src/sdl_input.c +++ b/src/sdl_input.c @@ -94,8 +94,10 @@ static int sdl_input_update(nes_Input_Reader* reader, if (SDL_QUIT == event.type) { status = input_Result_Quit; - } else if ( SDL_KEYDOWN == event.type || - SDL_KEYUP == event.type) { + } else if ( ( SDL_KEYDOWN == event.type || + SDL_KEYUP == event.type) && + 0 == event.key.repeat + ) { int index = button_index(event.key.keysym.sym, sdl_keycodes); if (index >= 0) { @@ -110,13 +112,19 @@ static int sdl_input_update(nes_Input_Reader* reader, SDL_KEYDOWN == event.type) { status = input_Result_Reset; - } else if ( sdl_save_key == event.key.keysym.sym && - SDL_KEYDOWN == event.type) { - status = input_Result_Save; + } else if (sdl_save_key == event.key.keysym.sym) { + if (SDL_KEYDOWN == event.type) { + status = input_Result_Save; + } else { + status = input_Result_Cancel; + } - } else if ( sdl_load_key == event.key.keysym.sym && - SDL_KEYDOWN == event.type) { - status = input_Result_Load; + } else if (sdl_load_key == event.key.keysym.sym) { + if (SDL_KEYDOWN == event.type) { + status = input_Result_Load; + } else { + status = input_Result_Cancel; + } } } else if ( SDL_CONTROLLERBUTTONDOWN == event.type ||