X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=menu.c;h=5d96b7e3ed773426ad9c5784a7e577f440a206d7;hb=HEAD;hp=65cb26a6b4ea2f002b53e67ea1b9abbe83d6dfe5;hpb=62128bad6decbd73a50a33fb8cba587aa8d41ba4;p=libpicofe.git diff --git a/menu.c b/menu.c index 65cb26a..27c72bf 100644 --- a/menu.c +++ b/menu.c @@ -55,11 +55,11 @@ static int menu_sel_color = -1; // disabled /* note: these might become non-constant in future */ #if MENU_X2 -static const int me_mfont_w = 16, me_mfont_h = 20; -static const int me_sfont_w = 12, me_sfont_h = 20; +const int me_mfont_w = 16, me_mfont_h = 20; +const int me_sfont_w = 12, me_sfont_h = 20; #else -static const int me_mfont_w = 8, me_mfont_h = 10; -static const int me_sfont_w = 6, me_sfont_h = 10; +const int me_mfont_w = 8, me_mfont_h = 10; +const int me_sfont_w = 6, me_sfont_h = 10; #endif static int g_menu_filter_off; @@ -77,9 +77,9 @@ 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_pp; - tr = (color & 0xf800) >> 8; - tg = (color & 0x07e0) >> 3; - tb = (color & 0x001f) << 3; + tr = PXGETR(color); + tg = PXGETG(color); + tb = PXGETB(color); if (text == (void *)1) { @@ -111,21 +111,21 @@ static void text_out16_(int x, int y, const char *text, int color) { int c, r, g, b; c = *src >> 4; - r = (*dst & 0xf800) >> 8; - g = (*dst & 0x07e0) >> 3; - b = (*dst & 0x001f) << 3; + r = PXGETR(*dst); + g = PXGETG(*dst); + b = PXGETB(*dst); r = (c^0xf)*r/15 + c*tr/15; g = (c^0xf)*g/15 + c*tg/15; b = (c^0xf)*b/15 + c*tb/15; - *dst++ = ((r<<8)&0xf800) | ((g<<3)&0x07e0) | (b>>3); + *dst++ = PXMAKE(r, g, b); c = *src & 0xf; - r = (*dst & 0xf800) >> 8; - g = (*dst & 0x07e0) >> 3; - b = (*dst & 0x001f) << 3; + r = PXGETR(*dst); + g = PXGETG(*dst); + b = PXGETB(*dst); r = (c^0xf)*r/15 + c*tr/15; g = (c^0xf)*g/15 + c*tg/15; b = (c^0xf)*b/15 + c*tb/15; - *dst++ = ((r<<8)&0xf800) | ((g<<3)&0x07e0) | (b>>3); + *dst++ = PXMAKE(r, g, b); } } dest += me_mfont_w; @@ -200,17 +200,17 @@ static void smalltext_out16_(int x, int y, const char *texto, int color) } } -static void smalltext_out16(int x, int y, const char *texto, int color) +void smalltext_out16(int x, int y, const char *texto, int color) { char buffer[128]; int maxw = (g_menuscreen_w - x) / me_sfont_w; if (maxw < 0) return; - - strncpy(buffer, texto, sizeof(buffer)); if (maxw > sizeof(buffer) - 1) maxw = sizeof(buffer) - 1; + + strncpy(buffer, texto, maxw); buffer[maxw] = 0; smalltext_out16_(x, y, buffer, color); @@ -241,11 +241,7 @@ static int parse_hex_color(char *buff) char *endp = buff; int t = (int) strtoul(buff, &endp, 16); if (endp != buff) -#ifdef PSP - return ((t<<8)&0xf800) | ((t>>5)&0x07e0) | ((t>>19)&0x1f); -#else - return ((t>>8)&0xf800) | ((t>>5)&0x07e0) | ((t>>3)&0x1f); -#endif + return PXMAKE((t>>16)&0xff, (t>>8)&0xff,t&0xff); return -1; } @@ -367,7 +363,7 @@ static void menu_darken_bg(void *dst, void *src, int pixels, int darker) while (pixels--) { unsigned int p = *sorc++; - *dest++ = ((p&0xf79ef79e)>>1) - ((p&0xc618c618)>>3); + *dest++ = (PXMASKH(p,1)>>1) - (PXMASKH(p,3)>>3); } } else @@ -375,7 +371,7 @@ static void menu_darken_bg(void *dst, void *src, int pixels, int darker) while (pixels--) { unsigned int p = *sorc++; - *dest++ = (p&0xf79ef79e)>>1; + *dest++ = (PXMASKH(p,1)>>1); } } } @@ -400,7 +396,7 @@ static void menu_darken_text_bg(void) ymax = g_menuscreen_h - 1; for (x = xmin; x <= xmax; x++) - screen[y * g_menuscreen_pp + x] = 0xa514; + screen[y * g_menuscreen_pp + x] = PXMAKE(0xa0, 0xa0, 0xa0); for (y++; y < ymax; y++) { ls = y * g_menuscreen_pp; @@ -409,7 +405,7 @@ static void menu_darken_text_bg(void) { unsigned int p = screen[ls + x]; if (p != menu_text_color) - screen[ls + x] = ((p&0xf79e)>>1) - ((p&0xc618)>>3); + screen[ls + x] = (PXMASKH(p,1)>>1) - (PXMASKH(p,3)>>3); } screen[ls + xmax] = 0xffff; } @@ -479,7 +475,7 @@ static int me_id2offset(const menu_entry *ent, menu_id id) static void me_enable(menu_entry *entries, menu_id id, int enable) { int i = me_id2offset(entries, id); - entries[i].enabled = enable; + entries[i].enabled = !!enable; } static int me_count(const menu_entry *ent) @@ -601,7 +597,7 @@ static void me_draw(const menu_entry *entries, int sel, void (*draw_more)(void)) name = ent->generate_name(ent->id, &offs); } if (name != NULL) { - text_out16(x, y, name); + text_out16(x, y, "%s", name); leftname_end = x + (strlen(name) + 1) * me_mfont_w; } @@ -609,7 +605,7 @@ static void me_draw(const menu_entry *entries, int sel, void (*draw_more)(void)) case MB_NONE: break; case MB_OPT_ONOFF: - text_out16(x + col2_offs, y, me_read_onoff(ent) ? "ON" : "OFF"); + text_out16(x + col2_offs, y, "%s", me_read_onoff(ent) ? "ON" : "OFF"); break; case MB_OPT_RANGE: text_out16(x + col2_offs, y, "%i", *(int *)ent->var); @@ -630,7 +626,7 @@ static void me_draw(const menu_entry *entries, int sel, void (*draw_more)(void)) offs = x + col2_offs; len = strlen(names[i]); if (len > 10) - offs += (10 - len - 2) * me_mfont_w; + offs += (10 - len) * me_mfont_w; if (offs < leftname_end) offs = leftname_end; if (i == *(int *)ent->var) { @@ -650,7 +646,7 @@ static void me_draw(const menu_entry *entries, int sel, void (*draw_more)(void)) h = (g_menuscreen_h - h) / 2; // bottom area height if (menu_error_msg[0] != 0) { if (h >= me_mfont_h + 4) - text_out16(5, g_menuscreen_h - me_mfont_h - 4, menu_error_msg); + text_out16(5, g_menuscreen_h - me_mfont_h - 4, "%s", menu_error_msg); else lprintf("menu msg doesn't fit!\n"); @@ -664,7 +660,7 @@ static void me_draw(const menu_entry *entries, int sel, void (*draw_more)(void)) tmp = strchr(tmp + 1, '\n'); if (h >= l * me_sfont_h + 4) for (tmp = ent_sel->help; l > 0; l--, tmp = strchr(tmp, '\n') + 1) - smalltext_out16(5, g_menuscreen_h - (l * me_sfont_h + 4), tmp, 0xffff); + smalltext_out16(5, g_menuscreen_h - (l * me_sfont_h + 4), tmp, PXMAKE(0xff, 0xff, 0xff)); } menu_separation(); @@ -813,7 +809,7 @@ static void draw_menu_message(const char *msg, void (*draw_more)(void)) menu_draw_begin(1, 0); for (p = msg; *p != 0 && y <= g_menuscreen_h - me_mfont_h; y += me_mfont_h) { - text_out16(x, y, p); + text_out16(x, y, "%s", p); for (; *p != 0 && *p != '\n'; p++) ; @@ -845,7 +841,7 @@ static void do_delete(const char *fpath, const char *fname) mid = g_menuscreen_w / 2; text_out16(mid - me_mfont_w * 15 / 2, 8 * me_mfont_h, "About to delete"); - smalltext_out16(mid - len * me_sfont_w / 2, 9 * me_mfont_h + 5, fname, 0xbdff); + smalltext_out16(mid - len * me_sfont_w / 2, 9 * me_mfont_h + 5, fname, PXMAKE(0xbf, 0xbf, 0xff)); text_out16(mid - me_mfont_w * 13 / 2, 11 * me_mfont_h, "Are you sure?"); nm = in_get_key_name(-1, -PBTN_MA3); @@ -855,7 +851,7 @@ static void do_delete(const char *fpath, const char *fname) snprintf(tmp + len, sizeof(tmp) - len, "%s - cancel)", nm); len = strlen(tmp); - text_out16(mid - me_mfont_w * len / 2, 12 * me_mfont_h, tmp); + text_out16(mid - me_mfont_w * len / 2, 12 * me_mfont_h, "%s", tmp); menu_draw_end(); while (in_menu_wait_any(NULL, 50) & (PBTN_MENU|PBTN_MA2)); @@ -886,20 +882,20 @@ static void draw_dirlist(char *curdir, struct dirent **namelist, x = 5 + me_mfont_w + 1; if (start - 2 >= 0) - smalltext_out16(14, (start - 2) * me_sfont_h, curdir, 0xffff); + smalltext_out16(14, (start - 2) * me_sfont_h, curdir, PXMAKE(0xff, 0xff, 0xff)); for (i = 0; i < n; i++) { pos = start + i; if (pos < 0) continue; if (pos >= max_cnt) break; if (namelist[i]->d_type == DT_DIR) { - smalltext_out16(x, pos * me_sfont_h, "/", 0xfff6); - smalltext_out16(x + me_sfont_w, pos * me_sfont_h, namelist[i]->d_name, 0xfff6); + smalltext_out16(x, pos * me_sfont_h, "/", PXMAKE(0xff, 0xff, 0xb0)); + smalltext_out16(x + me_sfont_w, pos * me_sfont_h, namelist[i]->d_name, PXMAKE(0xff, 0xff, 0xb0)); } else { unsigned short color = fname2color(namelist[i]->d_name); smalltext_out16(x, pos * me_sfont_h, namelist[i]->d_name, color); } } - smalltext_out16(5, max_cnt/2 * me_sfont_h, ">", 0xffff); + smalltext_out16(5, max_cnt/2 * me_sfont_h, ">", PXMAKE(0xff, 0xff, 0xff)); if (show_help) { darken_ptr = (short *)g_menuscreen_ptr @@ -909,17 +905,17 @@ static void draw_dirlist(char *curdir, struct dirent **namelist, 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); + smalltext_out16(x, g_menuscreen_h - me_sfont_h * 3 - 2, buff, PXMAKE(0xe0, 0xf0, 0x60)); 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); + smalltext_out16(x, g_menuscreen_h - me_sfont_h * 2 - 2, buff, PXMAKE(0xe0, 0xf0, 0x60)); 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); + smalltext_out16(x, g_menuscreen_h - me_sfont_h * 1 - 2, buff, PXMAKE(0xe0, 0xf0, 0x60)); } menu_draw_end(); @@ -981,10 +977,9 @@ static int dirent_seek_char(struct dirent **namelist, int len, int sel, char c) { int i; - sel++; for (i = sel + 1; ; i++) { if (i >= len) - i = 1; + i = 0; if (i == sel) break; @@ -992,13 +987,14 @@ static int dirent_seek_char(struct dirent **namelist, int len, int sel, char c) break; } - return i - 1; + return i; } -static const char *menu_loop_romsel(char *curr_path, int len, +static const char *menu_loop_romsel_d(char *curr_path, int len, const char **filter_exts, int (*extra_filter)(struct dirent **namelist, int count, - const char *basedir)) + const char *basedir), + void (*draw_prep)(void)) { static char rom_fname_reload[256]; // used for scratch and return char sel_fname[256]; @@ -1021,13 +1017,12 @@ static const char *menu_loop_romsel(char *curr_path, int len, curr_path_restore = p; snprintf(sel_fname, sizeof(sel_fname), "%s", p + 1); } - - if (rom_fname_reload[0] == 0) - show_help = 2; } + show_help = 2; rescan: if (namelist != NULL) { + n += !n; while (n-- > 0) free(namelist[n]); free(namelist); @@ -1039,16 +1034,17 @@ rescan: filter = scandir_filter; n = scandir(curr_path, &namelist, filter, (void *)scandir_cmp); - if (n < 0) { + if (n < 0 || !namelist) { lprintf("menu_loop_romsel failed, dir: %s\n", curr_path); // try data root plat_get_data_dir(curr_path, len); n = scandir(curr_path, &namelist, filter, (void *)scandir_cmp); - if (n < 0) { + if (n < 0 || !namelist) { // oops, we failed lprintf("menu_loop_romsel failed, dir: %s\n", curr_path); - return NULL; + namelist = malloc(sizeof(*namelist)); + namelist[0] = calloc(1, sizeof(**namelist)); } } @@ -1080,6 +1076,16 @@ rescan: if (n > 1) qsort(namelist, n, sizeof(namelist[0]), scandir_cmp); + // add ".." if it's somehow not there + if (n == 0 || strcmp(namelist[0]->d_name, "..")) { + struct dirent *dotdot = malloc(sizeof(*dotdot)); + *dotdot = (struct dirent) { .d_name="..", .d_type=DT_DIR }; + namelist = realloc(namelist, (n+1)*sizeof(*namelist)); + memmove(namelist+1, namelist, n*sizeof(*namelist)); + namelist[0] = dotdot; + n++; + } + // try to find selected file sel = 0; if (sel_fname[0] != 0) { @@ -1099,6 +1105,8 @@ rescan: for (;;) { + if (draw_prep != NULL) + draw_prep(); 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 @@ -1107,16 +1115,18 @@ rescan: g_menu_filter_off = !g_menu_filter_off; snprintf(sel_fname, sizeof(sel_fname), "%s", namelist[sel]->d_name); + show_help = 2; goto rescan; } - if (inp & PBTN_UP ) { sel--; if (sel < 0) sel = n-1; } - if (inp & PBTN_DOWN) { sel++; if (sel > n-1) 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-1) sel = n-1; } - if (inp & PBTN_R) { sel+=24; if (sel > n-1) sel = n-1; } - - if ((inp & PBTN_MOK) || (inp & (PBTN_MENU|PBTN_MA2)) == (PBTN_MENU|PBTN_MA2)) + int last = n ? n-1 : 0; + if (inp & PBTN_UP ) { sel--; if (sel < 0) sel = last; } + else if (inp & PBTN_DOWN) { sel++; if (sel > n-1) sel = 0; } + else if (inp & PBTN_LEFT) { sel-=10; if (sel < 0) sel = 0; } + else if (inp & PBTN_RIGHT) { sel+=10; if (sel > n-1) sel = last; } + else if (inp & PBTN_L) { sel-=24; if (sel < 0) sel = 0; } + else if (inp & PBTN_R) { sel+=24; if (sel > n-1) sel = last; } + + else if ((inp & PBTN_MOK) || (inp & (PBTN_MENU|PBTN_MA2)) == (PBTN_MENU|PBTN_MA2)) { if (namelist[sel]->d_type == DT_REG) { @@ -1151,11 +1161,11 @@ rescan: } else { strcpy(newdir, curr_path); p = newdir + strlen(newdir) - 1; - while (*p == '/' && p >= newdir) *p-- = 0; + while (p >= newdir && *p == '/') *p-- = 0; strcat(newdir, "/"); strcat(newdir, namelist[sel]->d_name); } - ret = menu_loop_romsel(newdir, newlen, filter_exts, extra_filter); + ret = menu_loop_romsel_d(newdir, newlen, filter_exts, extra_filter, draw_prep); free(newdir); break; } @@ -1189,6 +1199,14 @@ rescan: return ret; } +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)) +{ + return menu_loop_romsel_d(curr_path, len, filter_exts, extra_filter, NULL); +} + // ------------ savestate loader ------------ #define STATE_SLOT_COUNT 10 @@ -1319,10 +1337,10 @@ static char *action_binds(int player_idx, int action_mask, int dev_id) type = IN_BINDTYPE_EMU; if (player_idx >= 0) { can_combo = 0; - type = IN_BINDTYPE_PLAYER12; + type = IN_BINDTYPE_PLAYER12 + (player_idx >> 1); + if (player_idx & 1) + action_mask <<= 16; } - if (player_idx == 1) - action_mask <<= 16; if (dev_id >= 0) dev = dev_last = dev_id; @@ -1425,13 +1443,13 @@ static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_ snprintf(buff2, sizeof(buff2), "%s", in_get_key_name(-1, -PBTN_MOK)); snprintf(buff, sizeof(buff), "%s - bind, %s - clear", buff2, in_get_key_name(-1, -PBTN_MA2)); - text_out16(x, g_menuscreen_h - 4 * me_mfont_h, buff); + text_out16(x, g_menuscreen_h - 4 * me_mfont_h, "%s", buff); } else text_out16(x, g_menuscreen_h - 4 * me_mfont_h, "Press a button to bind/unbind"); if (dev_count > 1) { - text_out16(x, g_menuscreen_h - 3 * me_mfont_h, dev_name); + text_out16(x, g_menuscreen_h - 3 * me_mfont_h, "%s", dev_name); text_out16(x, g_menuscreen_h - 2 * me_mfont_h, "Press left/right for other devs"); } @@ -1459,9 +1477,12 @@ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_ dev_id = -1; // show all mask_shift = 0; - if (player_idx == 1) - mask_shift = 16; - bindtype = player_idx >= 0 ? IN_BINDTYPE_PLAYER12 : IN_BINDTYPE_EMU; + if (player_idx >= 0) { + if (player_idx & 1) + mask_shift = 16; + bindtype = IN_BINDTYPE_PLAYER12 + (player_idx >> 1); + } else + bindtype = IN_BINDTYPE_EMU; for (;;) {