From 4d616d8e27ca88efe9a86d4162bb09376b010c70 Mon Sep 17 00:00:00 2001 From: sorgelig Date: Sun, 28 Jul 2019 23:45:25 +0800 Subject: [PATCH] Some re-work in file lister, NeoGeo per-game xml support. --- file_io.cpp | 67 +++++++++++++++------------- file_io.h | 11 ++++- menu.cpp | 52 ++++++++++------------ support/neogeo/loader.cpp | 91 +++++++++++++++++++++++++++++++-------- support/neogeo/loader.h | 3 +- 5 files changed, 143 insertions(+), 81 deletions(-) diff --git a/file_io.cpp b/file_io.cpp index 4517fff..7031fc1 100644 --- a/file_io.cpp +++ b/file_io.cpp @@ -32,7 +32,7 @@ #define MIN(a,b) (((a)<(b)) ? (a) : (b)) -typedef std::vector DirentVector; +typedef std::vector DirentVector; static const size_t YieldIterations = 128; @@ -860,28 +860,28 @@ void FindStorage(void) struct DirentComp { - bool operator()(const dirent& de1, const dirent& de2) + bool operator()(const direntext_t& de1, const direntext_t& de2) { if (++iterations % YieldIterations == 0) { scheduler_yield(); } - if ((de1.d_type == DT_DIR) && !strcmp(de1.d_name, "..")) return true; - if ((de2.d_type == DT_DIR) && !strcmp(de2.d_name, "..")) return false; + if ((de1.de.d_type == DT_DIR) && !strcmp(de1.altname, "..")) return true; + if ((de2.de.d_type == DT_DIR) && !strcmp(de2.altname, "..")) return false; - if ((de1.d_type == DT_DIR) && (de2.d_type == DT_REG)) return true; - if ((de1.d_type == DT_REG) && (de2.d_type == DT_DIR)) return false; + if ((de1.de.d_type == DT_DIR) && (de2.de.d_type == DT_REG)) return true; + if ((de1.de.d_type == DT_REG) && (de2.de.d_type == DT_DIR)) return false; - if ((de1.d_type == DT_REG) && (de2.d_type == DT_REG)) + if (de1.de.d_type == de2.de.d_type) { - int len1 = strlen(de1.d_name); - int len2 = strlen(de2.d_name); - if ((len1 > 4) && (de1.d_name[len1 - 4] == '.')) len1 -= 4; - if ((len2 > 4) && (de2.d_name[len2 - 4] == '.')) len2 -= 4; + int len1 = strlen(de1.altname); + int len2 = strlen(de2.altname); + if ((len1 > 4) && (de1.altname[len1 - 4] == '.')) len1 -= 4; + if ((len2 > 4) && (de2.altname[len2 - 4] == '.')) len2 -= 4; int len = (len1 < len2) ? len1 : len2; - int ret = strncasecmp(de1.d_name, de2.d_name, len); + int ret = strncasecmp(de1.altname, de2.altname, len); if (!ret) { return len1 < len2; @@ -890,7 +890,7 @@ struct DirentComp return ret < 0; } - return strcasecmp(de1.d_name, de2.d_name) < 0; + return strcasecmp(de1.altname, de2.altname) < 0; } size_t iterations = 0; @@ -957,12 +957,7 @@ int ScanDirectory(char* path, int mode, const char *extension, int options, cons if (strlen(path) > len) { path[len] = 0; - dirent *nde = neogeo_set_altname(path + len + 1); - file_name[0] = 0; - if (nde) - { - strcpy(file_name, nde->d_name); - } + strcpy(file_name, path + len + 1); } } else @@ -1083,8 +1078,15 @@ int ScanDirectory(char* path, int mode, const char *extension, int options, cons if (!strcmp(de->d_name, ".")) continue; if (!strcmp(de->d_name, "..")) continue; - dirent *nde = neogeo_set_altname(de->d_name); - if(nde) DirItem.push_back(*nde); + full_path[path_len] = 0; + char *altname = neogeo_get_altname(full_path, de->d_name); + if (altname) + { + direntext_t dext = { *de, 0, "" }; + dext.de.d_type = DT_REG; + memcpy(dext.altname, altname, sizeof(dext.altname)); + DirItem.push_back(dext); + } } else { @@ -1162,7 +1164,12 @@ int ScanDirectory(char* path, int mode, const char *extension, int options, cons { continue; } - DirItem.push_back(*de); + + { + direntext_t dext = { *de, 0, "" }; + memcpy(dext.altname, de->d_name, sizeof(dext.altname)); + DirItem.push_back(dext); + } } } @@ -1173,7 +1180,9 @@ int ScanDirectory(char* path, int mode, const char *extension, int options, cons dirent up; up.d_type = DT_DIR; strcpy(up.d_name, ".."); - DirItem.push_back(up); + direntext_t dext = { up, 0, "" }; + memcpy(dext.altname, up.d_name, sizeof(dext.altname)); + DirItem.push_back(dext); mz_zip_reader_end(z); delete z; @@ -1192,7 +1201,7 @@ int ScanDirectory(char* path, int mode, const char *extension, int options, cons { for (int i = 0; i < flist_nDirEntries(); i++) { - if (!strcmp(file_name, DirItem[i].d_name)) + if (!strcmp(file_name, DirItem[i].de.d_name)) { iSelectedEntry = i; if (iSelectedEntry + (OsdGetSize() / 2) - 1 >= flist_nDirEntries()) iFirstEntry = flist_nDirEntries() - OsdGetSize(); @@ -1275,7 +1284,7 @@ int ScanDirectory(char* path, int mode, const char *extension, int options, cons { for (int i = 0; i < flist_nDirEntries(); i++) { - if((DirItem[i].d_type == DT_DIR) && !strcmp(DirItem[i].d_name, extension)) + if((DirItem[i].de.d_type == DT_DIR) && !strcmp(DirItem[i].altname, extension)) { iSelectedEntry = i; if (iSelectedEntry + (OsdGetSize() / 2) - 1 >= flist_nDirEntries()) iFirstEntry = flist_nDirEntries() - OsdGetSize(); @@ -1294,7 +1303,7 @@ int ScanDirectory(char* path, int mode, const char *extension, int options, cons int found = -1; for (int i = iSelectedEntry+1; i < flist_nDirEntries(); i++) { - if (toupper(DirItem[i].d_name[0]) == mode) + if (toupper(DirItem[i].altname[0]) == mode) { found = i; break; @@ -1305,7 +1314,7 @@ int ScanDirectory(char* path, int mode, const char *extension, int options, cons { for (int i = 0; i < flist_nDirEntries(); i++) { - if (toupper(DirItem[i].d_name[0]) == mode) + if (toupper(DirItem[i].altname[0]) == mode) { found = i; break; @@ -1342,12 +1351,12 @@ int flist_iSelectedEntry() return iSelectedEntry; } -dirent* flist_DirItem(int n) +direntext_t* flist_DirItem(int n) { return &DirItem[n]; } -dirent* flist_SelectedItem() +direntext_t* flist_SelectedItem() { return &DirItem[iSelectedEntry]; } diff --git a/file_io.h b/file_io.h index a0ec97c..b75f3a2 100644 --- a/file_io.h +++ b/file_io.h @@ -21,11 +21,18 @@ typedef struct char name[261]; } fileTYPE; +struct direntext_t +{ + dirent de; + int cookie; + char altname[256]; +}; + int flist_nDirEntries(); int flist_iFirstEntry(); int flist_iSelectedEntry(); -dirent* flist_DirItem(int n); -dirent* flist_SelectedItem(); +direntext_t* flist_DirItem(int n); +direntext_t* flist_SelectedItem(); // scanning flags #define SCANF_INIT 0 // start search from beginning of directory diff --git a/menu.cpp b/menu.cpp index 0450be7..35fc1e4 100644 --- a/menu.cpp +++ b/menu.cpp @@ -3036,7 +3036,7 @@ void HandleUI(void) if (menu) { - if (flist_nDirEntries() && flist_SelectedItem()->d_type != DT_DIR) + if (flist_nDirEntries() && flist_SelectedItem()->de.d_type != DT_DIR) { SelectedDir[0] = 0; if (strlen(SelectedPath)) @@ -3044,7 +3044,7 @@ void HandleUI(void) strcpy(SelectedDir, SelectedPath); strcat(SelectedPath, "/"); } - strcat(SelectedPath, flist_SelectedItem()->d_name); + strcat(SelectedPath, flist_SelectedItem()->de.d_name); } if (!strcasecmp(fs_pFileExt, "RBF")) SelectedPath[0] = 0; @@ -3104,9 +3104,9 @@ void HandleUI(void) if (select) { - if (flist_SelectedItem()->d_type == DT_DIR) + if (flist_SelectedItem()->de.d_type == DT_DIR) { - changeDir(flist_SelectedItem()->d_name); + changeDir(flist_SelectedItem()->de.d_name); menustate = MENU_FILE_SELECT1; } else @@ -3120,15 +3120,7 @@ void HandleUI(void) strcat(SelectedPath, "/"); } - if (fs_Options & SCANO_NEOGEO) - { - strcat(SelectedPath, neogeo_get_name(flist_SelectedItem()->d_ino)); - } - else - { - strcat(SelectedPath, flist_SelectedItem()->d_name); - } - + strcat(SelectedPath, flist_SelectedItem()->de.d_name); menustate = fs_MenuSelect; } } @@ -4129,7 +4121,7 @@ void HandleUI(void) helptext = 0; menumask = 1; menusub = 0; - OsdSetTitle((parentstate == MENU_BTPAIR) ? "BT Pairing" : flist_SelectedItem()->d_name, 0); + OsdSetTitle((parentstate == MENU_BTPAIR) ? "BT Pairing" : flist_SelectedItem()->de.d_name, 0); menustate = MENU_SCRIPTS1; if (parentstate != MENU_BTPAIR) parentstate = MENU_SCRIPTS; for (int i = 0; i < OsdGetSize() - 1; i++) OsdWrite(i, "", 0, 0); @@ -4182,7 +4174,7 @@ void HandleUI(void) if (!script_exited) { strcpy(script_command, "killall "); - strcat(script_command, (parentstate == MENU_BTPAIR) ? "btpair" : flist_SelectedItem()->d_name); + strcat(script_command, (parentstate == MENU_BTPAIR) ? "btpair" : flist_SelectedItem()->de.d_name); system(script_command); pclose(script_pipe); cpu_set_t set; @@ -4383,8 +4375,8 @@ void ScrollLongName(void) static int len; int max_len; - len = strlen(flist_SelectedItem()->d_name); // get name length - if (flist_SelectedItem()->d_type == DT_REG) // if a file + len = strlen(flist_SelectedItem()->altname); // get name length + if (flist_SelectedItem()->de.d_type == DT_REG) // if a file { if (fs_ExtLen <= 3) { @@ -4401,15 +4393,15 @@ void ScrollLongName(void) e[0] = '.'; e[4] = 0; int l = strlen(e); - if ((len>l) && !strncasecmp(flist_SelectedItem()->d_name + len - l, e, l)) len -= l; + if ((len>l) && !strncasecmp(flist_SelectedItem()->altname + len - l, e, l)) len -= l; } } max_len = 30; // number of file name characters to display (one more required for scrolling) - if (flist_SelectedItem()->d_type == DT_DIR) + if (flist_SelectedItem()->de.d_type == DT_DIR) max_len = 25; // number of directory name characters to display - ScrollText(flist_iSelectedEntry()-flist_iFirstEntry(), flist_SelectedItem()->d_name, 0, len, max_len, 1); + ScrollText(flist_iSelectedEntry()-flist_iFirstEntry(), flist_SelectedItem()->altname, 0, len, max_len, 1); } void PrintFileName(char *name, int row, int maxinv) @@ -4479,9 +4471,9 @@ void PrintDirectory(void) { k = flist_iFirstEntry() + i; - len = strlen(flist_DirItem(k)->d_name); // get name length + len = strlen(flist_DirItem(k)->altname); // get name length - if (!(flist_DirItem(k)->d_type == DT_DIR)) // if a file + if (!(flist_DirItem(k)->de.d_type == DT_DIR)) // if a file { if (fs_ExtLen <= 3) { @@ -4498,7 +4490,7 @@ void PrintDirectory(void) e[0] = '.'; e[4] = 0; int l = strlen(e); - if ((len>l) && !strncasecmp(flist_DirItem(k)->d_name + len - l, e, l)) + if ((len>l) && !strncasecmp(flist_DirItem(k)->altname + len - l, e, l)) { len -= l; } @@ -4506,9 +4498,9 @@ void PrintDirectory(void) } char *p = 0; - if ((fs_Options & SCANO_CORES) && len > 9 && !strncmp(flist_DirItem(k)->d_name + len - 9, "_20", 3)) + if ((fs_Options & SCANO_CORES) && len > 9 && !strncmp(flist_DirItem(k)->altname + len - 9, "_20", 3)) { - p = flist_DirItem(k)->d_name + len - 6; + p = flist_DirItem(k)->altname + len - 6; len -= 9; } @@ -4518,18 +4510,18 @@ void PrintDirectory(void) s[28] = 22; } - if((flist_DirItem(k)->d_type == DT_DIR) && (fs_Options & SCANO_CORES) && (flist_DirItem(k)->d_name[0] == '_')) + if((flist_DirItem(k)->de.d_type == DT_DIR) && (fs_Options & SCANO_CORES) && (flist_DirItem(k)->altname[0] == '_')) { - strncpy(s + 1, flist_DirItem(k)->d_name+1, len-1); + strncpy(s + 1, flist_DirItem(k)->altname+1, len-1); } else { - strncpy(s + 1, flist_DirItem(k)->d_name, len); // display only name + strncpy(s + 1, flist_DirItem(k)->altname, len); // display only name } - if (flist_DirItem(k)->d_type == DT_DIR) // mark directory with suffix + if (flist_DirItem(k)->de.d_type == DT_DIR) // mark directory with suffix { - if (!strcmp(flist_DirItem(k)->d_name, "..")) + if (!strcmp(flist_DirItem(k)->altname, "..")) { strcpy(&s[19], " "); } diff --git a/support/neogeo/loader.cpp b/support/neogeo/loader.cpp index 386c0ac..18cc851 100644 --- a/support/neogeo/loader.cpp +++ b/support/neogeo/loader.cpp @@ -192,6 +192,43 @@ static int xml_scan(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, const in return true; } +static int xml_get_altname(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, const int n, SAX_Data* sd) +{ + char* altname = (char*)sd->user; + + switch (evt) + { + case XML_EVENT_START_NODE: + if (!strcasecmp(node->tag, "romset") && (rom_cnt < (sizeof(roms) / sizeof(roms[0])))) + { + memset(&roms[rom_cnt], 0, sizeof(rom_info)); + for (int i = 0; i < node->n_attributes; i++) + { + if (!strcasecmp(node->attributes[i].name, "name")) strncpy(altname, node->attributes[i].value, 255); + } + + for (int i = 0; i < node->n_attributes; i++) + { + if (!strcasecmp(node->attributes[i].name, "altname")) strncpy(altname, node->attributes[i].value, 255); + } + rom_cnt++; + } + break; + + case XML_EVENT_END_NODE: + break; + + case XML_EVENT_ERROR: + printf("XML parse: %s: ERROR %d\n", text, n); + break; + default: + break; + } + + return true; +} + + int neogeo_scan_xml() { static char full_path[1024]; @@ -205,28 +242,35 @@ int neogeo_scan_xml() return rom_cnt; } -dirent *neogeo_set_altname(char *name) +char *neogeo_get_altname(char *path, char *name) { - static dirent de; + static char full_path[1024]; + strcpy(full_path, path); + strcat(full_path, "/"); + strcat(full_path, name); + strcat(full_path, "/romset.xml"); + + if (!access(full_path, F_OK)) + { + static char altname[256]; + altname[0] = 0; + + SAX_Callbacks sax; + SAX_Callbacks_init(&sax); + + sax.all_event = xml_get_altname; + XMLDoc_parse_file_SAX(full_path, &sax, &altname); + if (*altname) return altname; + } + for (uint32_t i = 0; i < rom_cnt; i++) { - if (!strcasecmp(name, roms[i].name)) - { - memcpy(de.d_name, roms[i].altname, sizeof(de.d_name)); - de.d_ino = i; - de.d_type = DT_REG; - return &de; - } + if (!strcasecmp(name, roms[i].name)) return roms[i].altname; } return NULL; } -const char *neogeo_get_name(uint32_t num) -{ - if (num < rom_cnt) return roms[num].name; - return ""; -} - +static int romsets = 0; static int xml_check_files(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, const int n, SAX_Data* sd) { const char* romset = (const char*)sd->user; @@ -236,8 +280,13 @@ static int xml_check_files(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, c switch (evt) { case XML_EVENT_START_NODE: + if (!strcasecmp(node->tag, "romsets")) romsets = 1; + if (!strcasecmp(node->tag, "romset")) { - if (!strcasecmp(node->attributes[0].value, romset)) { + if (!romsets) { + in_correct_romset = 1; + } + else if (!strcasecmp(node->attributes[0].value, romset)) { printf("Romset %s found !\n", romset); in_correct_romset = 1; } @@ -307,8 +356,9 @@ static int xml_load_files(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, co case XML_EVENT_START_NODE: if (!strcasecmp(node->tag, "romset")) { file_cnt = 0; + if (!romsets) in_correct_romset = 1; for (int i = 0; i < node->n_attributes; i++) { - if (!strcasecmp(node->attributes[i].name, "name")) { + if (romsets && !strcasecmp(node->attributes[i].name, "name")) { if (!strcasecmp(node->attributes[i].value, romset)) { printf("Romset %s found !\n", romset); in_correct_romset = 1; @@ -449,11 +499,16 @@ int neogeo_romset_tx(char* name) { if (!p) return 0; strncpy(romset, p + 1, strlen(p + 1)); - sprintf(full_path, "%s/neogeo/romsets.xml", getRootDir()); + sprintf(full_path, "%s/%s/romset.xml", getRootDir(), name); + if (access(full_path, F_OK)) sprintf(full_path, "%s/neogeo/romsets.xml", getRootDir()); + + printf("xml for %s: %s\n", name, full_path); + SAX_Callbacks sax; SAX_Callbacks_init(&sax); checked_ok = false; + romsets = 0; sax.all_event = xml_check_files; XMLDoc_parse_file_SAX(full_path, &sax, romset); if (!checked_ok) return 0; diff --git a/support/neogeo/loader.h b/support/neogeo/loader.h index 93b92dd..2778b94 100644 --- a/support/neogeo/loader.h +++ b/support/neogeo/loader.h @@ -8,5 +8,4 @@ extern bool checked_ok; int neogeo_romset_tx(char* name); int neogeo_scan_xml(); -dirent *neogeo_set_altname(char *name); -const char *neogeo_get_name(uint32_t num); +char *neogeo_get_altname(char *path, char *name);