changeset 2544:99e59fdddbc3

Better cassette tape UX
author Michael Pavone <pavone@retrodev.com>
date Mon, 09 Dec 2024 13:45:35 -0800
parents 9a07d299604b
children 6aa3025bbf5f
files blastem.c nuklear_ui/blastem_nuklear.c sms.c system.h
diffstat 4 files changed, 103 insertions(+), 65 deletions(-) [+]
line wrap: on
line diff
--- a/blastem.c	Thu Nov 28 23:44:36 2024 -0800
+++ b/blastem.c	Mon Dec 09 13:45:35 2024 -0800
@@ -441,9 +441,15 @@
 	free(lock_on.extension);
 	free(lock_on.orig_path);
 	if (lock_on_path) {
-		reload_media();
+		if (!current_system || !current_system->lockon_change) {
+			cart.chain = NULL;
+			reload_media();
+		}
 		cart.chain = &lock_on;
 		load_media(lock_on_path, &lock_on, NULL);
+		if (current_system && current_system->lockon_change) {
+			current_system->lockon_change(current_system, &lock_on);
+		}
 	} else {
 		lock_on.dir = NULL;
 		lock_on.name = NULL;
--- a/nuklear_ui/blastem_nuklear.c	Thu Nov 28 23:44:36 2024 -0800
+++ b/nuklear_ui/blastem_nuklear.c	Mon Dec 09 13:45:35 2024 -0800
@@ -22,6 +22,7 @@
 #include "../controller_info.h"
 #include "../bindings.h"
 #include "../mediaplayer.h"
+#include "../sms.h"
 
 static struct nk_context *context;
 static struct rawfb_context *fb_context;
@@ -242,6 +243,12 @@
 	view_file_browser(context, 0);
 }
 
+void view_load_tape(struct nk_context *context)
+{
+	browser_label = "Select Tape Image";
+	view_file_browser(context, 0);
+}
+
 void view_file_settings(struct nk_context *context)
 {
 	view_file_browser(context, 0);
@@ -2444,9 +2451,22 @@
 		{"Settings", view_settings},
 		{"Exit", NULL}
 	};
+	static menu_item sc3k_items[] = {
+		{"Resume", view_play},
+		{"Load ROM", view_load},
+		{"Load Tape", view_load_tape},
+		{"Save State", view_save_state},
+		{"Load State", view_load_state},
+		{"Settings", view_settings},
+		{"Exit", NULL}
+	};
 
 	if (nk_begin(context, "Main Menu", nk_rect(0, 0, render_width(), render_height()), 0)) {
-		menu(context, sizeof(items)/sizeof(*items), items, exit_handler);
+		if (current_system->type == SYSTEM_SMS && ((sms_context *)current_system)->i8255) {
+			menu(context, sizeof(sc3k_items)/sizeof(*sc3k_items), sc3k_items, exit_handler);
+		} else {
+			menu(context, sizeof(items)/sizeof(*items), items, exit_handler);
+		}
 		nk_end(context);
 	}
 }
--- a/sms.c	Thu Nov 28 23:44:36 2024 -0800
+++ b/sms.c	Mon Dec 09 13:45:35 2024 -0800
@@ -1491,6 +1491,7 @@
 	sms->cassette_state = TAPE_STOPPED;
 	sms->cassette_offset = data_sub_chunk;
 	sms->cassette = media;
+	sms->cassette_cycle = sms->z80->Z80_CYCLE;
 }
 
 static void start_vgm_log(system_header *system, char *filename)
@@ -1517,6 +1518,12 @@
 	sms->header.vgm_logging = 0;
 }
 
+static void lockon_change(system_header *system, system_media *media)
+{
+	sms_context *sms = (sms_context *)system;
+	load_cassette(sms, media);
+}
+
 sms_context *alloc_configure_sms(system_media *media, uint32_t opts, uint8_t force_region)
 {
 	sms_context *sms = calloc(1, sizeof(sms_context));
@@ -1660,6 +1667,9 @@
 	sms->header.toggle_debug_view = toggle_debug_view;
 	sms->header.cassette_action = cassette_action;
 	sms->header.type = SYSTEM_SMS;
+	if (is_sc3000) {
+		sms->header.lockon_change = lockon_change;
+	}
 
 	return sms;
 }
--- a/system.h	Thu Nov 28 23:44:36 2024 -0800
+++ b/system.h	Mon Dec 09 13:45:35 2024 -0800
@@ -45,69 +45,6 @@
 	CASSETTE_REWIND
 };
 
-typedef void (*system_fun)(system_header *);
-typedef uint16_t (*system_fun_r16)(system_header *);
-typedef void (*system_str_fun)(system_header *, char *);
-typedef uint8_t (*system_str_fun_r8)(system_header *, char *);
-typedef void (*system_u32_fun)(system_header *, uint32_t);
-typedef void (*system_u8_fun)(system_header *, uint8_t);
-typedef uint8_t (*system_u8_fun_r8)(system_header *, uint8_t);
-typedef void (*system_u8_u8_fun)(system_header *, uint8_t, uint8_t);
-typedef void (*system_mabs_fun)(system_header *, uint8_t, uint16_t, uint16_t);
-typedef void (*system_mrel_fun)(system_header *, uint8_t, int32_t, int32_t);
-typedef uint8_t *(*system_ptrszt_fun_rptr8)(system_header *, size_t *);
-typedef void (*system_ptr8_sizet_fun)(system_header *, uint8_t *, size_t);
-
-#include "arena.h"
-#include "romdb.h"
-typedef struct event_reader event_reader;
-
-struct system_header {
-	system_header     *next_context;
-	system_str_fun    start_context;
-	system_fun        resume_context;
-	system_fun        load_save;
-	system_fun        persist_save;
-	system_u8_fun_r8  load_state;
-	system_fun        request_exit;
-	system_fun        soft_reset;
-	system_fun        free_context;
-	system_fun_r16    get_open_bus_value;
-	system_u32_fun    set_speed_percent;
-	system_fun        inc_debug_mode;
-	system_u8_u8_fun  gamepad_down;
-	system_u8_u8_fun  gamepad_up;
-	system_u8_u8_fun  mouse_down;
-	system_u8_u8_fun  mouse_up;
-	system_mabs_fun   mouse_motion_absolute;
-	system_mrel_fun   mouse_motion_relative;
-	system_u8_fun     keyboard_down;
-	system_u8_fun     keyboard_up;
-	system_fun        config_updated;
-	system_ptrszt_fun_rptr8 serialize;
-	system_ptr8_sizet_fun   deserialize;
-	system_str_fun          start_vgm_log;
-	system_fun              stop_vgm_log;
-	system_u8_fun           toggle_debug_view;
-	system_u8_fun           cassette_action;
-	rom_info          info;
-	arena             *arena;
-	char              *next_rom;
-	char              *save_dir;
-	char              *paste_buffer;
-	uint32_t          paste_cur_char;
-	int               enter_debugger_frames;
-	uint8_t           enter_debugger;
-	uint8_t           should_exit;
-	uint8_t           save_state;
-	uint8_t           delayed_load_slot;
-	uint8_t           has_keyboard;
-	uint8_t                 vgm_logging;
-	uint8_t                 force_release;
-	debugger_type     debugger_type;
-	system_type       type;
-};
-
 typedef enum {
 	MEDIA_CART,
 	MEDIA_CDROM
@@ -164,6 +101,71 @@
 	uint8_t      byte_storage[3];
 };
 
+typedef void (*system_fun)(system_header *);
+typedef uint16_t (*system_fun_r16)(system_header *);
+typedef void (*system_str_fun)(system_header *, char *);
+typedef uint8_t (*system_str_fun_r8)(system_header *, char *);
+typedef void (*system_u32_fun)(system_header *, uint32_t);
+typedef void (*system_u8_fun)(system_header *, uint8_t);
+typedef uint8_t (*system_u8_fun_r8)(system_header *, uint8_t);
+typedef void (*system_u8_u8_fun)(system_header *, uint8_t, uint8_t);
+typedef void (*system_mabs_fun)(system_header *, uint8_t, uint16_t, uint16_t);
+typedef void (*system_mrel_fun)(system_header *, uint8_t, int32_t, int32_t);
+typedef uint8_t *(*system_ptrszt_fun_rptr8)(system_header *, size_t *);
+typedef void (*system_ptr8_sizet_fun)(system_header *, uint8_t *, size_t);
+typedef void (*system_media_fun)(system_header *, system_media *);
+
+#include "arena.h"
+#include "romdb.h"
+typedef struct event_reader event_reader;
+
+struct system_header {
+	system_header     *next_context;
+	system_str_fun    start_context;
+	system_fun        resume_context;
+	system_fun        load_save;
+	system_fun        persist_save;
+	system_u8_fun_r8  load_state;
+	system_fun        request_exit;
+	system_fun        soft_reset;
+	system_fun        free_context;
+	system_fun_r16    get_open_bus_value;
+	system_u32_fun    set_speed_percent;
+	system_fun        inc_debug_mode;
+	system_u8_u8_fun  gamepad_down;
+	system_u8_u8_fun  gamepad_up;
+	system_u8_u8_fun  mouse_down;
+	system_u8_u8_fun  mouse_up;
+	system_mabs_fun   mouse_motion_absolute;
+	system_mrel_fun   mouse_motion_relative;
+	system_u8_fun     keyboard_down;
+	system_u8_fun     keyboard_up;
+	system_fun        config_updated;
+	system_ptrszt_fun_rptr8 serialize;
+	system_ptr8_sizet_fun   deserialize;
+	system_str_fun          start_vgm_log;
+	system_fun              stop_vgm_log;
+	system_u8_fun           toggle_debug_view;
+	system_u8_fun           cassette_action;
+	system_media_fun        lockon_change;
+	rom_info          info;
+	arena             *arena;
+	char              *next_rom;
+	char              *save_dir;
+	char              *paste_buffer;
+	uint32_t          paste_cur_char;
+	int               enter_debugger_frames;
+	uint8_t           enter_debugger;
+	uint8_t           should_exit;
+	uint8_t           save_state;
+	uint8_t           delayed_load_slot;
+	uint8_t           has_keyboard;
+	uint8_t                 vgm_logging;
+	uint8_t                 force_release;
+	debugger_type     debugger_type;
+	system_type       type;
+};
+
 #define OPT_ADDRESS_LOG (1U << 31U)
 
 system_type detect_system_type(system_media *media);