diff --git a/src/86box.c b/src/86box.c index 0b5a26131..44e2d24f6 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1078,7 +1078,10 @@ usage: /* Build the global configuration file path. */ if (global == NULL) { plat_get_global_config_dir(global_cfg_path, sizeof(global_cfg_path)); - path_append_filename(global_cfg_path, global_cfg_path, GLOBAL_CONFIG_FILE); + // avoid strcpy global_cfg_path over itself (valgrind says it's bad...) + // path_append_filename(global_cfg_path, global_cfg_path, GLOBAL_CONFIG_FILE); + path_slash(global_cfg_path); + strcat(global_cfg_path, GLOBAL_CONFIG_FILE); } else { strncpy(global_cfg_path, global, sizeof(global_cfg_path) - 1); } diff --git a/src/include/86box/unix_osd.h b/src/include/86box/unix_osd.h index 4ae93a8c2..90c319fbe 100644 --- a/src/include/86box/unix_osd.h +++ b/src/include/86box/unix_osd.h @@ -3,6 +3,9 @@ #include +extern void osd_init(); +extern void osd_deinit(); + extern int osd_open(SDL_Event event); extern int osd_close(SDL_Event event); extern int osd_handle(SDL_Event event); diff --git a/src/unix/unix.c b/src/unix/unix.c index cbf41f6ed..0eefea211 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -753,7 +753,6 @@ ui_sb_set_ready(UNUSED(int ready)) /* No-op. */ } -char *xargv[512]; // From musl. char * @@ -915,7 +914,7 @@ plat_get_vmm_dir(char *outbuf, const size_t len) } bool -process_media_commands_3(uint8_t *id, char *fn, uint8_t *wp, int cmdargc) +process_media_commands_3(uint8_t *id, char *fn, uint8_t *wp, char **xargv, int cmdargc) { bool err = false; @@ -951,6 +950,7 @@ process_media_commands_3(uint8_t *id, char *fn, uint8_t *wp, int cmdargc) fn[strlen(fn) - 1] = '\0'; return err; } + char *(*f_readline)(const char *) = NULL; int (*f_add_history)(const char *) = NULL; void (*f_rl_callback_handler_remove)(void) = NULL; @@ -977,21 +977,23 @@ void unix_executeLine(char *line) { if (line) { + char *xargv[512]; int cmdargc = 0; - char *linecpy; + char *linecpy, *linespn; + + linecpy = linespn = strdup(line); + linecpy[strcspn(linecpy, "\r\n")] = 0; - line[strcspn(line, "\r\n")] = '\0'; - linecpy = strdup(line); if (!linecpy) { - free(line); - line = NULL; return; } + if (f_add_history) - f_add_history(line); + f_add_history(linecpy); + memset(xargv, 0, sizeof(xargv)); while (1) { - xargv[cmdargc++] = local_strsep(&linecpy, " "); + xargv[cmdargc++] = local_strsep(&linespn, " "); if (xargv[cmdargc - 1] == NULL || cmdargc >= 512) break; } @@ -1065,9 +1067,7 @@ unix_executeLine(char *line) char fn[PATH_MAX]; if (!xargv[2] || !xargv[1]) { - free(line); free(linecpy); - line = NULL; return; } id = atoi(xargv[1]); @@ -1121,12 +1121,10 @@ unix_executeLine(char *line) memset(fn, 0, sizeof(fn)); if (!xargv[2] || !xargv[1]) { - free(line); free(linecpy); - line = NULL; return; } - err = process_media_commands_3(&id, fn, &wp, cmdargc); + err = process_media_commands_3(&id, fn, &wp, xargv, cmdargc); if (!err) { if (fn[strlen(fn) - 1] == '\'' || fn[strlen(fn) - 1] == '"') @@ -1143,12 +1141,10 @@ unix_executeLine(char *line) memset(fn, 0, sizeof(fn)); if (!xargv[2] || !xargv[1]) { - free(line); free(linecpy); - line = NULL; return; } - err = process_media_commands_3(&id, fn, &wp, cmdargc); + err = process_media_commands_3(&id, fn, &wp, xargv, cmdargc); if (!err) { if (fn[strlen(fn) - 1] == '\'' || fn[strlen(fn) - 1] == '"') @@ -1165,12 +1161,10 @@ unix_executeLine(char *line) memset(fn, 0, sizeof(fn)); if (!xargv[2] || !xargv[1]) { - free(line); free(linecpy); - line = NULL; return; } - err = process_media_commands_3(&id, fn, &wp, cmdargc); + err = process_media_commands_3(&id, fn, &wp, xargv, cmdargc); if (!err) { if (fn[strlen(fn) - 1] == '\'' || fn[strlen(fn) - 1] == '"') @@ -1187,12 +1181,10 @@ unix_executeLine(char *line) memset(fn, 0, sizeof(fn)); if (!xargv[2] || !xargv[1]) { - free(line); free(linecpy); - line = NULL; return; } - err = process_media_commands_3(&id, fn, &wp, cmdargc); + err = process_media_commands_3(&id, fn, &wp, xargv, cmdargc); if (!err) { if (fn[strlen(fn) - 1] == '\'' || fn[strlen(fn) - 1] == '"') @@ -1201,9 +1193,7 @@ unix_executeLine(char *line) rdisk_mount(id, fn, wp); } } - free(line); free(linecpy); - line = NULL; } } @@ -1230,6 +1220,9 @@ monitor_thread(UNUSED(void *param)) } #endif unix_executeLine(line); + + free(line); + line = NULL; } } #endif @@ -1286,13 +1279,15 @@ main(int argc, char **argv) plat_pause(0); /* Initialize the rendering window, or fullscreen. */ - do_start(); + #ifndef USE_CLI thread_create(monitor_thread, NULL); #endif + SDL_AddTimer(1000, timer_onesec, NULL); - while (!is_quit) { + while (!is_quit) + { static int mouse_inside = 0; static int r_alt_pressed = 0; static int flag_osd_open = 0; @@ -1314,6 +1309,7 @@ main(int argc, char **argv) { extern void sdl_reinit_texture(void); + printf("reinit tex\n"); sdl_reinit_texture(); break; } diff --git a/src/unix/unix_osd.c b/src/unix/unix_osd.c index 910c84849..34fe5f09f 100644 --- a/src/unix/unix_osd.c +++ b/src/unix/unix_osd.c @@ -29,20 +29,23 @@ static int BOX_W = 240; static int BOX_H = 160; #define LINE_HEIGHT 16 #define TITLE_HEIGHT 16 -#define SCROLLBAR_WIDTH 6 #define CHAR_W 8 #define CHAR_H 8 // interface to SDL environment extern SDL_Window *sdl_win; extern SDL_Renderer *sdl_render; +extern SDL_mutex *sdl_mutex; // interface back to main unix monitor implementation extern void unix_executeLine(char *line); +static SDL_Texture *font_texture = NULL; + typedef enum { STATE_MENU, - STATE_FILESELECT + STATE_FILESELECT_FLOPPY, + STATE_FILESELECT_CD } AppState; static const char *menu_items[] = { @@ -67,7 +70,6 @@ static const char *menu_items[] = { static char selected_file[256] = ""; // memoria della selezione -static SDL_Texture *font_texture = NULL; static int font_cols = 16; // numero colonne nella bitmap font (16x16 caratteri) static int font_rows = 16; @@ -81,32 +83,38 @@ static int file_count = 0; static int max_visible = 0; -// ------------------- Funzione: trova i file .iso ------------------- -int load_iso_files(char files[][256], int max_files) { +int load_iso_files(char files[][256], int max_files, char *mask) +{ DIR *d; struct dirent *dir; int count = 0; d = opendir("."); - if (!d) return 0; + if (!d) + return 0; while ((dir = readdir(d)) != NULL && count < max_files) { - if (strstr(dir->d_name, ".iso")) { + if (strstr(dir->d_name, mask)) { strncpy(files[count], dir->d_name, 255); files[count][255] = '\0'; count++; } } + closedir(d); + return count; } -// ------------------- Disegna testo da bitmap font ------------------- -void draw_text(SDL_Renderer *renderer, const char *text, int x, int y, SDL_Color color) { - if (!font_texture) return; +void draw_text(SDL_Renderer *renderer, const char *text, int x, int y, SDL_Color color) +{ + if (!font_texture) + return; + SDL_SetTextureColorMod(font_texture, color.r, color.g, color.b); int i = 0; - while (text[i]) { + while (text[i]) + { unsigned char c = text[i]; int tx = (c % font_cols) * CHAR_W; int ty = (c / font_cols) * CHAR_H; @@ -117,8 +125,8 @@ void draw_text(SDL_Renderer *renderer, const char *text, int x, int y, SDL_Color } } -// ------------------- Disegna cornice rossa + riquadro ------------------- -void draw_box_with_border(SDL_Renderer *renderer, SDL_Rect box) { +void draw_box_with_border(SDL_Renderer *renderer, SDL_Rect box) +{ SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); SDL_RenderDrawRect(renderer, &box); @@ -130,10 +138,11 @@ void draw_box_with_border(SDL_Renderer *renderer, SDL_Rect box) { SDL_RenderFillRect(renderer, &inner); } -// ------------------- Disegna menu principale ------------------- -void draw_menu(SDL_Renderer *renderer, int selected) { - SDL_SetRenderDrawColor(renderer, 0, 0, 128, 255); - SDL_RenderClear(renderer); + +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; @@ -142,7 +151,8 @@ void draw_menu(SDL_Renderer *renderer, int selected) { draw_text(renderer, "MAIN MENU", x0 + 20, y0 + 5, (SDL_Color){255,255,255,255}); - for (int i = 0; i < MENU_ITEMS; i++) { + for (int i = 0; i < MENU_ITEMS; i++) + { int tx = x0 + 20; int ty = y0 + TITLE_HEIGHT + i * LINE_HEIGHT; @@ -160,31 +170,27 @@ void draw_menu(SDL_Renderer *renderer, int selected) { draw_text(renderer, menu_items[i], tx, ty, textColor); } - if (selected_file[0] != '\0') { - char buffer[300]; - snprintf(buffer, sizeof(buffer), "File: %s", selected_file); - draw_text(renderer, buffer, 20, SCREEN_H - 20, (SDL_Color){255,255,255,255}); - } - SDL_RenderPresent(renderer); } // ------------------- Disegna selezione file ------------------- void draw_file_selector(SDL_Renderer *renderer, + char *title, 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 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}; draw_box_with_border(renderer, box); - draw_text(renderer, "SELEZIONE FILE", x0 + 20, y0 + 5, (SDL_Color){255,255,255,255}); + draw_text(renderer, title, x0 + 20, y0 + 5, (SDL_Color){255,255,255,255}); if (file_count == 0) { - draw_text(renderer, "Nessun file trovato", + draw_text(renderer, "No files.", x0 + 20, y0 + TITLE_HEIGHT + 10, (SDL_Color){255, 255, 0, 255}); } else { @@ -211,6 +217,47 @@ void draw_file_selector(SDL_Renderer *renderer, SDL_RenderPresent(renderer); } +void osd_init() +{ + fprintf(stderr, "OSD INIT\n"); + + if (font_texture == NULL) + { + 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); + if (!rwop) + { + fprintf(stderr, "Cannot create a new SDL RW stream: %s\n", SDL_GetError()); + return; + } + + // auto-closes the stream + SDL_Surface *font_surface = SDL_LoadBMP_RW(rwop, 1); + if (!font_surface) { + fprintf(stderr, "Cannot create a surface using RW stream: %s\n", SDL_GetError()); + return; + } + + // Imposta trasparenza sul nero puro + SDL_SetColorKey(font_surface, SDL_TRUE, SDL_MapRGB(font_surface->format, 0, 0, 0)); + font_texture = SDL_CreateTextureFromSurface(sdl_render, font_surface); + SDL_FreeSurface(font_surface); + } +} + +void osd_deinit() +{ + // nothing to do + fprintf(stderr, "OSD DEINIT\n"); + + // will be implicitly freed on exit + // SDL_DestroyTexture(font_texture); + + font_texture = NULL; +} + int osd_open(SDL_Event event) { // ok opened @@ -222,26 +269,6 @@ int osd_open(SDL_Event event) max_visible = (BOX_H - TITLE_HEIGHT) / LINE_HEIGHT; - // Carica font bitmap (font.bmp 128x128, 16x16 caratteri, 8x8 ciascuno) - SDL_RWops *rwop = SDL_RWFromConstMem(_________font_bmp, _________font_bmp_len); - if (!rwop) - { - fprintf(stderr, "Cannot create a new SDL RW stream: %s\n", SDL_GetError()); - return 0; - } - - // auto-closes the stream - SDL_Surface *font_surface = SDL_LoadBMP_RW(rwop, 1); - if (!font_surface) { - fprintf(stderr, "Cannot create a surface using RW stream: %s\n", SDL_GetError()); - return 0; - } - - // Imposta trasparenza sul nero puro - SDL_SetColorKey(font_surface, SDL_TRUE, SDL_MapRGB(font_surface->format, 0, 0, 0)); - font_texture = SDL_CreateTextureFromSurface(sdl_render, font_surface); - SDL_FreeSurface(font_surface); - return 1; } @@ -250,21 +277,35 @@ int osd_close(SDL_Event event) // ok closed fprintf(stderr, "OSD CLOSE\n"); - SDL_DestroyTexture(font_texture); - return 1; } +static void osd_cmd_run(char *c) +{ + char *l = calloc(strlen(c)+2, 1); + strcpy(l, c); + unix_executeLine(l); + free(l); +} + int osd_handle(SDL_Event event) { fprintf(stderr, "OSD HANDLE\n"); + SDL_LockMutex(sdl_mutex); + if (state == STATE_MENU) { draw_menu(sdl_render, selected); - } else if (state == STATE_FILESELECT) { - draw_file_selector(sdl_render, files, file_count, file_selected, scroll_offset, max_visible); } + else if (state == STATE_FILESELECT_FLOPPY) { + draw_file_selector(sdl_render, "SELECT FLOPPY IMAGE", files, file_count, file_selected, scroll_offset, max_visible); + } + else if (state == STATE_FILESELECT_CD) { + draw_file_selector(sdl_render, "SELECT CD ISO IMAGE", files, file_count, file_selected, scroll_offset, max_visible); + } + + SDL_UnlockMutex(sdl_mutex); if (event.type == SDL_KEYUP) { @@ -287,75 +328,68 @@ int osd_handle(SDL_Event event) break; case SDLK_RETURN: case SDLK_KP_ENTER: - if (selected == MENU_ITEMS - 1) { - return 0; // Esci - } - else if (strcmp(menu_items[selected], "Carica partita") == 0) + switch (selected) { - file_count = load_iso_files(files, 100); - file_selected = 0; - scroll_offset = 0; - state = STATE_FILESELECT; - } - else - { - switch (selected) - { - case 0 : // "fddload - Load floppy disk image", - break; - case 1 : // "cdload - Load CD-ROM image", - break; - case 2 : // "rdiskload - Load removable disk image", - break; - case 3 : // "cartload - Load cartridge image", - break; - case 4 : // "moload - Load MO image", - break; - case 5 : // "fddeject - eject disk from floppy drive", - break; - case 6 : // "cdeject - eject disc from CD-ROM drive", - break; - case 7 : // "rdiskeject - eject removable disk", - break; - case 8 : // "carteject - eject cartridge", - break; - case 9 : // "moeject - eject image from MO drive", - break; - case 10 : // "hardreset - hard reset the emulated system", - unix_executeLine(strdup("hardreset")); - // directly close the OSD - return 0; - break; - case 11 : // "pause - pause the the emulated system", - unix_executeLine(strdup("pause")); - // directly close the OSD - return 0; - break; - case 12 : // "fullscreen - toggle fullscreen", - unix_executeLine(strdup("fullscreen")); - // directly close the OSD - return 0; - break; - case 13 : // "version - print version and license information", - unix_executeLine(strdup("version")); - // directly close the OSD - return 0; - break; - case 14 : // "exit - exit 86Box", - unix_executeLine(strdup("exit")); - // directly close the OSD - return 0; - break; - case 15 : // "close OSD" - // directly close the OSD - return 0; - } + case 0 : // "fddload - Load floppy disk image", + file_count = load_iso_files(files, 100, "*.img"); + file_selected = 0; + scroll_offset = 0; + 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; + state = STATE_FILESELECT_CD; + break; + case 2 : // "rdiskload - Load removable disk image", + break; + case 3 : // "cartload - Load cartridge image", + break; + case 4 : // "moload - Load MO image", + break; + case 5 : // "fddeject - eject disk from floppy drive", + osd_cmd_run("fddeject 0"); + break; + case 6 : // "cdeject - eject disc from CD-ROM drive", + osd_cmd_run("cdeject 0"); + break; + case 7 : // "rdiskeject - eject removable disk", + osd_cmd_run("rdiskeject 0"); + break; + case 8 : // "carteject - eject cartridge", + osd_cmd_run("carteject 0"); + break; + case 9 : // "moeject - eject image from MO drive", + osd_cmd_run("moeject 0"); + break; + case 10 : // "hardreset - hard reset the emulated system", + osd_cmd_run("hardreset"); + return 0; - printf("Hai scelto: %s\n", menu_items[selected]); + case 11 : // "pause - pause the the emulated system", + osd_cmd_run("pause"); + return 0; + + case 12 : // "fullscreen - toggle fullscreen", + osd_cmd_run("fullscreen"); + return 0; + + case 13 : // "version - print version and license information", + osd_cmd_run("version"); + return 0; + + case 14 : // "exit - exit 86Box", + osd_cmd_run("exit"); + return 0; + + case 15 : // "close OSD" + // return zero does directly close the OSD + return 0; } break; } - } else if (state == STATE_FILESELECT) { + } else if (state == STATE_FILESELECT_FLOPPY || state == STATE_FILESELECT_CD) { if (file_count == 0) { if (event.key.keysym.sym == SDLK_ESCAPE) { state = STATE_MENU; @@ -380,9 +414,14 @@ int osd_handle(SDL_Event event) break; case SDLK_RETURN: case SDLK_KP_ENTER: - strncpy(selected_file, files[file_selected], 255); - selected_file[255] = '\0'; - printf("Selezionato file: %s\n", selected_file); + char cmd[1024] = ""; + + if (state == STATE_FILESELECT_FLOPPY) + sprintf(cmd, "fddload 0 %s 0", files[file_selected]); + if (state == STATE_FILESELECT_CD) + sprintf(cmd, "cdload 0 %s", files[file_selected]); + + unix_executeLine(cmd); state = STATE_MENU; break; case SDLK_ESCAPE: diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index 651822335..0568b99ae 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -16,6 +16,7 @@ #include <86box/video.h> #include <86box/ui.h> #include <86box/version.h> +#include <86box/unix_osd.h> #include <86box/unix_sdl.h> #define RENDERER_FULL_SCREEN 1 @@ -45,7 +46,7 @@ static int cur_wy = 0; static int cur_ww = 0; static int cur_wh = 0; static volatile int sdl_enabled = 1; -static SDL_mutex *sdl_mutex = NULL; +SDL_mutex *sdl_mutex = NULL; int mouse_capture; int title_set = 0; int resize_pending = 0; @@ -314,6 +315,7 @@ sdl_select_best_hw_driver(void) void sdl_reinit_texture(void) { + osd_deinit(); sdl_destroy_texture(); if (sdl_flags & RENDERER_HARDWARE) { @@ -324,6 +326,7 @@ sdl_reinit_texture(void) sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 2048, 2048); + osd_init(); } void