#include "plat.h"\r
#include "posix.h"\r
\r
+#if defined(__GNUC__) && __GNUC__ >= 7\r
+#pragma GCC diagnostic ignored "-Wformat-truncation"\r
+#endif\r
+\r
static char static_buff[64];\r
static int menu_error_time = 0;\r
char menu_error_msg[64] = { 0, };\r
+// g_menuscreen is the current output buffer the menu is rendered to.\r
void *g_menuscreen_ptr;\r
-void *g_menubg_src_ptr;\r
+// g_menubg is the menu background and has the same w/h as g_menuscreen, but\r
+// pp=w. It is filled on menu entry from file or from g_menubg_src if available.\r
void *g_menubg_ptr;\r
+// g_menubg_src points to a buffer containing a bg image. This is usually either\r
+// the emulator screen buffer or the host frame buffer.\r
+void *g_menubg_src_ptr;\r
\r
int g_menuscreen_w;\r
int g_menuscreen_h;\r
+int g_menuscreen_pp;\r
+int g_menubg_src_w;\r
+int g_menubg_src_h;\r
+int g_menubg_src_pp;\r
\r
int g_autostateld_opt;\r
\r
static int g_border_style;\r
static int border_left, border_right, border_top, border_bottom;\r
\r
+void menuscreen_memset_lines(unsigned short *dst, int c, int l)\r
+{\r
+ for (; l > 0; l--, dst += g_menuscreen_pp)\r
+ memset(dst, c, g_menuscreen_w * 2);\r
+}\r
+\r
// draws text to current bbp16 screen\r
static void text_out16_(int x, int y, const char *text, int color)\r
{\r
int i, lh, tr, tg, tb, len;\r
- unsigned short *dest = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_w;\r
+ unsigned short *dest = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_pp;\r
tr = (color & 0xf800) >> 8;\r
tg = (color & 0x07e0) >> 3;\r
tb = (color & 0x001f) << 3;\r
unsigned short *dst = dest;\r
int u, l;\r
\r
- for (l = 0; l < lh; l++, dst += g_menuscreen_w - me_mfont_w)\r
+ for (l = 0; l < lh; l++, dst += g_menuscreen_pp - me_mfont_w)\r
{\r
for (u = me_mfont_w / 2; u > 0; u--, src++)\r
{\r
break;\r
\r
src = fontdata6x8[c];\r
- dst = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_w;\r
+ dst = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_pp;\r
\r
while (h--)\r
{\r
dst += multiplier;\r
}\r
\r
- dst += g_menuscreen_w - me_sfont_w;\r
+ dst += g_menuscreen_pp - me_sfont_w;\r
}\r
src++;\r
}\r
\r
if (maxw < 0)\r
return;\r
-\r
- strncpy(buffer, texto, sizeof(buffer));\r
if (maxw > sizeof(buffer) - 1)\r
maxw = sizeof(buffer) - 1;\r
+\r
+ strncpy(buffer, texto, maxw);\r
buffer[maxw] = 0;\r
\r
smalltext_out16_(x, y, buffer, color);\r
if (menu_sel_color < 0) return; // no selection hilight\r
\r
if (y > 0) y--;\r
- dest = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_w + me_mfont_w * 2 - 2;\r
+ dest = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_pp + me_mfont_w * 2 - 2;\r
for (h = me_mfont_h + 1; h > 0; h--)\r
{\r
dst = dest;\r
for (i = w - (me_mfont_w * 2 - 2); i > 0; i--)\r
*dst++ = menu_sel_color;\r
- dest += g_menuscreen_w;\r
+ dest += g_menuscreen_pp;\r
}\r
}\r
\r
return;\r
\r
// generate default 8x10 font from fontdata8x8\r
- for (c = 0, fd = menu_font_data; c < 256; c++)\r
+ for (c = 0, fd = menu_font_data; c < 128; c++)\r
{\r
for (l = 0; l < 8; l++)\r
{\r
unsigned char fd8x8 = fontdata8x8[c*8+l];\r
- if (fd8x8&0x80) *fd = 0xf0;\r
- if (fd8x8&0x40) *fd |= 0x0f; fd++;\r
- if (fd8x8&0x20) *fd = 0xf0;\r
- if (fd8x8&0x10) *fd |= 0x0f; fd++;\r
- if (fd8x8&0x08) *fd = 0xf0;\r
- if (fd8x8&0x04) *fd |= 0x0f; fd++;\r
- if (fd8x8&0x02) *fd = 0xf0;\r
- if (fd8x8&0x01) *fd |= 0x0f; fd++;\r
+ if (fd8x8&0x80) { *fd = 0xf0; }\r
+ if (fd8x8&0x40) { *fd |= 0x0f; }; fd++;\r
+ if (fd8x8&0x20) { *fd = 0xf0; }\r
+ if (fd8x8&0x10) { *fd |= 0x0f; }; fd++;\r
+ if (fd8x8&0x08) { *fd = 0xf0; }\r
+ if (fd8x8&0x04) { *fd |= 0x0f; }; fd++;\r
+ if (fd8x8&0x02) { *fd = 0xf0; }\r
+ if (fd8x8&0x01) { *fd |= 0x0f; }; fd++;\r
}\r
fd += 8*2/2; // 2 empty lines\r
}\r
ymax = g_menuscreen_h - 1;\r
\r
for (x = xmin; x <= xmax; x++)\r
- screen[y * g_menuscreen_w + x] = 0xa514;\r
+ screen[y * g_menuscreen_pp + x] = 0xa514;\r
for (y++; y < ymax; y++)\r
{\r
- ls = y * g_menuscreen_w;\r
+ ls = y * g_menuscreen_pp;\r
screen[ls + xmin] = 0xffff;\r
for (x = xmin + 1; x < xmax; x++)\r
{\r
}\r
screen[ls + xmax] = 0xffff;\r
}\r
- ls = y * g_menuscreen_w;\r
+ ls = y * g_menuscreen_pp;\r
for (x = xmin; x <= xmax; x++)\r
screen[ls + x] = 0xffff;\r
}\r
\r
static void menu_draw_begin(int need_bg, int no_borders)\r
{\r
+ int y;\r
+\r
plat_video_menu_begin();\r
\r
menu_reset_borders();\r
\r
if (need_bg) {\r
if (g_border_style && no_borders) {\r
- menu_darken_bg(g_menuscreen_ptr, g_menubg_ptr,\r
- g_menuscreen_w * g_menuscreen_h, 1);\r
+ for (y = 0; y < g_menuscreen_h; y++)\r
+ menu_darken_bg((short *)g_menuscreen_ptr + g_menuscreen_pp * y,\r
+ (short *)g_menubg_ptr + g_menuscreen_w * y, g_menuscreen_w, 1);\r
}\r
else {\r
- memcpy(g_menuscreen_ptr, g_menubg_ptr,\r
- g_menuscreen_w * g_menuscreen_h * 2);\r
+ for (y = 0; y < g_menuscreen_h; y++)\r
+ memcpy((short *)g_menuscreen_ptr + g_menuscreen_pp * y,\r
+ (short *)g_menubg_ptr + g_menuscreen_w * y, g_menuscreen_w * 2);\r
}\r
}\r
}\r
\r
static unsigned int me_read_onoff(const menu_entry *ent)\r
{\r
- // guess var size based on mask to avoid reading too much\r
- if (ent->mask & 0xffff0000)\r
- return *(unsigned int *)ent->var & ent->mask;\r
- else if (ent->mask & 0xff00)\r
- return *(unsigned short *)ent->var & ent->mask;\r
- else\r
- return *(unsigned char *)ent->var & ent->mask;\r
+ return *(unsigned int *)ent->var & ent->mask;\r
}\r
\r
static void me_toggle_onoff(menu_entry *ent)\r
{\r
- // guess var size based on mask to avoid reading too much\r
- if (ent->mask & 0xffff0000)\r
- *(unsigned int *)ent->var ^= ent->mask;\r
- else if (ent->mask & 0xff00)\r
- *(unsigned short *)ent->var ^= ent->mask;\r
- else\r
- *(unsigned char *)ent->var ^= ent->mask;\r
+ *(unsigned int *)ent->var ^= ent->mask;\r
}\r
\r
static void me_draw(const menu_entry *entries, int sel, void (*draw_more)(void))\r
name = ent->generate_name(ent->id, &offs);\r
}\r
if (name != NULL) {\r
- text_out16(x, y, name);\r
+ text_out16(x, y, "%s", name);\r
leftname_end = x + (strlen(name) + 1) * me_mfont_w;\r
}\r
\r
case MB_NONE:\r
break;\r
case MB_OPT_ONOFF:\r
- text_out16(x + col2_offs, y, me_read_onoff(ent) ? "ON" : "OFF");\r
+ text_out16(x + col2_offs, y, "%s", me_read_onoff(ent) ? "ON" : "OFF");\r
break;\r
case MB_OPT_RANGE:\r
text_out16(x + col2_offs, y, "%i", *(int *)ent->var);\r
offs = x + col2_offs;\r
len = strlen(names[i]);\r
if (len > 10)\r
- offs += (10 - len - 2) * me_mfont_w;\r
+ offs += (10 - len) * me_mfont_w;\r
if (offs < leftname_end)\r
offs = leftname_end;\r
- if (i == *(unsigned char *)ent->var) {\r
+ if (i == *(int *)ent->var) {\r
text_out16(offs, y, "%s", names[i]);\r
break;\r
}\r
h = (g_menuscreen_h - h) / 2; // bottom area height\r
if (menu_error_msg[0] != 0) {\r
if (h >= me_mfont_h + 4)\r
- text_out16(5, g_menuscreen_h - me_mfont_h - 4, menu_error_msg);\r
+ text_out16(5, g_menuscreen_h - me_mfont_h - 4, "%s", menu_error_msg);\r
else\r
lprintf("menu msg doesn't fit!\n");\r
\r
names = (const char **)entry->data;\r
for (c = 0; names[c] != NULL; c++)\r
;\r
- *(signed char *)entry->var += is_next ? 1 : -1;\r
- if (*(signed char *)entry->var < 0)\r
- *(signed char *)entry->var = 0;\r
- if (*(signed char *)entry->var >= c)\r
- *(signed char *)entry->var = c - 1;\r
+ *(int *)entry->var += is_next ? 1 : -1;\r
+ if (*(int *)entry->var < 0)\r
+ *(int *)entry->var = 0;\r
+ if (*(int *)entry->var >= c)\r
+ *(int *)entry->var = c - 1;\r
return 1;\r
default:\r
return 0;\r
menu_draw_begin(1, 0);\r
\r
for (p = msg; *p != 0 && y <= g_menuscreen_h - me_mfont_h; y += me_mfont_h) {\r
- text_out16(x, y, p);\r
+ text_out16(x, y, "%s", p);\r
\r
for (; *p != 0 && *p != '\n'; p++)\r
;\r
snprintf(tmp + len, sizeof(tmp) - len, "%s - cancel)", nm);\r
len = strlen(tmp);\r
\r
- text_out16(mid - me_mfont_w * len / 2, 12 * me_mfont_h, tmp);\r
+ text_out16(mid - me_mfont_w * len / 2, 12 * me_mfont_h, "%s", tmp);\r
menu_draw_end();\r
\r
while (in_menu_wait_any(NULL, 50) & (PBTN_MENU|PBTN_MA2));\r
\r
max_cnt = g_menuscreen_h / me_sfont_h;\r
start = max_cnt / 2 - sel;\r
- n--; // exclude current dir (".")\r
\r
menu_draw_begin(1, 1);\r
\r
// if (!rom_loaded)\r
// menu_darken_bg(gp2x_screen, 320*240, 0);\r
\r
- darken_ptr = (short *)g_menuscreen_ptr + g_menuscreen_w * max_cnt/2 * me_sfont_h;\r
- menu_darken_bg(darken_ptr, darken_ptr, g_menuscreen_w * me_sfont_h * 8 / 10, 0);\r
+ darken_ptr = (short *)g_menuscreen_ptr + g_menuscreen_pp * max_cnt/2 * me_sfont_h;\r
+ menu_darken_bg(darken_ptr, darken_ptr, g_menuscreen_pp * me_sfont_h * 8 / 10, 0);\r
\r
x = 5 + me_mfont_w + 1;\r
if (start - 2 >= 0)\r
pos = start + i;\r
if (pos < 0) continue;\r
if (pos >= max_cnt) break;\r
- if (namelist[i+1]->d_type == DT_DIR) {\r
+ if (namelist[i]->d_type == DT_DIR) {\r
smalltext_out16(x, pos * me_sfont_h, "/", 0xfff6);\r
- smalltext_out16(x + me_sfont_w, pos * me_sfont_h, namelist[i+1]->d_name, 0xfff6);\r
+ smalltext_out16(x + me_sfont_w, pos * me_sfont_h, namelist[i]->d_name, 0xfff6);\r
} else {\r
- unsigned short color = fname2color(namelist[i+1]->d_name);\r
- smalltext_out16(x, pos * me_sfont_h, namelist[i+1]->d_name, color);\r
+ unsigned short color = fname2color(namelist[i]->d_name);\r
+ smalltext_out16(x, pos * me_sfont_h, namelist[i]->d_name, color);\r
}\r
}\r
smalltext_out16(5, max_cnt/2 * me_sfont_h, ">", 0xffff);\r
\r
if (show_help) {\r
darken_ptr = (short *)g_menuscreen_ptr\r
- + g_menuscreen_w * (g_menuscreen_h - me_sfont_h * 5 / 2);\r
+ + g_menuscreen_pp * (g_menuscreen_h - me_sfont_h * 5 / 2);\r
menu_darken_bg(darken_ptr, darken_ptr,\r
- g_menuscreen_w * (me_sfont_h * 5 / 2), 1);\r
+ g_menuscreen_pp * (me_sfont_h * 5 / 2), 1);\r
\r
snprintf(buff, sizeof(buff), "%s - select, %s - back",\r
in_get_key_name(-1, -PBTN_MOK), in_get_key_name(-1, -PBTN_MBACK));\r
{\r
const struct dirent **d1 = (const struct dirent **)p1;\r
const struct dirent **d2 = (const struct dirent **)p2;\r
+ const char *p;\r
+ if ((p = (*d1)->d_name)[0] == '.' && p[1] == '.' && p[2] == 0)\r
+ return -1; // ".." first\r
+ if ((p = (*d2)->d_name)[0] == '.' && p[1] == '.' && p[2] == 0)\r
+ return 1;\r
if ((*d1)->d_type == (*d2)->d_type)\r
return alphasort(d1, d2);\r
if ((*d1)->d_type == DT_DIR)\r
- return -1; // put before\r
+ return -1; // directories before files/links\r
if ((*d2)->d_type == DT_DIR)\r
return 1;\r
\r
const char *ext;\r
int i;\r
\r
- if (ent == NULL || ent->d_name == NULL)\r
+ if (ent == NULL)\r
return 0;\r
\r
- if (ent->d_type == DT_DIR)\r
+ switch (ent->d_type) {\r
+ case DT_DIR:\r
+ // leave out useless reference to current directory\r
+ return strcmp(ent->d_name, ".") != 0;\r
+ case DT_LNK:\r
+ case DT_UNKNOWN:\r
+ // could be a dir, deal with it later..\r
return 1;\r
+ }\r
\r
ext = strrchr(ent->d_name, '.');\r
if (ext == NULL)\r
{\r
int i;\r
\r
- sel++;\r
for (i = sel + 1; ; i++) {\r
if (i >= len)\r
- i = 1;\r
+ i = 0;\r
if (i == sel)\r
break;\r
\r
break;\r
}\r
\r
- return i - 1;\r
+ return i;\r
}\r
\r
-static const char *menu_loop_romsel(char *curr_path, int len,\r
+static const char *menu_loop_romsel_d(char *curr_path, int len,\r
const char **filter_exts,\r
int (*extra_filter)(struct dirent **namelist, int count,\r
- const char *basedir))\r
+ const char *basedir),\r
+ void (*draw_prep)(void))\r
{\r
- static char rom_fname_reload[256]; // used for return\r
+ static char rom_fname_reload[256]; // used for scratch and return\r
char sel_fname[256];\r
int (*filter)(const struct dirent *);\r
struct dirent **namelist = NULL;\r
char *curr_path_restore = NULL;\r
const char *ret = NULL;\r
char cinp;\r
+ int r, i;\r
\r
filter_exts_internal = filter_exts;\r
sel_fname[0] = 0;\r
curr_path_restore = p;\r
snprintf(sel_fname, sizeof(sel_fname), "%s", p + 1);\r
}\r
-\r
- if (rom_fname_reload[0] == 0)\r
- show_help = 2;\r
}\r
+ show_help = 2;\r
\r
rescan:\r
if (namelist != NULL) {\r
+ n += !n;\r
while (n-- > 0)\r
free(namelist[n]);\r
free(namelist);\r
filter = scandir_filter;\r
\r
n = scandir(curr_path, &namelist, filter, (void *)scandir_cmp);\r
- if (n < 0) {\r
- char *t;\r
+ if (n < 0 || !namelist) {\r
lprintf("menu_loop_romsel failed, dir: %s\n", curr_path);\r
\r
- // try root\r
- t = getcwd(curr_path, len);\r
- if (t == NULL)\r
- plat_get_root_dir(curr_path, len);\r
+ // try data root\r
+ plat_get_data_dir(curr_path, len);\r
n = scandir(curr_path, &namelist, filter, (void *)scandir_cmp);\r
- if (n < 0) {\r
+ if (n < 0 || !namelist) {\r
// oops, we failed\r
lprintf("menu_loop_romsel failed, dir: %s\n", curr_path);\r
- return NULL;\r
+ namelist = malloc(sizeof(*namelist));\r
+ namelist[0] = calloc(1, sizeof(**namelist));\r
+ }\r
+ }\r
+\r
+ // try to resolve DT_UNKNOWN and symlinks\r
+ for (i = 0; i < n; i++) {\r
+ struct stat st;\r
+ char *slash;\r
+\r
+ if (namelist[i]->d_type == DT_REG || namelist[i]->d_type == DT_DIR)\r
+ continue;\r
+\r
+ r = strlen(curr_path);\r
+ slash = (r && curr_path[r-1] == '/') ? "" : "/";\r
+ snprintf(rom_fname_reload, sizeof(rom_fname_reload),\r
+ "%s%s%s", curr_path, slash, namelist[i]->d_name);\r
+ r = stat(rom_fname_reload, &st);\r
+ if (r == 0)\r
+ {\r
+ if (S_ISREG(st.st_mode))\r
+ namelist[i]->d_type = DT_REG;\r
+ else if (S_ISDIR(st.st_mode))\r
+ namelist[i]->d_type = DT_DIR;\r
}\r
}\r
\r
if (!g_menu_filter_off && extra_filter != NULL)\r
n = extra_filter(namelist, n, curr_path);\r
\r
+ if (n > 1)\r
+ qsort(namelist, n, sizeof(namelist[0]), scandir_cmp);\r
+\r
// try to find selected file\r
- // note: we don't show '.' so sel is namelist index - 1\r
sel = 0;\r
if (sel_fname[0] != 0) {\r
- int i;\r
- for (i = 1; i < n; i++) {\r
+ for (i = 0; i < n; i++) {\r
char *dname = namelist[i]->d_name;\r
if (dname[0] == sel_fname[0] && strcmp(dname, sel_fname) == 0) {\r
- sel = i - 1;\r
+ sel = i;\r
break;\r
}\r
}\r
\r
for (;;)\r
{\r
+ if (draw_prep != NULL)\r
+ draw_prep();\r
draw_dirlist(curr_path, namelist, n, sel, show_help);\r
inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT\r
| PBTN_L|PBTN_R|PBTN_MA2|PBTN_MA3|PBTN_MOK|PBTN_MBACK\r
if (inp & PBTN_MA3) {\r
g_menu_filter_off = !g_menu_filter_off;\r
snprintf(sel_fname, sizeof(sel_fname), "%s",\r
- namelist[sel+1]->d_name);\r
+ namelist[sel]->d_name);\r
+ show_help = 2;\r
goto rescan;\r
}\r
- if (inp & PBTN_UP ) { sel--; if (sel < 0) sel = n-2; }\r
- if (inp & PBTN_DOWN) { sel++; if (sel > n-2) sel = 0; }\r
- if (inp & PBTN_LEFT) { sel-=10; if (sel < 0) sel = 0; }\r
- if (inp & PBTN_L) { sel-=24; if (sel < 0) sel = 0; }\r
- if (inp & PBTN_RIGHT) { sel+=10; if (sel > n-2) sel = n-2; }\r
- if (inp & PBTN_R) { sel+=24; if (sel > n-2) sel = n-2; }\r
-\r
- if ((inp & PBTN_MOK) || (inp & (PBTN_MENU|PBTN_MA2)) == (PBTN_MENU|PBTN_MA2))\r
+ int last = n ? n-1 : 0;\r
+ if (inp & PBTN_UP ) { sel--; if (sel < 0) sel = last; }\r
+ else if (inp & PBTN_DOWN) { sel++; if (sel > n-1) sel = 0; }\r
+ else if (inp & PBTN_LEFT) { sel-=10; if (sel < 0) sel = 0; }\r
+ else if (inp & PBTN_RIGHT) { sel+=10; if (sel > n-1) sel = last; }\r
+ else if (inp & PBTN_L) { sel-=24; if (sel < 0) sel = 0; }\r
+ else if (inp & PBTN_R) { sel+=24; if (sel > n-1) sel = last; }\r
+\r
+ else if ((inp & PBTN_MOK) || (inp & (PBTN_MENU|PBTN_MA2)) == (PBTN_MENU|PBTN_MA2))\r
{\r
- again:\r
- if (namelist[sel+1]->d_type == DT_REG)\r
+ if (namelist[sel]->d_type == DT_REG)\r
{\r
+ int l = strlen(curr_path);\r
+ char *slash = l && curr_path[l-1] == '/' ? "" : "/";\r
snprintf(rom_fname_reload, sizeof(rom_fname_reload),\r
- "%s/%s", curr_path, namelist[sel+1]->d_name);\r
+ "%s%s%s", curr_path, slash, namelist[sel]->d_name);\r
if (inp & PBTN_MOK) { // return sel\r
ret = rom_fname_reload;\r
break;\r
}\r
- do_delete(rom_fname_reload, namelist[sel+1]->d_name);\r
+ do_delete(rom_fname_reload, namelist[sel]->d_name);\r
goto rescan;\r
}\r
- else if (namelist[sel+1]->d_type == DT_DIR)\r
+ else if (namelist[sel]->d_type == DT_DIR)\r
{\r
int newlen;\r
char *p, *newdir;\r
if (!(inp & PBTN_MOK))\r
continue;\r
- newlen = strlen(curr_path) + strlen(namelist[sel+1]->d_name) + 2;\r
+ newlen = strlen(curr_path) + strlen(namelist[sel]->d_name) + 2;\r
newdir = malloc(newlen);\r
if (newdir == NULL)\r
break;\r
- if (strcmp(namelist[sel+1]->d_name, "..") == 0) {\r
+ if (strcmp(namelist[sel]->d_name, "..") == 0) {\r
char *start = curr_path;\r
p = start + strlen(start) - 1;\r
while (*p == '/' && p > start) p--;\r
while (*p != '/' && p > start) p--;\r
- if (p <= start) strcpy(newdir, "/");\r
+ if (p <= start) plat_get_data_dir(newdir, newlen);\r
else { strncpy(newdir, start, p-start); newdir[p-start] = 0; }\r
} else {\r
strcpy(newdir, curr_path);\r
p = newdir + strlen(newdir) - 1;\r
while (*p == '/' && p >= newdir) *p-- = 0;\r
strcat(newdir, "/");\r
- strcat(newdir, namelist[sel+1]->d_name);\r
+ strcat(newdir, namelist[sel]->d_name);\r
}\r
- ret = menu_loop_romsel(newdir, newlen, filter_exts, extra_filter);\r
+ ret = menu_loop_romsel_d(newdir, newlen, filter_exts, extra_filter, draw_prep);\r
free(newdir);\r
break;\r
}\r
- else\r
- {\r
- // unknown file type, happens on NTFS mounts. Try to guess.\r
- FILE *tstf; int tmp;\r
- snprintf(rom_fname_reload, sizeof(rom_fname_reload),\r
- "%s/%s", curr_path, namelist[sel+1]->d_name);\r
- tstf = fopen(rom_fname_reload, "rb");\r
- if (tstf != NULL)\r
- {\r
- if (fread(&tmp, 1, 1, tstf) > 0 || ferror(tstf) == 0)\r
- namelist[sel+1]->d_type = DT_REG;\r
- else namelist[sel+1]->d_type = DT_DIR;\r
- fclose(tstf);\r
- goto again;\r
- }\r
- }\r
}\r
else if (inp & PBTN_MA2) {\r
g_autostateld_opt = !g_autostateld_opt;\r
return ret;\r
}\r
\r
+static const char *menu_loop_romsel(char *curr_path, int len,\r
+ const char **filter_exts,\r
+ int (*extra_filter)(struct dirent **namelist, int count,\r
+ const char *basedir))\r
+{\r
+ return menu_loop_romsel_d(curr_path, len, filter_exts, extra_filter, NULL);\r
+}\r
+\r
// ------------ savestate loader ------------\r
\r
#define STATE_SLOT_COUNT 10\r
type = IN_BINDTYPE_EMU;\r
if (player_idx >= 0) {\r
can_combo = 0;\r
- type = IN_BINDTYPE_PLAYER12;\r
+ type = IN_BINDTYPE_PLAYER12 + (player_idx >> 1);\r
+ if (player_idx & 1)\r
+ action_mask <<= 16;\r
}\r
- if (player_idx == 1)\r
- action_mask <<= 16;\r
\r
if (dev_id >= 0)\r
dev = dev_last = dev_id;\r
y = (g_menuscreen_h - 4 * me_mfont_h) / 2 - (2 + opt_cnt) * me_mfont_h / 2;\r
if (x < me_mfont_w * 2)\r
x = me_mfont_w * 2;\r
-\r
+ if (y < 0)\r
+ y = 0;\r
menu_draw_begin(1, 0);\r
if (player_idx >= 0)\r
text_out16(x, y, "Player %i controls", player_idx + 1);\r
snprintf(buff2, sizeof(buff2), "%s", in_get_key_name(-1, -PBTN_MOK));\r
snprintf(buff, sizeof(buff), "%s - bind, %s - clear", buff2,\r
in_get_key_name(-1, -PBTN_MA2));\r
- text_out16(x, g_menuscreen_h - 4 * me_mfont_h, buff);\r
+ text_out16(x, g_menuscreen_h - 4 * me_mfont_h, "%s", buff);\r
}\r
else\r
text_out16(x, g_menuscreen_h - 4 * me_mfont_h, "Press a button to bind/unbind");\r
\r
if (dev_count > 1) {\r
- text_out16(x, g_menuscreen_h - 3 * me_mfont_h, dev_name);\r
+ text_out16(x, g_menuscreen_h - 3 * me_mfont_h, "%s", dev_name);\r
text_out16(x, g_menuscreen_h - 2 * me_mfont_h, "Press left/right for other devs");\r
}\r
\r
\r
dev_id = -1; // show all\r
mask_shift = 0;\r
- if (player_idx == 1)\r
- mask_shift = 16;\r
- bindtype = player_idx >= 0 ? IN_BINDTYPE_PLAYER12 : IN_BINDTYPE_EMU;\r
+ if (player_idx >= 0) {\r
+ if (player_idx & 1)\r
+ mask_shift = 16;\r
+ bindtype = IN_BINDTYPE_PLAYER12 + (player_idx >> 1);\r
+ } else\r
+ bindtype = IN_BINDTYPE_EMU;\r
\r
for (;;)\r
{\r
in_unbind_all(bind_dev_id, opts[sel].mask << mask_shift, bindtype);\r
\r
in_bind_key(bind_dev_id, kc, opts[sel].mask << mask_shift, bindtype, 0);\r
+\r
+ // make sure bind change is displayed\r
+ if (dev_id != -1)\r
+ dev_id = bind_dev_id;\r
}\r
}\r
\r