diff --git a/src/gfx-sdl/sdlgfx.c b/src/gfx-sdl/sdlgfx.c index 18a2d7e..af3efad 100644 --- a/src/gfx-sdl/sdlgfx.c +++ b/src/gfx-sdl/sdlgfx.c @@ -47,6 +47,10 @@ #include "hotkeys.h" #include "sdlgfx.h" +#ifdef USE_SDL +#include "guidep/menu.h" +#endif + /* Uncomment for debugging output */ //#define DEBUG #ifdef DEBUG @@ -57,8 +61,6 @@ static SDL_Surface *display; static SDL_Surface *screen; -extern void menu_init(SDL_Surface *screen); - /* Standard P96 screen modes */ #define MAX_SCREEN_MODES 12 @@ -943,7 +945,9 @@ static int graphics_subinit (void) gui_message ("Unable to set video mode: %s\n", SDL_GetError ()); return 0; } else { - menu_init(screen); +#ifdef USE_SDL + menu_init(screen); //GEKKO +#endif /* Just in case we didn't get exactly what we asked for . . . */ fullscreen = ((screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN); is_hwsurface = ((screen->flags & SDL_HWSURFACE) == SDL_HWSURFACE); @@ -1140,6 +1144,9 @@ void graphics_leave (void) graphics_subshutdown (); SDL_QuitSubSystem(SDL_INIT_VIDEO); dumpcustom (); +#ifdef USE_SDL + menu_deinit(); //GEKKO +#endif } void graphics_notify_state (int state) @@ -1404,6 +1411,10 @@ int check_prefs_changed_gfx (void) currprefs.gfx_pfullscreen = changed_prefs.gfx_pfullscreen; #ifdef GEKKO currprefs.gfx_correct_ratio = changed_prefs.gfx_correct_ratio; + current_width = currprefs.gfx_width_win; + current_height = currprefs.gfx_height_win; + gfxvidinfo.width = current_width; + gfxvidinfo.height = current_height; #endif #ifdef PICASSO96 diff --git a/src/gui-sdl/VirtualKeyboard.c b/src/gui-sdl/VirtualKeyboard.c index 0257693..210a124 100644 --- a/src/gui-sdl/VirtualKeyboard.c +++ b/src/gui-sdl/VirtualKeyboard.c @@ -104,6 +104,12 @@ void VirtualKeyboard_init(SDL_Surface *screen) kbd_is_active=0; } +void VirtualKeyboard_fini(void) +{ + SDL_FreeSurface (image_kbd); + vkb_is_init = -1; + kbd_is_active = 0; +} void draw_vk() { @@ -199,6 +205,8 @@ struct virtkey* virtkbd_get_key() { virtkey_t *key; + if (FULL_DISPLAY_X != 640) {msgInfo("Virtual Keyboard only with 640X480 res",4000,NULL);return NULL;} + if (vkb_is_init != 1) return NULL; pause_sound(); diff --git a/src/gui-sdl/VirtualKeyboard.h b/src/gui-sdl/VirtualKeyboard.h index 0d15c01..1b2226c 100644 --- a/src/gui-sdl/VirtualKeyboard.h +++ b/src/gui-sdl/VirtualKeyboard.h @@ -30,7 +30,8 @@ typedef struct Virtual_Keyboard } VirtualKeyboard_struct; -extern void VirtualKeyboard_init(SDL_Surface *surf); +void VirtualKeyboard_init(SDL_Surface *surf); +void VirtualKeyboard_fini(void); extern struct virtkey *virtkbd_get_key(void); -extern void flip_VKB(); +void flip_VKB(); extern int kbd_is_active; \ No newline at end of file diff --git a/src/gui-sdl/gui-sdl.c b/src/gui-sdl/gui-sdl.c index 19e9487..a20d132 100644 --- a/src/gui-sdl/gui-sdl.c +++ b/src/gui-sdl/gui-sdl.c @@ -179,14 +179,16 @@ static const char *other_messages[] = { /*03*/ "^| 0 | 1 | 2 | 3 | 4 ", /*04*/ "Correct aspect ratio", /*05*/ "^|off|100%|95%|93%|90%|custom", - /*06*/ "Scanlines", - /*07*/ "^|on|off", - /*08*/ "Leds", + /*06*/ "Resolution", + /*07*/ "^|320X240|640X480", + /*08*/ "Scanlines", /*09*/ "^|on|off", - /*10*/ "Port", - /*11*/ "^|DEFAULT|SD|USB|SMB", - /*12*/ "Rumble", - /*13*/ "^|on|off", + /*10*/ "Leds", + /*11*/ "^|on|off", + /*12*/ "Port", + /*13*/ "^|DEFAULT|SD|USB|SMB", + /*14*/ "Rumble", + /*15*/ "^|on|off", NULL }; @@ -802,7 +804,7 @@ void make_hardfile(void) if (file_exists(hdf_path)) { - if (msgYesNo("Overwrite the existing file?", 0, FULL_DISPLAY_X /2-180, FULL_DISPLAY_Y /2-48)) + if (msgYesNo("Overwrite the existing file?", 0, FULL_DISPLAY_X /2-180/RATIO, FULL_DISPLAY_Y /2-48/RATIO)) unlink (hdf_path); else return; } @@ -821,7 +823,7 @@ void delete_hardfile(void) char dir[255]; strncpy(dir,prefs_get_attr("hardfile_path"),255); name = (char *) menu_select_file(dir, NULL, 0); - if (name && msgYesNo("Are you sure to delete the hardfile?", 0, FULL_DISPLAY_X /2-200, FULL_DISPLAY_Y /2-48)) + if (name && msgYesNo("Are you sure to delete the hardfile?", 0, FULL_DISPLAY_X /2-200/RATIO, FULL_DISPLAY_Y /2-48/RATIO)) {unlink (name); msgInfo("Hardfile deleted",3000,NULL);} } @@ -1216,10 +1218,28 @@ static void audio_options(void) fix_options_menu_sdl(1); } +static void set_gfx_resolution (int res) +{ + if (res) //640X480 + { + changed_prefs.gfx_width_win = 640; + changed_prefs.gfx_height_win = 480; + changed_prefs.gfx_lores = 0; + changed_prefs.gfx_linedbl = 1; + } + else //320X240 + { + changed_prefs.gfx_width_win = 320; + changed_prefs.gfx_height_win = 240; + changed_prefs.gfx_lores = 1; + changed_prefs.gfx_linedbl = 0; + } +} + static void other_options(void) { - int submenus[7]; - int opt, floppy_n; + int submenus[8]; + int opt, floppy_n, old_sub_3; memset(submenus, 0, sizeof(submenus)); @@ -1228,10 +1248,11 @@ static void other_options(void) submenus[0] = get_floppy_speed(); submenus[1] = floppy_n; submenus[2] = get_gfx_aspect_ratio(); - submenus[3] = !(changed_prefs.gfx_linedbl == 2) ; - submenus[4] = !changed_prefs.leds_on_screen; - submenus[5] = changed_prefs.Port; - submenus[6] = !changed_prefs.rumble; + submenus[3] = old_sub_3 = (changed_prefs.gfx_width_win == 640) ; + submenus[4] = !(changed_prefs.gfx_linedbl == 2) ; + submenus[5] = !changed_prefs.leds_on_screen; + submenus[6] = changed_prefs.Port; + submenus[7] = !changed_prefs.rumble; opt = menu_select_title("Other options menu", other_messages, submenus); @@ -1241,10 +1262,11 @@ static void other_options(void) set_floppy_speed(submenus[0]); set_floppy_number(submenus[1]); set_gfx_aspect_ratio(submenus[2]); - changed_prefs.gfx_linedbl = submenus[3] ? 1 : 2; - changed_prefs.leds_on_screen = !submenus[4]; - set_Port(submenus[5]); - changed_prefs.rumble = !submenus[6]; + if (old_sub_3 != submenus[3]) set_gfx_resolution(submenus[3]); + if (changed_prefs.gfx_width_win == 640) changed_prefs.gfx_linedbl = submenus[4] ? 1 : 2; + changed_prefs.leds_on_screen = !submenus[5]; + set_Port(submenus[6]); + changed_prefs.rumble = !submenus[7]; currprefs.leds_on_screen = changed_prefs.leds_on_screen; currprefs.rumble = changed_prefs.rumble; @@ -1737,7 +1759,7 @@ void gui_display(int shortcut) uae_reset(1); break; case 15: - if (msgYesNo("Are you sure to quit?", 0, FULL_DISPLAY_X /2-138, FULL_DISPLAY_Y /2-48)) + if (msgYesNo("Are you sure to quit?", 0, FULL_DISPLAY_X /2-138/RATIO, FULL_DISPLAY_Y /2-48/RATIO)) {currprefs.rumble=0; uae_quit();} break; default: diff --git a/src/gui-sdl/menu.c b/src/gui-sdl/menu.c index 30cacc0..43b2f1d 100644 --- a/src/gui-sdl/menu.c +++ b/src/gui-sdl/menu.c @@ -1,1167 +1,1213 @@ -/********************************************************************* -* -* Copyright (C) 2004,2008, Simon Kagstrom -* Copyright (C) 2010,2014, Fabio Olimpieri -* -* Filename: menu.c -* Author: Simon Kagstrom , Fabio Olimpieri -* Description: Code for menus (originally for Mophun) -* -* $Id$ -* -********************************************************************/ -#include -#include -#include -#include -#include -#include -#include - -#include "menu.h" -#include "VirtualKeyboard.h" - -#include "sysconfig.h" -#include "sysdeps.h" -#include "options.h" -#include "filesys.h" - - - -struct joyinfo { - SDL_Joystick *joy; - unsigned int axles; - unsigned int buttons; -}; - -extern unsigned int nr_joysticks; -extern struct joyinfo joys[]; - -typedef struct -{ - int n_entries; - int index; - int sel; -} submenu_t; - -typedef struct -{ - char title[256]; - const char **pp_msgs; - TTF_Font *p_font; - int x1,y1; - int x2,y2; - int text_w; - int text_h; - - int n_submenus; - submenu_t *p_submenus; - - int cur_sel; /* Main selection */ - int start_entry_visible; - int n_entries; -} menu_t; - -enum hdlist_cols { - HDLIST_DEVICE, - HDLIST_VOLUME, - HDLIST_PATH, - HDLIST_READONLY, - HDLIST_HEADS, - HDLIST_CYLS, - HDLIST_SECS, - HDLIST_RSRVD, - HDLIST_SIZE, - HDLIST_BLKSIZE, - HDLIST_BOOTPRI, - HDLIST_MAX_COLS -}; - - -static SDL_Surface *real_screen; - -#define IS_SUBMENU(p_msg) ( (p_msg)[0] == '^' ) -#define IS_TEXT(p_msg) ( (p_msg)[0] == '#' || (p_msg)[0] == ' ' ) -#define IS_MARKER(p_msg) ( (p_msg)[0] == '@' ) - -static int is_inited = 0; -static TTF_Font *menu_font16, *menu_font20; -static TTF_Font *menu_font_alt16; -#if defined(GEKKO) -#define FONT_PATH "/apps/uae/FreeMono.ttf" -#define FONT_ALT_PATH "/apps/uae/Smaller.ttf" -#else -#define FONT_PATH "FreeMono.ttf" -#define FONT_ALT_PATH "Smaller.ttf" -#endif - -int fh, fw; - -void flip_screen (void) -{ - SDL_Flip(real_screen); -} - -int msgInfo(char *text, int duration, SDL_Rect *irc) -{ - int len = strlen(text); - int X, Y; - SDL_Rect src; - SDL_Rect rc; - SDL_Rect brc; - - X = (FULL_DISPLAY_X /2) - (len / 2 + 1)*12; - Y = (FULL_DISPLAY_Y /2) - 24; - - brc.x = FULL_DISPLAY_X/2-2*12; - brc.y=Y+42; - brc.w=48; - brc.h=20; - - rc.x = X; - rc.y=Y; - rc.w=12*(len + 2); - rc.h=duration > 0 ? 48 : 80; - - src.x=rc.x+4; - src.y=rc.y+4; - src.w=rc.w; - src.h=rc.h; - - - if (irc) - { - irc->x=rc.x; - irc->y=rc.y; - irc->w=src.w; - irc->h=src.h; - } - SDL_FillRect(real_screen, &src, SDL_MapRGB(real_screen->format, 0, 96, 0)); - SDL_FillRect(real_screen, &rc, SDL_MapRGB(real_screen->format, 128, 128, 128)); - menu_print_font(real_screen, 255,255,255, X+12, Y+12, text,20); - SDL_UpdateRect(real_screen, src.x, src.y, src.w, src.h); - SDL_UpdateRect(real_screen, rc.x, rc.y, rc.w,rc.h); - if (duration > 0) - SDL_Delay(duration); - else if (duration < 0) - { - SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x00, 0x80, 0x00)); - menu_print_font(real_screen, 0,0,0, FULL_DISPLAY_X/2-12, Y+42, "OK",20); - SDL_UpdateRect(real_screen, brc.x, brc.y, brc.w, brc.h); - while (!(KEY_SELECT & menu_wait_key_press())) {} - - } - - return 1; -} - -/* -void msgKill(SDL_Rect *rc) -{ - SDL_UpdateRect(real_screen, rc->x, rc->y, rc->w,rc->h); -} -*/ - -int msgYesNo(char *text, int default_opt, int x, int y) -{ - int len = strlen(text); - int X, Y; - SDL_Rect src; - SDL_Rect rc; - SDL_Rect brc; - uint32_t key; - //int old; - - //old = default_opt; - - if (x < 0) - X = (FULL_DISPLAY_X /2) - (len / 2 + 1)*12; - else - X = x; - - if (y < 0) - Y = (FULL_DISPLAY_Y /2) - 48; - else - Y = y; - - rc.x=X; - rc.y=Y; - rc.w=12*(len + 2); - rc.h=80; - - src.x=rc.x+4; - src.y=rc.y+4; - src.w=rc.w; - src.h=rc.h; - - while (1) - { - SDL_FillRect(real_screen, &src, SDL_MapRGB(real_screen->format, 0, 96, 0)); - SDL_FillRect(real_screen, &rc, SDL_MapRGB(real_screen->format, 128, 128, 128)); - menu_print_font(real_screen, 255,255,255, X+12, Y+12, text,20); - - if (default_opt) - { - brc.x=rc.x + rc.w/2-5*12; - brc.y=rc.y+42; - brc.w=12*3; - brc.h=20; - SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x00, 0x80, 0x00)); - } - else - { - brc.x=rc.x + rc.w/2+5*12-2*12-6; - brc.y=rc.y+42; - brc.w=12*3; - brc.h=20; - SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x80, 0x00, 0x00)); - } - - menu_print_font(real_screen, 255,255,255, rc.x + rc.w/2-5*12, Y+42, "YES",20); - menu_print_font(real_screen, 255,255,255, rc.x + rc.w/2-5*12+8*12, Y+42, "NO",20); - - SDL_UpdateRect(real_screen, src.x, src.y, src.w, src.h); - SDL_UpdateRect(real_screen, rc.x, rc.y, rc.w,rc.h); - SDL_UpdateRect(real_screen, brc.x, brc.y, brc.w,brc.h); - - //SDL_Flip(real_screen); - key = menu_wait_key_press(); - if (key & KEY_SELECT) - { - return default_opt; - } - else if (key & KEY_ESCAPE) - { - return 0; - } - else if (key & KEY_LEFT) - { - default_opt = !default_opt; - } - else if (key & KEY_RIGHT) - { - default_opt = !default_opt; - } - } -} - - - -static int cmpstringp(const void *p1, const void *p2) -{ - const char *p1_s = *(const char**)p1; - const char *p2_s = *(const char**)p2; - - /* Put directories first */ - if (*p1_s == '[' && *p2_s != '[') - return -1; - if (*p1_s != '[' && *p2_s == '[') - return 1; - return strcasecmp(* (char * const *) p1, * (char * const *) p2); -} - -/* Return true if name ends with ext (for filenames) */ -int ext_matches(const char *name, const char *ext) -{ - int len = strlen(name); - int ext_len = strlen(ext); - - if (len <= ext_len) - return 0; - return (strcmp(name + len - ext_len, ext) == 0); -} - -static int ext_matches_list(const char *name, const char **exts) -{ - const char **p; - - for (p = exts; *p; p++) - { - if (ext_matches(name, *p)) - return 1; - } - - return 0; -} - -static const char **get_file_list(const char *base_dir) -{ - DIR *d = opendir(base_dir); - const char **file_list; - int cur = 0; - struct dirent *de; - int cnt = 16; - - if (!d) - return NULL; - - file_list = (const char**)malloc(cnt * sizeof(char*)); - file_list[cur++] = strdup("None"); - file_list[cur] = NULL; - - for (de = readdir(d); - de; - de = readdir(d)) - { - char buf[255]; - //ipf files are not enabled in UAE Wii - const char *exts[] = {".adf", ".ADF", ".adz", ".ADZ", ".zip",".ZIP",".dms", ".DMS", - ".sav", ".SAV", ".uss", ".USS", ".rom", ".ROM", ".hdf", ".HDF", NULL}; - struct stat st; - - snprintf(buf, 255, "%s/%s", base_dir, de->d_name); - if (stat(buf, &st) < 0) - continue; - if (S_ISDIR(st.st_mode)&&strcmp(".", de->d_name)) - { - char *p; - size_t len = strlen(de->d_name) + 4; - - p = (char*)malloc( len ); - snprintf(p, len, "[%s]", de->d_name); - file_list[cur++] = p; - file_list[cur] = NULL; - } - else if (ext_matches_list(de->d_name, exts)) - { - char *p; - - p = strdup(de->d_name); - file_list[cur++] = p; - file_list[cur] = NULL; - } - - if (cur > cnt - 2) - { - cnt = cnt + 32; - file_list = (const char**)realloc(file_list, cnt * sizeof(char*)); - if (!file_list) - return NULL; - } - } - closedir(d); - qsort(&file_list[1], cur-1, sizeof(const char *), cmpstringp); - - return file_list; -} - -const char **get_file_list_devices() -{ - char **device_list_menu; - - device_list_menu = (char**)malloc((MAX_DEVICE_ITEM+1) * sizeof(char*)); - device_list_menu[0] = NULL; - - #ifdef FILESYS - - int i, nr; - char texts[HDLIST_MAX_COLS][64]; - - nr = nr_units(currprefs.mountinfo); - - if (!nr) return NULL; - - for (i=0; in_submenus; i++) - { - if (p_menu->p_submenus[i].index == index) - return &p_menu->p_submenus[i]; - } - - return NULL; -} - -void menu_print_font(SDL_Surface *screen, int r, int g, int b, - int x, int y, const char *msg, int font_size) -{ -#define _MAX_STRING 64 - SDL_Surface *font_surf; - SDL_Rect dst = {x, y, 0, 0}; - SDL_Color color = {r, g, b}; - char buf[255]; - unsigned int i; - - memset(buf, 0, sizeof(buf)); - strncpy(buf, msg, 254); - if (buf[0] != '|' && buf[0] != '^' && buf[0] != '.' - && buf[0] != '-' && buf[0] != ' ' && !strstr(buf, " \"")) - { - if (strlen(buf)>_MAX_STRING) - { - //buf[_MAX_STRING-3] = '.'; - //buf[_MAX_STRING-2] = '.'; - //buf[_MAX_STRING-1] = '.'; - buf[_MAX_STRING] = '\0'; - } - } - /* Fixup multi-menu option look */ - for (i = 0; i < strlen(buf) ; i++) - { - if (buf[i] == '^' || buf[i] == '|') - buf[i] = ' '; - } - - if (font_size == 16) font_surf = TTF_RenderUTF8_Blended(menu_font16, buf, color); - else font_surf = TTF_RenderUTF8_Blended(menu_font20, buf, color); - if (!font_surf) - { - fprintf(stderr, "%s\n", TTF_GetError()); - exit(1); - } - - SDL_BlitSurface(font_surf, NULL, screen, &dst); - SDL_FreeSurface(font_surf); -} - -void menu_print_font_alt(SDL_Surface *screen, int r, int g, int b, int x, int y, const char *msg) -{ -#undef _MAX_STRING -#define _MAX_STRING 64 - SDL_Surface *font_surf; - SDL_Rect dst = {x, y, 0, 0}; - SDL_Color color = {r, g, b}; - char buf[255]; - unsigned int i; - - memset(buf, 0, sizeof(buf)); - strncpy(buf, msg, 254); - if (buf[0] != '|' && buf[0] != '^' && buf[0] != '.' - && buf[0] != '#' && buf[0] != ' ' ) - { - if (strlen(buf)>_MAX_STRING) - { - buf[_MAX_STRING-3] = '.'; - buf[_MAX_STRING-2] = '.'; - buf[_MAX_STRING-1] = '.'; - buf[_MAX_STRING] = '\0'; - } - } - - /* Fixup multi-menu option look */ - for (i = 0; i < strlen(buf) ; i++) - { - if (buf[i] == '^' || buf[i] == '|') - buf[i] = ' '; - } - - font_surf = TTF_RenderText_Blended(menu_font_alt16, buf, color); - if (!font_surf) - { - fprintf(stderr, "%s\n", TTF_GetError()); - exit(1); - } - - SDL_BlitSurface(font_surf, NULL, screen, &dst); - SDL_FreeSurface(font_surf); -} - - -static void menu_draw(SDL_Surface *screen, menu_t *p_menu, int sel, int font_size) -{ - int font_height = TTF_FontHeight(p_menu->p_font); - int line_height = (font_height + font_height / 4); - int x_start = p_menu->x1; - int y_start = p_menu->y1 + line_height; - SDL_Rect r; - int entries_visible = (p_menu->y2 - p_menu->y1) / line_height - 1; - - int i, y; - - if ( p_menu->n_entries * line_height > p_menu->y2 ) - y_start = p_menu->y1 + line_height; - - if (p_menu->cur_sel - p_menu->start_entry_visible > entries_visible) - { - while (p_menu->cur_sel - p_menu->start_entry_visible > entries_visible) - { - p_menu->start_entry_visible ++; - if (p_menu->start_entry_visible > p_menu->n_entries) - { - p_menu->start_entry_visible = 0; - break; - } - } - } - else if ( p_menu->cur_sel < p_menu->start_entry_visible ) - p_menu->start_entry_visible = p_menu->cur_sel; - - if (strlen(p_menu->title)) - { - r.x = p_menu->x1; - r.y = p_menu->y1; - r.w = p_menu->x2 - p_menu->x1; - r.h = line_height-1; - if (sel < 0) - SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0x40, 0x00, 0x00)); - else - SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0x00, 0xe7, 0xe7)); - menu_print_font(screen, 0,0,0, p_menu->x1, p_menu->y1, p_menu->title, font_size); - } - - for (i = p_menu->start_entry_visible; i <= p_menu->start_entry_visible + entries_visible; i++) - { - const char *msg = p_menu->pp_msgs[i]; - - if (i >= p_menu->n_entries) - break; - if (IS_MARKER(msg)) - p_menu->cur_sel = atoi(&msg[1]); - else - { - y = (i - p_menu->start_entry_visible) * line_height; - - if (sel < 0) - menu_print_font(screen, 0x40,0x40,0x40, - x_start, y_start + y, msg, font_size); - else if (p_menu->cur_sel == i) /* Selected - color */ - menu_print_font(screen, 0,200,0, - x_start, y_start + y, msg, font_size); - else if (IS_SUBMENU(msg)) - { - if (p_menu->cur_sel == i-1) - menu_print_font(screen, 0,200,0, - x_start, y_start + y, msg, font_size); - else - menu_print_font(screen, 0x40,0x40,0x40, - x_start, y_start + y, msg, font_size); - } - else if (msg[0] == '#') - { - switch (msg[1]) - { - case '1': - menu_print_font(screen, 0,0,255, - x_start, y_start + y, msg+2, font_size); - break; - case '2': - menu_print_font(screen, 0x40,0x40,0x40, - x_start, y_start + y, msg+2, font_size); - break; - default: - menu_print_font(screen, 0x40,0x40,0x40, - x_start, y_start + y, msg, font_size); - break; - } - } - else /* Otherwise white */ - menu_print_font(screen, 0x40,0x40,0x40, - x_start, y_start + y, msg, font_size); - if (IS_SUBMENU(msg)) - { - submenu_t *p_submenu = find_submenu(p_menu, i); - int n_pipe = 0; - int n; - - for (n=0; msg[n] != '\0'; n++) - { - /* Underline the selected entry */ - if (msg[n] == '|') - { - int16_t n_chars; - - for (n_chars = 1; msg[n+n_chars] && msg[n+n_chars] != '|'; n_chars++); - - n_pipe++; - if (p_submenu->sel == n_pipe-1) - { - int w; - int h; - - if (TTF_SizeText(p_menu->p_font, "X", &w, &h) < 0) - { - fw = w; - fh = h; - fprintf(stderr, "%s\n", TTF_GetError()); - exit(1); - } - - r = (SDL_Rect){ x_start + (n+1) * w-1, y_start + (i+ 1 - p_menu->start_entry_visible) * ((h + h/4)) -3, (n_chars - 1) * w, 2}; - if (p_menu->cur_sel == i-1) - SDL_FillRect(screen, &r, - SDL_MapRGB(screen->format, 255,0,0)); - else - SDL_FillRect(screen, &r, - SDL_MapRGB(screen->format, 0x40,0x40,0x40)); - break; - } - } - } - } - } - } -} - -static int get_next_seq_y(menu_t *p_menu, int v, int dy, int cicle) -{ - if (v + dy < 0) - {if (cicle) return (p_menu->n_entries - 1); else return 0;} - - if (v + dy > p_menu->n_entries - 1) - {if (cicle) return 0; else return (p_menu->n_entries - 1);} - return v + dy; -} - -static void select_next(menu_t *p_menu, int dx, int dy, int cicle) -{ - int next; - - p_menu->cur_sel = get_next_seq_y(p_menu, p_menu->cur_sel, dy, cicle); - next = get_next_seq_y(p_menu, p_menu->cur_sel, dy + 1, cicle); - if (IS_SUBMENU(p_menu->pp_msgs[p_menu->cur_sel])&&(dy!=1)&&(dy!=-1)) p_menu->cur_sel--; - if (p_menu->pp_msgs[p_menu->cur_sel][0] == ' ' || - p_menu->pp_msgs[p_menu->cur_sel][0] == '#' || - IS_SUBMENU(p_menu->pp_msgs[p_menu->cur_sel]) ) - select_next(p_menu, dx, dy, cicle); - - /* If the next is a submenu */ - if (dx != 0 && IS_SUBMENU(p_menu->pp_msgs[next])) - { - submenu_t *p_submenu = find_submenu(p_menu, next); - - p_submenu->sel = (p_submenu->sel + dx) < 0 ? p_submenu->n_entries - 1 : - (p_submenu->sel + dx) % p_submenu->n_entries; - } - else if (dx == -1 && !strcmp(p_menu->pp_msgs[0], "[..]")) - p_menu->cur_sel = 0; -} - -static void select_one(menu_t *p_menu, int sel) -{ - if (sel >= p_menu->n_entries) - sel = 0; - p_menu->cur_sel = sel; - if (p_menu->pp_msgs[p_menu->cur_sel][0] == ' ' || - p_menu->pp_msgs[p_menu->cur_sel][0] == '#' || - IS_SUBMENU(p_menu->pp_msgs[p_menu->cur_sel])) - select_next(p_menu, 0, 1 , 1); -} - -/* -static int is_submenu_title(menu_t *p_menu, int n) -{ - if (n+1 >= p_menu->n_entries) - return 0; - else - return IS_SUBMENU(p_menu->pp_msgs[n+1]); -} -*/ - -static void menu_init_internal(menu_t *p_menu, const char *title, - TTF_Font *p_font, const char **pp_msgs, - int16_t x1, int16_t y1, int16_t x2, int16_t y2) -{ - int submenu; - int j; - - memset(p_menu, 0, sizeof(menu_t)); - - p_menu->pp_msgs = pp_msgs; - p_menu->p_font = p_font; - p_menu->x1 = x1; - p_menu->y1 = y1; - p_menu->x2 = x2; - p_menu->y2 = y2; - - p_menu->text_w = 0; - p_menu->n_submenus = 0; - strcpy(p_menu->title, title); - - for (p_menu->n_entries = 0; p_menu->pp_msgs[p_menu->n_entries]; p_menu->n_entries++) - { - int text_w_font; - - /* Is this a submenu? */ - if (IS_SUBMENU(p_menu->pp_msgs[p_menu->n_entries])) - { - p_menu->n_submenus++; - continue; /* Length of submenus is unimportant */ - } - - if (TTF_SizeText(p_font, p_menu->pp_msgs[p_menu->n_entries], &text_w_font, NULL) != 0) - { - fprintf(stderr, "%s\n", TTF_GetError()); - exit(1); - } - if (text_w_font > p_menu->text_w) - p_menu->text_w = text_w_font; - } - if (p_menu->text_w > p_menu->x2 - p_menu->x1) - p_menu->text_w = p_menu->x2 - p_menu->x1; - - if ( !(p_menu->p_submenus = (submenu_t *)malloc(sizeof(submenu_t) * p_menu->n_submenus)) ) - { - perror("malloc failed!\n"); - exit(1); - } - - j=0; - submenu = 0; - for (; j < p_menu->n_entries; j++) - { - if (IS_SUBMENU(p_menu->pp_msgs[j])) - { - int n; - - p_menu->p_submenus[submenu].index = j; - p_menu->p_submenus[submenu].sel = 0; - p_menu->p_submenus[submenu].n_entries = 0; - for (n=0; p_menu->pp_msgs[j][n] != '\0'; n++) - { - if (p_menu->pp_msgs[j][n] == '|') - p_menu->p_submenus[submenu].n_entries++; - } - submenu++; - } - } - p_menu->text_h = p_menu->n_entries * (TTF_FontHeight(p_font) + TTF_FontHeight(p_font) / 4); -} - -static void menu_fini(menu_t *p_menu) -{ - free(p_menu->p_submenus); -} - -uint32_t menu_wait_key_press(void) -{ - SDL_Event ev; - uint32_t keys = 0; - - while (1) - { - int i, hats, nr; - SDL_Joystick *joy; - static int joy_keys_changed; - static int joy_keys_last; - - /* Wii-specific, sorry */ - for (nr = 0; nr < nr_joysticks; nr++) { - joy = joys[nr].joy; - if (!joy) - continue; - - hats = SDL_JoystickNumHats (joy); - for (i = 0; i < hats; i++) { - Uint8 v = SDL_JoystickGetHat (joy, i); - - if (v & SDL_HAT_UP) - keys |= KEY_UP; - if (v & SDL_HAT_DOWN) - keys |= KEY_DOWN; - if (v & SDL_HAT_LEFT) - keys |= KEY_LEFT; - if (v & SDL_HAT_RIGHT) - keys |= KEY_RIGHT; - } - - Sint16 axis0 = SDL_JoystickGetAxis(joy, 0); - Sint16 axis1 = SDL_JoystickGetAxis(joy, 1); - - if ( axis0 < -15000 ) keys |= KEY_LEFT; - else if (axis0 > 15000 ) keys |= KEY_RIGHT; - - if (axis1 < -15000 ) keys |= KEY_UP; - else if( axis1 > 15000 ) keys |= KEY_DOWN; - - - if (SDL_JoystickGetButton(joy, 0) != 0 || /* A */ - SDL_JoystickGetButton(joy, 3) != 0 || /* 2 */ - SDL_JoystickGetButton(joy, 9) != 0 || /* CA */ - SDL_JoystickGetButton(joy, 10) != 0) /* CB */ - keys |= KEY_SELECT; - if (SDL_JoystickGetButton(joy, 2) != 0 || /* 1 */ - SDL_JoystickGetButton(joy, 11) != 0 || /* CX */ - SDL_JoystickGetButton(joy, 12) != 0) /* CY */ - keys |= KEY_ESCAPE; - if (SDL_JoystickGetButton(joy, 5) != 0 || /* + */ - SDL_JoystickGetButton(joy, 18) != 0) /* C+ */ - keys |= KEY_PAGEUP; - if (SDL_JoystickGetButton(joy, 4) != 0 || /* - */ - SDL_JoystickGetButton(joy, 17) != 0) /* C- */ - keys |= KEY_PAGEDOWN; - } - joy_keys_changed = keys != joy_keys_last; - joy_keys_last = keys; - if (!joy_keys_changed) - keys = 0; - - if (SDL_PollEvent(&ev)) - { - switch(ev.type) - { - case SDL_KEYDOWN: - switch (ev.key.keysym.sym) - { - case SDLK_UP: - keys |= KEY_UP; - break; - case SDLK_DOWN: - keys |= KEY_DOWN; - break; - case SDLK_LEFT: - keys |= KEY_LEFT; - break; - case SDLK_RIGHT: - keys |= KEY_RIGHT; - break; - case SDLK_PAGEDOWN: - keys |= KEY_PAGEDOWN; - break; - case SDLK_PAGEUP: - keys |= KEY_PAGEUP; - break; - case SDLK_RETURN: - case SDLK_SPACE: - keys |= KEY_SELECT; - break; - case SDLK_HOME: - case SDLK_ESCAPE: - keys |= KEY_ESCAPE; - break; - default: - break; - } - break; - case SDL_QUIT: - exit(0); - break; - default: - break; - - } - break; - } - - if (keys != 0) - break; - SDL_Delay(20); - } - return keys; -} - - -extern void PicDisplay(char *name, int off_x, int off_y, int wait); -extern const char **get_t64_list(char *t64); -extern const char **get_prg_list(char *t64); - -extern char curdir[256]; - -static int menu_select_internal(SDL_Surface *screen, - menu_t *p_menu, int *p_submenus, int sel, - void (*select_next_cb)(menu_t *p, void *data), - void *select_next_cb_data, int font_size) -{ - int ret = -1; - int i; - - for (i = 0; i < p_menu->n_submenus; i++) - p_menu->p_submenus[i].sel = p_submenus[i]; - - while(1) - { - SDL_Rect r = {p_menu->x1, p_menu->y1, - p_menu->x2 - p_menu->x1, p_menu->y2 - p_menu->y1}; - uint32_t keys; - int sel_last = p_menu->cur_sel; - - SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff)); - - menu_draw(screen, p_menu, 0, font_size); - SDL_Flip(screen); - - keys = menu_wait_key_press(); - - if (keys & KEY_UP) - select_next(p_menu, 0, -1, 1); - else if (keys & KEY_DOWN) - select_next(p_menu, 0, 1, 1); - else if (keys & KEY_PAGEUP) - select_next(p_menu, 0, -19, 0); - else if (keys & KEY_PAGEDOWN) - select_next(p_menu, 0, 19, 0); - else if (keys & KEY_LEFT) - select_next(p_menu, -1, 0 ,1); - else if (keys & KEY_RIGHT) - select_next(p_menu, 1, 0 ,1); - else if (keys & KEY_ESCAPE) - break; - else if (keys & KEY_SELECT) - { - ret = p_menu->cur_sel; - int i; - - for (i=0; in_submenus; i++) - p_submenus[i] = p_menu->p_submenus[i].sel; - break; - } - /* Invoke the callback when an entry is selected */ - if (sel_last != p_menu->cur_sel && - select_next_cb != NULL) - select_next_cb(p_menu, select_next_cb_data); - } - - SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0)); - return ret; -} - -int menu_select_sized(const char *title, const char **msgs, int *submenus, int sel, - int x, int y, int x2, int y2, - void (*select_next_cb)(menu_t *p, void *data), - void *select_next_cb_data, int font_size) - -{ - menu_t menu; - int out; - /* - int info; - - if (!strcmp(title, "Folder") || !strcmp(title, "Single File") || - !strcmp(title, "C-64 Disc") || !strcmp(title, "C-64 Tape") || sel < 0) - info = 0; - else - info = 1; - */ - if (font_size == 16) menu_init_internal(&menu, title, menu_font16, msgs, x, y, x2, y2); - else menu_init_internal(&menu, title, menu_font20, msgs, x, y, x2, y2); - - if (sel >= 0) - select_one(&menu, sel); - out = menu_select_internal(real_screen, &menu, submenus, sel, - select_next_cb, select_next_cb_data, font_size); - - menu_fini(&menu); - - return out; -} - -int menu_select_title(const char *title, const char **msgs, int *submenus) -{ - SDL_FillRect(real_screen, 0, SDL_MapRGB(real_screen->format, 0, 0, 0)); - return menu_select_sized(title, msgs, submenus, 0, - 32, 20, FULL_DISPLAY_X-32, FULL_DISPLAY_Y-20, - NULL, NULL, 20); -} - -int menu_select(const char **msgs, int *submenus) -{ - return menu_select_title("", msgs, submenus); -} - -static const char *menu_select_file_internal(const char *dir_path, - int x, int y, int x2, int y2, const char *selected_file, int which) -{ - const char **file_list; - char *sel; - char *out; - const char *ptr_selected_file; - char *updir; - int opt; - int i; - char buf[64]; - - if (!strcmp(dir_path,"devices")) file_list = get_file_list_devices(); - else file_list = get_file_list(dir_path); - - if (file_list == NULL) - return NULL; - - if (selected_file) - { - ptr_selected_file= strrchr(selected_file,'/'); - if (ptr_selected_file) ptr_selected_file++; - else ptr_selected_file = selected_file; - snprintf(buf,64,"df%d:%s",which, ptr_selected_file); - opt = menu_select_sized(buf, file_list, NULL, 0, x, y, x2, y2, NULL, NULL, 16); - } - else opt = menu_select_sized("Select file", file_list, NULL, 0, x, y, x2, y2, NULL, NULL ,16); - - if (opt < 0) - return NULL; - sel = strdup(file_list[opt]); - - /* Cleanup everything - file_list is NULL-terminated */ - for ( i = 0; file_list[i]; i++ ) - free((void*)file_list[i]); - free(file_list); - - if (!sel) - return NULL; - - if (!strcmp(sel,"[..]")) //selected "[..]" - { - free((void*)sel); - updir=strrchr(dir_path,'/'); - if (updir!=NULL) // found "/" - { - *updir=0; //trunk dir_path at last / - if (strrchr(dir_path,'/')==NULL) {*updir='/'; *(updir+1)=0;} //check if it was root - } - - return menu_select_file(dir_path, selected_file, which); - } - - - /* If this is a folder, enter it recursively */ - if (sel[0] == '[') - { - char buf[255]; - int len = strlen(sel); - int s; - - /* Remove trailing ] */ - sel[len-1] = '\0'; - s = snprintf(buf, 128, "%s/%s", dir_path, sel + 1); - - /* We don't need this anymore */ - free((void*)sel); - /* Too deep recursion! */ - if (s >= sizeof(buf)) - return NULL; - return menu_select_file(buf, selected_file, which); - } - - out = (char*)malloc(strlen(dir_path) + strlen(sel) + 4); - snprintf(out, strlen(dir_path) + strlen(sel) + 4, - "%s/%s", dir_path, sel); - - free(sel); - return out; -} - -const char *menu_select_file(const char *dir_path,const char *selected_file, int which) -{ - if (dir_path == NULL) - dir_path = ""; - return menu_select_file_internal(dir_path, - 0, 20, FULL_DISPLAY_X, FULL_DISPLAY_Y - 20, selected_file, which); -} - -int menu_select_devices() -{ - const char *selected_device; - selected_device= menu_select_file_internal("devices", - 0, 20, FULL_DISPLAY_X, FULL_DISPLAY_Y - 20, NULL, 0); - if (!selected_device) return -1; else return (atoi(selected_device)); -} - -static TTF_Font *read_font(const char *path, int font_size) -{ - TTF_Font *out; - SDL_RWops *rw; - Uint8 *data = (Uint8*)malloc(1 * 1024*1024); - FILE *fp = fopen(path, "r"); - - if (!data) { - fprintf(stderr, "Malloc failed\n"); - exit(1); - } - if (!fp) { - fprintf(stderr, "Could not open font\n"); - exit(1); - } - fread(data, 1, 1 * 1024 * 1024, fp); - rw = SDL_RWFromMem(data, 1 * 1024 * 1024); - if (!rw) - { - fprintf(stderr, "Could not create RW: %s\n", SDL_GetError()); - exit(1); - } - out = TTF_OpenFontRW(rw, 1, font_size); - if (!out) - { - fprintf(stderr, "Unable to open font %s\n", path); - exit(1); - } - fclose(fp); - - return out; -} - -void menu_init(SDL_Surface *screen) -{ - TTF_Init(); - - menu_font16 = read_font(FONT_PATH, 16); - menu_font20 = read_font(FONT_PATH, 20); - - menu_font_alt16 = read_font(FONT_ALT_PATH,16); - - real_screen = screen; - VirtualKeyboard_init(screen); - is_inited = 1; -} - -int menu_is_inited(void) -{ - return is_inited; -} +/********************************************************************* +* +* Copyright (C) 2004,2008, Simon Kagstrom +* Copyright (C) 2010,2014, Fabio Olimpieri +* +* Filename: menu.c +* Author: Simon Kagstrom , Fabio Olimpieri +* Description: Code for menus (originally for Mophun) +* +* $Id$ +* +********************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#include "menu.h" +#include "VirtualKeyboard.h" + +#include "sysconfig.h" +#include "sysdeps.h" +#include "options.h" +#include "filesys.h" + + + +struct joyinfo { + SDL_Joystick *joy; + unsigned int axles; + unsigned int buttons; +}; + +extern unsigned int nr_joysticks; +extern struct joyinfo joys[]; + +typedef struct +{ + int n_entries; + int index; + int sel; +} submenu_t; + +typedef struct +{ + char title[256]; + const char **pp_msgs; + TTF_Font *p_font; + int x1,y1; + int x2,y2; + int text_w; + int text_h; + + int n_submenus; + submenu_t *p_submenus; + + int cur_sel; /* Main selection */ + int start_entry_visible; + int n_entries; +} menu_t; + +enum hdlist_cols { + HDLIST_DEVICE, + HDLIST_VOLUME, + HDLIST_PATH, + HDLIST_READONLY, + HDLIST_HEADS, + HDLIST_CYLS, + HDLIST_SECS, + HDLIST_RSRVD, + HDLIST_SIZE, + HDLIST_BLKSIZE, + HDLIST_BOOTPRI, + HDLIST_MAX_COLS +}; + +int FULL_DISPLAY_X; //640 +int FULL_DISPLAY_Y; //480 +int RATIO; + +static SDL_Surface *real_screen; + +#define IS_SUBMENU(p_msg) ( (p_msg)[0] == '^' ) +#define IS_TEXT(p_msg) ( (p_msg)[0] == '#' || (p_msg)[0] == ' ' ) +#define IS_MARKER(p_msg) ( (p_msg)[0] == '@' ) + +static int is_inited = 0; +static TTF_Font *menu_font16, *menu_font20,*menu_font8, *menu_font10 ; +static TTF_Font *menu_font_alt16; +#if defined(GEKKO) +#define FONT_PATH "/apps/uae/FreeMono.ttf" +#define FONT_ALT_PATH "/apps/uae/Smaller.ttf" +#else +#define FONT_PATH "FreeMono.ttf" +#define FONT_ALT_PATH "Smaller.ttf" +#endif + +int fh, fw; + +void flip_screen (void) +{ + SDL_Flip(real_screen); +} + +int msgInfo(char *text, int duration, SDL_Rect *irc) +{ + int len = strlen(text); + int X, Y; + SDL_Rect src; + SDL_Rect rc; + SDL_Rect brc; + + X = (FULL_DISPLAY_X /2) - (len / 2 + 1)*12/RATIO; + Y = (FULL_DISPLAY_Y /2) - 24/RATIO; + + brc.x = FULL_DISPLAY_X/2-2*12/RATIO; + brc.y=Y+42/RATIO; + brc.w=48/RATIO; + brc.h=20/RATIO; + + rc.x = X; + rc.y=Y; + rc.w=12*(len + 2)/RATIO; + rc.h=duration > 0 ? 48/RATIO : 80/RATIO; + + src.x=rc.x+4/RATIO; + src.y=rc.y+4/RATIO; + src.w=rc.w; + src.h=rc.h; + + + if (irc) + { + irc->x=rc.x; + irc->y=rc.y; + irc->w=src.w; + irc->h=src.h; + } + SDL_FillRect(real_screen, &src, SDL_MapRGB(real_screen->format, 0, 96, 0)); + SDL_FillRect(real_screen, &rc, SDL_MapRGB(real_screen->format, 128, 128, 128)); + menu_print_font(real_screen, 255,255,255, X+12/RATIO, Y+12/RATIO, text,20); + SDL_UpdateRect(real_screen, src.x, src.y, src.w, src.h); + SDL_UpdateRect(real_screen, rc.x, rc.y, rc.w,rc.h); + if (duration > 0) + SDL_Delay(duration); + else if (duration < 0) + { + SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x00, 0x80, 0x00)); + menu_print_font(real_screen, 0,0,0, FULL_DISPLAY_X/2-12/RATIO, Y+42/RATIO, "OK",20); + SDL_UpdateRect(real_screen, brc.x, brc.y, brc.w, brc.h); + while (!(KEY_SELECT & menu_wait_key_press())) {} + + } + + return 1; +} + +/* +void msgKill(SDL_Rect *rc) +{ + SDL_UpdateRect(real_screen, rc->x, rc->y, rc->w,rc->h); +} +*/ + +int msgYesNo(char *text, int default_opt, int x, int y) +{ + int len = strlen(text); + int X, Y; + SDL_Rect src; + SDL_Rect rc; + SDL_Rect brc; + uint32_t key; + //int old; + + //old = default_opt; + + if (x < 0) + X = (FULL_DISPLAY_X /2) - (len / 2 + 1)*12/RATIO; + else + X = x; + + if (y < 0) + Y = (FULL_DISPLAY_Y /2) - 48/RATIO; + else + Y = y; + + rc.x=X; + rc.y=Y; + rc.w=12*(len + 2)/RATIO; + rc.h=80/RATIO; + + src.x=rc.x+4/RATIO; + src.y=rc.y+4/RATIO; + src.w=rc.w; + src.h=rc.h; + + while (1) + { + SDL_FillRect(real_screen, &src, SDL_MapRGB(real_screen->format, 0, 96, 0)); + SDL_FillRect(real_screen, &rc, SDL_MapRGB(real_screen->format, 128, 128, 128)); + menu_print_font(real_screen, 255,255,255, X+12/RATIO, Y+12/RATIO, text,20); + + if (default_opt) + { + brc.x=rc.x + rc.w/2-5*12/RATIO; + brc.y=rc.y+42/RATIO; + brc.w=12*3/RATIO; + brc.h=20/RATIO; + SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x00, 0x80, 0x00)); + } + else + { + brc.x=rc.x + rc.w/2+5*12/RATIO-2*12/RATIO-6/RATIO; + brc.y=rc.y+42/RATIO; + brc.w=12*3/RATIO; + brc.h=20/RATIO; + SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x80, 0x00, 0x00)); + } + + menu_print_font(real_screen, 255,255,255, rc.x + rc.w/2-5*12/RATIO, Y+42/RATIO, "YES",20); + menu_print_font(real_screen, 255,255,255, rc.x + rc.w/2-5*12/RATIO+8*12/RATIO, Y+42/RATIO, "NO",20); + + SDL_UpdateRect(real_screen, src.x, src.y, src.w, src.h); + SDL_UpdateRect(real_screen, rc.x, rc.y, rc.w,rc.h); + SDL_UpdateRect(real_screen, brc.x, brc.y, brc.w,brc.h); + + //SDL_Flip(real_screen); + key = menu_wait_key_press(); + if (key & KEY_SELECT) + { + return default_opt; + } + else if (key & KEY_ESCAPE) + { + return 0; + } + else if (key & KEY_LEFT) + { + default_opt = !default_opt; + } + else if (key & KEY_RIGHT) + { + default_opt = !default_opt; + } + } +} + + + +static int cmpstringp(const void *p1, const void *p2) +{ + const char *p1_s = *(const char**)p1; + const char *p2_s = *(const char**)p2; + + /* Put directories first */ + if (*p1_s == '[' && *p2_s != '[') + return -1; + if (*p1_s != '[' && *p2_s == '[') + return 1; + return strcasecmp(* (char * const *) p1, * (char * const *) p2); +} + +/* Return true if name ends with ext (for filenames) */ +int ext_matches(const char *name, const char *ext) +{ + int len = strlen(name); + int ext_len = strlen(ext); + + if (len <= ext_len) + return 0; + return (strcmp(name + len - ext_len, ext) == 0); +} + +static int ext_matches_list(const char *name, const char **exts) +{ + const char **p; + + for (p = exts; *p; p++) + { + if (ext_matches(name, *p)) + return 1; + } + + return 0; +} + +static const char **get_file_list(const char *base_dir) +{ + DIR *d = opendir(base_dir); + const char **file_list; + int cur = 0; + struct dirent *de; + int cnt = 16; + + if (!d) + return NULL; + + file_list = (const char**)malloc(cnt * sizeof(char*)); + file_list[cur++] = strdup("None"); + file_list[cur] = NULL; + + for (de = readdir(d); + de; + de = readdir(d)) + { + char buf[255]; + //ipf files are not enabled in UAE Wii + const char *exts[] = {".adf", ".ADF", ".adz", ".ADZ", ".zip",".ZIP",".dms", ".DMS", + ".sav", ".SAV", ".uss", ".USS", ".rom", ".ROM", ".hdf", ".HDF", NULL}; + struct stat st; + + snprintf(buf, 255, "%s/%s", base_dir, de->d_name); + if (stat(buf, &st) < 0) + continue; + if (S_ISDIR(st.st_mode)&&strcmp(".", de->d_name)) + { + char *p; + size_t len = strlen(de->d_name) + 4; + + p = (char*)malloc( len ); + snprintf(p, len, "[%s]", de->d_name); + file_list[cur++] = p; + file_list[cur] = NULL; + } + else if (ext_matches_list(de->d_name, exts)) + { + char *p; + + p = strdup(de->d_name); + file_list[cur++] = p; + file_list[cur] = NULL; + } + + if (cur > cnt - 2) + { + cnt = cnt + 32; + file_list = (const char**)realloc(file_list, cnt * sizeof(char*)); + if (!file_list) + return NULL; + } + } + closedir(d); + qsort(&file_list[1], cur-1, sizeof(const char *), cmpstringp); + + return file_list; +} + +const char **get_file_list_devices() +{ + char **device_list_menu; + + device_list_menu = (char**)malloc((MAX_DEVICE_ITEM+1) * sizeof(char*)); + device_list_menu[0] = NULL; + + #ifdef FILESYS + + int i, nr; + char texts[HDLIST_MAX_COLS][64]; + + nr = nr_units(currprefs.mountinfo); + + if (!nr) return NULL; + + for (i=0; in_submenus; i++) + { + if (p_menu->p_submenus[i].index == index) + return &p_menu->p_submenus[i]; + } + + return NULL; +} + +void menu_print_font(SDL_Surface *screen, int r, int g, int b, + int x, int y, const char *msg, int font_size) +{ +#define _MAX_STRING 64 + SDL_Surface *font_surf; + SDL_Rect dst = {x, y, 0, 0}; + SDL_Color color = {r, g, b}; + char buf[255]; + unsigned int i; + + memset(buf, 0, sizeof(buf)); + strncpy(buf, msg, 254); + if (buf[0] != '|' && buf[0] != '^' && buf[0] != '.' + && buf[0] != '-' && buf[0] != ' ' && !strstr(buf, " \"")) + { + if (strlen(buf)>_MAX_STRING) + { + //buf[_MAX_STRING-3] = '.'; + //buf[_MAX_STRING-2] = '.'; + //buf[_MAX_STRING-1] = '.'; + buf[_MAX_STRING] = '\0'; + } + } + /* Fixup multi-menu option look */ + for (i = 0; i < strlen(buf) ; i++) + { + if (buf[i] == '^' || buf[i] == '|') + buf[i] = ' '; + } + + if (FULL_DISPLAY_X == 640) + { + if (font_size == 16) font_surf = TTF_RenderUTF8_Blended(menu_font16, buf, color); + else font_surf = TTF_RenderUTF8_Blended(menu_font20, buf, color); + } + else + { + if (font_size == 16) font_surf = TTF_RenderUTF8_Blended(menu_font8, buf, color); + else font_surf = TTF_RenderUTF8_Blended(menu_font10, buf, color); + } + + + if (!font_surf) + { + fprintf(stderr, "%s\n", TTF_GetError()); + exit(1); + } + + SDL_BlitSurface(font_surf, NULL, screen, &dst); + SDL_FreeSurface(font_surf); +} + +void menu_print_font_alt(SDL_Surface *screen, int r, int g, int b, int x, int y, const char *msg) +{ +#undef _MAX_STRING +#define _MAX_STRING 64 + SDL_Surface *font_surf; + SDL_Rect dst = {x, y, 0, 0}; + SDL_Color color = {r, g, b}; + char buf[255]; + unsigned int i; + + memset(buf, 0, sizeof(buf)); + strncpy(buf, msg, 254); + if (buf[0] != '|' && buf[0] != '^' && buf[0] != '.' + && buf[0] != '#' && buf[0] != ' ' ) + { + if (strlen(buf)>_MAX_STRING) + { + buf[_MAX_STRING-3] = '.'; + buf[_MAX_STRING-2] = '.'; + buf[_MAX_STRING-1] = '.'; + buf[_MAX_STRING] = '\0'; + } + } + + /* Fixup multi-menu option look */ + for (i = 0; i < strlen(buf) ; i++) + { + if (buf[i] == '^' || buf[i] == '|') + buf[i] = ' '; + } + + font_surf = TTF_RenderText_Blended(menu_font_alt16, buf, color); + if (!font_surf) + { + fprintf(stderr, "%s\n", TTF_GetError()); + exit(1); + } + + SDL_BlitSurface(font_surf, NULL, screen, &dst); + SDL_FreeSurface(font_surf); +} + + +static void menu_draw(SDL_Surface *screen, menu_t *p_menu, int sel, int font_size) +{ + int font_height = TTF_FontHeight(p_menu->p_font); + int line_height = (font_height + font_height / 4); + int x_start = p_menu->x1; + int y_start = p_menu->y1 + line_height; + SDL_Rect r; + int entries_visible = (p_menu->y2 - p_menu->y1 -5) / line_height - 1; + + int i, y; + + if ( p_menu->n_entries * line_height > p_menu->y2 ) + y_start = p_menu->y1 + line_height; + + if (p_menu->cur_sel - p_menu->start_entry_visible > entries_visible) + { + while (p_menu->cur_sel - p_menu->start_entry_visible > entries_visible) + { + p_menu->start_entry_visible ++; + if (p_menu->start_entry_visible > p_menu->n_entries) + { + p_menu->start_entry_visible = 0; + break; + } + } + } + else if ( p_menu->cur_sel < p_menu->start_entry_visible ) + p_menu->start_entry_visible = p_menu->cur_sel; + + if (strlen(p_menu->title)) + { + r.x = p_menu->x1; + r.y = p_menu->y1; + r.w = p_menu->x2 - p_menu->x1; + r.h = line_height-1; + if (sel < 0) + SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0x40, 0x00, 0x00)); + else + SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0x00, 0xe7, 0xe7)); + menu_print_font(screen, 0,0,0, p_menu->x1, p_menu->y1, p_menu->title, font_size); + } + + for (i = p_menu->start_entry_visible; i <= p_menu->start_entry_visible + entries_visible; i++) + { + const char *msg = p_menu->pp_msgs[i]; + + if (i >= p_menu->n_entries) + break; + if (IS_MARKER(msg)) + p_menu->cur_sel = atoi(&msg[1]); + else + { + y = (i - p_menu->start_entry_visible) * line_height; + + if (sel < 0) + menu_print_font(screen, 0x40,0x40,0x40, + x_start, y_start + y, msg, font_size); + else if (p_menu->cur_sel == i) /* Selected - color */ + menu_print_font(screen, 0,200,0, + x_start, y_start + y, msg, font_size); + else if (IS_SUBMENU(msg)) + { + if (p_menu->cur_sel == i-1) + menu_print_font(screen, 0,200,0, + x_start, y_start + y, msg, font_size); + else + menu_print_font(screen, 0x40,0x40,0x40, + x_start, y_start + y, msg, font_size); + } + else if (msg[0] == '#') + { + switch (msg[1]) + { + case '1': + menu_print_font(screen, 0,0,255, + x_start, y_start + y, msg+2, font_size); + break; + case '2': + menu_print_font(screen, 0x40,0x40,0x40, + x_start, y_start + y, msg+2, font_size); + break; + default: + menu_print_font(screen, 0x40,0x40,0x40, + x_start, y_start + y, msg, font_size); + break; + } + } + else /* Otherwise white */ + menu_print_font(screen, 0x40,0x40,0x40, + x_start, y_start + y, msg, font_size); + if (IS_SUBMENU(msg)) + { + submenu_t *p_submenu = find_submenu(p_menu, i); + int n_pipe = 0; + int n; + + for (n=0; msg[n] != '\0'; n++) + { + /* Underline the selected entry */ + if (msg[n] == '|') + { + int16_t n_chars; + + for (n_chars = 1; msg[n+n_chars] && msg[n+n_chars] != '|'; n_chars++); + + n_pipe++; + if (p_submenu->sel == n_pipe-1) + { + int w; + int h; + + if (TTF_SizeText(p_menu->p_font, "X", &w, &h) < 0) + { + fw = w; + fh = h; + fprintf(stderr, "%s\n", TTF_GetError()); + exit(1); + } + + r = (SDL_Rect){ x_start + (n+1) * w-1, y_start + (i+ 1 - p_menu->start_entry_visible) * ((h + h/4)) -3, (n_chars - 1) * w, 2}; + if (p_menu->cur_sel == i-1) + SDL_FillRect(screen, &r, + SDL_MapRGB(screen->format, 255,0,0)); + else + SDL_FillRect(screen, &r, + SDL_MapRGB(screen->format, 0x40,0x40,0x40)); + break; + } + } + } + } + } + } +} + +static int get_next_seq_y(menu_t *p_menu, int v, int dy, int cicle) +{ + if (v + dy < 0) + {if (cicle) return (p_menu->n_entries - 1); else return 0;} + + if (v + dy > p_menu->n_entries - 1) + {if (cicle) return 0; else return (p_menu->n_entries - 1);} + return v + dy; +} + +static void select_next(menu_t *p_menu, int dx, int dy, int cicle) +{ + int next; + + p_menu->cur_sel = get_next_seq_y(p_menu, p_menu->cur_sel, dy, cicle); + next = get_next_seq_y(p_menu, p_menu->cur_sel, dy + 1, cicle); + if (IS_SUBMENU(p_menu->pp_msgs[p_menu->cur_sel])&&(dy!=1)&&(dy!=-1)) p_menu->cur_sel--; + if (p_menu->pp_msgs[p_menu->cur_sel][0] == ' ' || + p_menu->pp_msgs[p_menu->cur_sel][0] == '#' || + IS_SUBMENU(p_menu->pp_msgs[p_menu->cur_sel]) ) + select_next(p_menu, dx, dy, cicle); + + /* If the next is a submenu */ + if (dx != 0 && IS_SUBMENU(p_menu->pp_msgs[next])) + { + submenu_t *p_submenu = find_submenu(p_menu, next); + + p_submenu->sel = (p_submenu->sel + dx) < 0 ? p_submenu->n_entries - 1 : + (p_submenu->sel + dx) % p_submenu->n_entries; + } + else if (dx == -1 && !strcmp(p_menu->pp_msgs[0], "[..]")) + p_menu->cur_sel = 0; +} + +static void select_one(menu_t *p_menu, int sel) +{ + if (sel >= p_menu->n_entries) + sel = 0; + p_menu->cur_sel = sel; + if (p_menu->pp_msgs[p_menu->cur_sel][0] == ' ' || + p_menu->pp_msgs[p_menu->cur_sel][0] == '#' || + IS_SUBMENU(p_menu->pp_msgs[p_menu->cur_sel])) + select_next(p_menu, 0, 1 , 1); +} + +/* +static int is_submenu_title(menu_t *p_menu, int n) +{ + if (n+1 >= p_menu->n_entries) + return 0; + else + return IS_SUBMENU(p_menu->pp_msgs[n+1]); +} +*/ + +static void menu_init_internal(menu_t *p_menu, const char *title, + TTF_Font *p_font, const char **pp_msgs, + int16_t x1, int16_t y1, int16_t x2, int16_t y2) +{ + int submenu; + int j; + + memset(p_menu, 0, sizeof(menu_t)); + + p_menu->pp_msgs = pp_msgs; + p_menu->p_font = p_font; + p_menu->x1 = x1; + p_menu->y1 = y1; + p_menu->x2 = x2; + p_menu->y2 = y2; + + p_menu->text_w = 0; + p_menu->n_submenus = 0; + strcpy(p_menu->title, title); + + for (p_menu->n_entries = 0; p_menu->pp_msgs[p_menu->n_entries]; p_menu->n_entries++) + { + int text_w_font; + + /* Is this a submenu? */ + if (IS_SUBMENU(p_menu->pp_msgs[p_menu->n_entries])) + { + p_menu->n_submenus++; + continue; /* Length of submenus is unimportant */ + } + + if (TTF_SizeText(p_font, p_menu->pp_msgs[p_menu->n_entries], &text_w_font, NULL) != 0) + { + fprintf(stderr, "%s\n", TTF_GetError()); + exit(1); + } + if (text_w_font > p_menu->text_w) + p_menu->text_w = text_w_font; + } + if (p_menu->text_w > p_menu->x2 - p_menu->x1) + p_menu->text_w = p_menu->x2 - p_menu->x1; + + if ( !(p_menu->p_submenus = (submenu_t *)malloc(sizeof(submenu_t) * p_menu->n_submenus)) ) + { + perror("malloc failed!\n"); + exit(1); + } + + j=0; + submenu = 0; + for (; j < p_menu->n_entries; j++) + { + if (IS_SUBMENU(p_menu->pp_msgs[j])) + { + int n; + + p_menu->p_submenus[submenu].index = j; + p_menu->p_submenus[submenu].sel = 0; + p_menu->p_submenus[submenu].n_entries = 0; + for (n=0; p_menu->pp_msgs[j][n] != '\0'; n++) + { + if (p_menu->pp_msgs[j][n] == '|') + p_menu->p_submenus[submenu].n_entries++; + } + submenu++; + } + } + p_menu->text_h = p_menu->n_entries * (TTF_FontHeight(p_font) + TTF_FontHeight(p_font) / 4); +} + +static void menu_fini(menu_t *p_menu) +{ + free(p_menu->p_submenus); +} + +uint32_t menu_wait_key_press(void) +{ + SDL_Event ev; + uint32_t keys = 0; + + while (1) + { + int i, hats, nr; + SDL_Joystick *joy; + static int joy_keys_changed; + static int joy_keys_last; + + /* Wii-specific, sorry */ + for (nr = 0; nr < nr_joysticks; nr++) { + joy = joys[nr].joy; + if (!joy) + continue; + + hats = SDL_JoystickNumHats (joy); + for (i = 0; i < hats; i++) { + Uint8 v = SDL_JoystickGetHat (joy, i); + + if (v & SDL_HAT_UP) + keys |= KEY_UP; + if (v & SDL_HAT_DOWN) + keys |= KEY_DOWN; + if (v & SDL_HAT_LEFT) + keys |= KEY_LEFT; + if (v & SDL_HAT_RIGHT) + keys |= KEY_RIGHT; + } + + Sint16 axis0 = SDL_JoystickGetAxis(joy, 0); + Sint16 axis1 = SDL_JoystickGetAxis(joy, 1); + + if ( axis0 < -15000 ) keys |= KEY_LEFT; + else if (axis0 > 15000 ) keys |= KEY_RIGHT; + + if (axis1 < -15000 ) keys |= KEY_UP; + else if( axis1 > 15000 ) keys |= KEY_DOWN; + + + if (SDL_JoystickGetButton(joy, 0) != 0 || /* A */ + SDL_JoystickGetButton(joy, 3) != 0 || /* 2 */ + SDL_JoystickGetButton(joy, 9) != 0 || /* CA */ + SDL_JoystickGetButton(joy, 10) != 0) /* CB */ + keys |= KEY_SELECT; + if (SDL_JoystickGetButton(joy, 2) != 0 || /* 1 */ + SDL_JoystickGetButton(joy, 11) != 0 || /* CX */ + SDL_JoystickGetButton(joy, 12) != 0) /* CY */ + keys |= KEY_ESCAPE; + if (SDL_JoystickGetButton(joy, 5) != 0 || /* + */ + SDL_JoystickGetButton(joy, 18) != 0) /* C+ */ + keys |= KEY_PAGEUP; + if (SDL_JoystickGetButton(joy, 4) != 0 || /* - */ + SDL_JoystickGetButton(joy, 17) != 0) /* C- */ + keys |= KEY_PAGEDOWN; + } + joy_keys_changed = keys != joy_keys_last; + joy_keys_last = keys; + if (!joy_keys_changed) + keys = 0; + + if (SDL_PollEvent(&ev)) + { + switch(ev.type) + { + case SDL_KEYDOWN: + switch (ev.key.keysym.sym) + { + case SDLK_UP: + keys |= KEY_UP; + break; + case SDLK_DOWN: + keys |= KEY_DOWN; + break; + case SDLK_LEFT: + keys |= KEY_LEFT; + break; + case SDLK_RIGHT: + keys |= KEY_RIGHT; + break; + case SDLK_PAGEDOWN: + keys |= KEY_PAGEDOWN; + break; + case SDLK_PAGEUP: + keys |= KEY_PAGEUP; + break; + case SDLK_RETURN: + case SDLK_SPACE: + keys |= KEY_SELECT; + break; + case SDLK_HOME: + case SDLK_ESCAPE: + keys |= KEY_ESCAPE; + break; + default: + break; + } + break; + case SDL_QUIT: + exit(0); + break; + default: + break; + + } + break; + } + + if (keys != 0) + break; + SDL_Delay(20); + } + return keys; +} + + +extern void PicDisplay(char *name, int off_x, int off_y, int wait); +extern const char **get_t64_list(char *t64); +extern const char **get_prg_list(char *t64); + +extern char curdir[256]; + +static int menu_select_internal(SDL_Surface *screen, + menu_t *p_menu, int *p_submenus, int sel, + void (*select_next_cb)(menu_t *p, void *data), + void *select_next_cb_data, int font_size) +{ + int ret = -1; + int i; + + for (i = 0; i < p_menu->n_submenus; i++) + p_menu->p_submenus[i].sel = p_submenus[i]; + + while(1) + { + SDL_Rect r = {p_menu->x1, p_menu->y1, + p_menu->x2 - p_menu->x1, p_menu->y2 - p_menu->y1}; + uint32_t keys; + int sel_last = p_menu->cur_sel; + + SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff)); + + menu_draw(screen, p_menu, 0, font_size); + SDL_Flip(screen); + + keys = menu_wait_key_press(); + + if (keys & KEY_UP) + select_next(p_menu, 0, -1, 1); + else if (keys & KEY_DOWN) + select_next(p_menu, 0, 1, 1); + else if (keys & KEY_PAGEUP) + select_next(p_menu, 0, -19, 0); + else if (keys & KEY_PAGEDOWN) + select_next(p_menu, 0, 19, 0); + else if (keys & KEY_LEFT) + select_next(p_menu, -1, 0 ,1); + else if (keys & KEY_RIGHT) + select_next(p_menu, 1, 0 ,1); + else if (keys & KEY_ESCAPE) + break; + else if (keys & KEY_SELECT) + { + ret = p_menu->cur_sel; + int i; + + for (i=0; in_submenus; i++) + p_submenus[i] = p_menu->p_submenus[i].sel; + break; + } + /* Invoke the callback when an entry is selected */ + if (sel_last != p_menu->cur_sel && + select_next_cb != NULL) + select_next_cb(p_menu, select_next_cb_data); + } + + SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0)); + return ret; +} + +int menu_select_sized(const char *title, const char **msgs, int *submenus, int sel, + int x, int y, int x2, int y2, + void (*select_next_cb)(menu_t *p, void *data), + void *select_next_cb_data, int font_size) + +{ + menu_t menu; + int out; + /* + int info; + + if (!strcmp(title, "Folder") || !strcmp(title, "Single File") || + !strcmp(title, "C-64 Disc") || !strcmp(title, "C-64 Tape") || sel < 0) + info = 0; + else + info = 1; + */ + if (FULL_DISPLAY_X == 640) + { + if (font_size == 16) menu_init_internal(&menu, title, menu_font16, msgs, x, y, x2, y2); + else menu_init_internal(&menu, title, menu_font20, msgs, x, y, x2, y2); + } + else + { + if (font_size == 16) menu_init_internal(&menu, title, menu_font8, msgs, x, y, x2, y2); + else menu_init_internal(&menu, title, menu_font10, msgs, x, y, x2, y2); + } + + + if (sel >= 0) + select_one(&menu, sel); + out = menu_select_internal(real_screen, &menu, submenus, sel, + select_next_cb, select_next_cb_data, font_size); + + menu_fini(&menu); + + return out; +} + +int menu_select_title(const char *title, const char **msgs, int *submenus) +{ + SDL_FillRect(real_screen, 0, SDL_MapRGB(real_screen->format, 0, 0, 0)); + return menu_select_sized(title, msgs, submenus, 0, + 32/RATIO, 16/RATIO, FULL_DISPLAY_X-32/RATIO, FULL_DISPLAY_Y-16/RATIO, + NULL, NULL, 20); +} + +int menu_select(const char **msgs, int *submenus) +{ + return menu_select_title("", msgs, submenus); +} + +static const char *menu_select_file_internal(const char *dir_path, + int x, int y, int x2, int y2, const char *selected_file, int which) +{ + const char **file_list; + char *sel; + char *out; + const char *ptr_selected_file; + char *updir; + int opt; + int i; + char buf[64]; + + if (!strcmp(dir_path,"devices")) file_list = get_file_list_devices(); + else file_list = get_file_list(dir_path); + + if (file_list == NULL) + return NULL; + + if (selected_file) + { + ptr_selected_file= strrchr(selected_file,'/'); + if (ptr_selected_file) ptr_selected_file++; + else ptr_selected_file = selected_file; + snprintf(buf,64,"df%d:%s",which, ptr_selected_file); + opt = menu_select_sized(buf, file_list, NULL, 0, x, y, x2, y2, NULL, NULL, 16); + } + else opt = menu_select_sized("Select file", file_list, NULL, 0, x, y, x2, y2, NULL, NULL ,16); + + if (opt < 0) + return NULL; + sel = strdup(file_list[opt]); + + /* Cleanup everything - file_list is NULL-terminated */ + for ( i = 0; file_list[i]; i++ ) + free((void*)file_list[i]); + free(file_list); + + if (!sel) + return NULL; + + if (!strcmp(sel,"[..]")) //selected "[..]" + { + free((void*)sel); + updir=strrchr(dir_path,'/'); + if (updir!=NULL) // found "/" + { + *updir=0; //trunk dir_path at last / + if (strrchr(dir_path,'/')==NULL) {*updir='/'; *(updir+1)=0;} //check if it was root + } + + return menu_select_file(dir_path, selected_file, which); + } + + + /* If this is a folder, enter it recursively */ + if (sel[0] == '[') + { + char buf[255]; + int len = strlen(sel); + int s; + + /* Remove trailing ] */ + sel[len-1] = '\0'; + s = snprintf(buf, 128, "%s/%s", dir_path, sel + 1); + + /* We don't need this anymore */ + free((void*)sel); + /* Too deep recursion! */ + if (s >= sizeof(buf)) + return NULL; + return menu_select_file(buf, selected_file, which); + } + + out = (char*)malloc(strlen(dir_path) + strlen(sel) + 4); + snprintf(out, strlen(dir_path) + strlen(sel) + 4, + "%s/%s", dir_path, sel); + + free(sel); + return out; +} + +const char *menu_select_file(const char *dir_path,const char *selected_file, int which) +{ + if (dir_path == NULL) + dir_path = ""; + return menu_select_file_internal(dir_path, + 0, 20/RATIO, FULL_DISPLAY_X, FULL_DISPLAY_Y - 20/RATIO, selected_file, which); +} + +int menu_select_devices() +{ + const char *selected_device; + selected_device= menu_select_file_internal("devices", + 0, 20/RATIO, FULL_DISPLAY_X, FULL_DISPLAY_Y - 20/RATIO, NULL, 0); + if (!selected_device) return -1; else return (atoi(selected_device)); +} + +static TTF_Font *read_font(const char *path, int font_size) +{ + TTF_Font *out; + SDL_RWops *rw; + Uint8 *data = (Uint8*)malloc(1 * 1024*1024); + FILE *fp = fopen(path, "r"); + + if (!data) { + fprintf(stderr, "Malloc failed\n"); + exit(1); + } + if (!fp) { + fprintf(stderr, "Could not open font\n"); + exit(1); + } + fread(data, 1, 1 * 1024 * 1024, fp); + rw = SDL_RWFromMem(data, 1 * 1024 * 1024); + if (!rw) + { + fprintf(stderr, "Could not create RW: %s\n", SDL_GetError()); + exit(1); + } + out = TTF_OpenFontRW(rw, 1, font_size); + if (!out) + { + fprintf(stderr, "Unable to open font %s\n", path); + exit(1); + } + fclose(fp); + + return out; +} + +void menu_init(SDL_Surface *screen) +{ + + FULL_DISPLAY_X = currprefs.gfx_width_win; + FULL_DISPLAY_Y = currprefs.gfx_height_win; + RATIO = 640/FULL_DISPLAY_X; + + if (is_inited) return; + + TTF_Init(); + + menu_font16 = read_font(FONT_PATH, 16); + menu_font20 = read_font(FONT_PATH, 20); + menu_font8 = read_font(FONT_PATH, 8); + menu_font10 = read_font(FONT_PATH, 10); + + menu_font_alt16 = read_font(FONT_ALT_PATH,16); + + real_screen = screen; + VirtualKeyboard_init(screen); + is_inited = 1; +} + +void menu_deinit(void) +{ + is_inited = 0; + VirtualKeyboard_fini(); + + TTF_CloseFont(menu_font16); + TTF_CloseFont(menu_font20); + TTF_CloseFont(menu_font8); + TTF_CloseFont(menu_font10); + TTF_CloseFont(menu_font_alt16); + + TTF_Quit(); +} + + +int menu_is_inited(void) +{ + return is_inited; +} diff --git a/src/gui-sdl/menu.h b/src/gui-sdl/menu.h index 4fa7895..e8bda69 100644 --- a/src/gui-sdl/menu.h +++ b/src/gui-sdl/menu.h @@ -30,10 +30,12 @@ extern "C" { #define KEY_PAGEDOWN 64 #define KEY_PAGEUP 128 #define KEY_HELP 256 -#define FULL_DISPLAY_X 640 -#define FULL_DISPLAY_Y 480 #define MAX_DEVICE_ITEM 32 +extern int FULL_DISPLAY_X; //640 +extern int FULL_DISPLAY_Y; //480 +extern int RATIO; + void menu_print_font(SDL_Surface *screen, int r, int g, int b, int x, int y, const char *msg, int font_size); void menu_print_font_alt(SDL_Surface *screen, int r, int g, int b, int x, int y, const char *msg); @@ -46,13 +48,15 @@ const char *menu_select_file_start(const char *dir_path, const char **d64_name); uint32_t menu_wait_key_press(void); -extern void msgKill(SDL_Rect *rc); -extern int msgInfo(char *text, int duration, SDL_Rect *rc); +void msgKill(SDL_Rect *rc); +int msgInfo(char *text, int duration, SDL_Rect *rc); -extern int msgYesNo(char *text, int def,int x, int y); +int msgYesNo(char *text, int def,int x, int y); void menu_init(SDL_Surface *screen); +void menu_deinit(void); + int menu_is_inited(void); int ext_matches(const char *name, const char *ext);