X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=menu.c;h=f32c3ce73e1ab07281e0437e4ff7b0eab20ea281;hb=795b71c571518b310a22138141bb6d1cd08d85f6;hp=04c0410c80a27fcd8f683d145cfe97afd6cf112a;hpb=ebf0e111a84cbd73511cc2b935c7bd688638cf5e;p=libpicofe.git diff --git a/menu.c b/menu.c index 04c0410..f32c3ce 100644 --- a/menu.c +++ b/menu.c @@ -24,6 +24,10 @@ #include "plat.h" #include "posix.h" +#if defined(__GNUC__) && __GNUC__ >= 7 +#pragma GCC diagnostic ignored "-Wformat-truncation" +#endif + static char static_buff[64]; static int menu_error_time = 0; char menu_error_msg[64] = { 0, }; @@ -33,6 +37,9 @@ void *g_menubg_ptr; int g_menuscreen_w; int g_menuscreen_h; +int g_menuscreen_pp; + +int g_autostateld_opt; static unsigned char *menu_font_data = NULL; static int menu_text_color = 0xfffe; // default to white @@ -51,11 +58,17 @@ static int g_menu_filter_off; static int g_border_style; static int border_left, border_right, border_top, border_bottom; +void menuscreen_memset_lines(unsigned short *dst, int c, int l) +{ + for (; l > 0; l--, dst += g_menuscreen_pp) + memset(dst, c, g_menuscreen_w * 2); +} + // draws text to current bbp16 screen static void text_out16_(int x, int y, const char *text, int color) { int i, lh, tr, tg, tb, len; - unsigned short *dest = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_w; + unsigned short *dest = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_pp; tr = (color & 0xf800) >> 8; tg = (color & 0x07e0) >> 3; tb = (color & 0x001f) << 3; @@ -84,7 +97,7 @@ static void text_out16_(int x, int y, const char *text, int color) unsigned short *dst = dest; int u, l; - for (l = 0; l < lh; l++, dst += g_menuscreen_w - me_mfont_w) + for (l = 0; l < lh; l++, dst += g_menuscreen_pp - me_mfont_w) { for (u = me_mfont_w / 2; u > 0; u--, src++) { @@ -157,7 +170,7 @@ static void smalltext_out16_(int x, int y, const char *texto, int color) break; src = fontdata6x8[c]; - dst = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_w; + dst = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_pp; while (h--) { @@ -172,7 +185,7 @@ static void smalltext_out16_(int x, int y, const char *texto, int color) dst += multiplier; } - dst += g_menuscreen_w - me_sfont_w; + dst += g_menuscreen_pp - me_sfont_w; } src++; } @@ -205,13 +218,13 @@ static void menu_draw_selection(int x, int y, int w) if (menu_sel_color < 0) return; // no selection hilight if (y > 0) y--; - dest = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_w + me_mfont_w * 2 - 2; + dest = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_pp + me_mfont_w * 2 - 2; for (h = me_mfont_h + 1; h > 0; h--) { dst = dest; for (i = w - (me_mfont_w * 2 - 2); i > 0; i--) *dst++ = menu_sel_color; - dest += g_menuscreen_w; + dest += g_menuscreen_pp; } } @@ -237,7 +250,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; @@ -250,19 +263,19 @@ 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++) { unsigned char fd8x8 = fontdata8x8[c*8+l]; - if (fd8x8&0x80) *fd = 0xf0; - if (fd8x8&0x40) *fd |= 0x0f; fd++; - if (fd8x8&0x20) *fd = 0xf0; - if (fd8x8&0x10) *fd |= 0x0f; fd++; - if (fd8x8&0x08) *fd = 0xf0; - if (fd8x8&0x04) *fd |= 0x0f; fd++; - if (fd8x8&0x02) *fd = 0xf0; - if (fd8x8&0x01) *fd |= 0x0f; fd++; + if (fd8x8&0x80) { *fd = 0xf0; } + if (fd8x8&0x40) { *fd |= 0x0f; }; fd++; + if (fd8x8&0x20) { *fd = 0xf0; } + if (fd8x8&0x10) { *fd |= 0x0f; }; fd++; + if (fd8x8&0x08) { *fd = 0xf0; } + if (fd8x8&0x04) { *fd |= 0x0f; }; fd++; + if (fd8x8&0x02) { *fd = 0xf0; } + if (fd8x8&0x01) { *fd |= 0x0f; }; fd++; } fd += 8*2/2; // 2 empty lines } @@ -292,17 +305,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) { @@ -378,10 +392,10 @@ static void menu_darken_text_bg(void) ymax = g_menuscreen_h - 1; for (x = xmin; x <= xmax; x++) - screen[y * g_menuscreen_w + x] = 0xa514; + screen[y * g_menuscreen_pp + x] = 0xa514; for (y++; y < ymax; y++) { - ls = y * g_menuscreen_w; + ls = y * g_menuscreen_pp; screen[ls + xmin] = 0xffff; for (x = xmin + 1; x < xmax; x++) { @@ -391,7 +405,7 @@ static void menu_darken_text_bg(void) } screen[ls + xmax] = 0xffff; } - ls = y * g_menuscreen_w; + ls = y * g_menuscreen_pp; for (x = xmin; x <= xmax; x++) screen[ls + x] = 0xffff; } @@ -408,6 +422,8 @@ static void menu_reset_borders(void) static void menu_draw_begin(int need_bg, int no_borders) { + int y; + plat_video_menu_begin(); menu_reset_borders(); @@ -415,12 +431,14 @@ static void menu_draw_begin(int need_bg, int no_borders) if (need_bg) { if (g_border_style && no_borders) { - menu_darken_bg(g_menuscreen_ptr, g_menubg_ptr, - g_menuscreen_w * g_menuscreen_h, 1); + for (y = 0; y < g_menuscreen_h; y++) + menu_darken_bg((short *)g_menuscreen_ptr + g_menuscreen_pp * y, + (short *)g_menubg_ptr + g_menuscreen_w * y, g_menuscreen_w, 1); } else { - memcpy(g_menuscreen_ptr, g_menubg_ptr, - g_menuscreen_w * g_menuscreen_h * 2); + for (y = 0; y < g_menuscreen_h; y++) + memcpy((short *)g_menuscreen_ptr + g_menuscreen_pp * y, + (short *)g_menubg_ptr + g_menuscreen_w * y, g_menuscreen_w * 2); } } } @@ -868,8 +886,8 @@ static void draw_dirlist(char *curdir, struct dirent **namelist, // if (!rom_loaded) // menu_darken_bg(gp2x_screen, 320*240, 0); - darken_ptr = (short *)g_menuscreen_ptr + g_menuscreen_w * max_cnt/2 * me_sfont_h; - menu_darken_bg(darken_ptr, darken_ptr, g_menuscreen_w * me_sfont_h * 8 / 10, 0); + darken_ptr = (short *)g_menuscreen_ptr + g_menuscreen_pp * max_cnt/2 * me_sfont_h; + menu_darken_bg(darken_ptr, darken_ptr, g_menuscreen_pp * me_sfont_h * 8 / 10, 0); x = 5 + me_mfont_w + 1; if (start - 2 >= 0) @@ -890,16 +908,22 @@ static void draw_dirlist(char *curdir, struct dirent **namelist, if (show_help) { darken_ptr = (short *)g_menuscreen_ptr - + g_menuscreen_w * (g_menuscreen_h - me_sfont_h * 5 / 2); + + g_menuscreen_pp * (g_menuscreen_h - me_sfont_h * 5 / 2); menu_darken_bg(darken_ptr, darken_ptr, - g_menuscreen_w * (me_sfont_h * 5 / 2), 1); + g_menuscreen_pp * (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 * 2 - 2, buff, 0xe78c); + 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); } @@ -928,11 +952,17 @@ static int scandir_filter(const struct dirent *ent) const char *ext; int i; - if (ent == NULL || ent->d_name == NULL) + if (ent == NULL) return 0; - if (ent->d_type == DT_DIR) + switch (ent->d_type) { + case DT_DIR: + return 1; + case DT_LNK: + case DT_UNKNOWN: + // could be a dir, deal with it later.. return 1; + } ext = strrchr(ent->d_name, '.'); if (ext == NULL) @@ -951,9 +981,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; @@ -967,14 +999,16 @@ static const char *menu_loop_romsel(char *curr_path, int len, int (*extra_filter)(struct dirent **namelist, int count, const char *basedir)) { - static char rom_fname_reload[256]; // used for return + static char rom_fname_reload[256]; // used for scratch and 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; + int changed; char cinp; + int r, i; filter_exts_internal = filter_exts; sel_fname[0] = 0; @@ -1021,14 +1055,40 @@ rescan: } } + // try to resolve DT_UNKNOWN and symlinks + changed = 0; + for (i = 0; i < n; i++) { + struct stat st; + + if (namelist[i]->d_type == DT_REG || namelist[i]->d_type == DT_DIR) + continue; + + snprintf(rom_fname_reload, sizeof(rom_fname_reload), + "%s/%s", curr_path, namelist[i]->d_name); + r = stat(rom_fname_reload, &st); + if (r == 0) + { + if (S_ISREG(st.st_mode)) { + namelist[i]->d_type = DT_REG; + changed = 1; + } + else if (S_ISDIR(st.st_mode)) { + namelist[i]->d_type = DT_DIR; + changed = 1; + } + } + } + if (!g_menu_filter_off && extra_filter != NULL) n = extra_filter(namelist, n, curr_path); + if (n > 1 && changed) + qsort(namelist, n, sizeof(namelist[0]), scandir_cmp); + // try to find selected file // note: we don't show '.' so sel is namelist index - 1 sel = 0; if (sel_fname[0] != 0) { - int i; for (i = 1; i < n; i++) { char *dname = namelist[i]->d_name; if (dname[0] == sel_fname[0] && strcmp(dname, sel_fname) == 0) { @@ -1049,22 +1109,21 @@ rescan: 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_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_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_MOK) || (inp & (PBTN_MENU|PBTN_MA2)) == (PBTN_MENU|PBTN_MA2)) { - again: if (namelist[sel+1]->d_type == DT_REG) { snprintf(rom_fname_reload, sizeof(rom_fname_reload), @@ -1104,23 +1163,16 @@ rescan: free(newdir); break; } - else - { - // unknown file type, happens on NTFS mounts. Try to guess. - FILE *tstf; int tmp; - 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) - { - if (fread(&tmp, 1, 1, tstf) > 0 || ferror(tstf) == 0) - namelist[sel+1]->d_type = DT_REG; - else namelist[sel+1]->d_type = DT_DIR; - fclose(tstf); - goto again; - } - } } + 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; @@ -1344,7 +1396,8 @@ static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_ y = (g_menuscreen_h - 4 * me_mfont_h) / 2 - (2 + opt_cnt) * me_mfont_h / 2; if (x < me_mfont_w * 2) x = me_mfont_w * 2; - + if (y < 0) + y = 0; menu_draw_begin(1, 0); if (player_idx >= 0) text_out16(x, y, "Player %i controls", player_idx + 1); @@ -1470,6 +1523,10 @@ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_ in_unbind_all(bind_dev_id, opts[sel].mask << mask_shift, bindtype); in_bind_key(bind_dev_id, kc, opts[sel].mask << mask_shift, bindtype, 0); + + // make sure bind change is displayed + if (dev_id != -1) + dev_id = bind_dev_id; } }