diff --git a/src/include/86box/unix_osd.h b/src/include/86box/unix_osd.h index b774cbea1..c6582b322 100644 --- a/src/include/86box/unix_osd.h +++ b/src/include/86box/unix_osd.h @@ -3,16 +3,23 @@ #include +// state management extern void osd_init(); extern void osd_deinit(); - extern int osd_open(SDL_Event event); extern int osd_close(SDL_Event event); + +// keyboard event handler extern int osd_handle(SDL_Event event); +// draw the osd interface, if it's open +extern void osd_present(); + +// future ui extern void osd_ui_sb_update_icon_state(int tag, int state); extern void osd_ui_sb_update_icon(int tag, int active); extern void osd_ui_sb_update_icon_write(int tag, int active); +extern void osd_ui_sb_update_icon_wp(int tag, int state); #endif /*_UNIX_OSD_H*/ diff --git a/src/unix/unix.c b/src/unix/unix.c index 0d4f0189f..629528394 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -473,24 +473,26 @@ plat_remove(char *path) remove(path); } -void -ui_sb_update_icon_state(UNUSED(int tag), UNUSED(int state)) +void ui_sb_update_icon_state(int tag, int state) { osd_ui_sb_update_icon_state(tag, state); } -void -ui_sb_update_icon(UNUSED(int tag), UNUSED(int active)) +void ui_sb_update_icon(int tag, int active) { osd_ui_sb_update_icon(tag, active); } -void -ui_sb_update_icon_write(UNUSED(int tag), UNUSED(int active)) +void ui_sb_update_icon_write(int tag, int active) { osd_ui_sb_update_icon_write(tag, active); } +void ui_sb_update_icon_wp(int tag, int state) +{ + osd_ui_sb_update_icon_wp(tag, state); +} + void plat_delay_ms(uint32_t count) { @@ -534,7 +536,6 @@ path_get_dirname(char *dest, const char *path) *dest++ = *path++; *dest = '\0'; } -volatile int cpu_thread_run = 1; void ui_sb_set_text_w(UNUSED(wchar_t *wstr)) @@ -554,6 +555,8 @@ strnicmp(const char *s1, const char *s2, size_t n) return strncasecmp(s1, s2, n); } +volatile int cpu_thread_run = 1; + void main_thread(UNUSED(void *param)) { @@ -567,15 +570,20 @@ main_thread(UNUSED(void *param)) // title_update = 1; old_time = SDL_GetTicks(); drawits = frames = 0; - while (!is_quit && cpu_thread_run) { + while (!is_quit && cpu_thread_run) + { /* See if it is time to run a frame of code. */ new_time = SDL_GetTicks(); + #ifdef USE_GDBSTUB if (gdbstub_next_asap && (drawits <= 0)) drawits = 10; else -#endif drawits += (new_time - old_time); +#else + drawits += (new_time - old_time); +#endif + old_time = new_time; if (drawits > 0 && !dopause) { /* Yes, so do one frame now. */ @@ -592,15 +600,18 @@ main_thread(UNUSED(void *param)) nvr_dosave = 0; frames = 0; } - } else /* Just so we dont overload the host OS. */ + } + else /* Just so we dont overload the host OS. */ SDL_Delay(1); /* If needed, handle a screen resize. */ if (atomic_load(&doresize_monitors[0]) && !video_fullscreen && !is_quit) { + if (vid_resize & 2) plat_resize(fixed_size_x, fixed_size_y, 0); else plat_resize(scrnsz_x, scrnsz_y, 0); + atomic_store(&doresize_monitors[0], 1); } } @@ -753,7 +764,6 @@ ui_sb_set_ready(UNUSED(int ready)) /* No-op. */ } - // From musl. char * local_strsep(char **str, const char *sep) @@ -961,11 +971,6 @@ void (*f_rl_callback_handler_remove)(void) = NULL; # define LIBEDIT_LIBRARY "libedit.so" #endif -void ui_sb_update_icon_wp(int tag, int state) -{ - /* No-op */ -} - uint32_t timer_onesec(uint32_t interval, UNUSED(void *param)) { @@ -1206,9 +1211,11 @@ monitor_thread(UNUSED(void *param)) size_t n; printf("86Box monitor console.\n"); - while (!exit_event) { + while (!exit_event) + { if (feof(stdin)) break; + #ifdef ENABLE_READLINE if (f_readline) line = f_readline("(86Box) "); @@ -1219,6 +1226,7 @@ monitor_thread(UNUSED(void *param)) #ifdef ENABLE_READLINE } #endif + unix_executeLine(line); free(line); @@ -1437,10 +1445,17 @@ main(int argc, char **argv) { // open OSD! flag_osd_open = osd_open(event); - // we can assume alt-gr has been released + + // we can assume alt-gr has been released, tell this also to the virtual machine r_alt_pressed = 0; + keyboard_input(0, sdl_to_xt[SDL_SCANCODE_RALT]); break; } + else + { + // invalidate r_alt_pressed is something happens between its keydown and keydown for G + r_alt_pressed = 0; + } switch (event.key.keysym.scancode) { default: @@ -1465,8 +1480,7 @@ main(int argc, char **argv) } } - // blit only if the OSD is closed - if (blitreq && !flag_osd_open) { + if (blitreq) { extern void sdl_blit(int x, int y, int w, int h); sdl_blit(params.x, params.y, params.w, params.h); } diff --git a/src/unix/unix_cdrom.c b/src/unix/unix_cdrom.c index 76c5f1501..131fe6139 100644 --- a/src/unix/unix_cdrom.c +++ b/src/unix/unix_cdrom.c @@ -46,13 +46,14 @@ cassette_mount(char *fn, uint8_t wp) memset(cassette_fname, 0, sizeof(cassette_fname)); cassette_ui_writeprot = wp; pc_cas_set_fname(cassette, fn); + if (fn != NULL) memcpy(cassette_fname, fn, MIN(511, strlen(fn))); + ui_sb_update_icon_state(SB_CASSETTE, (fn == NULL) ? 1 : 0); -#if 0 - media_menu_update_cassette(); -#endif + ui_sb_update_tip(SB_CASSETTE); + config_save(); } @@ -61,11 +62,11 @@ cassette_eject(void) { pc_cas_set_fname(cassette, NULL); memset(cassette_fname, 0x00, sizeof(cassette_fname)); + ui_sb_update_icon_state(SB_CASSETTE, 1); -#if 0 - media_menu_update_cassette(); -#endif + ui_sb_update_tip(SB_CASSETTE); + config_save(); } @@ -74,11 +75,11 @@ cartridge_mount(uint8_t id, char *fn, UNUSED(uint8_t wp)) { cart_close(id); cart_load(id, fn); + ui_sb_update_icon_state(SB_CARTRIDGE | id, strlen(cart_fns[id]) ? 0 : 1); -#if 0 - media_menu_update_cartridge(id); -#endif + ui_sb_update_tip(SB_CARTRIDGE | id); + config_save(); } @@ -86,11 +87,11 @@ void cartridge_eject(uint8_t id) { cart_close(id); + ui_sb_update_icon_state(SB_CARTRIDGE | id, 1); -#if 0 - media_menu_update_cartridge(id); -#endif + ui_sb_update_tip(SB_CARTRIDGE | id); + config_save(); } @@ -100,11 +101,11 @@ floppy_mount(uint8_t id, char *fn, uint8_t wp) fdd_close(id); ui_writeprot[id] = wp; fdd_load(id, fn); + ui_sb_update_icon_state(SB_FLOPPY | id, strlen(floppyfns[id]) ? 0 : 1); -#if 0 - media_menu_update_floppy(id); -#endif + ui_sb_update_tip(SB_FLOPPY | id); + config_save(); } @@ -112,11 +113,11 @@ void floppy_eject(uint8_t id) { fdd_close(id); + ui_sb_update_icon_state(SB_FLOPPY | id, 1); -#if 0 - media_menu_update_floppy(id); -#endif + ui_sb_update_tip(SB_FLOPPY | id); + config_save(); } @@ -131,9 +132,6 @@ plat_cdrom_ui_update(uint8_t id, UNUSED(uint8_t reload)) ui_sb_update_icon_state(SB_CDROM | id, 0); } -#if 0 - media_menu_update_cdrom(id); -#endif ui_sb_update_tip(SB_CDROM | id); } @@ -142,30 +140,8 @@ cdrom_mount(uint8_t id, char *fn) { int ret = cdrom_load( &(cdrom[id]), fn, 0); - /* - strcpy(cdrom[id].prev_image_path, cdrom[id].image_path); - if (cdrom[id].ops && cdrom[id].ops->close) - cdrom[id].ops->close(cdrom[id].local); - cdrom[id].ops = NULL; - memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path)); - if ((fn != NULL) && (strlen(fn) >= 1) && (fn[strlen(fn) - 1] == '\\')) - fn[strlen(fn) - 1] = '/'; - image_open(&(cdrom[id]), fn); - // Signal media change to the emulated machine. - if (cdrom[id].insert) - cdrom[id].insert(cdrom[id].priv); + plat_cdrom_ui_update(id, 0); - if (cdrom[id].image_path[0] == 0x00) - ui_sb_update_icon_state(SB_CDROM | id, 0); - else - ui_sb_update_icon_state(SB_CDROM | id, 1); - */ - - ui_sb_update_icon_state(SB_CDROM | id, ret == 0 ? 1 : 0); -#if 0 - media_menu_update_cdrom(id); -#endif - ui_sb_update_tip(SB_CDROM | id); config_save(); } @@ -181,9 +157,7 @@ mo_eject(uint8_t id) } ui_sb_update_icon_state(SB_MO | id, 1); -#if 0 - media_menu_update_mo(id); -#endif + ui_sb_update_tip(SB_MO | id); config_save(); } @@ -198,9 +172,7 @@ mo_mount(uint8_t id, char *fn, uint8_t wp) mo_load(dev, fn, 0); ui_sb_update_icon_state(SB_MO | id, strlen(mo_drives[id].image_path) ? 0 : 1); -#if 0 - media_menu_update_mo(id); -#endif + ui_sb_update_tip(SB_MO | id); config_save(); @@ -218,9 +190,6 @@ mo_reload(uint8_t id) ui_sb_update_icon_state(SB_MO | id, 0); } -#if 0 - media_menu_update_mo(id); -#endif ui_sb_update_tip(SB_MO | id); config_save(); @@ -238,10 +207,9 @@ rdisk_eject(uint8_t id) } ui_sb_update_icon_state(SB_RDISK | id, 1); -#if 0 - media_menu_update_rdisk(id); -#endif + ui_sb_update_tip(SB_RDISK | id); + config_save(); } @@ -255,9 +223,7 @@ rdisk_mount(uint8_t id, char *fn, uint8_t wp) rdisk_load(dev, fn, 0); ui_sb_update_icon_state(SB_RDISK | id, strlen(rdisk_drives[id].image_path) ? 0 : 1); -#if 0 - media_menu_update_rdisk(id); -#endif + ui_sb_update_tip(SB_RDISK | id); config_save(); @@ -275,9 +241,6 @@ rdisk_reload(uint8_t id) ui_sb_update_icon_state(SB_RDISK | id, 0); } -#if 0 - media_menu_update_rdisk(id); -#endif ui_sb_update_tip(SB_RDISK | id); config_save(); diff --git a/src/unix/unix_osd.c b/src/unix/unix_osd.c index 42517c866..11b255656 100644 --- a/src/unix/unix_osd.c +++ b/src/unix/unix_osd.c @@ -32,6 +32,9 @@ static int BOX_H = 160; #define CHAR_W 8 #define CHAR_H 8 +// this makes the osd embeddable in the 86box main sdl loop +#define OSD_INSIDE_MAIN_LOOP + // interface to SDL environment extern SDL_Window *sdl_win; extern SDL_Renderer *sdl_render; @@ -70,32 +73,53 @@ static const char *menu_items[] = { static char selected_file[256] = ""; // memoria della selezione -static int font_cols = 16; // numero colonne nella bitmap font (16x16 caratteri) +// chars per cols and rows +static int font_cols = 16; static int font_rows = 16; static int selected = 0; static int file_selected = 0; static int scroll_offset = 0; + +static int osd_is_open = 0; static AppState state = STATE_MENU; -static char files[100][256]; +static char files[100][1024]; static int file_count = 0; static int max_visible = 0; -int load_iso_files(char files[][256], int max_files, char *mask) +int reset_iso_files() +{ + file_selected = 0; + scroll_offset = 0; + + file_count = 0; + memzero(files, sizeof(files)); +} + +static int endswith(char *s1, char *mask) +{ + return strlen(s1) >= strlen(mask) && strncasecmp(s1+strlen(s1)-strlen(mask), mask, strlen(mask)); +} + +int load_iso_files(char *basedir, char files[][1024], int max_files, char *mask) { DIR *d; struct dirent *dir; - int count = 0; - d = opendir("."); + int count = file_count; + d = opendir(basedir); if (!d) - return 0; + return file_count; + + while ((dir = readdir(d)) != NULL && count < max_files) + { + if (endswith(dir->d_name, mask)) + { + strcpy(files[count], basedir); + strcat(files[count], "/"); + strcat(files[count], dir->d_name); - while ((dir = readdir(d)) != NULL && count < max_files) { - if (strstr(dir->d_name, mask)) { - strncpy(files[count], dir->d_name, 255); - files[count][255] = '\0'; count++; } } @@ -141,9 +165,6 @@ void draw_box_with_border(SDL_Renderer *renderer, SDL_Rect box) void draw_menu(SDL_Renderer *renderer, int selected) { - // SDL_SetRenderDrawColor(renderer, 0, 0, 128, 255); - // SDL_RenderClear(renderer); - int x0 = (SCREEN_W - BOX_W) / 2; int y0 = (SCREEN_H - BOX_H) / 2; SDL_Rect box = {x0, y0, BOX_W, BOX_H}; @@ -170,7 +191,9 @@ void draw_menu(SDL_Renderer *renderer, int selected) draw_text(renderer, menu_items[i], tx, ty, textColor); } +#ifndef OSD_INSIDE_MAIN_LOOP SDL_RenderPresent(renderer); +#endif } // ------------------- Disegna selezione file ------------------- @@ -179,9 +202,6 @@ void draw_file_selector(SDL_Renderer *renderer, char files[][256], int file_count, int selected, int scroll_offset, int max_visible) { - // SDL_SetRenderDrawColor(renderer, 0, 0, 128, 255); - // SDL_RenderClear(renderer); - int x0 = (SCREEN_W - BOX_W) / 2; int y0 = (SCREEN_H - BOX_H) / 2; SDL_Rect box = {x0, y0, BOX_W, BOX_H}; @@ -214,16 +234,18 @@ void draw_file_selector(SDL_Renderer *renderer, } } +#ifndef OSD_INSIDE_MAIN_LOOP SDL_RenderPresent(renderer); +#endif } void osd_init() { - fprintf(stderr, "OSD INIT\n"); + // debug: fprintf(stderr, "OSD INIT\n"); if (font_texture == NULL) { - fprintf(stderr, "OSD INIT FONT\n"); + // debug: fprintf(stderr, "OSD INIT FONT\n"); // Carica font bitmap (font.bmp 128x128, 16x16 caratteri, 8x8 ciascuno) SDL_RWops *rwop = SDL_RWFromConstMem(_________font_bmp, _________font_bmp_len); @@ -250,7 +272,7 @@ void osd_init() void osd_deinit() { // nothing to do - fprintf(stderr, "OSD DEINIT\n"); + // debug: fprintf(stderr, "OSD DEINIT\n"); // will be implicitly freed on exit // SDL_DestroyTexture(font_texture); @@ -261,7 +283,7 @@ void osd_deinit() int osd_open(SDL_Event event) { // ok opened - fprintf(stderr, "OSD OPEN\n"); + // debug: fprintf(stderr, "OSD OPEN\n"); SDL_GetWindowSize(sdl_win, &SCREEN_W, &SCREEN_H); BOX_W = (SCREEN_W / 4) * 3; @@ -269,13 +291,17 @@ int osd_open(SDL_Event event) max_visible = (BOX_H - TITLE_HEIGHT) / LINE_HEIGHT; + osd_is_open = 1; + return 1; } int osd_close(SDL_Event event) { // ok closed - fprintf(stderr, "OSD CLOSE\n"); + // debug: fprintf(stderr, "OSD CLOSE\n"); + + osd_is_open = 0; return 1; } @@ -288,12 +314,15 @@ static void osd_cmd_run(char *c) free(l); } - -int osd_handle(SDL_Event event) +void osd_present() { - fprintf(stderr, "OSD HANDLE\n"); + // shortcut + if (!osd_is_open) + return; +#ifndef OSD_INSIDE_MAIN_LOOP SDL_LockMutex(sdl_mutex); +#endif if (state == STATE_MENU) { draw_menu(sdl_render, selected); @@ -305,49 +334,71 @@ int osd_handle(SDL_Event event) draw_file_selector(sdl_render, "SELECT CD ISO IMAGE", files, file_count, file_selected, scroll_offset, max_visible); } +#ifndef OSD_INSIDE_MAIN_LOOP SDL_UnlockMutex(sdl_mutex); +#endif +} + +int osd_handle(SDL_Event event) +{ + // debug: fprintf(stderr, "OSD HANDLE\n"); if (event.type == SDL_KEYUP) { if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) { // Close the OSD - fprintf(stderr, "OSD HANDLE: escape\n"); + // debug: fprintf(stderr, "OSD HANDLE: escape\n"); return 0; } } - if (event.type == SDL_KEYDOWN) { - if (state == STATE_MENU) { - switch (event.key.keysym.sym) { + if (event.type == SDL_KEYDOWN) + { + if (state == STATE_MENU) + { + switch (event.key.keysym.sym) + { case SDLK_UP: selected = (selected - 1 + MENU_ITEMS) % MENU_ITEMS; break; + case SDLK_DOWN: selected = (selected + 1) % MENU_ITEMS; break; + case SDLK_RETURN: case SDLK_KP_ENTER: switch (selected) { case 0 : // "fddload - Load floppy disk image", - file_count = load_iso_files(files, 100, ".img"); - file_selected = 0; - scroll_offset = 0; + reset_iso_files(); + file_count = load_iso_files(".", files, 100, ".img"); + file_count = load_iso_files("/mnt", files, 100, ".img"); + file_count = load_iso_files("/mnt/usbkey", files, 100, ".img"); state = STATE_FILESELECT_FLOPPY; break; + case 1 : // "cdload - Load CD-ROM image", - file_count = load_iso_files(files, 100, ".iso"); - file_selected = 0; - scroll_offset = 0; + reset_iso_files(); + file_count = load_iso_files(".", files, 100, ".iso"); + file_count = load_iso_files("/mnt", files, 100, ".iso"); + file_count = load_iso_files("/mnt/usbkey", files, 100, ".iso"); state = STATE_FILESELECT_CD; break; + case 2 : // "rdiskload - Load removable disk image", + reset_iso_files(); break; + case 3 : // "cartload - Load cartridge image", + reset_iso_files(); break; + case 4 : // "moload - Load MO image", + reset_iso_files(); break; + case 5 : // "fddeject - eject disk from floppy drive", osd_cmd_run("fddeject 0"); return 0; @@ -394,12 +445,18 @@ int osd_handle(SDL_Event event) } break; } - } else if (state == STATE_FILESELECT_FLOPPY || state == STATE_FILESELECT_CD) { - if (file_count == 0) { + } + else if (state == STATE_FILESELECT_FLOPPY || state == STATE_FILESELECT_CD) + { + if (file_count == 0) + { + // no files, there is nothing else to do if (event.key.keysym.sym == SDLK_ESCAPE) { state = STATE_MENU; } - } else { + } + else + { switch (event.key.keysym.sym) { case SDLK_UP: if (file_selected > 0) { @@ -417,6 +474,7 @@ int osd_handle(SDL_Event event) } } break; + case SDLK_RETURN: case SDLK_KP_ENTER: char cmd[1024] = ""; @@ -446,12 +504,14 @@ void osd_ui_sb_update_icon_state(UNUSED(int tag), UNUSED(int state)) { } -void -osd_ui_sb_update_icon(UNUSED(int tag), UNUSED(int active)) +void osd_ui_sb_update_icon(UNUSED(int tag), UNUSED(int active)) { } -void -osd_ui_sb_update_icon_write(UNUSED(int tag), UNUSED(int active)) +void osd_ui_sb_update_icon_write(UNUSED(int tag), UNUSED(int active)) +{ +} + +void osd_ui_sb_update_icon_wp(UNUSED(int tag), UNUSED(int state)) { } diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index 0568b99ae..26115deff 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -190,6 +190,9 @@ sdl_real_blit(SDL_Rect *r_src) if (ret) fprintf(stderr, "SDL: unable to copy texture to renderer (%s)\n", SDL_GetError()); + // give the osd an opportunity to draw itself + osd_present(); + SDL_RenderPresent(sdl_render); } @@ -215,6 +218,7 @@ sdl_blit(int x, int y, int w, int h) sdl_resize(resize_w, resize_h); resize_pending = 0; } + r_src.x = x; r_src.y = y; r_src.w = w;