X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=libpicofe.git;a=blobdiff_plain;f=menu.c;h=2447bcecc9cf2f502790dbd16991a1494d3de89c;hp=63a9943388886f1f8fe45ee626dd3b1a574e03e0;hb=d1453cf7e6d5d6758cc5d72c6d3af7d37156bf72;hpb=675d1d368c75ef01523108f3180090a9ed12edf4 diff --git a/menu.c b/menu.c index 63a9943..2447bce 100644 --- a/menu.c +++ b/menu.c @@ -5,6 +5,7 @@ * (at your option): * - GNU GPL, version 2 or later. * - GNU LGPL, version 2.1 or later. + * - MAME license. * See the COPYING file in the top-level directory. */ @@ -29,15 +30,14 @@ char menu_error_msg[64] = { 0, }; void *g_menuscreen_ptr; void *g_menubg_src_ptr; void *g_menubg_ptr; -static char rom_fname_reload[256]; -#if !MSCREEN_SIZE_FIXED int g_menuscreen_w; int g_menuscreen_h; -#endif + +int g_autostateld_opt; static unsigned char *menu_font_data = NULL; -static int menu_text_color = 0xffff; // default to white +static int menu_text_color = 0xfffe; // default to white static int menu_sel_color = -1; // disabled /* note: these might become non-constant in future */ @@ -49,6 +49,7 @@ static const int me_mfont_w = 8, me_mfont_h = 10; static const int me_sfont_w = 6, me_sfont_h = 10; #endif +static int g_menu_filter_off; static int g_border_style; static int border_left, border_right, border_top, border_bottom; @@ -238,7 +239,7 @@ static char tolower_simple(char c) void menu_init_base(void) { - int i, c, l; + int i, c, l, pos; unsigned char *fd, *fds; char buff[256]; FILE *f; @@ -251,7 +252,7 @@ void menu_init_base(void) return; // generate default 8x10 font from fontdata8x8 - for (c = 0, fd = menu_font_data; c < 256; c++) + for (c = 0, fd = menu_font_data; c < 128; c++) { for (l = 0; l < 8; l++) { @@ -293,17 +294,18 @@ void menu_init_base(void) } // load custom font and selector (stored as 1st symbol in font table) - emu_make_path(buff, "skin/font.png", sizeof(buff)); + pos = plat_get_skin_dir(buff, sizeof(buff)); + strcpy(buff + pos, "font.png"); readpng(menu_font_data, buff, READPNG_FONT, MENU_X2 ? 256 : 128, MENU_X2 ? 320 : 160); // default selector symbol is '>' memcpy(menu_font_data, menu_font_data + ((int)'>') * me_mfont_w * me_mfont_h / 2, me_mfont_w * me_mfont_h / 2); - emu_make_path(buff, "skin/selector.png", sizeof(buff)); + strcpy(buff + pos, "selector.png"); readpng(menu_font_data, buff, READPNG_SELECTOR, me_mfont_w, me_mfont_h); // load custom colors - emu_make_path(buff, "skin/skin.txt", sizeof(buff)); + strcpy(buff + pos, "skin.txt"); f = fopen(buff, "r"); if (f != NULL) { @@ -387,7 +389,7 @@ static void menu_darken_text_bg(void) for (x = xmin + 1; x < xmax; x++) { unsigned int p = screen[ls + x]; - if (p != 0xffff) + if (p != menu_text_color) screen[ls + x] = ((p&0xf79e)>>1) - ((p&0xc618)>>3); } screen[ls + xmax] = 0xffff; @@ -631,6 +633,8 @@ static void me_draw(const menu_entry *entries, int sel, void (*draw_more)(void)) y += me_mfont_h; } + menu_separation(); + /* display help or message if we have one */ h = (g_menuscreen_h - h) / 2; // bottom area height if (menu_error_msg[0] != 0) { @@ -851,10 +855,12 @@ static void do_delete(const char *fpath, const char *fname) // -------------- ROM selector -------------- -static void draw_dirlist(char *curdir, struct dirent **namelist, int n, int sel) +static void draw_dirlist(char *curdir, struct dirent **namelist, + int n, int sel, int show_help) { int max_cnt, start, i, x, pos; void *darken_ptr; + char buff[64]; max_cnt = g_menuscreen_h / me_sfont_h; start = max_cnt / 2 - sel; @@ -884,6 +890,28 @@ static void draw_dirlist(char *curdir, struct dirent **namelist, int n, int sel) } } smalltext_out16(5, max_cnt/2 * me_sfont_h, ">", 0xffff); + + if (show_help) { + darken_ptr = (short *)g_menuscreen_ptr + + g_menuscreen_w * (g_menuscreen_h - me_sfont_h * 5 / 2); + menu_darken_bg(darken_ptr, darken_ptr, + g_menuscreen_w * (me_sfont_h * 5 / 2), 1); + + snprintf(buff, sizeof(buff), "%s - select, %s - back", + in_get_key_name(-1, -PBTN_MOK), in_get_key_name(-1, -PBTN_MBACK)); + smalltext_out16(x, g_menuscreen_h - me_sfont_h * 3 - 2, buff, 0xe78c); + + snprintf(buff, sizeof(buff), g_menu_filter_off ? + "%s - hide unknown files" : "%s - show all files", + in_get_key_name(-1, -PBTN_MA3)); + smalltext_out16(x, g_menuscreen_h - me_sfont_h * 2 - 2, buff, 0xe78c); + + snprintf(buff, sizeof(buff), g_autostateld_opt ? + "%s - autoload save is ON" : "%s - autoload save is OFF", + in_get_key_name(-1, -PBTN_MA2)); + smalltext_out16(x, g_menuscreen_h - me_sfont_h * 1 - 2, buff, 0xe78c); + } + menu_draw_end(); } @@ -901,21 +929,30 @@ static int scandir_cmp(const void *p1, const void *p2) return alphasort(d1, d2); } +static const char **filter_exts_internal; + static int scandir_filter(const struct dirent *ent) { - const char *p; + const char **filter = filter_exts_internal; + const char *ext; int i; - if (ent == NULL || ent->d_name == NULL) return 0; - if (strlen(ent->d_name) < 5) return 1; + if (ent == NULL || ent->d_name == NULL) + return 0; - p = ent->d_name + strlen(ent->d_name) - 4; + if (ent->d_type == DT_DIR) + return 1; - for (i = 0; i < array_size(filter_exts); i++) - if (strcmp(p, filter_exts[i]) == 0) - return 0; + ext = strrchr(ent->d_name, '.'); + if (ext == NULL) + return 0; + + ext++; + for (i = 0; filter[i] != NULL; i++) + if (strcasecmp(ext, filter[i]) == 0) + return 1; - return 1; + return 0; } static int dirent_seek_char(struct dirent **namelist, int len, int sel, char c) @@ -923,9 +960,11 @@ static int dirent_seek_char(struct dirent **namelist, int len, int sel, char c) int i; sel++; - for (i = sel + 1; i != sel; i++) { + for (i = sel + 1; ; i++) { if (i >= len) i = 1; + if (i == sel) + break; if (tolower_simple(namelist[i]->d_name[0]) == c) break; @@ -934,24 +973,49 @@ static int dirent_seek_char(struct dirent **namelist, int len, int sel, char c) return i - 1; } -static char *menu_loop_romsel(char *curr_path, int len) +static const char *menu_loop_romsel(char *curr_path, int len, + const char **filter_exts, + int (*extra_filter)(struct dirent **namelist, int count, + const char *basedir)) { - struct dirent **namelist; - int n, inp, sel = 0; - char *ret = NULL, *fname = NULL; + static char rom_fname_reload[256]; // used for return + char sel_fname[256]; + int (*filter)(const struct dirent *); + struct dirent **namelist = NULL; + int n = 0, inp = 0, sel = 0, show_help = 0; + char *curr_path_restore = NULL; + const char *ret = NULL; char cinp; -rescan: + filter_exts_internal = filter_exts; + sel_fname[0] = 0; + // is this a dir or a full path? if (!plat_is_dir(curr_path)) { - char *p = curr_path + strlen(curr_path) - 1; - for (; p > curr_path && *p != '/'; p--) - ; - *p = 0; - fname = p+1; + char *p = strrchr(curr_path, '/'); + if (p != NULL) { + *p = 0; + curr_path_restore = p; + snprintf(sel_fname, sizeof(sel_fname), "%s", p + 1); + } + + if (rom_fname_reload[0] == 0) + show_help = 2; } - n = scandir(curr_path, &namelist, scandir_filter, (void *)scandir_cmp); +rescan: + if (namelist != NULL) { + while (n-- > 0) + free(namelist[n]); + free(namelist); + namelist = NULL; + } + + filter = NULL; + if (!g_menu_filter_off) + filter = scandir_filter; + + n = scandir(curr_path, &namelist, filter, (void *)scandir_cmp); if (n < 0) { char *t; lprintf("menu_loop_romsel failed, dir: %s\n", curr_path); @@ -960,7 +1024,7 @@ rescan: t = getcwd(curr_path, len); if (t == NULL) plat_get_root_dir(curr_path, len); - n = scandir(curr_path, &namelist, scandir_filter, (void *)scandir_cmp); + n = scandir(curr_path, &namelist, filter, (void *)scandir_cmp); if (n < 0) { // oops, we failed lprintf("menu_loop_romsel failed, dir: %s\n", curr_path); @@ -968,13 +1032,17 @@ rescan: } } - // try to find sel + if (!g_menu_filter_off && extra_filter != NULL) + n = extra_filter(namelist, n, curr_path); + + // try to find selected file // note: we don't show '.' so sel is namelist index - 1 - if (fname != NULL) { + sel = 0; + if (sel_fname[0] != 0) { int i; for (i = 1; i < n; i++) { char *dname = namelist[i]->d_name; - if (dname[0] == fname[0] && strcmp(dname, fname) == 0) { + if (dname[0] == sel_fname[0] && strcmp(dname, sel_fname) == 0) { sel = i - 1; break; } @@ -982,39 +1050,41 @@ rescan: } /* make sure action buttons are not pressed on entering menu */ - draw_dirlist(curr_path, namelist, n, sel); + draw_dirlist(curr_path, namelist, n, sel, show_help); while (in_menu_wait_any(NULL, 50) & (PBTN_MOK|PBTN_MBACK|PBTN_MENU)) ; for (;;) { - draw_dirlist(curr_path, namelist, n, sel); - inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT| - PBTN_L|PBTN_R|PBTN_MA2|PBTN_MOK|PBTN_MBACK|PBTN_MENU|PBTN_CHAR, &cinp, 33); + draw_dirlist(curr_path, namelist, n, sel, show_help); + inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT + | PBTN_L|PBTN_R|PBTN_MA2|PBTN_MA3|PBTN_MOK|PBTN_MBACK + | PBTN_MENU|PBTN_CHAR, &cinp, 33); + if (inp & PBTN_MA3) { + g_menu_filter_off = !g_menu_filter_off; + snprintf(sel_fname, sizeof(sel_fname), "%s", + namelist[sel+1]->d_name); + goto rescan; + } if (inp & PBTN_UP ) { sel--; if (sel < 0) sel = n-2; } if (inp & PBTN_DOWN) { sel++; if (sel > n-2) sel = 0; } if (inp & PBTN_LEFT) { sel-=10; if (sel < 0) sel = 0; } if (inp & PBTN_L) { sel-=24; if (sel < 0) sel = 0; } if (inp & PBTN_RIGHT) { sel+=10; if (sel > n-2) sel = n-2; } if (inp & PBTN_R) { sel+=24; if (sel > n-2) sel = n-2; } - if (inp & PBTN_CHAR) sel = dirent_seek_char(namelist, n, sel, cinp); + if ((inp & PBTN_MOK) || (inp & (PBTN_MENU|PBTN_MA2)) == (PBTN_MENU|PBTN_MA2)) { again: if (namelist[sel+1]->d_type == DT_REG) { - strcpy(rom_fname_reload, curr_path); - strcat(rom_fname_reload, "/"); - strcat(rom_fname_reload, namelist[sel+1]->d_name); + snprintf(rom_fname_reload, sizeof(rom_fname_reload), + "%s/%s", curr_path, namelist[sel+1]->d_name); if (inp & PBTN_MOK) { // return sel ret = rom_fname_reload; break; } do_delete(rom_fname_reload, namelist[sel+1]->d_name); - if (n > 0) { - while (n--) free(namelist[n]); - free(namelist); - } goto rescan; } else if (namelist[sel+1]->d_type == DT_DIR) @@ -1041,7 +1111,7 @@ rescan: strcat(newdir, "/"); strcat(newdir, namelist[sel+1]->d_name); } - ret = menu_loop_romsel(newdir, newlen); + ret = menu_loop_romsel(newdir, newlen, filter_exts, extra_filter); free(newdir); break; } @@ -1049,9 +1119,8 @@ rescan: { // unknown file type, happens on NTFS mounts. Try to guess. FILE *tstf; int tmp; - strcpy(rom_fname_reload, curr_path); - strcat(rom_fname_reload, "/"); - strcat(rom_fname_reload, namelist[sel+1]->d_name); + snprintf(rom_fname_reload, sizeof(rom_fname_reload), + "%s/%s", curr_path, namelist[sel+1]->d_name); tstf = fopen(rom_fname_reload, "rb"); if (tstf != NULL) { @@ -1063,21 +1132,31 @@ rescan: } } } + else if (inp & PBTN_MA2) { + g_autostateld_opt = !g_autostateld_opt; + show_help = 3; + } + else if (inp & PBTN_CHAR) { + // must be last + sel = dirent_seek_char(namelist, n, sel, cinp); + } + if (inp & PBTN_MBACK) break; + + if (show_help > 0) + show_help--; } if (n > 0) { - while (n--) free(namelist[n]); + while (n-- > 0) + free(namelist[n]); free(namelist); } // restore curr_path - if (fname != NULL) { - n = strlen(curr_path); - if (curr_path + n + 1 == fname) - curr_path[n] = '/'; - } + if (curr_path_restore != NULL) + *curr_path_restore = '/'; return ret; } @@ -1304,7 +1383,7 @@ static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_ if (dev_id < 0) dev_name = "(all devices)"; else - dev_name = in_get_dev_name(dev_id, 1, 1); + dev_name = in_get_dev_name(dev_id, 0, 1); w = strlen(dev_name) * me_mfont_w; if (w < 30 * me_mfont_w) w = 30 * me_mfont_w; @@ -1367,7 +1446,7 @@ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_ for (i = 0, dev_id--; i < IN_MAX_DEVS + 1; i++, dev_id--) { if (dev_id < -1) dev_id = IN_MAX_DEVS - 1; - if (dev_id == -1 || in_get_dev_name(dev_id, 1, 0) != NULL) + if (dev_id == -1 || in_get_dev_name(dev_id, 0, 0) != NULL) break; } continue; @@ -1375,7 +1454,7 @@ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_ for (i = 0, dev_id++; i < IN_MAX_DEVS; i++, dev_id++) { if (dev_id >= IN_MAX_DEVS) dev_id = -1; - if (dev_id == -1 || in_get_dev_name(dev_id, 1, 0) != NULL) + if (dev_id == -1 || in_get_dev_name(dev_id, 0, 0) != NULL) break; } continue;