diff --git a/src/linux/port.c b/src/linux/port.c index 381a851..5fc7544 100644 --- a/src/linux/port.c +++ b/src/linux/port.c @@ -83,6 +83,8 @@ void* nese_alloc(int size) { * Platform-specific features and controls */ +#define PLAT_FILENAME_SIZE (1024U) + typedef enum { Flag_Turbo = 0b1, } Platform_Flags; @@ -95,6 +97,7 @@ typedef struct { Overlay overlay; int fps_msg_id; Platform_Flags flags; + char filename[PLAT_FILENAME_SIZE]; } platform_data; @@ -277,26 +280,10 @@ int64_t time_sleep_until(int64_t t_target) { return t_diff * 1000; } +static nese_Action select_rom(platform_data* plat, char* file, int sz_file); int nese_frame_ready(void* plat_data) { platform_data* plat = (platform_data*)plat_data; -/* - static int frame = 0; - static int ignore = 1; - static struct timespec t_last = {0}; - struct timespec t_now = {0}; - - ++frame; - clock_gettime(CLOCK_MONOTONIC, &t_now); - - if (t_now.tv_sec > t_last.tv_sec) { - if (!ignore) printf("%d\n", frame); - frame = 0; - ignore = 0; - } - - t_last = t_now; -*/ /* uint8_t* ptr = &plat->sys->core.memory.ppu.vram[0x3C0]; for (int y = 0; y < 16; y += 2) { @@ -332,7 +319,6 @@ int nese_frame_ready(void* plat_data) { nese_Action action = process_events(plat->sys); switch (action) { - case Action_Menu: case Action_Quit: status = -1; break; @@ -358,6 +344,15 @@ int nese_frame_ready(void* plat_data) { plat->flags ^= Flag_Turbo; break; + case Action_Menu: + action = select_rom(plat, plat->filename, PLAT_FILENAME_SIZE); + if (Action_OK == action) { + nes_reset(plat->sys); + } else if (Action_Quit == action || NULL == plat->sys->cart_header) { + status = -1; + } + break; + default: } @@ -399,7 +394,6 @@ int nese_frame_ready(void* plat_data) { } - return status; } @@ -408,7 +402,7 @@ int nese_frame_ready(void* plat_data) { void nese_draw_begin(void* plat_data) { platform_data* plat = (platform_data*)plat_data; - draw_begin(&plat->renderer, NULL != plat->cart.filename); + draw_begin(&plat->renderer, NULL != plat->sys->cart_header); } void nese_draw_text(void* plat_data, const char* str, int x, int y, uint32_t c) { @@ -464,8 +458,10 @@ static nese_Action run_rom_menu(platform_data* plat, Menu_State* state, if (NULL != state) menu = *state; // Add 4 to skip past "rom/" - int current = find_file(&files, filename + 4); - if (current >= 0) menu.cursor = current; + if (strlen(filename) > 4) { + int current = find_file(&files, filename + 4); + if (current >= 0) menu.cursor = current; + } action = run_menu(plat, &menu, &files, 20); @@ -487,6 +483,45 @@ static nese_Action run_rom_menu(platform_data* plat, Menu_State* state, return action; } +static nese_Action nese_load_cart(platform_data* plat, const char* filename) { + nese_Action action = Action_OK; + unload_cart(&plat->cart); + plat->sys->cart_header = NULL; + int status = load_cart(&plat->cart, filename, plat->sys); + if (0 != status) { + char message[1024]; + snprintf(message, sizeof(message), "Failed to load\n%s", filename); + action = modal_popup(plat, message, color_error); + if (Action_Quit != action) action = Action_Cancel; + } + return action; +} + +static nese_Action select_rom(platform_data* plat, char* file, int sz_file) { + nese_Action action = Action_OK; + Menu_State menu = {0}; + + while (Action_OK == action || NULL == plat->sys->cart_header) { + action = run_rom_menu(plat, &menu, file, sz_file); + if (Action_OK == action) { + plat->sys->cart_header = NULL; + action = nese_load_cart(plat, file); + if (Action_OK == action) break; + // Failure - Now no ROM is currently loaded + render_clear(&plat->renderer); + file[0] = '\0'; + if (Action_Quit != action) action = Action_OK; + } else if ( ( Action_Cancel == action && + NULL == plat->sys->cart_header) || + Action_Quit == action) { + // If no cart is loaded, or the user tried to quit, just leave + break; + } + } + + return action; +} + /* Platform Data */ @@ -517,7 +552,6 @@ static nes sys = {0}; int main(int argc, char* argv[]) { int status = 0; - char filename[1024] = {0}; // This should be tiny enough to keep on the stack. platform_data plat = { @@ -530,32 +564,23 @@ int main(int argc, char* argv[]) { if (0 == status) { if (1 < argc) { - strncpy(filename, argv[1], sizeof(filename) - 1); - filename[sizeof(filename) - 1] = '\0'; + strncpy(plat.filename, argv[1], PLAT_FILENAME_SIZE - 1); + plat.filename[PLAT_FILENAME_SIZE - 1] = '\0'; + nese_Action action = nese_load_cart(&plat, plat.filename); + status = (Action_OK == action) ? 0 : -1; } - while (NULL == sys.cart_header && 0 == status) { - if (filename[0]) { - status = load_cart(&plat.cart, filename, &sys); - if (0 != status) { - char message[1039]; - snprintf(message, sizeof(message), - "Failed to load %s", filename); - modal_popup(&plat, message, color_error); - } - } - - if (NULL == sys.cart_header) { - nese_Action action = run_rom_menu(&plat, NULL, - filename, sizeof(filename)); - status = (Action_OK == action) ? 0 : -1; - } + if (NULL == sys.cart_header) { + nese_Action action = select_rom( + &plat, plat.filename, PLAT_FILENAME_SIZE + ); + status = (Action_OK == action) ? 0 : -1; } + } - // This shall invoke menus as needed - if (0 == status) { - status = nese_start(&sys, &plat); - } + // This shall invoke menus as needed + if (0 == status) { + status = nese_start(&sys, &plat); } unload_cart(&plat.cart); diff --git a/src/sdl/render.c b/src/sdl/render.c index c103dd4..7d2b83e 100644 --- a/src/sdl/render.c +++ b/src/sdl/render.c @@ -57,6 +57,9 @@ int render_frame_end(Render_Info* renderer) { return 0; } +void render_clear(Render_Info* renderer) { + SDL_FillRect(renderer->target, NULL, color_background); +} int render_info_init(Render_Info* renderer, nes* sys) { int status = SDL_Init( @@ -106,7 +109,7 @@ int render_info_init(Render_Info* renderer, nes* sys) { } else { SDL_LockTextureToSurface(renderer->texture, NULL, &renderer->target); - SDL_FillRect(renderer->target, NULL, color_background); + render_clear(renderer); } } diff --git a/src/sdl/render.h b/src/sdl/render.h index 6a341d0..6ca15f5 100644 --- a/src/sdl/render.h +++ b/src/sdl/render.h @@ -18,9 +18,11 @@ typedef struct { int render_info_init(Render_Info*, nes*); void render_info_done(Render_Info*); +void render_clear(Render_Info*); + int render_frame_start(Render_Info*, uint8_t background); int render_frame(Render_Info*); int render_frame_end(Render_Info*); -#endif // NESE_RENDER_H_ \ No newline at end of file +#endif // NESE_RENDER_H_