X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=menu.c;h=929713dc6b553402dcf3f7c38e1210a032a63b09;hb=4919040522d4c6a0d3fb64ebee2ffb51c37c8230;hp=e7adb5a7ba35d10c34c1cac4a65b56a3cf636d80;hpb=68c85e2a0bc59b51c520e5dd97cd14fd795a9a5d;p=libpicofe.git diff --git a/menu.c b/menu.c index e7adb5a..929713d 100644 --- a/menu.c +++ b/menu.c @@ -207,10 +207,10 @@ static void smalltext_out16(int x, int y, const char *texto, int color) 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); @@ -494,24 +494,12 @@ static int me_count(const menu_entry *ent) static unsigned int me_read_onoff(const menu_entry *ent) { - // guess var size based on mask to avoid reading too much - if (ent->mask & 0xffff0000) - return *(unsigned int *)ent->var & ent->mask; - else if (ent->mask & 0xff00) - return *(unsigned short *)ent->var & ent->mask; - else - return *(unsigned char *)ent->var & ent->mask; + return *(unsigned int *)ent->var & ent->mask; } static void me_toggle_onoff(menu_entry *ent) { - // guess var size based on mask to avoid reading too much - if (ent->mask & 0xffff0000) - *(unsigned int *)ent->var ^= ent->mask; - else if (ent->mask & 0xff00) - *(unsigned short *)ent->var ^= ent->mask; - else - *(unsigned char *)ent->var ^= ent->mask; + *(unsigned int *)ent->var ^= ent->mask; } static void me_draw(const menu_entry *entries, int sel, void (*draw_more)(void)) @@ -613,7 +601,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; } @@ -621,7 +609,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); @@ -642,10 +630,10 @@ 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 == *(unsigned char *)ent->var) { + if (i == *(int *)ent->var) { text_out16(offs, y, "%s", names[i]); break; } @@ -662,7 +650,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"); @@ -710,11 +698,11 @@ static int me_process(menu_entry *entry, int is_next, int is_lr) names = (const char **)entry->data; for (c = 0; names[c] != NULL; c++) ; - *(signed char *)entry->var += is_next ? 1 : -1; - if (*(signed char *)entry->var < 0) - *(signed char *)entry->var = 0; - if (*(signed char *)entry->var >= c) - *(signed char *)entry->var = c - 1; + *(int *)entry->var += is_next ? 1 : -1; + if (*(int *)entry->var < 0) + *(int *)entry->var = 0; + if (*(int *)entry->var >= c) + *(int *)entry->var = c - 1; return 1; default: return 0; @@ -825,7 +813,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++) ; @@ -867,7 +855,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)); @@ -887,7 +875,6 @@ static void draw_dirlist(char *curdir, struct dirent **namelist, max_cnt = g_menuscreen_h / me_sfont_h; start = max_cnt / 2 - sel; - n--; // exclude current dir (".") menu_draw_begin(1, 1); @@ -904,12 +891,12 @@ static void draw_dirlist(char *curdir, struct dirent **namelist, pos = start + i; if (pos < 0) continue; if (pos >= max_cnt) break; - if (namelist[i+1]->d_type == DT_DIR) { + 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+1]->d_name, 0xfff6); + smalltext_out16(x + me_sfont_w, pos * me_sfont_h, namelist[i]->d_name, 0xfff6); } else { - unsigned short color = fname2color(namelist[i+1]->d_name); - smalltext_out16(x, pos * me_sfont_h, namelist[i+1]->d_name, color); + 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); @@ -942,10 +929,15 @@ static int scandir_cmp(const void *p1, const void *p2) { const struct dirent **d1 = (const struct dirent **)p1; const struct dirent **d2 = (const struct dirent **)p2; + const char *p; + if ((p = (*d1)->d_name)[0] == '.' && p[1] == '.' && p[2] == 0) + return -1; // ".." first + if ((p = (*d2)->d_name)[0] == '.' && p[1] == '.' && p[2] == 0) + return 1; if ((*d1)->d_type == (*d2)->d_type) return alphasort(d1, d2); if ((*d1)->d_type == DT_DIR) - return -1; // put before + return -1; // directories before files/links if ((*d2)->d_type == DT_DIR) return 1; @@ -965,7 +957,8 @@ static int scandir_filter(const struct dirent *ent) switch (ent->d_type) { case DT_DIR: - return 1; + // leave out useless reference to current directory + return strcmp(ent->d_name, ".") != 0; case DT_LNK: case DT_UNKNOWN: // could be a dir, deal with it later.. @@ -1014,7 +1007,6 @@ static const char *menu_loop_romsel(char *curr_path, int len, 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; @@ -1048,13 +1040,10 @@ rescan: n = scandir(curr_path, &namelist, filter, (void *)scandir_cmp); if (n < 0) { - char *t; lprintf("menu_loop_romsel failed, dir: %s\n", curr_path); - // try root - t = getcwd(curr_path, len); - if (t == NULL) - plat_get_root_dir(curr_path, len); + // try data root + plat_get_data_dir(curr_path, len); n = scandir(curr_path, &namelist, filter, (void *)scandir_cmp); if (n < 0) { // oops, we failed @@ -1064,43 +1053,40 @@ rescan: } // try to resolve DT_UNKNOWN and symlinks - changed = 0; for (i = 0; i < n; i++) { struct stat st; + char *slash; if (namelist[i]->d_type == DT_REG || namelist[i]->d_type == DT_DIR) continue; + r = strlen(curr_path); + slash = (r && curr_path[r-1] == '/') ? "" : "/"; snprintf(rom_fname_reload, sizeof(rom_fname_reload), - "%s/%s", curr_path, namelist[i]->d_name); + "%s%s%s", curr_path, slash, namelist[i]->d_name); r = stat(rom_fname_reload, &st); if (r == 0) { - if (S_ISREG(st.st_mode)) { + if (S_ISREG(st.st_mode)) namelist[i]->d_type = DT_REG; - changed = 1; - } - else if (S_ISDIR(st.st_mode)) { + 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) + if (n > 1) 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) { - for (i = 1; i < n; i++) { + for (i = 0; i < n; i++) { char *dname = namelist[i]->d_name; if (dname[0] == sel_fname[0] && strcmp(dname, sel_fname) == 0) { - sel = i - 1; + sel = i; break; } } @@ -1120,52 +1106,54 @@ rescan: if (inp & PBTN_MA3) { g_menu_filter_off = !g_menu_filter_off; snprintf(sel_fname, sizeof(sel_fname), "%s", - namelist[sel+1]->d_name); + namelist[sel]->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_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-2) sel = n-2; } - if (inp & PBTN_R) { sel+=24; if (sel > n-2) sel = n-2; } + 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)) { - if (namelist[sel+1]->d_type == DT_REG) + if (namelist[sel]->d_type == DT_REG) { + int l = strlen(curr_path); + char *slash = l && curr_path[l-1] == '/' ? "" : "/"; snprintf(rom_fname_reload, sizeof(rom_fname_reload), - "%s/%s", curr_path, namelist[sel+1]->d_name); + "%s%s%s", curr_path, slash, namelist[sel]->d_name); if (inp & PBTN_MOK) { // return sel ret = rom_fname_reload; break; } - do_delete(rom_fname_reload, namelist[sel+1]->d_name); + do_delete(rom_fname_reload, namelist[sel]->d_name); goto rescan; } - else if (namelist[sel+1]->d_type == DT_DIR) + else if (namelist[sel]->d_type == DT_DIR) { int newlen; char *p, *newdir; if (!(inp & PBTN_MOK)) continue; - newlen = strlen(curr_path) + strlen(namelist[sel+1]->d_name) + 2; + newlen = strlen(curr_path) + strlen(namelist[sel]->d_name) + 2; newdir = malloc(newlen); if (newdir == NULL) break; - if (strcmp(namelist[sel+1]->d_name, "..") == 0) { + if (strcmp(namelist[sel]->d_name, "..") == 0) { char *start = curr_path; p = start + strlen(start) - 1; while (*p == '/' && p > start) p--; while (*p != '/' && p > start) p--; - if (p <= start) strcpy(newdir, "/"); + if (p <= start) plat_get_data_dir(newdir, newlen); else { strncpy(newdir, start, p-start); newdir[p-start] = 0; } } else { strcpy(newdir, curr_path); p = newdir + strlen(newdir) - 1; while (*p == '/' && p >= newdir) *p-- = 0; strcat(newdir, "/"); - strcat(newdir, namelist[sel+1]->d_name); + strcat(newdir, namelist[sel]->d_name); } ret = menu_loop_romsel(newdir, newlen, filter_exts, extra_filter); free(newdir); @@ -1331,10 +1319,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; @@ -1437,13 +1425,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"); } @@ -1471,9 +1459,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 (;;) {