Play Station >> PCSX RaARMed

支援中文檔名(倚天字型)


程式如下:

diff -Naur old/frontend/libpicofe/menu.c new/frontend/libpicofe/menu.c
--- old/frontend/libpicofe/menu.c  2019-11-08 05:37:33.854980903 -0500
+++ new/frontend/libpicofe/menu.c  2019-11-08 05:35:51.902532050 -0500
@@ -15,7 +15,9 @@
 #include <stdarg.h>
 #include <time.h>
 #include <locale.h> // savestate date
+#include <iconv.h>
 
+#include "big5font.h"
 #include "menu.h"
 #include "fonts.h"
 #include "readpng.h"
@@ -24,6 +26,9 @@
 #include "plat.h"
 #include "posix.h"
 
+extern iconv_t cd;
+extern uint8_t big5font[];
+
 static char static_buff[64];
 static int  menu_error_time = 0;
 char menu_error_msg[64] = { 0, };
@@ -56,1126 +61,1176 @@
 // 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;
-  tr = (color & 0xf800) >> 8;
-  tg = (color & 0x07e0) >> 3;
-  tb = (color & 0x001f) << 3;
-
-  if (text == (void *)1)
-  {
-    // selector symbol
-    text = "";
-    len = 1;
-  }
-  else
-  {
-    const char *p;
-    for (p = text; *p != 0 && *p != '\n'; p++)
-      ;
-    len = p - text;
-  }
-
-  lh = me_mfont_h;
-  if (y + lh > g_menuscreen_h)
-    lh = g_menuscreen_h - y;
-
-  for (i = 0; i < len; i++)
-  {
-    unsigned char  *src = menu_font_data + (unsigned int)text[i] * me_mfont_w * me_mfont_h / 2;
-    unsigned short *dst = dest;
-    int u, l;
-
-    for (l = 0; l < lh; l++, dst += g_menuscreen_w - me_mfont_w)
-    {
-      for (u = me_mfont_w / 2; u > 0; u--, src++)
-      {
-        int c, r, g, b;
-        c = *src >> 4;
-        r = (*dst & 0xf800) >> 8;
-        g = (*dst & 0x07e0) >> 3;
-        b = (*dst & 0x001f) << 3;
-        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);
-        c = *src & 0xf;
-        r = (*dst & 0xf800) >> 8;
-        g = (*dst & 0x07e0) >> 3;
-        b = (*dst & 0x001f) << 3;
-        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);
-      }
-    }
-    dest += me_mfont_w;
-  }
-
-  if (x < border_left)
-    border_left = x;
-  if (x + i * me_mfont_w > border_right)
-    border_right = x + i * me_mfont_w;
-  if (y < border_top)
-    border_top = y;
-  if (y + me_mfont_h > border_bottom)
-    border_bottom = y + me_mfont_h;
+  int i, lh, tr, tg, tb, len;
+  unsigned short *dest = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_w;
+  tr = (color & 0xf800) >> 8;
+  tg = (color & 0x07e0) >> 3;
+  tb = (color & 0x001f) << 3;
+
+  if (text == (void *)1)
+  {
+    // selector symbol
+    text = "";
+    len = 1;
+  }
+  else
+  {
+    const char *p;
+    for (p = text; *p != 0 && *p != '\n'; p++)
+      ;
+    len = p - text;
+  }
+
+  lh = me_mfont_h;
+  if (y + lh > g_menuscreen_h)
+    lh = g_menuscreen_h - y;
+
+  for (i = 0; i < len; i++)
+  {
+    unsigned char  *src = menu_font_data + (unsigned int)text[i] * me_mfont_w * me_mfont_h / 2;
+    unsigned short *dst = dest;
+    int u, l;
+
+    for (l = 0; l < lh; l++, dst += g_menuscreen_w - me_mfont_w)
+    {
+      for (u = me_mfont_w / 2; u > 0; u--, src++)
+      {
+        int c, r, g, b;
+        c = *src >> 4;
+        r = (*dst & 0xf800) >> 8;
+        g = (*dst & 0x07e0) >> 3;
+        b = (*dst & 0x001f) << 3;
+        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);
+        c = *src & 0xf;
+        r = (*dst & 0xf800) >> 8;
+        g = (*dst & 0x07e0) >> 3;
+        b = (*dst & 0x001f) << 3;
+        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);
+      }
+    }
+    dest += me_mfont_w;
+  }
+
+  if (x < border_left)
+    border_left = x;
+  if (x + i * me_mfont_w > border_right)
+    border_right = x + i * me_mfont_w;
+  if (y < border_top)
+    border_top = y;
+  if (y + me_mfont_h > border_bottom)
+    border_bottom = y + me_mfont_h;
 }
 
 void text_out16(int x, int y, const char *texto, ...)
 {
-  va_list args;
-  char    buffer[256];
-  int     maxw = (g_menuscreen_w - x) / me_mfont_w;
-
-  if (maxw < 0)
-    return;
-
-  va_start(args, texto);
-  vsnprintf(buffer, sizeof(buffer), texto, args);
-  va_end(args);
-
-  if (maxw > sizeof(buffer) - 1)
-    maxw = sizeof(buffer) - 1;
-  buffer[maxw] = 0;
+  va_list args;
+  char    buffer[256];
+  int     maxw = (g_menuscreen_w - x) / me_mfont_w;
+
+  if (maxw < 0)
+    return;
+
+  va_start(args, texto);
+  vsnprintf(buffer, sizeof(buffer), texto, args);
+  va_end(args);
+
+  if (maxw > sizeof(buffer) - 1)
+    maxw = sizeof(buffer) - 1;
+  buffer[maxw] = 0;
 
-  text_out16_(x,y,buffer,menu_text_color);
+  text_out16_(x,y,buffer,menu_text_color);
 }
 
 /* draws in 6x8 font, might multiply size by integer */
 static void smalltext_out16_(int x, int y, const char *texto, int color)
 {
-  unsigned char  *src;
-  unsigned short *dst;
-  int multiplier = me_sfont_w / 6;
-  int i;
-
-  for (i = 0;; i++, x += me_sfont_w)
-  {
-    unsigned char c = (unsigned char) texto[i];
-    int h = 8;
-
-    if (!c || c == '\n')
-      break;
-
-    src = fontdata6x8[c];
-    dst = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_w;
-
-    while (h--)
-    {
-      int m, w2, h2;
-      for (h2 = multiplier; h2 > 0; h2--)
-      {
-        for (m = 0x20; m; m >>= 1) {
-          if (*src & m)
-            for (w2 = multiplier; w2 > 0; w2--)
+  unsigned char  *src;
+  unsigned short *dst;
+  int i, multiplier = me_sfont_w / 6, acc_x=0;
+
+  for (i = 0;; i++, x += me_sfont_w)
+  {
+    unsigned char c = (unsigned char) texto[i];
+    int h = 8;
+
+    if (!c || c == '\n')
+      break;
+   
+    if(c < 0x80){
+      src = fontdata6x8[c];
+      dst = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_w + acc_x;
+
+      while (h--)
+      {
+        int m, w2, h2;
+        for (h2 = multiplier; h2 > 0; h2--)
+        {
+          for (m = 0x20; m; m >>= 1) {
+            if (*src & m)
+              for (w2 = multiplier; w2 > 0; w2--)
+                *dst++ = color;
+            else
+              dst += multiplier;
+          }
+
+          dst += g_menuscreen_w - me_sfont_w;
+        }
+        src++;
+      }
+    }
+    else{
+      char *sin;
+      char *sout;
+      size_t in_len=0;
+      size_t out_len=0;
+      char in_buf[4]={0};
+      char out_buf[4]={0};
+      unsigned int high, low;
+      unsigned char top[30]={0};
+
+      in_buf[0] = texto[i++];
+      in_buf[1] = texto[i++];
+      in_buf[2] = texto[i];
+      sin = in_buf;
+      sout = out_buf;
+      in_len = 3;
+      out_len = sizeof(out_buf);
+      memset(out_buf, 0, out_len);
+      iconv(cd, &sin, &in_len, &sout, &out_len);
+      low = (unsigned char)out_buf[1];
+      high = 157 * (unsigned char)((unsigned char)out_buf[0] - 164);
+      if(low < 127){
+        low-= 64;
+      }
+      else{
+        low-= 98;
+      }
+      memcpy(top, &big5font[(high + low) * 30], 30);
+      dst = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_w + acc_x;
+
+      int x, y, z, t, cnt=0;
+      for(y=0; y<15;y++){
+        for(z=0; z<2;z++){
+          t = top[cnt++];
+          for(x=0; x<8;x++){
+            if(t & 0x80){
               *dst++ = color;
-          else
-            dst += multiplier;
+            }
+            else{
+              dst+= 1;
+            }
+            t<<=1;
+          }
         }
-
-        dst += g_menuscreen_w - me_sfont_w;
+        dst += g_menuscreen_w - 16;
       }
-      src++;
-    }
-  }
+      acc_x+= (16 - me_sfont_w);
+    }
+  }
 }
 
 static void smalltext_out16(int x, int y, const char *texto, int color)
 {
-  char buffer[128];
-  int maxw = (g_menuscreen_w - x) / me_sfont_w;
+  char buffer[128];
+  int maxw = (g_menuscreen_w - x) / me_sfont_w;
 
-  if (maxw < 0)
-    return;
+  if (maxw < 0)
+    return;
 
-  strncpy(buffer, texto, sizeof(buffer));
-  if (maxw > sizeof(buffer) - 1)
-    maxw = sizeof(buffer) - 1;
-  buffer[maxw] = 0;
+  strncpy(buffer, texto, sizeof(buffer));
+  if (maxw > sizeof(buffer) - 1)
+    maxw = sizeof(buffer) - 1;
+  buffer[maxw] = 0;
 
-  smalltext_out16_(x, y, buffer, color);
+  smalltext_out16_(x, y, buffer, color);
 }
 
 static void menu_draw_selection(int x, int y, int w)
 {
-  int i, h;
-  unsigned short *dst, *dest;
+  int i, h;
+  unsigned short *dst, *dest;
 
-  text_out16_(x, y, (void *)1, (menu_sel_color < 0) ? menu_text_color : menu_sel_color);
+  text_out16_(x, y, (void *)1, (menu_sel_color < 0) ? menu_text_color : menu_sel_color);
 
-  if (menu_sel_color < 0) return; // no selection hilight
+  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;
-  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;
-  }
+  if (y > 0) y--;
+  dest = (unsigned short *)g_menuscreen_ptr + x + y * g_menuscreen_w + 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;
+  }
 }
 
 static int parse_hex_color(char *buff)
 {
-  char *endp = buff;
-  int t = (int) strtoul(buff, &endp, 16);
-  if (endp != 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);
+    return ((t<<8)&0xf800) | ((t>>5)&0x07e0) | ((t>>19)&0x1f);
 #else
-    return ((t>>8)&0xf800) | ((t>>5)&0x07e0) | ((t>>3)&0x1f);
+    return ((t>>8)&0xf800) | ((t>>5)&0x07e0) | ((t>>3)&0x1f);
 #endif
-  return -1;
+  return -1;
 }
 
 static char tolower_simple(char c)
 {
-  if ('A' <= c && c <= 'Z')
-    c = c - 'A' + 'a';
-  return c;
+  if ('A' <= c && c <= 'Z')
+    c = c - 'A' + 'a';
+  return c;
 }
 
 void menu_init_base(void)
 {
-  int i, c, l, pos;
-  unsigned char *fd, *fds;
-  char buff[256];
-  FILE *f;
-
-  if (menu_font_data != NULL)
-    free(menu_font_data);
-
-  menu_font_data = calloc((MENU_X2 ? 256 * 320 : 128 * 160) / 2, 1);
-  if (menu_font_data == NULL)
-    return;
-
-  // generate default 8x10 font from fontdata8x8
-  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++;
-    }
-    fd += 8*2/2; // 2 empty lines
-  }
-
-  if (MENU_X2) {
-    // expand default font
-    fds = menu_font_data + 128 * 160 / 2 - 4;
-    fd  = menu_font_data + 256 * 320 / 2 - 1;
-    for (c = 255; c >= 0; c--)
-    {
-      for (l = 9; l >= 0; l--, fds -= 4)
-      {
-        for (i = 3; i >= 0; i--) {
-          int px = fds[i] & 0x0f;
-          *fd-- = px | (px << 4);
-          px = (fds[i] >> 4) & 0x0f;
-          *fd-- = px | (px << 4);
-        }
-        for (i = 3; i >= 0; i--) {
-          int px = fds[i] & 0x0f;
-          *fd-- = px | (px << 4);
-          px = (fds[i] >> 4) & 0x0f;
-          *fd-- = px | (px << 4);
-        }
-      }
-    }
-  }
+  int i, c, l, pos;
+  unsigned char *fd, *fds;
+  char buff[256];
+  FILE *f;
+
+  if (menu_font_data != NULL)
+    free(menu_font_data);
+
+  menu_font_data = calloc((MENU_X2 ? 256 * 320 : 128 * 160) / 2, 1);
+  if (menu_font_data == NULL)
+    return;
+
+  // generate default 8x10 font from fontdata8x8
+  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++;
+    }
+    fd += 8*2/2; // 2 empty lines
+  }
+
+  if (MENU_X2) {
+    // expand default font
+    fds = menu_font_data + 128 * 160 / 2 - 4;
+    fd  = menu_font_data + 256 * 320 / 2 - 1;
+    for (c = 255; c >= 0; c--)
+    {
+      for (l = 9; l >= 0; l--, fds -= 4)
+      {
+        for (i = 3; i >= 0; i--) {
+          int px = fds[i] & 0x0f;
+          *fd-- = px | (px << 4);
+          px = (fds[i] >> 4) & 0x0f;
+          *fd-- = px | (px << 4);
+        }
+        for (i = 3; i >= 0; i--) {
+          int px = fds[i] & 0x0f;
+          *fd-- = px | (px << 4);
+          px = (fds[i] >> 4) & 0x0f;
+          *fd-- = px | (px << 4);
+        }
+      }
+    }
+  }
+
+  // load custom font and selector (stored as 1st symbol in font table)
+  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);
+  strcpy(buff + pos, "selector.png");
+  readpng(menu_font_data, buff, READPNG_SELECTOR, me_mfont_w, me_mfont_h);
+
+  // load custom colors
+  strcpy(buff + pos, "skin.txt");
+  f = fopen(buff, "r");
+  if (f != NULL)
+  {
+    lprintf("found skin.txt\n");
+    while (!feof(f))
+    {
+      if (fgets(buff, sizeof(buff), f) == NULL)
+        break;
+      if (buff[0] == '#'  || buff[0] == '/')  continue; // comment
+      if (buff[0] == '\r' || buff[0] == '\n') continue; // empty line
+      if (strncmp(buff, "text_color=", 11) == 0)
+      {
+        int tmp = parse_hex_color(buff+11);
+        if (tmp >= 0) menu_text_color = tmp;
+        else lprintf("skin.txt: parse error for text_color\n");
+      }
+      else if (strncmp(buff, "selection_color=", 16) == 0)
+      {
+        int tmp = parse_hex_color(buff+16);
+        if (tmp >= 0) menu_sel_color = tmp;
+        else lprintf("skin.txt: parse error for selection_color\n");
+      }
+      else
+        lprintf("skin.txt: parse error: %s\n", buff);
+    }
+    fclose(f);
+  }
 
-  // load custom font and selector (stored as 1st symbol in font table)
-  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);
-  strcpy(buff + pos, "selector.png");
-  readpng(menu_font_data, buff, READPNG_SELECTOR, me_mfont_w, me_mfont_h);
-
-  // load custom colors
-  strcpy(buff + pos, "skin.txt");
-  f = fopen(buff, "r");
-  if (f != NULL)
-  {
-    lprintf("found skin.txt\n");
-    while (!feof(f))
-    {
-      if (fgets(buff, sizeof(buff), f) == NULL)
-        break;
-      if (buff[0] == '#'  || buff[0] == '/')  continue; // comment
-      if (buff[0] == '\r' || buff[0] == '\n') continue; // empty line
-      if (strncmp(buff, "text_color=", 11) == 0)
-      {
-        int tmp = parse_hex_color(buff+11);
-        if (tmp >= 0) menu_text_color = tmp;
-        else lprintf("skin.txt: parse error for text_color\n");
-      }
-      else if (strncmp(buff, "selection_color=", 16) == 0)
-      {
-        int tmp = parse_hex_color(buff+16);
-        if (tmp >= 0) menu_sel_color = tmp;
-        else lprintf("skin.txt: parse error for selection_color\n");
-      }
-      else
-        lprintf("skin.txt: parse error: %s\n", buff);
-    }
-    fclose(f);
-  }
-
-  // use user's locale for savestate date display
-  setlocale(LC_TIME, "");
+  // use user's locale for savestate date display
+  setlocale(LC_TIME, "");
 }
 
 static void menu_darken_bg(void *dst, void *src, int pixels, int darker)
 {
-  unsigned int *dest = dst;
-  unsigned int *sorc = src;
-  pixels /= 2;
-  if (darker)
-  {
-    while (pixels--)
-    {
-      unsigned int p = *sorc++;
-      *dest++ = ((p&0xf79ef79e)>>1) - ((p&0xc618c618)>>3);
-    }
-  }
-  else
-  {
-    while (pixels--)
-    {
-      unsigned int p = *sorc++;
-      *dest++ = (p&0xf79ef79e)>>1;
-    }
-  }
+  unsigned int *dest = dst;
+  unsigned int *sorc = src;
+  pixels /= 2;
+  if (darker)
+  {
+    while (pixels--)
+    {
+      unsigned int p = *sorc++;
+      *dest++ = ((p&0xf79ef79e)>>1) - ((p&0xc618c618)>>3);
+    }
+  }
+  else
+  {
+    while (pixels--)
+    {
+      unsigned int p = *sorc++;
+      *dest++ = (p&0xf79ef79e)>>1;
+    }
+  }
 }
 
 static void menu_darken_text_bg(void)
 {
-  int x, y, xmin, xmax, ymax, ls;
-  unsigned short *screen = g_menuscreen_ptr;
+  int x, y, xmin, xmax, ymax, ls;
+  unsigned short *screen = g_menuscreen_ptr;
 
-  xmin = border_left - 3;
-  if (xmin < 0)
-    xmin = 0;
-  xmax = border_right + 2;
-  if (xmax > g_menuscreen_w - 1)
-    xmax = g_menuscreen_w - 1;
-
-  y = border_top - 3;
-  if (y < 0)
-    y = 0;
-  ymax = border_bottom + 2;
-  if (ymax > g_menuscreen_h - 1)
-    ymax = g_menuscreen_h - 1;
-
-  for (x = xmin; x <= xmax; x++)
-    screen[y * g_menuscreen_w + x] = 0xa514;
-  for (y++; y < ymax; y++)
-  {
-    ls = y * g_menuscreen_w;
-    screen[ls + xmin] = 0xffff;
-    for (x = xmin + 1; x < xmax; x++)
-    {
-      unsigned int p = screen[ls + x];
-      if (p != menu_text_color)
-        screen[ls + x] = ((p&0xf79e)>>1) - ((p&0xc618)>>3);
-    }
-    screen[ls + xmax] = 0xffff;
-  }
-  ls = y * g_menuscreen_w;
-  for (x = xmin; x <= xmax; x++)
-    screen[ls + x] = 0xffff;
+  xmin = border_left - 3;
+  if (xmin < 0)
+    xmin = 0;
+  xmax = border_right + 2;
+  if (xmax > g_menuscreen_w - 1)
+    xmax = g_menuscreen_w - 1;
+
+  y = border_top - 3;
+  if (y < 0)
+    y = 0;
+  ymax = border_bottom + 2;
+  if (ymax > g_menuscreen_h - 1)
+    ymax = g_menuscreen_h - 1;
+
+  for (x = xmin; x <= xmax; x++)
+    screen[y * g_menuscreen_w + x] = 0xa514;
+  for (y++; y < ymax; y++)
+  {
+    ls = y * g_menuscreen_w;
+    screen[ls + xmin] = 0xffff;
+    for (x = xmin + 1; x < xmax; x++)
+    {
+      unsigned int p = screen[ls + x];
+      if (p != menu_text_color)
+        screen[ls + x] = ((p&0xf79e)>>1) - ((p&0xc618)>>3);
+    }
+    screen[ls + xmax] = 0xffff;
+  }
+  ls = y * g_menuscreen_w;
+  for (x = xmin; x <= xmax; x++)
+    screen[ls + x] = 0xffff;
 }
 
 static int borders_pending;
 
 static void menu_reset_borders(void)
 {
-  border_left = g_menuscreen_w;
-  border_right = 0;
-  border_top = g_menuscreen_h;
-  border_bottom = 0;
+  border_left = g_menuscreen_w;
+  border_right = 0;
+  border_top = g_menuscreen_h;
+  border_bottom = 0;
 }
 
 static void menu_draw_begin(int need_bg, int no_borders)
 {
-  plat_video_menu_begin();
+  plat_video_menu_begin();
 
-  menu_reset_borders();
-  borders_pending = g_border_style && !no_borders;
+  menu_reset_borders();
+  borders_pending = g_border_style && !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);
-    }
-    else {
-      memcpy(g_menuscreen_ptr, g_menubg_ptr,
-        g_menuscreen_w * g_menuscreen_h * 2);
-    }
-  }
+  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);
+    }
+    else {
+      memcpy(g_menuscreen_ptr, g_menubg_ptr,
+        g_menuscreen_w * g_menuscreen_h * 2);
+    }
+  }
 }
 
 static void menu_draw_end(void)
 {
-  if (borders_pending)
-    menu_darken_text_bg();
-  plat_video_menu_end();
+  if (borders_pending)
+    menu_darken_text_bg();
+  plat_video_menu_end();
 }
 
 static void menu_separation(void)
 {
-  if (borders_pending) {
-    menu_darken_text_bg();
-    menu_reset_borders();
-  }
+  if (borders_pending) {
+    menu_darken_text_bg();
+    menu_reset_borders();
+  }
 }
 
 static int me_id2offset(const menu_entry *ent, menu_id id)
 {
-  int i;
-  for (i = 0; ent->name; ent++, i++)
-    if (ent->id == id) return i;
+  int i;
+  for (i = 0; ent->name; ent++, i++)
+    if (ent->id == id) return i;
 
-  lprintf("%s: id %i not found\n", __FUNCTION__, id);
-  return 0;
+  lprintf("%s: id %i not found\n", __FUNCTION__, id);
+  return 0;
 }
 
 static void me_enable(menu_entry *entries, menu_id id, int enable)
 {
-  int i = me_id2offset(entries, id);
-  entries[i].enabled = enable;
+  int i = me_id2offset(entries, id);
+  entries[i].enabled = enable;
 }
 
 static int me_count(const menu_entry *ent)
 {
-  int ret;
+  int ret;
 
-  for (ret = 0; ent->name; ent++, ret++)
-    ;
+  for (ret = 0; ent->name; ent++, ret++)
+    ;
 
-  return ret;
+  return ret;
 }
 
 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;
+  // 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;
 }
 
 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;
+  // 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;
 }
 
 static void me_draw(const menu_entry *entries, int sel, void (*draw_more)(void))
 {
-  const menu_entry *ent, *ent_sel = entries;
-  int x, y, w = 0, h = 0;
-  int offs, col2_offs = 27 * me_mfont_w;
-  int vi_sel_ln = 0;
-  const char *name;
-  int i, n;
-
-  /* calculate size of menu rect */
-  for (ent = entries, i = n = 0; ent->name; ent++, i++)
-  {
-    int wt;
-
-    if (!ent->enabled)
-      continue;
-
-    if (i == sel) {
-      ent_sel = ent;
-      vi_sel_ln = n;
-    }
-
-    name = NULL;
-    wt = strlen(ent->name) * me_mfont_w;
-    if (wt == 0 && ent->generate_name)
-      name = ent->generate_name(ent->id, &offs);
-    if (name != NULL)
-      wt = strlen(name) * me_mfont_w;
-
-    if (ent->beh != MB_NONE)
-    {
-      if (wt > col2_offs)
-        col2_offs = wt + me_mfont_w;
-      wt = col2_offs;
-
-      switch (ent->beh) {
-      case MB_NONE:
-        break;
-      case MB_OPT_ONOFF:
-      case MB_OPT_RANGE:
-        wt += me_mfont_w * 3;
-        break;
-      case MB_OPT_CUSTOM:
-      case MB_OPT_CUSTONOFF:
-      case MB_OPT_CUSTRANGE:
-        name = NULL;
-        offs = 0;
-        if (ent->generate_name != NULL)
-          name = ent->generate_name(ent->id, &offs);
-        if (name != NULL)
-          wt += (strlen(name) + offs) * me_mfont_w;
-        break;
-      case MB_OPT_ENUM:
-        wt += 10 * me_mfont_w;
-        break;
-      }
-    }
+  const menu_entry *ent, *ent_sel = entries;
+  int x, y, w = 0, h = 0;
+  int offs, col2_offs = 27 * me_mfont_w;
+  int vi_sel_ln = 0;
+  const char *name;
+  int i, n;
+
+  /* calculate size of menu rect */
+  for (ent = entries, i = n = 0; ent->name; ent++, i++)
+  {
+    int wt;
+
+    if (!ent->enabled)
+      continue;
+
+    if (i == sel) {
+      ent_sel = ent;
+      vi_sel_ln = n;
+    }
+
+    name = NULL;
+    wt = strlen(ent->name) * me_mfont_w;
+    if (wt == 0 && ent->generate_name)
+      name = ent->generate_name(ent->id, &offs);
+    if (name != NULL)
+      wt = strlen(name) * me_mfont_w;
+
+    if (ent->beh != MB_NONE)
+    {
+      if (wt > col2_offs)
+        col2_offs = wt + me_mfont_w;
+      wt = col2_offs;
+
+      switch (ent->beh) {
+      case MB_NONE:
+        break;
+      case MB_OPT_ONOFF:
+      case MB_OPT_RANGE:
+        wt += me_mfont_w * 3;
+        break;
+      case MB_OPT_CUSTOM:
+      case MB_OPT_CUSTONOFF:
+      case MB_OPT_CUSTRANGE:
+        name = NULL;
+        offs = 0;
+        if (ent->generate_name != NULL)
+          name = ent->generate_name(ent->id, &offs);
+        if (name != NULL)
+          wt += (strlen(name) + offs) * me_mfont_w;
+        break;
+      case MB_OPT_ENUM:
+        wt += 10 * me_mfont_w;
+        break;
+      }
+    }
+
+    if (wt > w)
+      w = wt;
+    n++;
+  }
+  h = n * me_mfont_h;
+  w += me_mfont_w * 2; /* selector */
+
+  if (w > g_menuscreen_w) {
+    lprintf("width %d > %d\n", w, g_menuscreen_w);
+    w = g_menuscreen_w;
+  }
+  if (h > g_menuscreen_h) {
+    lprintf("height %d > %d\n", w, g_menuscreen_h);
+    h = g_menuscreen_h;
+  }
 
-    if (wt > w)
-      w = wt;
-    n++;
-  }
-  h = n * me_mfont_h;
-  w += me_mfont_w * 2; /* selector */
-
-  if (w > g_menuscreen_w) {
-    lprintf("width %d > %d\n", w, g_menuscreen_w);
-    w = g_menuscreen_w;
-  }
-  if (h > g_menuscreen_h) {
-    lprintf("height %d > %d\n", w, g_menuscreen_h);
-    h = g_menuscreen_h;
-  }
-
-  x = g_menuscreen_w / 2 - w / 2;
-  y = g_menuscreen_h / 2 - h / 2;
+  x = g_menuscreen_w / 2 - w / 2;
+  y = g_menuscreen_h / 2 - h / 2;
 #ifdef MENU_ALIGN_LEFT
-  if (x > 12) x = 12;
+  if (x > 12) x = 12;
 #endif
 
-  /* draw */
-  menu_draw_begin(1, 0);
-  menu_draw_selection(x, y + vi_sel_ln * me_mfont_h, w);
-  x += me_mfont_w * 2;
-
-  for (ent = entries; ent->name; ent++)
-  {
-    const char **names;
-    int len, leftname_end = 0;
-
-    if (!ent->enabled)
-      continue;
-
-    name = ent->name;
-    if (strlen(name) == 0) {
-      if (ent->generate_name)
-        name = ent->generate_name(ent->id, &offs);
-    }
-    if (name != NULL) {
-      text_out16(x, y, name);
-      leftname_end = x + (strlen(name) + 1) * me_mfont_w;
-    }
-
-    switch (ent->beh) {
-    case MB_NONE:
-      break;
-    case MB_OPT_ONOFF:
-      text_out16(x + col2_offs, y, me_read_onoff(ent) ? "ON" : "OFF");
-      break;
-    case MB_OPT_RANGE:
-      text_out16(x + col2_offs, y, "%i", *(int *)ent->var);
-      break;
-    case MB_OPT_CUSTOM:
-    case MB_OPT_CUSTONOFF:
-    case MB_OPT_CUSTRANGE:
-      name = NULL;
-      offs = 0;
-      if (ent->generate_name)
-        name = ent->generate_name(ent->id, &offs);
-      if (name != NULL)
-        text_out16(x + col2_offs + offs * me_mfont_w, y, "%s", name);
-      break;
-    case MB_OPT_ENUM:
-      names = (const char **)ent->data;
-      for (i = 0; names[i] != NULL; i++) {
-        offs = x + col2_offs;
-        len = strlen(names[i]);
-        if (len > 10)
-          offs += (10 - len - 2) * me_mfont_w;
-        if (offs < leftname_end)
-          offs = leftname_end;
-        if (i == *(unsigned char *)ent->var) {
-          text_out16(offs, y, "%s", names[i]);
-          break;
-        }
-      }
-      break;
-    }
-
-    y += me_mfont_h;
-  }
-
-  menu_separation();
+  /* draw */
+  menu_draw_begin(1, 0);
+  menu_draw_selection(x, y + vi_sel_ln * me_mfont_h, w);
+  x += me_mfont_w * 2;
+
+  for (ent = entries; ent->name; ent++)
+  {
+    const char **names;
+    int len, leftname_end = 0;
+
+    if (!ent->enabled)
+      continue;
+
+    name = ent->name;
+    if (strlen(name) == 0) {
+      if (ent->generate_name)
+        name = ent->generate_name(ent->id, &offs);
+    }
+    if (name != NULL) {
+      text_out16(x, y, name);
+      leftname_end = x + (strlen(name) + 1) * me_mfont_w;
+    }
+
+    switch (ent->beh) {
+    case MB_NONE:
+      break;
+    case MB_OPT_ONOFF:
+      text_out16(x + col2_offs, y, me_read_onoff(ent) ? "ON" : "OFF");
+      break;
+    case MB_OPT_RANGE:
+      text_out16(x + col2_offs, y, "%i", *(int *)ent->var);
+      break;
+    case MB_OPT_CUSTOM:
+    case MB_OPT_CUSTONOFF:
+    case MB_OPT_CUSTRANGE:
+      name = NULL;
+      offs = 0;
+      if (ent->generate_name)
+        name = ent->generate_name(ent->id, &offs);
+      if (name != NULL)
+        text_out16(x + col2_offs + offs * me_mfont_w, y, "%s", name);
+      break;
+    case MB_OPT_ENUM:
+      names = (const char **)ent->data;
+      for (i = 0; names[i] != NULL; i++) {
+        offs = x + col2_offs;
+        len = strlen(names[i]);
+        if (len > 10)
+          offs += (10 - len - 2) * me_mfont_w;
+        if (offs < leftname_end)
+          offs = leftname_end;
+        if (i == *(unsigned char *)ent->var) {
+          text_out16(offs, y, "%s", names[i]);
+          break;
+        }
+      }
+      break;
+    }
+
+    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) {
+    if (h >= me_mfont_h + 4)
+      text_out16(5, g_menuscreen_h - me_mfont_h - 4, menu_error_msg);
+    else
+      lprintf("menu msg doesn't fit!\n");
+
+    if (plat_get_ticks_ms() - menu_error_time > 2048)
+      menu_error_msg[0] = 0;
+  }
+  else if (ent_sel->help != NULL) {
+    const char *tmp = ent_sel->help;
+    int l;
+    for (l = 0; tmp != NULL && *tmp != 0; l++)
+      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);
+  }
 
-  /* display help or message if we have one */
-  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);
-    else
-      lprintf("menu msg doesn't fit!\n");
-
-    if (plat_get_ticks_ms() - menu_error_time > 2048)
-      menu_error_msg[0] = 0;
-  }
-  else if (ent_sel->help != NULL) {
-    const char *tmp = ent_sel->help;
-    int l;
-    for (l = 0; tmp != NULL && *tmp != 0; l++)
-      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);
-  }
+  menu_separation();
 
-  menu_separation();
+  if (draw_more != NULL)
+    draw_more();
 
-  if (draw_more != NULL)
-    draw_more();
-
-  menu_draw_end();
+  menu_draw_end();
 }
 
 static int me_process(menu_entry *entry, int is_next, int is_lr)
 {
-  const char **names;
-  int c;
-  switch (entry->beh)
-  {
-    case MB_OPT_ONOFF:
-    case MB_OPT_CUSTONOFF:
-      me_toggle_onoff(entry);
-      return 1;
-    case MB_OPT_RANGE:
-    case MB_OPT_CUSTRANGE:
-      c = is_lr ? 10 : 1;
-      *(int *)entry->var += is_next ? c : -c;
-      if (*(int *)entry->var < (int)entry->min)
-        *(int *)entry->var = (int)entry->max;
-      if (*(int *)entry->var > (int)entry->max)
-        *(int *)entry->var = (int)entry->min;
-      return 1;
-    case MB_OPT_ENUM:
-      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;
-      return 1;
-    default:
-      return 0;
-  }
+  const char **names;
+  int c;
+  switch (entry->beh)
+  {
+    case MB_OPT_ONOFF:
+    case MB_OPT_CUSTONOFF:
+      me_toggle_onoff(entry);
+      return 1;
+    case MB_OPT_RANGE:
+    case MB_OPT_CUSTRANGE:
+      c = is_lr ? 10 : 1;
+      *(int *)entry->var += is_next ? c : -c;
+      if (*(int *)entry->var < (int)entry->min)
+        *(int *)entry->var = (int)entry->max;
+      if (*(int *)entry->var > (int)entry->max)
+        *(int *)entry->var = (int)entry->min;
+      return 1;
+    case MB_OPT_ENUM:
+      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;
+      return 1;
+    default:
+      return 0;
+  }
 }
 
 static void debug_menu_loop(void);
 
 static int me_loop_d(menu_entry *menu, int *menu_sel, void (*draw_prep)(void), void (*draw_more)(void))
 {
-  int ret = 0, inp, sel = *menu_sel, menu_sel_max;
+  int ret = 0, inp, sel = *menu_sel, menu_sel_max;
 
-  menu_sel_max = me_count(menu) - 1;
-  if (menu_sel_max < 0) {
-    lprintf("no enabled menu entries\n");
-    return 0;
-  }
-
-  while ((!menu[sel].enabled || !menu[sel].selectable) && sel < menu_sel_max)
-    sel++;
-
-  /* make sure action buttons are not pressed on entering menu */
-  me_draw(menu, sel, NULL);
-  while (in_menu_wait_any(NULL, 50) & (PBTN_MOK|PBTN_MBACK|PBTN_MENU));
-
-  for (;;)
-  {
-    if (draw_prep != NULL)
-      draw_prep();
-
-    me_draw(menu, sel, draw_more);
-    inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|
-      PBTN_MOK|PBTN_MBACK|PBTN_MENU|PBTN_L|PBTN_R, NULL, 70);
-    if (inp & (PBTN_MENU|PBTN_MBACK))
-      break;
-
-    if (inp & PBTN_UP  ) {
-      do {
-        sel--;
-        if (sel < 0)
-          sel = menu_sel_max;
-      }
-      while (!menu[sel].enabled || !menu[sel].selectable);
-    }
-    if (inp & PBTN_DOWN) {
-      do {
-        sel++;
-        if (sel > menu_sel_max)
-          sel = 0;
-      }
-      while (!menu[sel].enabled || !menu[sel].selectable);
-    }
-
-    /* a bit hacky but oh well */
-    if ((inp & (PBTN_L|PBTN_R)) == (PBTN_L|PBTN_R))
-      debug_menu_loop();
-
-    if (inp & (PBTN_LEFT|PBTN_RIGHT|PBTN_L|PBTN_R)) { /* multi choice */
-      if (me_process(&menu[sel], (inp & (PBTN_RIGHT|PBTN_R)) ? 1 : 0,
-            inp & (PBTN_L|PBTN_R)))
-        continue;
-    }
-
-    if (inp & (PBTN_MOK|PBTN_LEFT|PBTN_RIGHT|PBTN_L|PBTN_R))
-    {
-      /* require PBTN_MOK for MB_NONE */
-      if (menu[sel].handler != NULL && (menu[sel].beh != MB_NONE || (inp & PBTN_MOK))) {
-        ret = menu[sel].handler(menu[sel].id, inp);
-        if (ret) break;
-        menu_sel_max = me_count(menu) - 1; /* might change, so update */
-      }
-    }
-  }
-  *menu_sel = sel;
+  menu_sel_max = me_count(menu) - 1;
+  if (menu_sel_max < 0) {
+    lprintf("no enabled menu entries\n");
+    return 0;
+  }
+
+  while ((!menu[sel].enabled || !menu[sel].selectable) && sel < menu_sel_max)
+    sel++;
+
+  /* make sure action buttons are not pressed on entering menu */
+  me_draw(menu, sel, NULL);
+  while (in_menu_wait_any(NULL, 50) & (PBTN_MOK|PBTN_MBACK|PBTN_MENU));
+
+  for (;;)
+  {
+    if (draw_prep != NULL)
+      draw_prep();
+
+    me_draw(menu, sel, draw_more);
+    inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|
+      PBTN_MOK|PBTN_MBACK|PBTN_MENU|PBTN_L|PBTN_R, NULL, 70);
+    if (inp & (PBTN_MENU|PBTN_MBACK))
+      break;
+
+    if (inp & PBTN_UP  ) {
+      do {
+        sel--;
+        if (sel < 0)
+          sel = menu_sel_max;
+      }
+      while (!menu[sel].enabled || !menu[sel].selectable);
+    }
+    if (inp & PBTN_DOWN) {
+      do {
+        sel++;
+        if (sel > menu_sel_max)
+          sel = 0;
+      }
+      while (!menu[sel].enabled || !menu[sel].selectable);
+    }
+
+    /* a bit hacky but oh well */
+    if ((inp & (PBTN_L|PBTN_R)) == (PBTN_L|PBTN_R))
+      debug_menu_loop();
+
+    if (inp & (PBTN_LEFT|PBTN_RIGHT|PBTN_L|PBTN_R)) { /* multi choice */
+      if (me_process(&menu[sel], (inp & (PBTN_RIGHT|PBTN_R)) ? 1 : 0,
+            inp & (PBTN_L|PBTN_R)))
+        continue;
+    }
+
+    if (inp & (PBTN_MOK|PBTN_LEFT|PBTN_RIGHT|PBTN_L|PBTN_R))
+    {
+      /* require PBTN_MOK for MB_NONE */
+      if (menu[sel].handler != NULL && (menu[sel].beh != MB_NONE || (inp & PBTN_MOK))) {
+        ret = menu[sel].handler(menu[sel].id, inp);
+        if (ret) break;
+        menu_sel_max = me_count(menu) - 1; /* might change, so update */
+      }
+    }
+  }
+  *menu_sel = sel;
 
-  return ret;
+  return ret;
 }
 
 static int me_loop(menu_entry *menu, int *menu_sel)
 {
-  return me_loop_d(menu, menu_sel, NULL, NULL);
+  return me_loop_d(menu, menu_sel, NULL, NULL);
 }
 
 /* ***************************************** */
 
 static void draw_menu_message(const char *msg, void (*draw_more)(void))
 {
-  int x, y, h, w, wt;
-  const char *p;
+  int x, y, h, w, wt;
+  const char *p;
 
-  p = msg;
-  for (h = 1, w = 0; *p != 0; h++) {
-    for (wt = 0; *p != 0 && *p != '\n'; p++)
-      wt++;
-
-    if (wt > w)
-      w = wt;
-    if (*p == 0)
-      break;
-    p++;
-  }
-
-  x = g_menuscreen_w / 2 - w * me_mfont_w / 2;
-  y = g_menuscreen_h / 2 - h * me_mfont_h / 2;
-  if (x < 0) x = 0;
-  if (y < 0) y = 0;
-
-  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);
-
-    for (; *p != 0 && *p != '\n'; p++)
-      ;
-    if (*p != 0)
-      p++;
-  }
+  p = msg;
+  for (h = 1, w = 0; *p != 0; h++) {
+    for (wt = 0; *p != 0 && *p != '\n'; p++)
+      wt++;
+
+    if (wt > w)
+      w = wt;
+    if (*p == 0)
+      break;
+    p++;
+  }
+
+  x = g_menuscreen_w / 2 - w * me_mfont_w / 2;
+  y = g_menuscreen_h / 2 - h * me_mfont_h / 2;
+  if (x < 0) x = 0;
+  if (y < 0) y = 0;
+
+  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);
+
+    for (; *p != 0 && *p != '\n'; p++)
+      ;
+    if (*p != 0)
+      p++;
+  }
 
-  menu_separation();
+  menu_separation();
 
-  if (draw_more != NULL)
-    draw_more();
+  if (draw_more != NULL)
+    draw_more();
 
-  menu_draw_end();
+  menu_draw_end();
 }
 
 // -------------- del confirm ---------------
 
 static void do_delete(const char *fpath, const char *fname)
 {
-  int len, mid, inp;
-  const char *nm;
-  char tmp[64];
-
-  menu_draw_begin(1, 0);
-
-  len = strlen(fname);
-  if (len > g_menuscreen_w / me_sfont_w)
-    len = g_menuscreen_w / me_sfont_w;
-
-  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);
-  text_out16(mid - me_mfont_w * 13 / 2, 11 * me_mfont_h, "Are you sure?");
-
-  nm = in_get_key_name(-1, -PBTN_MA3);
-  snprintf(tmp, sizeof(tmp), "(%s - confirm, ", nm);
-  len = strlen(tmp);
-  nm = in_get_key_name(-1, -PBTN_MBACK);
-  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);
-  menu_draw_end();
-
-  while (in_menu_wait_any(NULL, 50) & (PBTN_MENU|PBTN_MA2));
-  inp = in_menu_wait(PBTN_MA3|PBTN_MBACK, NULL, 100);
-  if (inp & PBTN_MA3)
-    remove(fpath);
+  int len, mid, inp;
+  const char *nm;
+  char tmp[64];
+
+  menu_draw_begin(1, 0);
+
+  len = strlen(fname);
+  if (len > g_menuscreen_w / me_sfont_w)
+    len = g_menuscreen_w / me_sfont_w;
+
+  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);
+  text_out16(mid - me_mfont_w * 13 / 2, 11 * me_mfont_h, "Are you sure?");
+
+  nm = in_get_key_name(-1, -PBTN_MA3);
+  snprintf(tmp, sizeof(tmp), "(%s - confirm, ", nm);
+  len = strlen(tmp);
+  nm = in_get_key_name(-1, -PBTN_MBACK);
+  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);
+  menu_draw_end();
+
+  while (in_menu_wait_any(NULL, 50) & (PBTN_MENU|PBTN_MA2));
+  inp = in_menu_wait(PBTN_MA3|PBTN_MBACK, NULL, 100);
+  if (inp & PBTN_MA3)
+    remove(fpath);
 }
 
 // -------------- ROM selector --------------
-
 static void draw_dirlist(char *curdir, struct dirent **namelist,
-  int n, int sel, int show_help)
+  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;
-  n--; // exclude current dir (".")
-
-  menu_draw_begin(1, 1);
-
-//  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);
-
-  x = 5 + me_mfont_w + 1;
-  if (start - 2 >= 0)
-    smalltext_out16(14, (start - 2) * me_sfont_h, curdir, 0xffff);
-  for (i = 0; i < n; i++) {
-    pos = start + i;
-    if (pos < 0)  continue;
-    if (pos >= max_cnt) break;
-    if (namelist[i+1]->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);
-    } else {
-      unsigned short color = fname2color(namelist[i+1]->d_name);
-      smalltext_out16(x, pos * me_sfont_h, namelist[i+1]->d_name, color);
-    }
-  }
-  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);
-  }
+  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;
+  n--; // exclude current dir (".")
+
+  menu_draw_begin(1, 1);
+
+//  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);
+
+  x = 5 + me_mfont_w + 1;
+  if (start - 2 >= 0)
+    smalltext_out16(14, (start - 2) * me_sfont_h, curdir, 0xffff);
+  for (i = 0; i < n; i++) {
+    pos = start + i;
+    if (pos < 0)  continue;
+    if (pos >= max_cnt) break;
+
+    if (namelist[i+1]->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);
+    } else {
+      unsigned short color = fname2color(namelist[i+1]->d_name);
+      smalltext_out16(x, pos * me_sfont_h, namelist[i+1]->d_name, color);
+    }
+  }
+  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();
+  menu_draw_end();
 }
 
 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;
-  if ((*d1)->d_type == (*d2)->d_type)
-    return alphasort(d1, d2);
-  if ((*d1)->d_type == DT_DIR)
-    return -1; // put before
-  if ((*d2)->d_type == DT_DIR)
-    return  1;
+  const struct dirent **d1 = (const struct dirent **)p1;
+  const struct dirent **d2 = (const struct dirent **)p2;
+  if ((*d1)->d_type == (*d2)->d_type)
+    return alphasort(d1, d2);
+  if ((*d1)->d_type == DT_DIR)
+    return -1; // put before
+  if ((*d2)->d_type == DT_DIR)
+    return  1;
 
-  return alphasort(d1, d2);
+  return alphasort(d1, d2);
 }
 
 static const char **filter_exts_internal;
 
 static int scandir_filter(const struct dirent *ent)
 {
-  const char **filter = filter_exts_internal;
-  const char *ext;
-  int i;
-
-  if (ent == NULL || ent->d_name == NULL)
-    return 0;
-
-  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)
-    return 0;
-
-  ext++;
-  for (i = 0; filter[i] != NULL; i++)
-    if (strcasecmp(ext, filter[i]) == 0)
-      return 1;
+  const char **filter = filter_exts_internal;
+  const char *ext;
+  int i;
+
+  if (ent == NULL || ent->d_name == NULL)
+    return 0;
+
+  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)
+    return 0;
+
+  ext++;
+  for (i = 0; filter[i] != NULL; i++)
+    if (strcasecmp(ext, filter[i]) == 0)
+      return 1;
 
-  return 0;
+  return 0;
 }
 
 static int dirent_seek_char(struct dirent **namelist, int len, int sel, char c)
 {
-  int i;
+  int i;
 
-  sel++;
-  for (i = sel + 1; ; i++) {
-    if (i >= len)
-      i = 1;
-    if (i == sel)
-      break;
-
-    if (tolower_simple(namelist[i]->d_name[0]) == c)
-      break;
-  }
+  sel++;
+  for (i = sel + 1; ; i++) {
+    if (i >= len)
+      i = 1;
+    if (i == sel)
+      break;
+
+    if (tolower_simple(namelist[i]->d_name[0]) == c)
+      break;
+  }
 
-  return i - 1;
+  return i - 1;
 }
 
 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))
-{
-  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;
-
-  // is this a dir or a full path?
-  if (!plat_is_dir(curr_path)) {
-    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;
-  }
+  const char **filter_exts,
+  int (*extra_filter)(struct dirent **namelist, int count,
+          const char *basedir))
+{
+  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;
+
+  // is this a dir or a full path?
+  if (!plat_is_dir(curr_path)) {
+    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;
+  }
 
 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);
-
-    // try root
-    t = getcwd(curr_path, len);
-    if (t == NULL)
-      plat_get_root_dir(curr_path, len);
-    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);
-      return NULL;
-    }
-  }
-
-  // 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);
+  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);
+
+    // try root
+    t = getcwd(curr_path, len);
+    if (t == NULL)
+      plat_get_root_dir(curr_path, len);
+    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);
+      return NULL;
+    }
+  }
+
+  // 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) {
+    for (i = 1; i < n; i++) {
+      char *dname = namelist[i]->d_name;
+      if (dname[0] == sel_fname[0] && strcmp(dname, sel_fname) == 0) {
+        sel = i - 1;
+        break;
+      }
+    }
+  }
+
+  /* make sure action buttons are not pressed on entering menu */
+  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, 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_MOK) || (inp & (PBTN_MENU|PBTN_MA2)) == (PBTN_MENU|PBTN_MA2))
+    {
+      if (namelist[sel+1]->d_type == DT_REG)
+      {
+        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);
+        goto rescan;
+      }
+      else if (namelist[sel+1]->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;
+        newdir = malloc(newlen);
+        if (newdir == NULL)
+          break;
+        if (strcmp(namelist[sel+1]->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, "/");
+          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);
+        }
+        ret = menu_loop_romsel(newdir, newlen, filter_exts, extra_filter);
+        free(newdir);
+        break;
+      }
+    }
+    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-- > 0)
+      free(namelist[n]);
+    free(namelist);
+  }
+
+  // restore curr_path
+  if (curr_path_restore != NULL)
+    *curr_path_restore = '/';
 
-  // 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++) {
-      char *dname = namelist[i]->d_name;
-      if (dname[0] == sel_fname[0] && strcmp(dname, sel_fname) == 0) {
-        sel = i - 1;
-        break;
-      }
-    }
-  }
-
-  /* make sure action buttons are not pressed on entering menu */
-  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, 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_MOK) || (inp & (PBTN_MENU|PBTN_MA2)) == (PBTN_MENU|PBTN_MA2))
-    {
-      if (namelist[sel+1]->d_type == DT_REG)
-      {
-        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);
-        goto rescan;
-      }
-      else if (namelist[sel+1]->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;
-        newdir = malloc(newlen);
-        if (newdir == NULL)
-          break;
-        if (strcmp(namelist[sel+1]->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, "/");
-          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);
-        }
-        ret = menu_loop_romsel(newdir, newlen, filter_exts, extra_filter);
-        free(newdir);
-        break;
-      }
-    }
-    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-- > 0)
-      free(namelist[n]);
-    free(namelist);
-  }
-
-  // restore curr_path
-  if (curr_path_restore != NULL)
-    *curr_path_restore = '/';
-
-  return ret;
+  return ret;
 }
 
 // ------------ savestate loader ------------
@@ -1187,330 +1242,330 @@
 
 static void state_check_slots(void)
 {
-  int slot;
+  int slot;
 
-  state_slot_flags = 0;
+  state_slot_flags = 0;
 
-  for (slot = 0; slot < STATE_SLOT_COUNT; slot++) {
-    state_slot_times[slot] = 0;
-    if (emu_check_save_file(slot, &state_slot_times[slot]))
-      state_slot_flags |= 1 << slot;
-  }
+  for (slot = 0; slot < STATE_SLOT_COUNT; slot++) {
+    state_slot_times[slot] = 0;
+    if (emu_check_save_file(slot, &state_slot_times[slot]))
+      state_slot_flags |= 1 << slot;
+  }
 }
 
 static void draw_savestate_bg(int slot);
 
 static void draw_savestate_menu(int menu_sel, int is_loading)
 {
-  int i, x, y, w, h;
-  char time_buf[32];
+  int i, x, y, w, h;
+  char time_buf[32];
 
-  if (state_slot_flags & (1 << menu_sel))
-    draw_savestate_bg(menu_sel);
+  if (state_slot_flags & (1 << menu_sel))
+    draw_savestate_bg(menu_sel);
 
-  w = (13 + 2) * me_mfont_w;
-  h = (1+2+STATE_SLOT_COUNT+1) * me_mfont_h;
-  x = g_menuscreen_w / 2 - w / 2;
-  if (x < 0) x = 0;
-  y = g_menuscreen_h / 2 - h / 2;
-  if (y < 0) y = 0;
+  w = (13 + 2) * me_mfont_w;
+  h = (1+2+STATE_SLOT_COUNT+1) * me_mfont_h;
+  x = g_menuscreen_w / 2 - w / 2;
+  if (x < 0) x = 0;
+  y = g_menuscreen_h / 2 - h / 2;
+  if (y < 0) y = 0;
 #ifdef MENU_ALIGN_LEFT
-  if (x > 12 + me_mfont_w * 2)
-    x = 12 + me_mfont_w * 2;
+  if (x > 12 + me_mfont_w * 2)
+    x = 12 + me_mfont_w * 2;
 #endif
 
-  menu_draw_begin(1, 1);
+  menu_draw_begin(1, 1);
 
-  text_out16(x, y, is_loading ? "Load state" : "Save state");
-  y += 3 * me_mfont_h;
+  text_out16(x, y, is_loading ? "Load state" : "Save state");
+  y += 3 * me_mfont_h;
 
-  menu_draw_selection(x - me_mfont_w * 2, y + menu_sel * me_mfont_h, (23 + 2) * me_mfont_w + 4);
+  menu_draw_selection(x - me_mfont_w * 2, y + menu_sel * me_mfont_h, (23 + 2) * me_mfont_w + 4);
 
-  /* draw all slots */
-  for (i = 0; i < STATE_SLOT_COUNT; i++, y += me_mfont_h)
-  {
-    if (!(state_slot_flags & (1 << i)))
-      strcpy(time_buf, "free");
-    else {
-      strcpy(time_buf, "USED");
-      if (state_slot_times[i] != 0) {
-        time_t time = state_slot_times[i];
-        struct tm *t = localtime(&time);
-        strftime(time_buf, sizeof(time_buf), "%x %R", t);
-      }
-    }
+  /* draw all slots */
+  for (i = 0; i < STATE_SLOT_COUNT; i++, y += me_mfont_h)
+  {
+    if (!(state_slot_flags & (1 << i)))
+      strcpy(time_buf, "free");
+    else {
+      strcpy(time_buf, "USED");
+      if (state_slot_times[i] != 0) {
+        time_t time = state_slot_times[i];
+        struct tm *t = localtime(&time);
+        strftime(time_buf, sizeof(time_buf), "%x %R", t);
+      }
+    }
+
+    text_out16(x, y, "SLOT %i (%s)", i, time_buf);
+  }
+  text_out16(x, y, "back");
 
-    text_out16(x, y, "SLOT %i (%s)", i, time_buf);
-  }
-  text_out16(x, y, "back");
-
-  menu_draw_end();
+  menu_draw_end();
 }
 
 static int menu_loop_savestate(int is_loading)
 {
-  static int menu_sel = STATE_SLOT_COUNT;
-  int menu_sel_max = STATE_SLOT_COUNT;
-  unsigned long inp = 0;
-  int ret = 0;
-
-  state_check_slots();
-
-  if (!(state_slot_flags & (1 << menu_sel)) && is_loading)
-    menu_sel = menu_sel_max;
-
-  for (;;)
-  {
-    draw_savestate_menu(menu_sel, is_loading);
-    inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_MOK|PBTN_MBACK, NULL, 100);
-    if (inp & PBTN_UP) {
-      do {
-        menu_sel--;
-        if (menu_sel < 0)
-          menu_sel = menu_sel_max;
-      } while (!(state_slot_flags & (1 << menu_sel)) && menu_sel != menu_sel_max && is_loading);
-    }
-    if (inp & PBTN_DOWN) {
-      do {
-        menu_sel++;
-        if (menu_sel > menu_sel_max)
-          menu_sel = 0;
-      } while (!(state_slot_flags & (1 << menu_sel)) && menu_sel != menu_sel_max && is_loading);
-    }
-    if (inp & PBTN_MOK) { // save/load
-      if (menu_sel < STATE_SLOT_COUNT) {
-        state_slot = menu_sel;
-        if (emu_save_load_game(is_loading, 0)) {
-          menu_update_msg(is_loading ? "Load failed" : "Save failed");
-          break;
-        }
-        ret = 1;
-        break;
-      }
-      break;
-    }
-    if (inp & PBTN_MBACK)
-      break;
-  }
+  static int menu_sel = STATE_SLOT_COUNT;
+  int menu_sel_max = STATE_SLOT_COUNT;
+  unsigned long inp = 0;
+  int ret = 0;
+
+  state_check_slots();
+
+  if (!(state_slot_flags & (1 << menu_sel)) && is_loading)
+    menu_sel = menu_sel_max;
+
+  for (;;)
+  {
+    draw_savestate_menu(menu_sel, is_loading);
+    inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_MOK|PBTN_MBACK, NULL, 100);
+    if (inp & PBTN_UP) {
+      do {
+        menu_sel--;
+        if (menu_sel < 0)
+          menu_sel = menu_sel_max;
+      } while (!(state_slot_flags & (1 << menu_sel)) && menu_sel != menu_sel_max && is_loading);
+    }
+    if (inp & PBTN_DOWN) {
+      do {
+        menu_sel++;
+        if (menu_sel > menu_sel_max)
+          menu_sel = 0;
+      } while (!(state_slot_flags & (1 << menu_sel)) && menu_sel != menu_sel_max && is_loading);
+    }
+    if (inp & PBTN_MOK) { // save/load
+      if (menu_sel < STATE_SLOT_COUNT) {
+        state_slot = menu_sel;
+        if (emu_save_load_game(is_loading, 0)) {
+          menu_update_msg(is_loading ? "Load failed" : "Save failed");
+          break;
+        }
+        ret = 1;
+        break;
+      }
+      break;
+    }
+    if (inp & PBTN_MBACK)
+      break;
+  }
 
-  return ret;
+  return ret;
 }
 
 // -------------- key config --------------
 
 static char *action_binds(int player_idx, int action_mask, int dev_id)
 {
-  int dev = 0, dev_last = IN_MAX_DEVS - 1;
-  int can_combo = 1, type;
+  int dev = 0, dev_last = IN_MAX_DEVS - 1;
+  int can_combo = 1, type;
 
-  static_buff[0] = 0;
+  static_buff[0] = 0;
 
-  type = IN_BINDTYPE_EMU;
-  if (player_idx >= 0) {
-    can_combo = 0;
-    type = IN_BINDTYPE_PLAYER12;
-  }
-  if (player_idx == 1)
-    action_mask <<= 16;
-
-  if (dev_id >= 0)
-    dev = dev_last = dev_id;
-
-  for (; dev <= dev_last; dev++) {
-    int k, count = 0, combo = 0;
-    const int *binds;
-
-    binds = in_get_dev_binds(dev);
-    if (binds == NULL)
-      continue;
-
-    in_get_config(dev, IN_CFG_BIND_COUNT, &count);
-    in_get_config(dev, IN_CFG_DOES_COMBOS, &combo);
-    combo = combo && can_combo;
-
-    for (k = 0; k < count; k++) {
-      const char *xname;
-      int len;
-
-      if (!(binds[IN_BIND_OFFS(k, type)] & action_mask))
-        continue;
-
-      xname = in_get_key_name(dev, k);
-      len = strlen(static_buff);
-      if (len) {
-        strncat(static_buff, combo ? " + " : ", ",
-          sizeof(static_buff) - len - 1);
-        len += combo ? 3 : 2;
-      }
-      strncat(static_buff, xname, sizeof(static_buff) - len - 1);
-    }
-  }
+  type = IN_BINDTYPE_EMU;
+  if (player_idx >= 0) {
+    can_combo = 0;
+    type = IN_BINDTYPE_PLAYER12;
+  }
+  if (player_idx == 1)
+    action_mask <<= 16;
+
+  if (dev_id >= 0)
+    dev = dev_last = dev_id;
+
+  for (; dev <= dev_last; dev++) {
+    int k, count = 0, combo = 0;
+    const int *binds;
+
+    binds = in_get_dev_binds(dev);
+    if (binds == NULL)
+      continue;
+
+    in_get_config(dev, IN_CFG_BIND_COUNT, &count);
+    in_get_config(dev, IN_CFG_DOES_COMBOS, &combo);
+    combo = combo && can_combo;
+
+    for (k = 0; k < count; k++) {
+      const char *xname;
+      int len;
+
+      if (!(binds[IN_BIND_OFFS(k, type)] & action_mask))
+        continue;
+
+      xname = in_get_key_name(dev, k);
+      len = strlen(static_buff);
+      if (len) {
+        strncat(static_buff, combo ? " + " : ", ",
+          sizeof(static_buff) - len - 1);
+        len += combo ? 3 : 2;
+      }
+      strncat(static_buff, xname, sizeof(static_buff) - len - 1);
+    }
+  }
 
-  return static_buff;
+  return static_buff;
 }
 
 static int count_bound_keys(int dev_id, int action_mask, int bindtype)
 {
-  const int *binds;
-  int k, keys = 0;
-  int count = 0;
-
-  binds = in_get_dev_binds(dev_id);
-  if (binds == NULL)
-    return 0;
-
-  in_get_config(dev_id, IN_CFG_BIND_COUNT, &count);
-  for (k = 0; k < count; k++)
-  {
-    if (binds[IN_BIND_OFFS(k, bindtype)] & action_mask)
-      keys++;
-  }
+  const int *binds;
+  int k, keys = 0;
+  int count = 0;
+
+  binds = in_get_dev_binds(dev_id);
+  if (binds == NULL)
+    return 0;
+
+  in_get_config(dev_id, IN_CFG_BIND_COUNT, &count);
+  for (k = 0; k < count; k++)
+  {
+    if (binds[IN_BIND_OFFS(k, bindtype)] & action_mask)
+      keys++;
+  }
 
-  return keys;
+  return keys;
 }
 
 static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_idx,
-    int sel, int dev_id, int dev_count, int is_bind)
+    int sel, int dev_id, int dev_count, int is_bind)
 {
-  char buff[64], buff2[32];
-  const char *dev_name;
-  int x, y, w, i;
-
-  w = ((player_idx >= 0) ? 20 : 30) * me_mfont_w;
-  x = g_menuscreen_w / 2 - w / 2;
-  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;
-
-  menu_draw_begin(1, 0);
-  if (player_idx >= 0)
-    text_out16(x, y, "Player %i controls", player_idx + 1);
-  else
-    text_out16(x, y, "Emulator controls");
-
-  y += 2 * me_mfont_h;
-  menu_draw_selection(x - me_mfont_w * 2, y + sel * me_mfont_h, w + 2 * me_mfont_w);
-
-  for (i = 0; i < opt_cnt; i++, y += me_mfont_h)
-    text_out16(x, y, "%s : %s", opts[i].name,
-      action_binds(player_idx, opts[i].mask, dev_id));
-
-  menu_separation();
-
-  if (dev_id < 0)
-    dev_name = "(all devices)";
-  else
-    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;
-  if (w > g_menuscreen_w)
-    w = g_menuscreen_w;
-
-  x = g_menuscreen_w / 2 - w / 2;
-
-  if (!is_bind) {
-    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);
-  }
-  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 - 2 * me_mfont_h, "Press left/right for other devs");
-  }
+  char buff[64], buff2[32];
+  const char *dev_name;
+  int x, y, w, i;
+
+  w = ((player_idx >= 0) ? 20 : 30) * me_mfont_w;
+  x = g_menuscreen_w / 2 - w / 2;
+  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;
+
+  menu_draw_begin(1, 0);
+  if (player_idx >= 0)
+    text_out16(x, y, "Player %i controls", player_idx + 1);
+  else
+    text_out16(x, y, "Emulator controls");
+
+  y += 2 * me_mfont_h;
+  menu_draw_selection(x - me_mfont_w * 2, y + sel * me_mfont_h, w + 2 * me_mfont_w);
+
+  for (i = 0; i < opt_cnt; i++, y += me_mfont_h)
+    text_out16(x, y, "%s : %s", opts[i].name,
+      action_binds(player_idx, opts[i].mask, dev_id));
+
+  menu_separation();
+
+  if (dev_id < 0)
+    dev_name = "(all devices)";
+  else
+    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;
+  if (w > g_menuscreen_w)
+    w = g_menuscreen_w;
+
+  x = g_menuscreen_w / 2 - w / 2;
+
+  if (!is_bind) {
+    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);
+  }
+  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 - 2 * me_mfont_h, "Press left/right for other devs");
+  }
 
-  menu_draw_end();
+  menu_draw_end();
 }
 
 static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_idx)
 {
-  int i, sel = 0, menu_sel_max = opt_cnt - 1, does_combos = 0;
-  int dev_id, bind_dev_id, dev_count, kc, is_down, mkey;
-  int unbind, bindtype, mask_shift;
-
-  for (i = 0, dev_id = -1, dev_count = 0; i < IN_MAX_DEVS; i++) {
-    if (in_get_dev_name(i, 1, 0) != NULL) {
-      dev_count++;
-      if (dev_id < 0)
-        dev_id = i;
-    }
-  }
-
-  if (dev_id == -1) {
-    lprintf("no devs, can't do config\n");
-    return;
-  }
-
-  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;
-
-  for (;;)
-  {
-    draw_key_config(opts, opt_cnt, player_idx, sel, dev_id, dev_count, 0);
-    mkey = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT
-        |PBTN_MBACK|PBTN_MOK|PBTN_MA2, NULL, 100);
-    switch (mkey) {
-      case PBTN_UP:   sel--; if (sel < 0) sel = menu_sel_max; continue;
-      case PBTN_DOWN: sel++; if (sel > menu_sel_max) sel = 0; continue;
-      case PBTN_LEFT:
-        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, 0, 0) != NULL)
-            break;
-        }
-        continue;
-      case PBTN_RIGHT:
-        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, 0, 0) != NULL)
-            break;
-        }
-        continue;
-      case PBTN_MBACK:
-        return;
-      case PBTN_MOK:
-        if (sel >= opt_cnt)
-          return;
-        while (in_menu_wait_any(NULL, 30) & PBTN_MOK)
-          ;
-        break;
-      case PBTN_MA2:
-        in_unbind_all(dev_id, opts[sel].mask << mask_shift, bindtype);
-        continue;
-      default:continue;
-    }
-
-    draw_key_config(opts, opt_cnt, player_idx, sel, dev_id, dev_count, 1);
-
-    /* wait for some up event */
-    for (is_down = 1; is_down; )
-      kc = in_update_keycode(&bind_dev_id, &is_down, NULL, -1);
-
-    i = count_bound_keys(bind_dev_id, opts[sel].mask << mask_shift, bindtype);
-    unbind = (i > 0);
-
-    /* allow combos if device supports them */
-    in_get_config(bind_dev_id, IN_CFG_DOES_COMBOS, &does_combos);
-    if (i == 1 && bindtype == IN_BINDTYPE_EMU && does_combos)
-      unbind = 0;
-
-    if (unbind)
-      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;
-  }
+  int i, sel = 0, menu_sel_max = opt_cnt - 1, does_combos = 0;
+  int dev_id, bind_dev_id, dev_count, kc, is_down, mkey;
+  int unbind, bindtype, mask_shift;
+
+  for (i = 0, dev_id = -1, dev_count = 0; i < IN_MAX_DEVS; i++) {
+    if (in_get_dev_name(i, 1, 0) != NULL) {
+      dev_count++;
+      if (dev_id < 0)
+        dev_id = i;
+    }
+  }
+
+  if (dev_id == -1) {
+    lprintf("no devs, can't do config\n");
+    return;
+  }
+
+  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;
+
+  for (;;)
+  {
+    draw_key_config(opts, opt_cnt, player_idx, sel, dev_id, dev_count, 0);
+    mkey = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT
+        |PBTN_MBACK|PBTN_MOK|PBTN_MA2, NULL, 100);
+    switch (mkey) {
+      case PBTN_UP:   sel--; if (sel < 0) sel = menu_sel_max; continue;
+      case PBTN_DOWN: sel++; if (sel > menu_sel_max) sel = 0; continue;
+      case PBTN_LEFT:
+        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, 0, 0) != NULL)
+            break;
+        }
+        continue;
+      case PBTN_RIGHT:
+        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, 0, 0) != NULL)
+            break;
+        }
+        continue;
+      case PBTN_MBACK:
+        return;
+      case PBTN_MOK:
+        if (sel >= opt_cnt)
+          return;
+        while (in_menu_wait_any(NULL, 30) & PBTN_MOK)
+          ;
+        break;
+      case PBTN_MA2:
+        in_unbind_all(dev_id, opts[sel].mask << mask_shift, bindtype);
+        continue;
+      default:continue;
+    }
+
+    draw_key_config(opts, opt_cnt, player_idx, sel, dev_id, dev_count, 1);
+
+    /* wait for some up event */
+    for (is_down = 1; is_down; )
+      kc = in_update_keycode(&bind_dev_id, &is_down, NULL, -1);
+
+    i = count_bound_keys(bind_dev_id, opts[sel].mask << mask_shift, bindtype);
+    unbind = (i > 0);
+
+    /* allow combos if device supports them */
+    in_get_config(bind_dev_id, IN_CFG_DOES_COMBOS, &does_combos);
+    if (i == 1 && bindtype == IN_BINDTYPE_EMU && does_combos)
+      unbind = 0;
+
+    if (unbind)
+      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;
+  }
 }
 
diff -Naur old/frontend/plat_sdl.c new/frontend/plat_sdl.c
--- old/frontend/plat_sdl.c  2019-11-08 05:37:18.434916809 -0500
+++ new/frontend/plat_sdl.c  2019-11-08 04:18:26.214438328 -0500
@@ -8,6 +8,7 @@
  * See the COPYING file in the top-level directory.
  */
 
+#include <iconv.h>
 #include <stdio.h>
 #include <SDL.h>
 
@@ -88,6 +89,7 @@
   .jmap_size = sizeof(in_sdl_joy_map) / sizeof(in_sdl_joy_map[0]),
 };
 
+iconv_t cd=0;
 static int psx_w, psx_h;
 static void *shadow_fb, *menubg_img;
 static int in_menu;
@@ -136,6 +138,13 @@
   int shadow_size;
   int ret;
 
+  cd = iconv_open("big5", "utf-8");
+  printf("iconv_open: 0x%x\n", cd);
+  if(cd == -1){
+    printf("failed to open iconv !\n");
+    return -1;
+  }
+ 
   plat_sdl_quit_cb = quit_cb;
   plat_sdl_resize_cb = resize_cb;
 
@@ -167,6 +176,7 @@
 
 void plat_finish(void)
 {
+  iconv_close(cd);
   free(shadow_fb);
   shadow_fb = NULL;
   free(menubg_img);

修改前


修改後




返回上一頁