alsa: don't leak memory
[libpicofe.git] / menu.c
diff --git a/menu.c b/menu.c
index eb728da..7d2b14e 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -239,7 +239,7 @@ static char tolower_simple(char c)
 \r
 void menu_init_base(void)\r
 {\r
-       int i, c, l;\r
+       int i, c, l, pos;\r
        unsigned char *fd, *fds;\r
        char buff[256];\r
        FILE *f;\r
@@ -252,7 +252,7 @@ void menu_init_base(void)
                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
@@ -294,17 +294,18 @@ void menu_init_base(void)
        }\r
 \r
        // load custom font and selector (stored as 1st symbol in font table)\r
-       emu_make_path(buff, "skin/font.png", sizeof(buff));\r
+       pos = plat_get_skin_dir(buff, sizeof(buff));\r
+       strcpy(buff + pos, "font.png");\r
        readpng(menu_font_data, buff, READPNG_FONT,\r
                MENU_X2 ? 256 : 128, MENU_X2 ? 320 : 160);\r
        // default selector symbol is '>'\r
        memcpy(menu_font_data, menu_font_data + ((int)'>') * me_mfont_w * me_mfont_h / 2,\r
                me_mfont_w * me_mfont_h / 2);\r
-       emu_make_path(buff, "skin/selector.png", sizeof(buff));\r
+       strcpy(buff + pos, "selector.png");\r
        readpng(menu_font_data, buff, READPNG_SELECTOR, me_mfont_w, me_mfont_h);\r
 \r
        // load custom colors\r
-       emu_make_path(buff, "skin/skin.txt", sizeof(buff));\r
+       strcpy(buff + pos, "skin.txt");\r
        f = fopen(buff, "r");\r
        if (f != NULL)\r
        {\r
@@ -939,8 +940,14 @@ static int scandir_filter(const struct dirent *ent)
        if (ent == NULL || ent->d_name == NULL)\r
                return 0;\r
 \r
-       if (ent->d_type == DT_DIR)\r
+       switch (ent->d_type) {\r
+       case DT_DIR:\r
                return 1;\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
@@ -959,9 +966,11 @@ static int dirent_seek_char(struct dirent **namelist, int len, int sel, char c)
        int i;\r
 \r
        sel++;\r
-       for (i = sel + 1; i != sel; i++) {\r
+       for (i = sel + 1; ; i++) {\r
                if (i >= len)\r
                        i = 1;\r
+               if (i == sel)\r
+                       break;\r
 \r
                if (tolower_simple(namelist[i]->d_name[0]) == c)\r
                        break;\r
@@ -975,14 +984,16 @@ static const char *menu_loop_romsel(char *curr_path, int len,
        int (*extra_filter)(struct dirent **namelist, int count,\r
                            const char *basedir))\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
        int n = 0, inp = 0, sel = 0, show_help = 0;\r
        char *curr_path_restore = NULL;\r
        const char *ret = NULL;\r
+       int changed;\r
        char cinp;\r
+       int r, i;\r
 \r
        filter_exts_internal = filter_exts;\r
        sel_fname[0] = 0;\r
@@ -1029,14 +1040,40 @@ rescan:
                }\r
        }\r
 \r
+       // try to resolve DT_UNKNOWN and symlinks\r
+       changed = 0;\r
+       for (i = 0; i < n; i++) {\r
+               struct stat st;\r
+\r
+               if (namelist[i]->d_type == DT_REG || namelist[i]->d_type == DT_DIR)\r
+                       continue;\r
+\r
+               snprintf(rom_fname_reload, sizeof(rom_fname_reload),\r
+                       "%s/%s", curr_path, 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
+                               changed = 1;\r
+                       }\r
+                       else if (S_ISDIR(st.st_mode)) {\r
+                               namelist[i]->d_type = DT_DIR;\r
+                               changed = 1;\r
+                       }\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 && changed)\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
                        char *dname = namelist[i]->d_name;\r
                        if (dname[0] == sel_fname[0] && strcmp(dname, sel_fname) == 0) {\r
@@ -1072,7 +1109,6 @@ rescan:
 \r
                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
                        {\r
                                snprintf(rom_fname_reload, sizeof(rom_fname_reload),\r
@@ -1112,22 +1148,6 @@ rescan:
                                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