diff options
Diffstat (limited to 'docs/release/src/osd/winui/treeview.cpp')
-rw-r--r-- | docs/release/src/osd/winui/treeview.cpp | 2264 |
1 files changed, 950 insertions, 1314 deletions
diff --git a/docs/release/src/osd/winui/treeview.cpp b/docs/release/src/osd/winui/treeview.cpp index cd132629536..eb8b560fc72 100644 --- a/docs/release/src/osd/winui/treeview.cpp +++ b/docs/release/src/osd/winui/treeview.cpp @@ -1,13 +1,5 @@ +// license:BSD-3-Clause // For licensing and usage information, read docs/release/winui_license.txt -//**************************************************************************** - -/*************************************************************************** - - treeview.c - - TreeView support routines - MSH 11/19/1998 - -***************************************************************************/ // standard windows headers #include <windows.h> @@ -28,6 +20,7 @@ #include "treeview.h" #include "resource.h" #include "mui_opts.h" +#include "mui_util.h" #include "emu_opts.h" #include "dialogs.h" #include "winutf8.h" @@ -35,47 +28,47 @@ #include "drivenum.h" #include "corestr.h" -#ifdef _MSC_VER -#define snprintf _snprintf -#endif +HANDLE winui2_find_first_file_utf8(const char* filename, WIN32_FIND_DATA *findfiledata) +{ + wchar_t *t_filename = ui_wstring_from_utf8(filename); -#define MAX_EXTRA_FOLDERS 256 + if (!t_filename) + return NULL; -/*************************************************************************** - public structures - ***************************************************************************/ + HANDLE result = FindFirstFile(t_filename, findfiledata); + free(t_filename); + return result; +} + +bool winui_move_file_utf8(const char* existingfilename, const char* newfilename) +{ + bool result = false; + + wchar_t *t_existingfilename = ui_wstring_from_utf8(existingfilename); -#define ICON_MAX (sizeof(treeIconNames) / sizeof(treeIconNames[0])) + if (!t_existingfilename) + return result; -/* Name used for user-defined custom icons */ -/* external *.ico file to look for. */ + wchar_t *t_newfilename = ui_wstring_from_utf8(newfilename); -typedef struct -{ - int nResourceID; - LPCSTR lpName; -} TREEICON; + if (!t_newfilename) + { + free(t_existingfilename); + return result; + } -static TREEICON treeIconNames[] = + result = MoveFile(t_existingfilename, t_newfilename); + free(t_newfilename); + free(t_existingfilename); + return result; +} + +const char* GetFolderDir() { - { IDI_FOLDER_OPEN, "foldopen" }, - { IDI_FOLDER, "folder" }, - { IDI_FOLDER_AVAILABLE, "foldavail" }, - { IDI_FOLDER_MANUFACTURER, "foldmanu" }, - { IDI_FOLDER_UNAVAILABLE, "foldunav" }, - { IDI_FOLDER_YEAR, "foldyear" }, - { IDI_FOLDER_SOURCE, "foldsrc" }, - { IDI_FOLDER_HORIZONTAL, "horz" }, - { IDI_FOLDER_VERTICAL, "vert" }, - { IDI_MANUFACTURER, "manufact" }, - { IDI_FOLDER_WORKING, "working" }, - { IDI_FOLDER_NONWORKING, "nonwork" }, - { IDI_YEAR, "year" }, - { IDI_SOUND, "sound" }, - { IDI_CPU, "cpu" }, - { IDI_FOLDER_HARDDISK, "harddisk" }, - { IDI_SOURCE, "source" } -}; + string a = dir_get_value(24); + return a.c_str(); +} + /*************************************************************************** private variables @@ -83,20 +76,18 @@ static TREEICON treeIconNames[] = /* this has an entry for every folder eventually in the UI, including subfolders */ static TREEFOLDER **treeFolders = 0; -static UINT numFolders = 0; /* Number of folder in the folder array */ -static UINT next_folder_id = MAX_FOLDERS; -static UINT folderArrayLength = 0; /* Size of the folder array */ +static UINT numFolders = 0; /* Number of folder in the folder array */ +static UINT next_folder_id = MAX_FOLDERS; +static UINT folderArrayLength = 0; /* Size of the folder array */ static LPTREEFOLDER lpCurrentFolder = 0; /* Currently selected folder */ -static UINT nCurrentFolder = 0; /* Current folder ID */ -static WNDPROC g_lpTreeWndProc = 0; /* for subclassing the TreeView */ -static HIMAGELIST hTreeSmall = 0; /* TreeView Image list of icons */ - +static UINT nCurrentFolder = 0; /* Current folder ID */ +static WNDPROC g_lpTreeWndProc = 0; /* for subclassing the TreeView */ +static HIMAGELIST hTreeSmall = 0; /* TreeView Image list of icons */ /* this only has an entry for each TOP LEVEL extra folder + SubFolders*/ LPEXFOLDERDATA ExtraFolderData[MAX_EXTRA_FOLDERS * MAX_EXTRA_SUBFOLDERS]; static int numExtraFolders = 0; static int numExtraIcons = 0; static char *ExtraFolderIcons[MAX_EXTRA_FOLDERS]; - // built in folders and filters static LPCFOLDERDATA g_lpFolderData; static LPCFILTER_ITEM g_lpFilterList; @@ -105,73 +96,86 @@ static LPCFILTER_ITEM g_lpFilterList; private function prototypes ***************************************************************************/ -extern BOOL InitFolders(void); -static BOOL CreateTreeIcons(void); -static void TreeCtrlOnPaint(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -static const char *ParseManufacturer(const char *s, int *pParsedChars ); -static const char *TrimManufacturer(const char *s); -static BOOL AddFolder(LPTREEFOLDER lpFolder); +static bool InitFolders(void); +static bool CreateTreeIcons(void); +static void CreateAllChildFolders(void); +static bool AddFolder(LPTREEFOLDER lpFolder); static LPTREEFOLDER NewFolder(const char *lpTitle, UINT nFolderId, int nParent, UINT nIconId, DWORD dwFlags); static void DeleteFolder(LPTREEFOLDER lpFolder); static LRESULT CALLBACK TreeWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); static int InitExtraFolders(void); static void FreeExtraFolders(void); static void SetExtraIcons(char *name, int *id); -static BOOL TryAddExtraFolderAndChildren(int parent_index); -static BOOL TrySaveExtraFolder(LPTREEFOLDER lpFolder); -static void SaveExternalFolders(int parent_index, const char *fname); +static bool TryAddExtraFolderAndChildren(int parent_index); +static bool TrySaveExtraFolder(LPTREEFOLDER lpFolder); +static void LoadExternalFolders(int parent_index, int id); +static void SaveExternalFolders(int parent_index); +//static bool FilterAvailable(int driver_index); /*************************************************************************** - public functions + Functions to build builtin folder lists + ***************************************************************************/ +#if 0 +static void CreateManufacturerFolders(int parent_index); +static void CreateYearFolders(int parent_index); +static void CreateSourceFolders(int parent_index); +static void CreateDeficiencyFolders(int parent_index); +static void CreateBIOSFolders(int parent_index); +static void CreateCPUFolders(int parent_index); +static void CreateSoundFolders(int parent_index); +static void CreateScreenFolders(int parent_index); +static void CreateFPSFolders(int parent_index); +static void CreateResolutionFolders(int parent_index); +static void CreateSaveStateFolders(int parent_index); +static void CreateDumpingFolders(int parent_index); +#endif +/*************************************************************************** + public structures ***************************************************************************/ -BOOL win_move_file_utf8(const char *existingfilename, const char *newfilename) -{ - BOOL result = false; - - TCHAR *t_existingfilename = ui_wstring_from_utf8(existingfilename); - if( !t_existingfilename ) - return result; - - TCHAR *t_newfilename = ui_wstring_from_utf8(newfilename); - if( !t_newfilename ) { - free(t_existingfilename); - return result; - } - - result = MoveFile(t_existingfilename, t_newfilename); - - free(t_newfilename); - free(t_existingfilename); - - return result; -} - -/************************************************************************** - * ci_strncmp - case insensitive character array compare - * - * Returns zero if the first n characters of s1 and s2 are equal, - * ignoring case. - * stolen from datafile.c - **************************************************************************/ -static int ci_strncmp (const char *s1, const char *s2, int n) +static const TREEICON treeIconNames[] = { - int c1 = 0, c2 = 0; - while (n) - { - if ((c1 = tolower (*s1)) != (c2 = tolower (*s2))) - return (c1 - c2); - else - if (!c1) - break; - --n; - s1++; - s2++; - } - return 0; -} - +// { IDI_FOLDER_OPEN, "foldopen" }, + { IDI_FOLDER, "folder" }, + { IDI_FOLDER_ALLGAMES, "allgames" }, + { IDI_FOLDER_AVAILABLE, "foldavail" }, + { IDI_FOLDER_BIOS, "foldcsb" }, + { IDI_FOLDER_CLONES, "foldclone" }, + { IDI_FOLDER_CPU, "foldcsb" }, + { IDI_FOLDER_DUMP, "foldcsb" }, + { IDI_FOLDER_FPS, "foldfps" }, + { IDI_FOLDER_HARDDISK, "harddisk" }, + { IDI_FOLDER_HORIZONTAL, "horz" }, + { IDI_FOLDER_IMPERFECT, "foldimp" }, + { IDI_FOLDER_LIGHTGUN, "foldgun" }, + { IDI_FOLDER_MANUFACTURER, "foldmanu" }, + { IDI_FOLDER_MECHANICAL, "mechanical" }, + { IDI_FOLDER_MONITOR, "multimon" }, + { IDI_FOLDER_NONWORKING, "nonwork" }, + { IDI_FOLDER_ORIGINALS, "foldorig" }, + { IDI_FOLDER_RASTER, "foldrast" }, + { IDI_FOLDER_RESOL, "foldres" }, + { IDI_FOLDER_SAMPLES, "foldsamp" }, + { IDI_FOLDER_SAVESTATE, "savestate" }, + { IDI_FOLDER_SOUND, "foldsamp" }, + { IDI_FOLDER_SOURCE, "foldsrc" }, + { IDI_SOURCE, "source" }, + { IDI_FOLDER_TRACKBALL, "foldball" }, + { IDI_FOLDER_UNAVAILABLE, "foldunav" }, + { IDI_FOLDER_VECTOR, "foldvect" }, + { IDI_FOLDER_VERTICAL, "vert" }, + { IDI_FOLDER_WORKING, "working" }, + { IDI_FOLDER_YEAR, "foldyear" }, + { IDI_BIOS, "bios" }, + { IDI_CHIP, "chip" }, + { IDI_MANUFACTURER, "manufact" }, + { IDI_MONITOR, "monitor" }, + { IDI_YEAR, "year" }, +}; +/*************************************************************************** + public functions + ***************************************************************************/ /* De-allocate all folder memory */ void FreeFolders(void) @@ -190,9 +194,11 @@ void FreeFolders(void) treeFolders[i] = NULL; numFolders--; } + free(treeFolders); treeFolders = NULL; } + numFolders = 0; } @@ -210,7 +216,6 @@ void InitTree(LPCFOLDERDATA lpFolderData, LPCFILTER_ITEM lpFilterList) g_lpFilterList = lpFilterList; InitFolders(); - /* this will subclass the treeview (where WM_DRAWITEM gets sent for the header control) */ LONG_PTR l = GetWindowLongPtr(GetTreeView(), GWLP_WNDPROC); g_lpTreeWndProc = (WNDPROC)l; @@ -245,9 +250,11 @@ LPTREEFOLDER GetFolder(UINT nFolder) LPTREEFOLDER GetFolderByID(UINT nID) { - for (UINT i = 0; i < numFolders; i++) + for (int i = 0; i < numFolders; i++) + { if (treeFolders[i]->m_nFolderId == nID) return treeFolders[i]; + } return (LPTREEFOLDER)0; } @@ -271,23 +278,22 @@ int FindGame(LPTREEFOLDER lpFolder, int nGame) // Called to re-associate games with folders void ResetWhichGamesInFolders(void) { - int nGames = driver_list::total(); - - for (UINT i = 0; i < numFolders; i++) + for (int i = 0; i < numFolders; i++) { LPTREEFOLDER lpFolder = treeFolders[i]; // setup the games in our built-in folders - for (UINT k = 0; g_lpFolderData[k].m_lpTitle; k++) + for (int k = 0; g_lpFolderData[k].m_lpTitle; k++) { if (lpFolder->m_nFolderId == g_lpFolderData[k].m_nFolderId) { if (g_lpFolderData[k].m_pfnQuery || g_lpFolderData[k].m_bExpectedResult) { SetAllBits(lpFolder->m_lpGameBits, false); - for (UINT jj = 0; jj < nGames; jj++) + + for (int jj = 0; jj < driver_list::total(); jj++) { // invoke the query function - BOOL b = g_lpFolderData[k].m_pfnQuery ? g_lpFolderData[k].m_pfnQuery(jj) : true; + bool b = g_lpFolderData[k].m_pfnQuery ? g_lpFolderData[k].m_pfnQuery(jj) : true; // if we expect false, flip the result if (!g_lpFolderData[k].m_bExpectedResult) @@ -304,32 +310,33 @@ void ResetWhichGamesInFolders(void) } } - /* Used to build the GameList */ -BOOL GameFiltered(int nGame, DWORD dwMask) +bool GameFiltered(int nGame, DWORD dwMask) { LPTREEFOLDER lpFolder = GetCurrentFolder(); - LPTREEFOLDER lpParent = NULL; //Filter out the Bioses on all Folders, except for the Bios Folder - if( lpFolder->m_nFolderId != FOLDER_BIOS ) + if(lpFolder && lpFolder->m_nFolderId != FOLDER_BIOS) { -// if( !( (driver_list::driver(nGame).flags & MACHINE_IS_BIOS_ROOT ) == 0) ) -// return true; - if( driver_list::driver(nGame).name[0] == '_' ) + if(DriverIsBios(nGame)) return true; } + + if(driver_list::driver(nGame).name[0] == '_') + return true; + // Filter games--return true if the game should be HIDDEN in this view - if( GetFilterInherit() ) + if(GetFilterInherit()) { - if( lpFolder ) + if(lpFolder) { - lpParent = GetFolder( lpFolder->m_nParent ); - if( lpParent ) + LPTREEFOLDER lpParent = GetFolder(lpFolder->m_nParent); + + if(lpParent) { - /* Check the Parent Filters and inherit them on child, - * The inherited filters don't display on the custom Filter Dialog for the Child folder - * No need to promote all games to parent folder, works as is */ + /* Check the Parent Filters and inherit them on child, + * The inherited filters don't display on the custom Filter Dialog for the Child folder + * No need to promote all games to parent folder, works as is */ dwMask |= lpParent->m_dwFlags; } } @@ -345,9 +352,8 @@ BOOL GameFiltered(int nGame, DWORD dwMask) MyStrStrI(driver_list::driver(nGame).name,GetFilterText()) == NULL && MyStrStrI(driver_list::driver(nGame).type.source(),GetFilterText()) == NULL && MyStrStrI(driver_list::driver(nGame).manufacturer,GetFilterText()) == NULL) - { return true; - } + // Are there filters set on this folder? if ((dwMask & F_MASK) == 0) return false; @@ -365,11 +371,11 @@ BOOL GameFiltered(int nGame, DWORD dwMask) } /* Get the parent of game in this view */ -BOOL GetParentFound(int nGame) // not used +bool GetParentFound(int nGame) { LPTREEFOLDER lpFolder = GetCurrentFolder(); - if( lpFolder ) + if(lpFolder) { int nParentIndex = GetParentIndex(&driver_list::driver(nGame)); @@ -399,513 +405,224 @@ LPCFILTER_ITEM GetFilterList(void) /*************************************************************************** private functions ***************************************************************************/ - +//#if 0 void CreateSourceFolders(int parent_index) { - int i, k=0; - int nGames = driver_list::total(); + int i = 0; int start_folder = numFolders; LPTREEFOLDER lpFolder = treeFolders[parent_index]; + LPTREEFOLDER lpTemp; // no games in top level folder - SetAllBits(lpFolder->m_lpGameBits,false); - for (int jj = 0; jj < nGames; jj++) + SetAllBits(lpFolder->m_lpGameBits, false); + + for (int jj = 0; jj < driver_list::total(); jj++) { - const char *s = GetDriverFilename(jj); - - if (s == NULL || s[0] == '\0') - continue; + const char *source = GetDriverFilename(jj); // look for an existant source treefolder for this game // (likely to be the previous one, so start at the end) - for (i=numFolders-1;i>=start_folder;i--) + for (i = numFolders - 1; i >= start_folder; i--) { - if (strcmp(treeFolders[i]->m_lpTitle,s) == 0) + if (strcmp(treeFolders[i]->m_lpTitle, source) == 0) { AddGame(treeFolders[i], jj); break; } } - if (i == start_folder-1) + if (i == start_folder - 1) { // nope, it's a source file we haven't seen before, make it. - LPTREEFOLDER lpTemp = NewFolder(s, next_folder_id, parent_index, IDI_SOURCE, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); - - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_SOURCE; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, s ); - ExtraFolderData[next_folder_id]->m_dwFlags = 0; - - // Increment next_folder_id here in case code is added above - next_folder_id++; - + lpTemp = NewFolder(source, next_folder_id++, parent_index, IDI_SOURCE, GetFolderFlags(numFolders)); AddFolder(lpTemp); AddGame(lpTemp, jj); } } - SetNumOptionFolders(k-1); - const char *fname = "Source"; - SaveExternalFolders(parent_index, fname); + + SetNumOptionFolders(-1); } -void CreateScreenFolders(int parent_index) +void CreateManufacturerFolders(int parent_index) { - int i, k=0; - int nGames = driver_list::total(); + int i = 0; int start_folder = numFolders; LPTREEFOLDER lpFolder = treeFolders[parent_index]; + LPTREEFOLDER lpTemp; // no games in top level folder - SetAllBits(lpFolder->m_lpGameBits,false); - for (int jj = 0; jj < nGames; jj++) + SetAllBits(lpFolder->m_lpGameBits, false); + + for (int jj = 0; jj < driver_list::total(); jj++) { - int screens = DriverNumScreens(jj); - char s[2]; - itoa(screens, s, 10); + const char *made = driver_list::driver(jj).manufacturer; - // look for an existant screens treefolder for this game + // look for an existant manufacturer treefolder for this game // (likely to be the previous one, so start at the end) - for (i=numFolders-1;i>=start_folder;i--) + for (i = numFolders - 1; i >= start_folder; i--) { - if (strcmp(treeFolders[i]->m_lpTitle,s) == 0) + if (strcmp(treeFolders[i]->m_lpTitle, made) == 0) { AddGame(treeFolders[i], jj); break; } } - if (i == start_folder-1) + if (i == start_folder - 1) { - // nope, it's a screen file we haven't seen before, make it. - LPTREEFOLDER lpTemp = NewFolder(s, next_folder_id, parent_index, IDI_SCREEN, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); - - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_SCREEN; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, s ); - ExtraFolderData[next_folder_id]->m_dwFlags = 0; - - // Increment next_folder_id here in case code is added above - next_folder_id++; - + // nope, it's a manufacturer we haven't seen before, make it. + lpTemp = NewFolder(made, next_folder_id++, parent_index, IDI_MANUFACTURER, GetFolderFlags(numFolders)); AddFolder(lpTemp); AddGame(lpTemp, jj); } } - SetNumOptionFolders(k-1); - const char *fname = "Screen"; - SaveExternalFolders(parent_index, fname); } - -void CreateManufacturerFolders(int parent_index) +void CreateDeficiencyFolders(int parent_index) { - int i; - int nGames = driver_list::total(); - int start_folder = numFolders; LPTREEFOLDER lpFolder = treeFolders[parent_index]; + LPTREEFOLDER lpWrongCol, lpImpCol, lpImpGraph, lpMissSnd, lpImpSnd, lpIncomplete, lpNoSndHw; // no games in top level folder - SetAllBits(lpFolder->m_lpGameBits,false); + SetAllBits(lpFolder->m_lpGameBits, false); + // create our subfolders + lpWrongCol = NewFolder("Wrong Colors", next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + lpImpCol = NewFolder("Imperfect Colors", next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + lpImpGraph = NewFolder("Imperfect Graphics", next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + lpMissSnd = NewFolder("Missing Sound", next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + lpImpSnd = NewFolder("Imperfect Sound", next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + lpIncomplete = NewFolder("Incomplete Prototype", next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + lpNoSndHw = NewFolder("No Sound Hardware", next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + AddFolder(lpWrongCol); + AddFolder(lpImpCol); + AddFolder(lpImpGraph); + AddFolder(lpMissSnd); + AddFolder(lpImpSnd); + AddFolder(lpIncomplete); + AddFolder(lpNoSndHw); - for (int jj = 0; jj < nGames; jj++) + for (int jj = 0; jj < driver_list::total(); jj++) { - const char *manufacturer = driver_list::driver(jj).manufacturer; - int iChars = 0; - while( manufacturer != NULL && manufacturer[0] != '\0' ) - { - const char *s = ParseManufacturer(manufacturer, &iChars); - manufacturer += iChars; - //shift to next start char - if( s != NULL && *s != 0 ) - { - const char *t = TrimManufacturer(s); - for (i=numFolders-1;i>=start_folder;i--) - { - //RS Made it case insensitive - if (ci_strncmp(treeFolders[i]->m_lpTitle,t,20) == 0 ) - { - AddGame(treeFolders[i],jj); - break; - } - } + uint32_t cache = GetDriverCacheLower(jj); + if (BIT(cache, 21)) + AddGame(lpWrongCol, jj); - if (i == start_folder-1) - { - // nope, it's a manufacturer we haven't seen before, make it. - LPTREEFOLDER lpTemp = NewFolder(t, next_folder_id, parent_index, IDI_MANUFACTURER, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); - - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_MANUFACTURER; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, s ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpTemp); - AddGame(lpTemp,jj); - } - } - } - } - const char *fname = "Manufacturer"; - SaveExternalFolders(parent_index, fname); -} + if (BIT(cache, 20)) + AddGame(lpImpCol, jj); -/* Make a reasonable name out of the one found in the driver array */ -static const char *ParseManufacturer(const char *s, int *pParsedChars ) -{ - static char tmp[256]; - char *ptmp; - char *t; - *pParsedChars= 0; + if (BIT(cache, 18)) + AddGame(lpImpGraph, jj); - if ( *s == '?' || *s == '<' || s[3] == '?' ) - { - (*pParsedChars) = strlen(s); - return "<unknown>"; + if (BIT(cache, 17)) + AddGame(lpMissSnd, jj); + + if (BIT(cache, 16)) + AddGame(lpImpSnd, jj); + + if (BIT(cache, 15)) + AddGame(lpIncomplete, jj); + + if (BIT(cache, 13)) + AddGame(lpNoSndHw, jj); } +} - ptmp = tmp; - /*if first char is a space, skip it*/ - if( *s == ' ' ) +void CreateYearFolders(int parent_index) +{ + if (!RequiredDriverCache()) { - (*pParsedChars)++; - ++s; + LoadExternalFolders(parent_index, IDI_YEAR); + return; } - while( *s ) - { - /* combinations where to end string */ - if ( - ( (*s == ' ') && ( s[1] == '(' || s[1] == '/' || s[1] == '+' ) ) || - ( *s == ']' ) || ( *s == '/' ) || ( *s == '?' ) ) - { - (*pParsedChars)++; - if( s[1] == '/' || s[1] == '+' ) - (*pParsedChars)++; - break; - } - if( s[0] == ' ' && s[1] == '?' ) - { - (*pParsedChars) += 2; - s+=2; - } + int i = 0; + int nGames = driver_list::total(); + int start_folder = numFolders; + LPTREEFOLDER lpFolder = treeFolders[parent_index]; - /* skip over opening braces*/ + // no games in top level folder + SetAllBits(lpFolder->m_lpGameBits, false); - if ( *s != '[' ) - { - *ptmp++ = *s; - } - (*pParsedChars)++; - /*for "distributed by" and "supported by" handling*/ - if( ( (s[1] == ',') && (s[2] == ' ') && ( (s[3] == 's') || (s[3] == 'd') ) ) ) - { - //*ptmp++ = *s; - ++s; - break; - } - ++s; - } - *ptmp = '\0'; - t = tmp; - if( tmp[0] == '(' || tmp[strlen(tmp)-1] == ')' || tmp[0] == ',') + for (int jj = 0; jj < nGames; jj++) { - ptmp = strchr( tmp,'(' ); - if ( ptmp == NULL ) - { - ptmp = strchr( tmp,',' ); - if( ptmp != NULL) - { - //parse the new "supported by" and "distributed by" - ptmp++; + char s[16]; + int t1 = sizeof(s); + memset(s, '\0', sizeof(s)); + int t2 = sizeof(driver_list::driver(jj).year)+1; + if (t2 > t1) + t2 = t1; + if (t2) + strcpy_s(s, t2, driver_list::driver(jj).year); - if (ci_strncmp(ptmp, " supported by", 13) == 0) - { - ptmp += 13; - } - else if (ci_strncmp(ptmp, " distributed by", 15) == 0) - { - ptmp += 15; - } - else - { - return NULL; - } - } - else - { - ptmp = tmp; - if ( ptmp == NULL ) - { - return NULL; - } - } - } - if( tmp[0] == '(' || tmp[0] == ',') - { - ptmp++; - } - if (ci_strncmp(ptmp, "licensed from ", 14) == 0) - { - ptmp += 14; - } - // for the licenced from case - if (ci_strncmp(ptmp, "licenced from ", 14) == 0) - { - ptmp += 14; - } + if (s[0] == '\0' || s[0] == '?') + continue; - while ( (*ptmp != ')' ) && (*ptmp != '/' ) && *ptmp != '\0') + if (s[4] == '?') + s[4] = '\0'; + + // look for an extant year treefolder for this game + // (likely to be the previous one, so start at the end) + for (i=numFolders-1;i>=start_folder;i--) { - if (*ptmp == ' ' && ci_strncmp(ptmp, " license", 8) == 0) - { - break; - } - if (*ptmp == ' ' && ci_strncmp(ptmp, " licence", 8) == 0) + if (strncmp(treeFolders[i]->m_lpTitle, s, 4) == 0) { + AddGame(treeFolders[i], jj); break; } - *t++ = *ptmp++; } - - *t = '\0'; - } - - *ptmp = '\0'; - return tmp; -} - -/* Analyze Manufacturer Names for typical patterns, that don't distinguish between companies (e.g. Co., Ltd., Inc., etc. */ -static const char *TrimManufacturer(const char *s) -{ - //Also remove Country specific suffixes (e.g. Japan, Italy, America, USA, ...) - char strTemp[256]; - static char strTemp2[256]; - int j, k ,l; - memset(strTemp, '\0', 256 ); - memset(strTemp2, '\0', 256 ); - //start analyzing from the back, as these are usually suffixes - for(int i = strlen(s)-1; i>=0; i-- ) - { - l = strlen(strTemp); - for(k=l; k>=0; k--) - strTemp[k+1] = strTemp[k]; - strTemp[0] = s[i]; - strTemp[++l] = '\0'; - switch (l) + if (i == start_folder-1) { - case 2: - if( ci_strncmp(strTemp, "co", 2) == 0 ) - { - j=l; - while( s[strlen(s)-j-1] == ' ' || s[strlen(s)-j-1] == ',' ) - { - j++; - } - if( j!=l) - { - memset(strTemp2, '\0', 256 ); - strncpy(strTemp2, s, strlen(s)-j ); - } - } - break; - case 3: - if( ci_strncmp(strTemp, "co.", 3) == 0 || ci_strncmp(strTemp, "ltd", 3) == 0 || ci_strncmp(strTemp, "inc", 3) == 0 || ci_strncmp(strTemp, "SRL", 3) == 0 || ci_strncmp(strTemp, "USA", 3) == 0) - { - j=l; - while( s[strlen(s)-j-1] == ' ' || s[strlen(s)-j-1] == ',' ) - { - j++; - } - if( j!=l) - { - memset(strTemp2, '\0', 256 ); - strncpy(strTemp2, s, strlen(s)-j ); - } - } - break; - case 4: - if( ci_strncmp(strTemp, "inc.", 4) == 0 || ci_strncmp(strTemp, "ltd.", 4) == 0 || ci_strncmp(strTemp, "corp", 4) == 0 || ci_strncmp(strTemp, "game", 4) == 0) - { - j=l; - while( s[strlen(s)-j-1] == ' ' || s[strlen(s)-j-1] == ',' ) - { - j++; - } - if( j!=l) - { - memset(strTemp2, '\0', 256 ); - strncpy(strTemp2, s, strlen(s)-j ); - } - } - break; - case 5: - if( ci_strncmp(strTemp, "corp.", 5) == 0 || ci_strncmp(strTemp, "Games", 5) == 0 || ci_strncmp(strTemp, "Italy", 5) == 0 || ci_strncmp(strTemp, "Japan", 5) == 0) - { - j=l; - while( s[strlen(s)-j-1] == ' ' || s[strlen(s)-j-1] == ',' ) - { - j++; - } - if( j!=l) - { - memset(strTemp2, '\0', 256 ); - strncpy(strTemp2, s, strlen(s)-j ); - } - } - break; - case 6: - if( ci_strncmp(strTemp, "co-ltd", 6) == 0 || ci_strncmp(strTemp, "S.R.L.", 6) == 0) - { - j=l; - while( s[strlen(s)-j-1] == ' ' || s[strlen(s)-j-1] == ',' ) - { - j++; - } - if( j!=l) - { - memset(strTemp2, '\0', 256 ); - strncpy(strTemp2, s, strlen(s)-j ); - } - } - break; - case 7: - if( ci_strncmp(strTemp, "co. ltd", 7) == 0 || ci_strncmp(strTemp, "America", 7) == 0) - { - j=l; - while( s[strlen(s)-j-1] == ' ' || s[strlen(s)-j-1] == ',' ) - { - j++; - } - if( j!=l) - { - memset(strTemp2, '\0', 256 ); - strncpy(strTemp2, s, strlen(s)-j ); - } - } - break; - case 8: - if( ci_strncmp(strTemp, "co. ltd.", 8) == 0 ) - { - j=l; - while( s[strlen(s)-j-1] == ' ' || s[strlen(s)-j-1] == ',' ) - { - j++; - } - if( j!=l) - { - memset(strTemp2, '\0', 256 ); - strncpy(strTemp2, s, strlen(s)-j ); - } - } - break; - case 9: - if( ci_strncmp(strTemp, "co., ltd.", 9) == 0 || ci_strncmp(strTemp, "gmbh & co", 9) == 0 ) - { - j=l; - while( s[strlen(s)-j-1] == ' ' || s[strlen(s)-j-1] == ',' ) - { - j++; - } - if( j!=l) - { - memset(strTemp2, '\0', 256 ); - strncpy(strTemp2, s, strlen(s)-j ); - } - } - break; - case 10: - if( ci_strncmp(strTemp, "corp, ltd.", 10) == 0 || ci_strncmp(strTemp, "industries", 10) == 0 || ci_strncmp(strTemp, "of America", 10) == 0) - { - j=l; - while( s[strlen(s)-j-1] == ' ' || s[strlen(s)-j-1] == ',' ) - { - j++; - } - if( j!=l) - { - memset(strTemp2, '\0', 256 ); - strncpy(strTemp2, s, strlen(s)-j ); - } - } - break; - case 11: - if( ci_strncmp(strTemp, "corporation", 11) == 0 || ci_strncmp(strTemp, "enterprises", 11) == 0 ) - { - j=l; - while( s[strlen(s)-j-1] == ' ' || s[strlen(s)-j-1] == ',' ) - { - j++; - } - if( j!=l) - { - memset(strTemp2, '\0', 256 ); - strncpy(strTemp2, s, strlen(s)-j ); - } - } - break; - case 16: - if( ci_strncmp(strTemp, "industries japan", 16) == 0 ) - { - j=l; - while( s[strlen(s)-j-1] == ' ' || s[strlen(s)-j-1] == ',' ) - { - j++; - } - if( j!=l) - { - memset(strTemp2, '\0', 256 ); - strncpy(strTemp2, s, strlen(s)-j ); - } - } - break; - default: - break; + // nope, it's a year we haven't seen before, make it. + //printf("%s ",s); + LPTREEFOLDER lpTemp = NewFolder(s, next_folder_id, parent_index, IDI_YEAR, GetFolderFlags(numFolders)); + ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); + memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); + ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; + ExtraFolderData[next_folder_id]->m_nIconId = IDI_YEAR; + ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; + ExtraFolderData[next_folder_id]->m_nSubIconId = -1; + strcpy( ExtraFolderData[next_folder_id]->m_szTitle, s ); + ExtraFolderData[next_folder_id++]->m_dwFlags = 0; + AddFolder(lpTemp); + AddGame(lpTemp, jj); } } - if( *strTemp2 == 0 ) - return s; - return strTemp2; + + SaveExternalFolders(parent_index); } void CreateBIOSFolders(int parent_index) { - int i, nGames = driver_list::total(); + int i = 0; int start_folder = numFolders; const game_driver *drv; int nParentIndex = -1; LPTREEFOLDER lpFolder = treeFolders[parent_index]; + LPTREEFOLDER lpTemp; // no games in top level folder SetAllBits(lpFolder->m_lpGameBits, false); - for (int jj = 0; jj < nGames; jj++) + for (int jj = 0; jj < driver_list::total(); jj++) { - if ( DriverIsClone(jj) ) + if (DriverIsClone(jj)) { nParentIndex = GetParentIndex(&driver_list::driver(jj)); - if (nParentIndex < 0) return; + + if (nParentIndex < 0) + return; + drv = &driver_list::driver(nParentIndex); } else drv = &driver_list::driver(jj); + nParentIndex = GetParentIndex(drv); if (nParentIndex < 0 || !driver_list::driver(nParentIndex).type.fullname()) continue; - for (i = numFolders-1; i >= start_folder; i--) + for (i = numFolders - 1; i >= start_folder; i--) { if (strcmp(treeFolders[i]->m_lpTitle, driver_list::driver(nParentIndex).type.fullname()) == 0) { @@ -914,573 +631,616 @@ void CreateBIOSFolders(int parent_index) } } - if (i == start_folder-1) + if (i == start_folder - 1) { - LPTREEFOLDER lpTemp = NewFolder(driver_list::driver(nParentIndex).type.fullname(), next_folder_id++, parent_index, IDI_CPU, GetFolderFlags(numFolders)); + lpTemp = NewFolder(driver_list::driver(nParentIndex).type.fullname(), next_folder_id++, parent_index, IDI_BIOS, GetFolderFlags(numFolders)); AddFolder(lpTemp); AddGame(lpTemp, jj); } } - const char *fname = "BIOS"; - SaveExternalFolders(parent_index, fname); } -void CreateCPUFolders(int parent_index) +void CreateScreenFoldersIni(int parent_index) { - int device_folder_count = 0; - LPTREEFOLDER device_folders[1024]; - LPTREEFOLDER folder; - int nFolder = numFolders; + int i = 0; + int start_folder = numFolders; + LPTREEFOLDER lpFolder = treeFolders[parent_index]; + LPTREEFOLDER lpTemp; - for (int i = 0; i < driver_list::total(); i++) + // no games in top level folder + SetAllBits(lpFolder->m_lpGameBits, false); + + for (int jj = 0; jj < driver_list::total(); jj++) { - machine_config config(driver_list::driver(i),MameUIGlobal()); + char screen[4]; + snprintf(screen, std::size(screen), "%d", DriverNumScreens(jj)); + + // look for an existant screen treefolder for this game + // (likely to be the previous one, so start at the end) + for (i = numFolders - 1; i >= start_folder; i--) + { + if (strcmp(treeFolders[i]->m_lpTitle, screen) == 0) + { + AddGame(treeFolders[i], jj); + break; + } + } + + if (i == start_folder - 1) + { + // nope, it's a screen we haven't seen before, make it. + lpTemp = NewFolder(screen, next_folder_id++, parent_index, IDI_MONITOR, GetFolderFlags(numFolders)); + AddFolder(lpTemp); + AddGame(lpTemp, jj); + } + } +} + +void CreateCPUFoldersIni(int parent_index) +{ + int i = 0; + int start_folder = numFolders; + LPTREEFOLDER lpFolder = treeFolders[parent_index]; + LPTREEFOLDER lpTemp; + + // no games in top level folder + SetAllBits(lpFolder->m_lpGameBits, false); + + for (int jj = 0; jj < driver_list::total(); jj++) + { + machine_config config(driver_list::driver(jj), MameUIGlobal()); // enumerate through all devices for (device_execute_interface &device : execute_interface_enumerator(config.root_device())) { // get the name - const char* dev_name = device.device().name(); + const char *cpu = device.device().name(); - if (dev_name) + // look for an existant CPU treefolder for this game + // (likely to be the previous one, so start at the end) + for (i = numFolders - 1; i >= start_folder; i--) { - // do we have a folder for this device? - folder = NULL; - for (int j = 0; j < device_folder_count; j++) - { - if (strcmp(dev_name, device_folders[j]->m_lpTitle)==0) - { - folder = device_folders[j]; - break; - } - } - - // are we forced to create a folder? - if (folder == NULL) + if (strcmp(treeFolders[i]->m_lpTitle, cpu) == 0) { - LPTREEFOLDER lpTemp = NewFolder(dev_name, next_folder_id, parent_index, IDI_CPU, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_CPU; - ExtraFolderData[next_folder_id]->m_nParent = treeFolders[parent_index]->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, dev_name ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpTemp); - folder = treeFolders[nFolder++]; - - // record that we found this folder - device_folders[device_folder_count++] = folder; - if (device_folder_count >= std::size(device_folders)) - { - printf("CreateCPUFolders buffer overrun: %d\n",device_folder_count); - fflush(stdout); - } + AddGame(treeFolders[i], jj); + break; } + } - // cpu type #'s are one-based - AddGame(folder, i); + if (i == start_folder - 1) + { + // nope, it's a CPU we haven't seen before, make it. + lpTemp = NewFolder(cpu, next_folder_id++, parent_index, IDI_CHIP, GetFolderFlags(numFolders)); + AddFolder(lpTemp); + AddGame(lpTemp, jj); } } } - const char *fname = "CPU"; - SaveExternalFolders(parent_index, fname); } -void CreateSoundFolders(int parent_index) +void CreateSoundFoldersIni(int parent_index) { - int device_folder_count = 0; - LPTREEFOLDER device_folders[512]; - LPTREEFOLDER folder; - int nFolder = numFolders; + int i = 0; + int start_folder = numFolders; + LPTREEFOLDER lpFolder = treeFolders[parent_index]; + LPTREEFOLDER lpTemp; - for (int i = 0; i < driver_list::total(); i++) + // no games in top level folder + SetAllBits(lpFolder->m_lpGameBits, false); + + for (int jj = 0; jj < driver_list::total(); jj++) { - machine_config config(driver_list::driver(i),MameUIGlobal()); + machine_config config(driver_list::driver(jj), MameUIGlobal()); // enumerate through all devices - for (device_sound_interface &device : sound_interface_enumerator(config.root_device())) { // get the name - const char* dev_name = device.device().name(); + const char *sound = device.device().name(); - if (dev_name) + // look for an existant sound chip treefolder for this game + // (likely to be the previous one, so start at the end) + for (i = numFolders - 1; i >= start_folder; i--) { - // do we have a folder for this device? - folder = NULL; - for (int j = 0; j < device_folder_count; j++) - { - if (strcmp(dev_name, device_folders[j]->m_lpTitle)==0) - { - folder = device_folders[j]; - break; - } - } - - // are we forced to create a folder? - if (folder == NULL) + if (strcmp(treeFolders[i]->m_lpTitle, sound) == 0) { - LPTREEFOLDER lpTemp = NewFolder(dev_name, next_folder_id, parent_index, IDI_SOUND, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); - - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_SOUND; - ExtraFolderData[next_folder_id]->m_nParent = treeFolders[parent_index]->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, dev_name ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpTemp); - folder = treeFolders[nFolder++]; - - // record that we found this folder - device_folders[device_folder_count++] = folder; - if (device_folder_count >= std::size(device_folders)) - { - printf("CreateSoundFolders buffer overrun: %d\n",device_folder_count); - fflush(stdout); - } + AddGame(treeFolders[i], jj); + break; } + } - // cpu type #'s are one-based - AddGame(folder, i); + if (i == start_folder - 1) + { + // nope, it's a sound chip we haven't seen before, make it. + lpTemp = NewFolder(sound, next_folder_id++, parent_index, IDI_CHIP, GetFolderFlags(numFolders)); + AddFolder(lpTemp); + AddGame(lpTemp, jj); } } } - const char *fname = "Sound"; - SaveExternalFolders(parent_index, fname); } -void CreateDeficiencyFolders(int parent_index) +void CreateSaveStateFolders(int parent_index) { - int nGames = driver_list::total(); LPTREEFOLDER lpFolder = treeFolders[parent_index]; + LPTREEFOLDER lpSupported, lpUnsupported; - // create our subfolders - LPTREEFOLDER lpProt, lpWrongCol, lpImpCol, lpImpGraph, lpMissSnd, lpImpSnd, lpFlip, lpArt; - lpProt = NewFolder("Unemulated Protection", next_folder_id, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); - - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_FOLDER; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, "Unemulated Protection" ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpProt); - lpWrongCol = NewFolder("Wrong Colors", next_folder_id, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); - - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_FOLDER; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, "Wrong Colors" ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpWrongCol); + // no games in top level folder + SetAllBits(lpFolder->m_lpGameBits,false); + // create our two subfolders + lpSupported = NewFolder("Supported", next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + lpUnsupported = NewFolder("Unsupported", next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + AddFolder(lpSupported); + AddFolder(lpUnsupported); - lpImpCol = NewFolder("Imperfect Colors", next_folder_id, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); + for (int jj = 0; jj < driver_list::total(); jj++) + { + if (DriverSupportsSaveState(jj)) + AddGame(lpSupported, jj); + else + AddGame(lpUnsupported, jj); + } +} - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_FOLDER; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, "Imperfect Colors" ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpImpCol); +void CreateResolutionFoldersIni(int parent_index) +{ + int i = 0; + int start_folder = numFolders; + LPTREEFOLDER lpFolder = treeFolders[parent_index]; + LPTREEFOLDER lpTemp, lpVectorH, lpVectorV, lpScreenless; - lpImpGraph = NewFolder("Imperfect Graphics", next_folder_id, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); + // no games in top level folder + SetAllBits(lpFolder->m_lpGameBits, false); + // create our two subfolders + lpVectorH = NewFolder("Vector (H)", next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + lpVectorV = NewFolder("Vector (V)", next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + lpScreenless = NewFolder("Screenless", next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + AddFolder(lpVectorH); + AddFolder(lpVectorV); + AddFolder(lpScreenless); + + for (int jj = 0; jj < driver_list::total(); jj++) + { + machine_config config(driver_list::driver(jj), MameUIGlobal()); + char res[32]; - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_FOLDER; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, "Imperfect Graphics" ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpImpGraph); + if (DriverIsVector(jj)) + { + if (DriverIsVertical(jj)) + { + AddGame(lpVectorV, jj); + continue; + } + else + { + AddGame(lpVectorH, jj); + continue; + } + } - lpMissSnd = NewFolder("Missing Sound", next_folder_id, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); + const screen_device *screen = screen_device_enumerator(config.root_device()).first(); - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_FOLDER; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, "Missing Sound" ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpMissSnd); + if (screen == nullptr) + { + AddGame(lpScreenless, jj); + continue; + } - lpImpSnd = NewFolder("Imperfect Sound", next_folder_id, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); + const rectangle &visarea = screen->visible_area(); - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_FOLDER; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, "Imperfect Sound" ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpImpSnd); + if (DriverIsVertical(jj)) + snprintf(res, std::size(res), "%d x %d (V)", visarea.width(), visarea.height()); + else + snprintf(res, std::size(res), "%d x %d (H)", visarea.width(), visarea.height()); - lpFlip = NewFolder("No Cocktail", next_folder_id, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); - - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_FOLDER; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, "No Cocktail" ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpFlip); - - lpArt = NewFolder("Requires Artwork", next_folder_id, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA) ); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); - - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_FOLDER; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, "Requires Artwork" ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpArt); - // no games in top level folder - SetAllBits(lpFolder->m_lpGameBits,false); + // look for an existant resolution treefolder for this game + // (likely to be the previous one, so start at the end) + for (i = numFolders - 1; i >= start_folder; i--) + { + if (strcmp(treeFolders[i]->m_lpTitle, res) == 0) + { + AddGame(treeFolders[i], jj); + break; + } + } - for (int jj = 0; jj < nGames; jj++) - { - uint32_t cache = GetDriverCacheLower(jj); - if (BIT(cache, 21)) - AddGame(lpWrongCol,jj); + if (i == start_folder - 1) + { + // nope, it's a resolution we haven't seen before, make it. + lpTemp = NewFolder(res, next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + AddFolder(lpTemp); + AddGame(lpTemp, jj); + } + } +} - if (BIT(cache, 22)) - AddGame(lpProt,jj); +void CreateFPSFoldersIni(int parent_index) +{ + int i = 0; + int start_folder = numFolders; + LPTREEFOLDER lpFolder = treeFolders[parent_index]; + LPTREEFOLDER lpTemp, lpVector, lpScreenless; - if (BIT(cache, 20)) - AddGame(lpImpCol,jj); + // no games in top level folder + SetAllBits(lpFolder->m_lpGameBits, false); + // create our two subfolders + lpVector = NewFolder("Vector", next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + lpScreenless = NewFolder("Screenless", next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + AddFolder(lpVector); + AddFolder(lpScreenless); - if (BIT(cache, 18)) - AddGame(lpImpGraph,jj); + for (int jj = 0; jj < driver_list::total(); jj++) + { + machine_config config(driver_list::driver(jj), MameUIGlobal()); + char fps[16]; + + if (DriverIsVector(jj)) + { + AddGame(lpVector, jj); + continue; + } - if (BIT(cache, 17)) - AddGame(lpMissSnd,jj); + const screen_device *screen = screen_device_enumerator(config.root_device()).first(); - if (BIT(cache, 16)) - AddGame(lpImpSnd,jj); + if (screen == nullptr) + { + AddGame(lpScreenless, jj); + continue; + } - if (BIT(cache, 8)) - AddGame(lpFlip,jj); + snprintf(fps, std::size(fps), "%f Hz", ATTOSECONDS_TO_HZ(screen->refresh_attoseconds())); - if (BIT(cache, 10)) - AddGame(lpArt,jj); + // look for an existant refresh treefolder for this game + // (likely to be the previous one, so start at the end) + for (i = numFolders - 1; i >= start_folder; i--) + { + if (strcmp(treeFolders[i]->m_lpTitle, fps) == 0) + { + AddGame(treeFolders[i], jj); + break; + } + } + + if (i == start_folder - 1) + { + // nope, it's a refresh we haven't seen before, make it. + lpTemp = NewFolder(fps, next_folder_id++, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + AddFolder(lpTemp); + AddGame(lpTemp, jj); + } } } -void CreateDumpingFolders(int parent_index) +void CreateDumpingFoldersIni(int parent_index) { - BOOL bBadDump = false; - BOOL bNoDump = false; - int nGames = driver_list::total(); LPTREEFOLDER lpFolder = treeFolders[parent_index]; - const rom_entry *rom; - const game_driver *gamedrv; - - // create our two subfolders - LPTREEFOLDER lpBad, lpNo; - lpBad = NewFolder("Bad Dump", next_folder_id, parent_index, IDI_FOLDER_DUMP, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); - - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_FOLDER_DUMP; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, "Bad Dump" ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpBad); - lpNo = NewFolder("No Dump", next_folder_id, parent_index, IDI_FOLDER_DUMP, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); - - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_FOLDER_DUMP; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, "No Dump" ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpNo); + LPTREEFOLDER lpBadDump, lpNoDump, lpGoodDump; // no games in top level folder SetAllBits(lpFolder->m_lpGameBits,false); - - for (int jj = 0; jj < nGames; jj++) + // create our two subfolders + lpNoDump = NewFolder("No Dump", next_folder_id, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + lpBadDump = NewFolder("Bad Dump", next_folder_id, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + lpGoodDump = NewFolder("Good Dump", next_folder_id, parent_index, IDI_FOLDER, GetFolderFlags(numFolders)); + AddFolder(lpNoDump); + AddFolder(lpBadDump); + AddFolder(lpGoodDump); + + for (int jj = 0; jj < driver_list::total(); jj++) { - gamedrv = &driver_list::driver(jj); + machine_config config(driver_list::driver(jj), MameUIGlobal()); + bool bBadDump = false; + bool bNoDump = false; - if (!gamedrv->rom) + if (!DriverUsesRoms(jj)) continue; - bBadDump = false; - bNoDump = false; - /* Allocate machine config */ - machine_config config(*gamedrv,MameUIGlobal()); for (device_t &device : device_enumerator(config.root_device())) { - for (const rom_entry *region = rom_first_region(device); region; region = rom_next_region(region)) + for (const rom_entry *region = rom_first_region(device); region != nullptr; region = rom_next_region(region)) { - for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) + for (const rom_entry *rom = rom_first_file(region); rom != nullptr; rom = rom_next_file(rom)) { - if (ROMREGION_ISROMDATA(region) || ROMREGION_ISDISKDATA(region) ) + if (ROMREGION_ISROMDATA(region) || ROMREGION_ISDISKDATA(region)) { - //name = ROM_GETNAME(rom); util::hash_collection hashes(rom->hashdata()); - if (hashes.flag(util::hash_collection::FLAG_BAD_DUMP)) - bBadDump = true; + if (hashes.flag(util::hash_collection::FLAG_NO_DUMP)) bNoDump = true; + + if (hashes.flag(util::hash_collection::FLAG_BAD_DUMP)) + bBadDump = true; } } } } - if (bBadDump) - AddGame(lpBad,jj); if (bNoDump) - AddGame(lpNo,jj); + { + AddGame(lpNoDump, jj); + continue; + } + + if (bBadDump) + { + AddGame(lpBadDump, jj); + continue; + } + + AddGame(lpGoodDump, jj); } - const char *fname = "Dumping"; - SaveExternalFolders(parent_index, fname); } +void CreateCPUFolders(int parent_index) +{ + if (RequiredDriverCache()) + { + CreateCPUFoldersIni(parent_index); + SaveExternalFolders(parent_index); + } + else + LoadExternalFolders(parent_index, IDI_CHIP); + + SendMessage(GetProgressBar(), PBM_SETPOS, 20, 0); +} -void CreateYearFolders(int parent_index) +void CreateSoundFolders(int parent_index) { - int i,jj; - int nGames = driver_list::total(); - int start_folder = numFolders; - LPTREEFOLDER lpFolder = treeFolders[parent_index]; + if (RequiredDriverCache()) + { + CreateSoundFoldersIni(parent_index); + SaveExternalFolders(parent_index); + } + else + LoadExternalFolders(parent_index, IDI_CHIP); - // no games in top level folder - SetAllBits(lpFolder->m_lpGameBits, false); + SendMessage(GetProgressBar(), PBM_SETPOS, 95, 0); +} - for (jj = 0; jj < nGames; jj++) +void CreateScreenFolders(int parent_index) +{ + if (RequiredDriverCache()) { - char s[strlen(driver_list::driver(jj).year)+1]; - strcpy(s,driver_list::driver(jj).year); + CreateScreenFoldersIni(parent_index); + SaveExternalFolders(parent_index); + } + else + LoadExternalFolders(parent_index, IDI_MONITOR); - if (s[0] == '\0' || s[0] == '?') - continue; + SendMessage(GetProgressBar(), PBM_SETPOS, 80, 0); +} - if (s[4] == '?') - s[4] = '\0'; +void CreateResolutionFolders(int parent_index) +{ + if (RequiredDriverCache()) + { + CreateResolutionFoldersIni(parent_index); + SaveExternalFolders(parent_index); + } + else + LoadExternalFolders(parent_index, IDI_FOLDER); - // look for an extant year treefolder for this game - // (likely to be the previous one, so start at the end) - for (i=numFolders-1;i>=start_folder;i--) - { - if (strncmp(treeFolders[i]->m_lpTitle, s, 4) == 0) - { - AddGame(treeFolders[i], jj); - break; - } - } - if (i == start_folder-1) - { - // nope, it's a year we haven't seen before, make it. - LPTREEFOLDER lpTemp; - lpTemp = NewFolder(s, next_folder_id, parent_index, IDI_YEAR, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); + SendMessage(GetProgressBar(), PBM_SETPOS, 65, 0); +} - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_YEAR; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, s ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpTemp); - AddGame(lpTemp, jj); - } +void CreateFPSFolders(int parent_index) +{ + if (RequiredDriverCache()) + { + CreateFPSFoldersIni(parent_index); + SaveExternalFolders(parent_index); } - const char *fname = "Year"; - SaveExternalFolders(parent_index, fname); + else + LoadExternalFolders(parent_index, IDI_FOLDER); + + SendMessage(GetProgressBar(), PBM_SETPOS, 50, 0); } -void CreateResolutionFolders(int parent_index) +void CreateDumpingFolders(int parent_index) { - int i,jj; - int nGames = driver_list::total(); - int start_folder = numFolders; - char Screen[2048]; - const game_driver *gamedrv; + if (RequiredDriverCache()) + { + CreateDumpingFoldersIni(parent_index); + SaveExternalFolders(parent_index); + } + else + LoadExternalFolders(parent_index, IDI_FOLDER); + + SendMessage(GetProgressBar(), PBM_SETPOS, 35, 0); +} + +static void LoadExternalFolders(int parent_index, int id) +{ + const char* fname = NULL; LPTREEFOLDER lpFolder = treeFolders[parent_index]; - // no games in top level folder - SetAllBits(lpFolder->m_lpGameBits, false); + for (int j = 0; g_lpFolderData[j].m_lpTitle; j++) + if (strcmp(lpFolder->m_lpTitle, g_lpFolderData[j].m_lpTitle)==0) + fname = g_lpFolderData[j].short_name; - for (jj = 0; jj < nGames; jj++) - { - gamedrv = &driver_list::driver(jj); - /* Allocate machine config */ - machine_config config(*gamedrv,MameUIGlobal()); + if (fname == NULL) + return; - if (isDriverVector(&config)) - sprintf(Screen, "Vector"); - else + char filename[MAX_PATH]; + snprintf(filename, std::size(filename), "%s\\%s.ini", GetFolderDir(), fname); + FILE *f = fopen(filename, "r"); + + if (f == NULL) + return; + + char readbuf[256]; + char *name = NULL; + LPTREEFOLDER lpTemp = NULL; + int current_id = lpFolder->m_nFolderId; + + while (fgets(readbuf, 256, f)) + { + /* do we have [...] ? */ + if (readbuf[0] == '[') { - screen_device_enumerator iter(config.root_device()); - const screen_device *screen = iter.first(); - if (screen == NULL) - strcpy(Screen, "Screenless Game"); + char *p = strchr(readbuf, ']'); + + if (p == NULL) + continue; + + *p = '\0'; + name = &readbuf[1]; + + /* is it [FOLDER_SETTINGS]? */ + if (strcmp(name, "FOLDER_SETTINGS") == 0) + { + current_id = -1; + continue; + } else { - for (screen_device &screen : screen_device_enumerator(config.root_device())) + /* is it [ROOT_FOLDER]? */ + if (!strcmp(name, "ROOT_FOLDER")) { - const rectangle &visarea = screen.visible_area(); - - sprintf(Screen,"%d x %d (%c)", visarea.max_y - visarea.min_y + 1, visarea.max_x - visarea.min_x + 1, - (driver_list::driver(jj).flags & ORIENTATION_SWAP_XY) ? 'V':'H'); - - // look for an existant screen treefolder for this game - // (likely to be the previous one, so start at the end) - for (i=numFolders-1;i>=start_folder;i--) - { - if (strcmp(treeFolders[i]->m_lpTitle, Screen) == 0) - { - AddGame(treeFolders[i],jj); - break; - } - } - if (i == start_folder-1) - { - // nope, it's a screen we haven't seen before, make it. - LPTREEFOLDER lpTemp = NewFolder(Screen, next_folder_id++, parent_index, IDI_SCREEN, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); - - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_SCREEN; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, Screen ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpTemp); - AddGame(lpTemp,jj); - } + current_id = lpFolder->m_nFolderId; + lpTemp = lpFolder; } + else + { + current_id = next_folder_id++; + lpTemp = NewFolder(name, current_id, parent_index, id, GetFolderFlags(numFolders)); + AddFolder(lpTemp); + } + } + } + else if (current_id != -1) + { + /* string on a line by itself -- game name */ + name = strtok(readbuf, " \t\r\n"); + + if (name == NULL) + { + current_id = -1; + continue; } + + AddGame(lpTemp, GetGameNameIndex(name)); } } - const char *fname = "Resolution"; - SaveExternalFolders(parent_index, fname); + + fclose(f); } -void CreateFPSFolders(int parent_index) +static void SaveExternalFolders(int parent_index) { - int i,jj; - int nGames = driver_list::total(); - int start_folder = numFolders; - char Screen[2048]; - const game_driver *gamedrv; + const char* fname = NULL; LPTREEFOLDER lpFolder = treeFolders[parent_index]; - // no games in top level folder - SetAllBits(lpFolder->m_lpGameBits, false); + for (int j = 0; g_lpFolderData[j].m_lpTitle; j++) + if (strcmp(lpFolder->m_lpTitle, g_lpFolderData[j].m_lpTitle)==0) + fname = g_lpFolderData[j].short_name; + + if (fname == NULL) + return; + + char filename[MAX_PATH]; + snprintf(filename, std::size(filename), "%s\\%s.ini", GetFolderDir(), fname); + wchar_t *temp = ui_wstring_from_utf8(GetFolderDir()); + CreateDirectory(temp, NULL); + free(temp); + FILE *f = fopen(filename, "w"); + + if (f == NULL) + return; + + fprintf(f, "[FOLDER_SETTINGS]\n"); + fprintf(f, "RootFolderIcon custom\n"); + fprintf(f, "SubFolderIcon custom\n"); + + /* need to loop over all our TREEFOLDERs--first the root one, then each child. + start with the root */ + TREEFOLDER *folder_data = lpFolder; + fprintf(f, "\n[ROOT_FOLDER]\n"); + + for (int i = 0; i < driver_list::total(); i++) + if (TestBit(folder_data->m_lpGameBits, i)) + fprintf(f, "%s\n", driver_list::driver(i).name); - for (jj = 0; jj < nGames; jj++) + /* look through the custom folders for ones with our root as parent */ + for (int jj = 0; jj < numFolders; jj++) { - gamedrv = &driver_list::driver(jj); - /* Allocate machine config */ - machine_config config(*gamedrv,MameUIGlobal()); + folder_data = treeFolders[jj]; - if (isDriverVector(&config)) - sprintf(Screen, "Vector"); - else + if (folder_data->m_nParent >= 0 && treeFolders[folder_data->m_nParent] == lpFolder) { - screen_device_enumerator iter(config.root_device()); - const screen_device *screen = iter.first(); - if (screen == NULL) - strcpy(Screen, "Screenless Game"); - else - { - for (screen_device &screen : screen_device_enumerator(config.root_device())) - { - sprintf(Screen,"%f Hz", ATTOSECONDS_TO_HZ(screen.refresh_attoseconds())); + fprintf(f, "\n[%s]\n", folder_data->m_lpTitle); - // look for an existant screen treefolder for this game - // (likely to be the previous one, so start at the end) - for (i=numFolders-1;i>=start_folder;i--) - { - if (strcmp(treeFolders[i]->m_lpTitle, Screen) == 0) - { - AddGame(treeFolders[i],jj); - break; - } - } - if (i == start_folder-1) - { - // nope, it's a screen we haven't seen before, make it. - LPTREEFOLDER lpTemp = NewFolder(Screen, next_folder_id++, parent_index, IDI_SCREEN, GetFolderFlags(numFolders)); - ExtraFolderData[next_folder_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); - memset(ExtraFolderData[next_folder_id], 0, sizeof(EXFOLDERDATA)); - - ExtraFolderData[next_folder_id]->m_nFolderId = next_folder_id; - ExtraFolderData[next_folder_id]->m_nIconId = IDI_SCREEN; - ExtraFolderData[next_folder_id]->m_nParent = lpFolder->m_nFolderId; - ExtraFolderData[next_folder_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[next_folder_id]->m_szTitle, Screen ); - ExtraFolderData[next_folder_id++]->m_dwFlags = 0; - AddFolder(lpTemp); - AddGame(lpTemp,jj); - } - } - } + for (int i = 0; i < driver_list::total(); i++) + if (TestBit(folder_data->m_lpGameBits, i)) + fprintf(f, "%s\n", driver_list::driver(i).name); } } - const char *fname = "Refresh"; - SaveExternalFolders(parent_index, fname); + + fclose(f); } +// creates child folders of all the top level folders, including custom ones +void CreateAllChildFolders(void) +{ + int num_top_level_folders = numFolders; + + for (int i = 0; i < num_top_level_folders; i++) + { + LPTREEFOLDER lpFolder = treeFolders[i]; + LPCFOLDERDATA lpFolderData = NULL; + + for (int j = 0; g_lpFolderData[j].m_lpTitle; j++) + { + if (g_lpFolderData[j].m_nFolderId == lpFolder->m_nFolderId) + { + lpFolderData = &g_lpFolderData[j]; + break; + } + } -#pragma GCC diagnostic ignored "-Wunused-but-set-variable" + if (lpFolderData) + { + if (lpFolderData->m_pfnCreateFolders) + lpFolderData->m_pfnCreateFolders(i); + } + else + { + if ((lpFolder->m_dwFlags & F_CUSTOM) == 0) + continue; + + // load the extra folder files, which also adds children + if (TryAddExtraFolderAndChildren(i) == false) + lpFolder->m_nFolderId = FOLDER_NONE; + } + } +} // adds these folders to the treeview void ResetTreeViewFolders(void) { HWND hTreeView = GetTreeView(); + TVITEM tvi; + TVINSERTSTRUCT tvs; // currently "cached" parent - HTREEITEM shti, hti_parent = NULL; + HTREEITEM hti_parent = NULL; int index_parent = -1; - BOOL res = TreeView_DeleteAllItems(hTreeView); - - //printf("Adding folders to tree ui indices %i to %i\n",start_index,end_index); - - TVINSERTSTRUCT tvs; - tvs.hInsertAfter = TVI_SORT; + (void)TreeView_DeleteAllItems(hTreeView); + tvs.hInsertAfter = TVI_LAST; // main items inserted according to g_folderData[] array - TVITEM tvi; - for (int i=0; i<numFolders; i++) + for (int i = 0; i < numFolders; i++) { LPTREEFOLDER lpFolder = treeFolders[i]; if (lpFolder->m_nParent == -1) { if (lpFolder->m_nFolderId < MAX_FOLDERS) + { // it's a built in folder, let's see if we should show it if (GetShowFolder(lpFolder->m_nFolderId) == false) continue; + } tvi.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; tvs.hParent = TVI_ROOT; @@ -1492,15 +1252,14 @@ void ResetTreeViewFolders(void) // Add root branch hti_parent = TreeView_InsertItem(hTreeView, &tvs); - continue; } // not a top level branch, so look for parent if (treeFolders[i]->m_nParent != index_parent) { - hti_parent = TreeView_GetRoot(hTreeView); + while (1) { if (hti_parent == NULL) @@ -1510,11 +1269,13 @@ void ResetTreeViewFolders(void) tvi.hItem = hti_parent; tvi.mask = TVIF_PARAM; - res = TreeView_GetItem(hTreeView,&tvi); + + (void)TreeView_GetItem(hTreeView, &tvi); + if (((LPTREEFOLDER)tvi.lParam) == treeFolders[treeFolders[i]->m_nParent]) break; - hti_parent = TreeView_GetNextSibling(hTreeView,hti_parent); + hti_parent = TreeView_GetNextSibling(hTreeView, hti_parent); } // if parent is not shown, then don't show the child either obviously! @@ -1533,50 +1294,49 @@ void ResetTreeViewFolders(void) tvs.item = tvi; // Add it to this tree branch - shti = TreeView_InsertItem(hTreeView, &tvs); // for current child branches + tvs.hInsertAfter = TVI_SORT; // sub items always sorted + (void)TreeView_InsertItem(hTreeView, &tvs); + tvs.hInsertAfter = TVI_LAST; // restore for next main item } } -#pragma GCC diagnostic error "-Wunused-but-set-variable" void SelectTreeViewFolder(int folder_id) { - BOOL res = false; HWND hTreeView = GetTreeView(); - HTREEITEM hti; + HTREEITEM hti = TreeView_GetRoot(hTreeView); TVITEM tvi; - memset(&tvi,0,sizeof(tvi)); - hti = TreeView_GetRoot(hTreeView); + memset(&tvi, 0, sizeof(TVITEM)); while (hti != NULL) { - HTREEITEM hti_next; - tvi.hItem = hti; tvi.mask = TVIF_PARAM; - res = TreeView_GetItem(hTreeView,&tvi); - if (tvi.lParam) + (void)TreeView_GetItem(hTreeView, &tvi); + + if (((LPTREEFOLDER)tvi.lParam)->m_nFolderId == folder_id) { - if (((LPTREEFOLDER)tvi.lParam)->m_nFolderId == folder_id) - { - res = TreeView_SelectItem(hTreeView,tvi.hItem); - SetCurrentFolder((LPTREEFOLDER)tvi.lParam); - return; - } + (void)TreeView_SelectItem(hTreeView,tvi.hItem); + SetCurrentFolder((LPTREEFOLDER)tvi.lParam); + return; } - hti_next = TreeView_GetChild(hTreeView,hti); + HTREEITEM hti_next = TreeView_GetChild(hTreeView, hti); + if (hti_next == NULL) { - hti_next = TreeView_GetNextSibling(hTreeView,hti); + hti_next = TreeView_GetNextSibling(hTreeView, hti); + if (hti_next == NULL) { - hti_next = TreeView_GetParent(hTreeView,hti); + hti_next = TreeView_GetParent(hTreeView, hti); + if (hti_next != NULL) - hti_next = TreeView_GetNextSibling(hTreeView,hti_next); + hti_next = TreeView_GetNextSibling(hTreeView, hti_next); } } + hti = hti_next; } @@ -1584,10 +1344,11 @@ void SelectTreeViewFolder(int folder_id) // make sure we select something tvi.hItem = TreeView_GetRoot(hTreeView); tvi.mask = TVIF_PARAM; - res = TreeView_GetItem(hTreeView,&tvi); - res = TreeView_SelectItem(hTreeView,tvi.hItem); + + (void)TreeView_GetItem(hTreeView, &tvi); + (void)TreeView_SelectItem(hTreeView, tvi.hItem); SetCurrentFolder((LPTREEFOLDER)tvi.lParam); - res++; + } /* @@ -1595,8 +1356,18 @@ void SelectTreeViewFolder(int folder_id) * Currently only true for FOLDER_VECTOR and children * of FOLDER_SOURCE. */ -static BOOL FolderHasIni(LPTREEFOLDER lpFolder) +static bool FolderHasIni(LPTREEFOLDER lpFolder) { +#if 0 + if (FOLDER_RASTER == lpFolder->m_nFolderId || FOLDER_VECTOR == lpFolder->m_nFolderId || + FOLDER_VERTICAL == lpFolder->m_nFolderId || FOLDER_HORIZONTAL == lpFolder->m_nFolderId) + return true; + + if (lpFolder->m_nParent != -1 && FOLDER_SOURCE == treeFolders[lpFolder->m_nParent]->m_nFolderId) + return true; + + return false; +#endif LPCFOLDERDATA data = FindFilter(lpFolder->m_nFolderId); if (data) if (data->m_opttype < OPTIONS_MAX) @@ -1609,21 +1380,25 @@ static BOOL FolderHasIni(LPTREEFOLDER lpFolder) } /* Add a folder to the list. Does not allocate */ -static BOOL AddFolder(LPTREEFOLDER lpFolder) +static bool AddFolder(LPTREEFOLDER lpFolder) { TREEFOLDER **tmpTree = NULL; UINT oldFolderArrayLength = folderArrayLength; + if (numFolders + 1 >= folderArrayLength) { folderArrayLength += 500; tmpTree = (TREEFOLDER **)malloc(sizeof(TREEFOLDER **) * folderArrayLength); - memcpy(tmpTree,treeFolders,sizeof(TREEFOLDER **) * oldFolderArrayLength); - if (treeFolders) free(treeFolders); + memcpy(tmpTree, treeFolders, sizeof(TREEFOLDER **) * oldFolderArrayLength); + + if (treeFolders) + free(treeFolders); + treeFolders = tmpTree; } /* Is there an folder.ini that can be edited? */ - if (FolderHasIni(lpFolder)) + if (FolderHasIni(lpFolder)) lpFolder->m_dwFlags |= F_INIEDIT; treeFolders[numFolders] = lpFolder; @@ -1635,9 +1410,9 @@ static BOOL AddFolder(LPTREEFOLDER lpFolder) static LPTREEFOLDER NewFolder(const char *lpTitle, UINT nFolderId, int nParent, UINT nIconId, DWORD dwFlags) { LPTREEFOLDER lpFolder = (LPTREEFOLDER)malloc(sizeof(TREEFOLDER)); - memset(lpFolder, '\0', sizeof (TREEFOLDER)); - lpFolder->m_lpTitle = (LPSTR)malloc(strlen(lpTitle) + 1); - strcpy((char *)lpFolder->m_lpTitle,lpTitle); + memset(lpFolder, 0, sizeof(TREEFOLDER)); + lpFolder->m_lpTitle = (char *)malloc(strlen(lpTitle) + 1); + strcpy((char *)lpFolder->m_lpTitle, lpTitle); lpFolder->m_lptTitle = ui_wstring_from_utf8(lpFolder->m_lpTitle); lpFolder->m_lpGameBits = NewBits(driver_list::total()); lpFolder->m_nFolderId = nFolderId; @@ -1657,21 +1432,22 @@ static void DeleteFolder(LPTREEFOLDER lpFolder) DeleteBits(lpFolder->m_lpGameBits); lpFolder->m_lpGameBits = 0; } + free(lpFolder->m_lptTitle); lpFolder->m_lptTitle = 0; free(lpFolder->m_lpTitle); lpFolder->m_lpTitle = 0; free(lpFolder); - lpFolder = 0; } } /* Can be called to re-initialize the array of treeFolders */ -BOOL InitFolders(void) +static bool InitFolders(void) { int i = 0; - DWORD dwFolderFlags; - if (treeFolders != NULL) + DWORD dwFolderFlags = 0; + + if (treeFolders) { for (i = numFolders - 1; i >= 0; i--) { @@ -1680,94 +1456,52 @@ BOOL InitFolders(void) numFolders--; } } + numFolders = 0; + if (folderArrayLength == 0) { folderArrayLength = 200; treeFolders = (TREEFOLDER **)malloc(sizeof(TREEFOLDER **) * folderArrayLength); + if (!treeFolders) { folderArrayLength = 0; return 0; } else - memset(treeFolders,'\0', sizeof(TREEFOLDER **) * folderArrayLength); + memset(treeFolders, 0, sizeof(TREEFOLDER **) * folderArrayLength); } + // built-in top level folders for (i = 0; g_lpFolderData[i].m_lpTitle; i++) { - if (RequiredDriverCache() || (!RequiredDriverCache() && !g_lpFolderData[i].m_process)) - { - LPCFOLDERDATA fData = &g_lpFolderData[i]; - /* get the saved folder flags */ - dwFolderFlags = GetFolderFlags(numFolders); - /* create the folder */ - AddFolder(NewFolder(fData->m_lpTitle, fData->m_nFolderId, -1, fData->m_nIconId, dwFolderFlags)); - } + LPCFOLDERDATA fData = &g_lpFolderData[i]; + /* get the saved folder flags */ + dwFolderFlags = GetFolderFlags(numFolders); + /* create the folder */ + AddFolder(NewFolder(fData->m_lpTitle, fData->m_nFolderId, -1, fData->m_nIconId, dwFolderFlags)); } numExtraFolders = InitExtraFolders(); for (i = 0; i < numExtraFolders; i++) { - LPEXFOLDERDATA fExData = ExtraFolderData[i]; + LPEXFOLDERDATA fExData = ExtraFolderData[i]; // OR in the saved folder flags dwFolderFlags = fExData->m_dwFlags | GetFolderFlags(numFolders); - // create the folder, but if we are building the cache, the name must not be a pre-built one + // create the folder int k = 0; - if (RequiredDriverCache()) + //if (RequiredDriverCache()) for (int j = 0; g_lpFolderData[j].m_lpTitle; j++) - if (strcmp(fExData->m_szTitle, g_lpFolderData[j].m_lpTitle)==0) + if (strcmp(fExData->m_szTitle, g_lpFolderData[j].short_name)==0) k++; if (k == 0) - AddFolder(NewFolder(fExData->m_szTitle,fExData->m_nFolderId,fExData->m_nParent, fExData->m_nIconId,dwFolderFlags)); - } - -// creates child folders of all the top level folders, including custom ones - int num_top_level_folders = numFolders; - - for (int i = 0; i < num_top_level_folders; i++) - { - LPTREEFOLDER lpFolder = treeFolders[i]; - LPCFOLDERDATA lpFolderData = NULL; - - for (int j = 0; g_lpFolderData[j].m_lpTitle; j++) - { - if (g_lpFolderData[j].m_nFolderId == lpFolder->m_nFolderId) - { - lpFolderData = &g_lpFolderData[j]; - break; - } - } - - if (lpFolderData) - { - if (lpFolderData->m_pfnCreateFolders) - { - if (RequiredDriverCache() && lpFolderData->m_process) // rebuild cache - lpFolderData->m_pfnCreateFolders(i); - else - if (!lpFolderData->m_process) // build every time (CreateDeficiencyFolders) - lpFolderData->m_pfnCreateFolders(i); - } - } - else - { - if ((lpFolder->m_dwFlags & F_CUSTOM) == 0) - { - printf("Internal inconsistency with non-built-in folder, but not custom\n"); - continue; - } - - //printf("Loading custom folder %i %i\n",i,lpFolder->m_nFolderId); - - // load the extra folder files, which also adds children - if (TryAddExtraFolderAndChildren(i) == false) - lpFolder->m_nFolderId = FOLDER_NONE; - } + AddFolder(NewFolder(fExData->m_szTitle, fExData->m_nFolderId, fExData->m_nParent, fExData->m_nIconId, dwFolderFlags)); } + CreateAllChildFolders(); CreateTreeIcons(); ResetWhichGamesInFolders(); ResetTreeViewFolders(); @@ -1777,38 +1511,36 @@ BOOL InitFolders(void) } // create iconlist and Treeview control -static BOOL CreateTreeIcons() +static bool CreateTreeIcons(void) { - HICON hIcon; - INT i; - HINSTANCE hInst = GetModuleHandle(0); - + HICON hIcon = NULL; + HINSTANCE hInst = GetModuleHandle(NULL); int numIcons = ICON_MAX + numExtraIcons; + hTreeSmall = ImageList_Create (16, 16, ILC_COLORDDB | ILC_MASK, numIcons, numIcons); - //printf("Trying to load %i normal icons\n",ICON_MAX); - for (i = 0; i < ICON_MAX; i++) + for (int i = 0; i < ICON_MAX; i++) { hIcon = LoadIconFromFile(treeIconNames[i].lpName); + if (!hIcon) hIcon = LoadIcon(hInst, MAKEINTRESOURCE(treeIconNames[i].nResourceID)); - if (ImageList_AddIcon (hTreeSmall, hIcon) == -1) + if (ImageList_AddIcon(hTreeSmall, hIcon) == -1) { - ErrorMsg("Error creating icon on regular folder, %i %i",i,hIcon != NULL); + ErrorMessageBox("Error creating icon on regular folder, %i %i", i, hIcon != NULL); return false; } } - //printf("Trying to load %i extra custom-folder icons\n",numExtraIcons); - for (i = 0; i < numExtraIcons; i++) + for (int i = 0; i < numExtraIcons; i++) { if ((hIcon = LoadIconFromFile(ExtraFolderIcons[i])) == 0) - hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IDI_FOLDER)); + hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_FOLDER)); if (ImageList_AddIcon(hTreeSmall, hIcon) == -1) { - ErrorMsg("Error creating icon on extra folder, %i %i",i,hIcon != NULL); + ErrorMessageBox("Error creating icon on extra folder, %i %i", i, hIcon != NULL); return false; } } @@ -1816,25 +1548,22 @@ static BOOL CreateTreeIcons() // Be sure that all the small icons were added. if (ImageList_GetImageCount(hTreeSmall) < numIcons) { - ErrorMsg("Error with icon list--too few images. %i %i", ImageList_GetImageCount(hTreeSmall),numIcons); + ErrorMessageBox("Error with icon list--too few images. %i %i", ImageList_GetImageCount(hTreeSmall), numIcons); return false; } // Be sure that all the small icons were added. - if (ImageList_GetImageCount (hTreeSmall) < ICON_MAX) { - ErrorMsg("Error with icon list--too few images. %i < %i", ImageList_GetImageCount(hTreeSmall),(INT)ICON_MAX); + ErrorMessageBox("Error with icon list--too few images. %i < %i", ImageList_GetImageCount(hTreeSmall), ICON_MAX); return false; } // Associate the image lists with the list view control. (void)TreeView_SetImageList(GetTreeView(), hTreeSmall, TVSIL_NORMAL); - return true; } - static void TreeCtrlOnPaint(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; @@ -1979,7 +1708,7 @@ static LRESULT CALLBACK TreeWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM } /* - * Filter code + * Filter code - should be moved to filter.c/filter.h * Added 01/09/99 - MSH <mhaaland@hypertech.com> */ @@ -1997,138 +1726,133 @@ LPTREEFOLDER GetFolderByName(int nParentId, const char *pszFolderName) { //First Get the Parent TreeviewItem //Enumerate Children - for(int i = 0; i < numFolders/* ||treeFolders[i] != NULL*/; i++) + for (int i = 0; i < numFolders; i++) { if (!strcmp(treeFolders[i]->m_lpTitle, pszFolderName)) { int nParent = treeFolders[i]->m_nParent; + if ((nParent >= 0) && treeFolders[nParent]->m_nFolderId == nParentId) return treeFolders[i]; } } + return NULL; } static int InitExtraFolders(void) { - struct stat stat_buffer; - struct _finddata_t files; - int i, count = 0; - char * ext; - char buf[2048]; - char curdir[MAX_PATH]; - const std::string t = dir_get_value(24); - const char *dir = t.c_str(); - memset(ExtraFolderData, 0, (MAX_EXTRA_FOLDERS * MAX_EXTRA_SUBFOLDERS)* sizeof(LPEXFOLDERDATA)); + WIN32_FIND_DATA FindFileData; + int count = 0; + char buf[256]; + char path[MAX_PATH]; + const char *dir = GetFolderDir(); - /* NPW 9-Feb-2003 - MSVC stat() doesn't like stat() called with an empty string */ - if (!dir) - return 0; //dir = "."; + memset(ExtraFolderData, 0, (MAX_EXTRA_FOLDERS * MAX_EXTRA_SUBFOLDERS)* sizeof(LPEXFOLDERDATA)); // Why create the directory if it doesn't exist, just return 0 folders. - if (stat(dir, &stat_buffer) != 0) + if (osd::directory::open(dir) == nullptr) return 0; - _getcwd(curdir, MAX_PATH); - - chdir(dir); + snprintf(path, std::size(path), "%s\\*.*", dir); + HANDLE hFind = winui2_find_first_file_utf8(path, &FindFileData); - for (i = 0; i < MAX_EXTRA_FOLDERS; i++) + for (int i = 0; i < MAX_EXTRA_FOLDERS; i++) + { ExtraFolderIcons[i] = NULL; + } numExtraIcons = 0; - intptr_t hLong = 0L; - - if ( (hLong = _findfirst("*.ini", &files)) == -1L ) - return 0; - do + if (hFind != INVALID_HANDLE_VALUE) { - if ((files.attrib & _A_SUBDIR) == 0) + while (FindNextFile (hFind, &FindFileData) != 0) { - FILE *fp; + char *file = ui_utf8_from_wstring(FindFileData.cFileName); + char inifile[MAX_PATH]; - fp = fopen(files.name, "r"); - if (fp != NULL) + memset(&inifile, 0, sizeof(inifile)); + snprintf(inifile, std::size(inifile), "%s\\%s", dir, file); + FILE *readfile = fopen(inifile, "r"); + + if (readfile != NULL) { int icon[2] = { 0, 0 }; - char *p, *name; - while (fgets(buf, 256, fp)) + while (fgets(buf, 256, readfile)) { if (buf[0] == '[') { - p = strchr(buf, ']'); + char *p = strchr(buf, ']'); + if (p == NULL) continue; *p = '\0'; - name = &buf[1]; + char *name = &buf[1]; + if (!strcmp(name, "FOLDER_SETTINGS")) { - while (fgets(buf, 256, fp)) + while (fgets(buf, 256, readfile)) { name = strtok(buf, " =\r\n"); + if (name == NULL) break; if (!strcmp(name, "RootFolderIcon")) { name = strtok(NULL, " =\r\n"); + if (name != NULL) SetExtraIcons(name, &icon[0]); } if (!strcmp(name, "SubFolderIcon")) { name = strtok(NULL, " =\r\n"); + if (name != NULL) SetExtraIcons(name, &icon[1]); } } + break; } } } - fclose(fp); - strcpy(buf, files.name); - ext = strrchr(buf, '.'); + fclose(readfile); + strcpy(buf, file); + char *ext = strrchr(buf, '.'); + free(file); - if (ext && *(ext + 1) && (core_stricmp(ext + 1, "ini")==0)) + if (ext && *(ext + 1) && !core_stricmp(ext + 1, "ini")) { ExtraFolderData[count] =(EXFOLDERDATA*) malloc(sizeof(EXFOLDERDATA)); + if (ExtraFolderData[count]) { *ext = '\0'; - memset(ExtraFolderData[count], 0, sizeof(EXFOLDERDATA)); - strncpy(ExtraFolderData[count]->m_szTitle, buf, 63); - ExtraFolderData[count]->m_nFolderId = next_folder_id++; - ExtraFolderData[count]->m_nParent = -1; - ExtraFolderData[count]->m_dwFlags = F_CUSTOM; - ExtraFolderData[count]->m_nIconId = icon[0] ? -icon[0] : IDI_FOLDER; - ExtraFolderData[count]->m_nSubIconId = icon[1] ? -icon[1] : IDI_FOLDER; - //printf("extra folder with icon %i, subicon %i\n", - //ExtraFolderData[count]->m_nIconId, - //ExtraFolderData[count]->m_nSubIconId); + ExtraFolderData[count]->m_nFolderId = next_folder_id++; + ExtraFolderData[count]->m_nParent = -1; + ExtraFolderData[count]->m_dwFlags = F_CUSTOM; + ExtraFolderData[count]->m_nIconId = icon[0] ? -icon[0] : IDI_FOLDER; + ExtraFolderData[count]->m_nSubIconId = icon[1] ? -icon[1] : IDI_FOLDER; count++; } } } } - } while( _findnext(hLong, &files) == 0); + } - chdir(curdir); - _findclose(hLong); return count; } void FreeExtraFolders(void) { - int i; - - for (i = 0; i < numExtraFolders; i++) + for (int i = 0; i < numExtraFolders; i++) { if (ExtraFolderData[i]) { @@ -2137,11 +1861,12 @@ void FreeExtraFolders(void) } } - for (i = 0; i < numExtraIcons; i++) + for (int i = 0; i < numExtraIcons; i++) + { free(ExtraFolderIcons[i]); + } numExtraIcons = 0; - } @@ -2153,6 +1878,7 @@ static void SetExtraIcons(char *name, int *id) *p = '\0'; ExtraFolderIcons[numExtraIcons] = (char*)malloc(strlen(name) + 1); + if (ExtraFolderIcons[numExtraIcons]) { *id = ICON_MAX + numExtraIcons; @@ -2163,47 +1889,36 @@ static void SetExtraIcons(char *name, int *id) // Called to add child folders of the top level extra folders already created -BOOL TryAddExtraFolderAndChildren(int parent_index) +bool TryAddExtraFolderAndChildren(int parent_index) { - FILE* fp = NULL; char fname[MAX_PATH]; char readbuf[256]; - char *p; - char *name; - int i; + char *name = NULL; LPTREEFOLDER lpTemp = NULL; LPTREEFOLDER lpFolder = treeFolders[parent_index]; int current_id = lpFolder->m_nFolderId; - int id = lpFolder->m_nFolderId - MAX_FOLDERS; - - /* "folder\title.ini" */ - - const std::string t = dir_get_value(24); - sprintf( fname, "%s\\%s.ini", t.c_str(), ExtraFolderData[id]->m_szTitle); - - fp = fopen(fname, "r"); - if (fp == NULL) + snprintf(fname, std::size(fname), "%s\\%s.ini", GetFolderDir(), ExtraFolderData[id]->m_szTitle); + FILE *f = fopen(fname, "r"); + + if (f == NULL) return false; - while ( fgets(readbuf, 256, fp) ) + while (fgets(readbuf, 256, f)) { /* do we have [...] ? */ - if (readbuf[0] == '[') { - p = strchr(readbuf, ']'); + char *p = strchr(readbuf, ']'); + if (p == NULL) - { continue; - } *p = '\0'; name = &readbuf[1]; /* is it [FOLDER_SETTINGS]? */ - if (strcmp(name, "FOLDER_SETTINGS") == 0) { current_id = -1; @@ -2211,32 +1926,26 @@ BOOL TryAddExtraFolderAndChildren(int parent_index) } else { - /* it it [ROOT_FOLDER]? */ - + /* is it [ROOT_FOLDER]? */ if (!strcmp(name, "ROOT_FOLDER")) { current_id = lpFolder->m_nFolderId; lpTemp = lpFolder; - } else { /* must be [folder name] */ - current_id = next_folder_id++; /* create a new folder with this name, - and the flags for this folder as read from the registry */ - lpTemp = NewFolder(name,current_id,parent_index, - ExtraFolderData[id]->m_nSubIconId, - GetFolderFlags(numFolders) | F_CUSTOM); + and the flags for this folder as read from the registry */ + lpTemp = NewFolder(name, current_id, parent_index, ExtraFolderData[id]->m_nSubIconId, GetFolderFlags(numFolders) | F_CUSTOM); ExtraFolderData[current_id] = (EXFOLDERDATA*)malloc(sizeof(EXFOLDERDATA)); memset(ExtraFolderData[current_id], 0, sizeof(EXFOLDERDATA)); - ExtraFolderData[current_id]->m_nFolderId = current_id - MAX_EXTRA_FOLDERS; ExtraFolderData[current_id]->m_nIconId = ExtraFolderData[id]->m_nSubIconId; ExtraFolderData[current_id]->m_nParent = ExtraFolderData[id]->m_nFolderId; ExtraFolderData[current_id]->m_nSubIconId = -1; - strcpy( ExtraFolderData[current_id]->m_szTitle, name ); + strcpy(ExtraFolderData[current_id]->m_szTitle, name); ExtraFolderData[current_id]->m_dwFlags = ExtraFolderData[id]->m_dwFlags; AddFolder(lpTemp); } @@ -2245,8 +1954,8 @@ BOOL TryAddExtraFolderAndChildren(int parent_index) else if (current_id != -1) { /* string on a line by itself -- game name */ - name = strtok(readbuf, " \t\r\n"); + if (name == NULL) { current_id = -1; @@ -2254,22 +1963,21 @@ BOOL TryAddExtraFolderAndChildren(int parent_index) } /* IMPORTANT: This assumes that all driver names are lowercase! */ - for (i = 0; name[i]; i++) + for (int i = 0; name[i]; i++) name[i] = tolower(name[i]); if (lpTemp == NULL) { - ErrorMsg("Error parsing %s: missing [folder name] or [ROOT_FOLDER]", fname); + ErrorMessageBox("Error parsing %s: missing [folder name] or [ROOT_FOLDER]", fname); current_id = lpFolder->m_nFolderId; lpTemp = lpFolder; } - AddGame(lpTemp,GetGameNameIndex(name)); + + AddGame(lpTemp, GetGameNameIndex(name)); } } - if ( fp ) - fclose( fp ); - + fclose(f); return true; } @@ -2280,39 +1988,39 @@ void GetFolders(TREEFOLDER ***folders,int *num_folders) *num_folders = numFolders; } -static BOOL TryRenameCustomFolderIni(LPTREEFOLDER lpFolder, const char *old_name, const char *new_name) +static bool TryRenameCustomFolderIni(LPTREEFOLDER lpFolder, const char *old_name, const char *new_name) { char filename[MAX_PATH]; char new_filename[MAX_PATH]; - LPTREEFOLDER lpParent = NULL; - string ini_dir = GetIniDir(); - const char* inidir = ini_dir.c_str(); + if (lpFolder->m_nParent >= 0) { //it is a custom SubFolder - lpParent = GetFolder( lpFolder->m_nParent ); - if( lpParent ) + LPTREEFOLDER lpParent = GetFolder(lpFolder->m_nParent); + + if(lpParent) { - snprintf(filename,std::size(filename),"%s\\%s\\%s.ini",inidir,lpParent->m_lpTitle, old_name ); - snprintf(new_filename,std::size(new_filename),"%s\\%s\\%s.ini",inidir,lpParent->m_lpTitle, new_name ); - win_move_file_utf8(filename,new_filename); + snprintf(filename, std::size(filename), "%s\\%s\\%s.ini", GetIniDir().c_str(), lpParent->m_lpTitle, old_name); + snprintf(new_filename, std::size(new_filename), "%s\\%s\\%s.ini", GetIniDir().c_str(), lpParent->m_lpTitle, new_name); + winui_move_file_utf8(filename, new_filename); } } else { //Rename the File, if it exists - snprintf(filename,std::size(filename),"%s\\%s.ini",inidir,old_name ); - snprintf(new_filename,std::size(new_filename),"%s\\%s.ini",inidir, new_name ); - win_move_file_utf8(filename,new_filename); + snprintf(filename, std::size(filename), "%s\\%s.ini", GetIniDir().c_str(), old_name); + snprintf(new_filename, std::size(new_filename), "%s\\%s.ini", GetIniDir().c_str(), new_name); + winui_move_file_utf8(filename, new_filename); //Rename the Directory, if it exists - snprintf(filename,std::size(filename),"%s\\%s",inidir,old_name ); - snprintf(new_filename,std::size(new_filename),"%s\\%s",inidir, new_name ); - win_move_file_utf8(filename,new_filename); + snprintf(filename, std::size(filename), "%s\\%s", GetIniDir().c_str(), old_name); + snprintf(new_filename, std::size(new_filename), "%s\\%s", GetIniDir().c_str(), new_name); + winui_move_file_utf8(filename, new_filename); } + return true; } -BOOL TryRenameCustomFolder(LPTREEFOLDER lpFolder, const char *new_name) +bool TryRenameCustomFolder(LPTREEFOLDER lpFolder, const char *new_name) { char filename[MAX_PATH]; char new_filename[MAX_PATH]; @@ -2320,13 +2028,11 @@ BOOL TryRenameCustomFolder(LPTREEFOLDER lpFolder, const char *new_name) if (lpFolder->m_nParent >= 0) { // a child extra folder was renamed, so do the rename and save the parent - // save old title char *old_title = lpFolder->m_lpTitle; - // set new title lpFolder->m_lpTitle = (char *)malloc(strlen(new_name) + 1); - strcpy(lpFolder->m_lpTitle,new_name); + strcpy(lpFolder->m_lpTitle, new_name); // try to save if (TrySaveExtraFolder(lpFolder) == false) @@ -2336,6 +2042,7 @@ BOOL TryRenameCustomFolder(LPTREEFOLDER lpFolder, const char *new_name) lpFolder->m_lpTitle = old_title; return false; } + TryRenameCustomFolderIni(lpFolder, old_title, new_name); // successful, so free old title free(old_title); @@ -2343,72 +2050,65 @@ BOOL TryRenameCustomFolder(LPTREEFOLDER lpFolder, const char *new_name) } // a parent extra folder was renamed, so rename the file - - const std::string t = dir_get_value(24); - snprintf(new_filename,std::size(new_filename),"%s\\%s.ini", t.c_str(), new_name); - snprintf(filename,std::size(filename),"%s\\%s.ini", t.c_str(), lpFolder->m_lpTitle); - - BOOL retval = win_move_file_utf8(filename,new_filename); + snprintf(new_filename, std::size(new_filename), "%s\\%s.ini", GetFolderDir(), new_name); + snprintf(filename, std::size(filename), "%s\\%s.ini", GetFolderDir(), lpFolder->m_lpTitle); + bool retval = winui_move_file_utf8(filename, new_filename); if (retval) { TryRenameCustomFolderIni(lpFolder, lpFolder->m_lpTitle, new_name); free(lpFolder->m_lpTitle); lpFolder->m_lpTitle = (char *)malloc(strlen(new_name) + 1); - strcpy(lpFolder->m_lpTitle,new_name); + strcpy(lpFolder->m_lpTitle, new_name); } else - { - char buf[2048]; - snprintf(buf,std::size(buf),"Error while renaming custom file %s to %s", filename,new_filename); - win_message_box_utf8(GetMainWindow(), buf, MAMEUINAME, MB_OK | MB_ICONERROR); - } + ErrorMessageBox("Error while renaming custom file %s to %s", filename, new_filename); + return retval; } -void AddToCustomFolder(LPTREEFOLDER lpFolder,int driver_index) +void AddToCustomFolder(LPTREEFOLDER lpFolder, int driver_index) { if ((lpFolder->m_dwFlags & F_CUSTOM) == 0) { - win_message_box_utf8(GetMainWindow(),"Unable to add game to non-custom folder", MAMEUINAME,MB_OK | MB_ICONERROR); + ErrorMessageBox("Unable to add game to non-custom folder"); return; } - if (TestBit(lpFolder->m_lpGameBits,driver_index) == 0) + if (TestBit(lpFolder->m_lpGameBits, driver_index) == 0) { - AddGame(lpFolder,driver_index); + AddGame(lpFolder, driver_index); + if (TrySaveExtraFolder(lpFolder) == false) - RemoveGame(lpFolder,driver_index); // undo on error + RemoveGame(lpFolder, driver_index); // undo on error } } -void RemoveFromCustomFolder(LPTREEFOLDER lpFolder,int driver_index) +void RemoveFromCustomFolder(LPTREEFOLDER lpFolder, int driver_index) { if ((lpFolder->m_dwFlags & F_CUSTOM) == 0) { - win_message_box_utf8(GetMainWindow(),"Unable to remove game from non-custom folder", MAMEUINAME,MB_OK | MB_ICONERROR); + ErrorMessageBox("Unable to remove game from non-custom folder"); return; } - if (TestBit(lpFolder->m_lpGameBits,driver_index) != 0) + if (TestBit(lpFolder->m_lpGameBits, driver_index) != 0) { - RemoveGame(lpFolder,driver_index); + RemoveGame(lpFolder, driver_index); + if (TrySaveExtraFolder(lpFolder) == false) - AddGame(lpFolder,driver_index); // undo on error + AddGame(lpFolder, driver_index); // undo on error } } -BOOL TrySaveExtraFolder(LPTREEFOLDER lpFolder) +bool TrySaveExtraFolder(LPTREEFOLDER lpFolder) { char fname[MAX_PATH]; - FILE *fp; - BOOL error = false; - int i,j; - + bool error = false; LPTREEFOLDER root_folder = NULL; LPEXFOLDERDATA extra_folder = NULL; - for (i=0; i<numExtraFolders; i++) + for (int i = 0; i < numExtraFolders; i++) { if (ExtraFolderData[i]->m_nFolderId == lpFolder->m_nFolderId) { @@ -2417,8 +2117,7 @@ BOOL TrySaveExtraFolder(LPTREEFOLDER lpFolder) break; } - if (lpFolder->m_nParent >= 0 && - ExtraFolderData[i]->m_nFolderId == treeFolders[lpFolder->m_nParent]->m_nFolderId) + if (lpFolder->m_nParent >= 0 && ExtraFolderData[i]->m_nFolderId == treeFolders[lpFolder->m_nParent]->m_nFolderId) { root_folder = treeFolders[lpFolder->m_nParent]; extra_folder = ExtraFolderData[i]; @@ -2428,75 +2127,65 @@ BOOL TrySaveExtraFolder(LPTREEFOLDER lpFolder) if (extra_folder == NULL || root_folder == NULL) { - MessageBox(GetMainWindow(), TEXT("Error finding custom file name to save"), TEXT(MAMEUINAME), MB_OK | MB_ICONERROR); + ErrorMessageBox("Error finding custom file name to save"); return false; } - /* "folder\title.ini" */ - const std::string t = dir_get_value(24); - snprintf( fname, sizeof(fname), "%s\\%s.ini", t.c_str(), extra_folder->m_szTitle); + snprintf(fname, std::size(fname), "%s\\%s.ini", GetFolderDir(), extra_folder->m_szTitle); + wchar_t *temp = ui_wstring_from_utf8(GetFolderDir()); + CreateDirectory(temp, NULL); + free(temp); + FILE *f = fopen(fname, "w"); - fp = fopen(fname, "wt"); - if (fp == NULL) + if (f == NULL) error = true; else { TREEFOLDER *folder_data; - fprintf(fp,"[FOLDER_SETTINGS]\n"); + fprintf(f, "[FOLDER_SETTINGS]\n"); + // negative values for icons means it's custom, so save 'em if (extra_folder->m_nIconId < 0) - { - fprintf(fp, "RootFolderIcon %s\n", ExtraFolderIcons[(-extra_folder->m_nIconId) - ICON_MAX]); - } - if (extra_folder->m_nSubIconId < 0) - { - fprintf(fp,"SubFolderIcon %s\n", ExtraFolderIcons[(-extra_folder->m_nSubIconId) - ICON_MAX]); - } + fprintf(f, "RootFolderIcon %s\n", ExtraFolderIcons[(-extra_folder->m_nIconId) - ICON_MAX]); - /* need to loop over all our TREEFOLDERs--first the root one, then each child. Start with the root */ + if (extra_folder->m_nSubIconId < 0) + fprintf(f, "SubFolderIcon %s\n", ExtraFolderIcons[(-extra_folder->m_nSubIconId) - ICON_MAX]); + /* need to loop over all our TREEFOLDERs--first the root one, then each child. + start with the root */ folder_data = root_folder; + fprintf(f, "\n[ROOT_FOLDER]\n"); - fprintf(fp,"\n[ROOT_FOLDER]\n"); - - for (i=0;i<driver_list::total();i++) + for (int i = 0; i < driver_list::total(); i++) { if (TestBit(folder_data->m_lpGameBits, i)) - { - fprintf(fp,"%s\n",driver_list::driver(i).name); - } + fprintf(f, "%s\n", driver_list::driver(i).name); } /* look through the custom folders for ones with our root as parent */ - for (j=0;j<numFolders;j++) + for (int j = 0; j < numFolders; j++) { folder_data = treeFolders[j]; - if (folder_data->m_nParent >= 0 && - treeFolders[folder_data->m_nParent] == root_folder) + if (folder_data->m_nParent >= 0 && treeFolders[folder_data->m_nParent] == root_folder) { - fprintf(fp,"\n[%s]\n",folder_data->m_lpTitle); + fprintf(f, "\n[%s]\n", folder_data->m_lpTitle); - for (i=0;i<driver_list::total();i++) + for (int i = 0; i < driver_list::total(); i++) { if (TestBit(folder_data->m_lpGameBits, i)) - { - fprintf(fp,"%s\n",driver_list::driver(i).name); - } + fprintf(f, "%s\n", driver_list::driver(i).name); } } } - if (fclose(fp) != 0) - error = true; + + fclose(f); } if (error) - { - char buf[500]; - snprintf(buf,std::size(buf),"Error while saving custom file %s",fname); - win_message_box_utf8(GetMainWindow(), buf, MAMEUINAME, MB_OK | MB_ICONERROR); - } + ErrorMessageBox("Error while saving custom file %s", fname); + return !error; } @@ -2510,79 +2199,26 @@ int GetTreeViewIconIndex(int icon_id) if (icon_id < 0) return -icon_id; - for (int i = 0; i < sizeof(treeIconNames) / sizeof(treeIconNames[0]); i++) + for (int i = 0; i < std::size(treeIconNames); i++) + { if (icon_id == treeIconNames[i].nResourceID) return i; + } return -1; } - -static void SaveExternalFolders(int parent_index, const char *fname) +#if 0 +bool FilterAvailable(int driver_index) { - string val = dir_get_value(24); - char s[val.size()+1]; - strcpy(s, val.c_str()); - char *fdir = strtok(s, ";"); // get first dir - - // create directory if needed - wchar_t *temp = ui_wstring_from_utf8(fdir); - BOOL res = CreateDirectory(temp, NULL); - free(temp); - if (!res) - { - if (GetLastError() == ERROR_PATH_NOT_FOUND) - { - printf("SaveExternalFolders: Unable to create the directory \"%s\".\n",fdir); - return; - } - } - - // create/truncate file - string filename = fdir + string("\\") + fname + string(".ini"); - FILE *f = fopen(filename.c_str(), "w"); - if (f == NULL) - { - printf("SaveExternalFolders: Unable to open file %s for writing.\n",filename.c_str()); - return; - } - - // Populate the file - fprintf(f, "[FOLDER_SETTINGS]\n"); - fprintf(f, "RootFolderIcon custom\n"); - fprintf(f, "SubFolderIcon custom\n"); - - /* need to loop over all our TREEFOLDERs--first the root one, then each child. - start with the root */ - LPTREEFOLDER lpFolder = treeFolders[parent_index]; - TREEFOLDER *folder_data = lpFolder; - fprintf(f, "\n[ROOT_FOLDER]\n"); - - int i; - for (i = 0; i < driver_list::total(); i++) + if (!DriverUsesRoms(driver_index)) { - if (TestBit(folder_data->m_lpGameBits, i)) - fprintf(f, "%s\n", GetGameName(i).c_str()); - } - - /* look through the custom folders for ones with our root as parent */ - for (int jj = 0; jj < numFolders; jj++) - { - folder_data = treeFolders[jj]; - - if (folder_data->m_nParent >= 0 && treeFolders[folder_data->m_nParent] == lpFolder) - { - fprintf(f, "\n[%s]\n", folder_data->m_lpTitle); - - for (i = 0; i < driver_list::total(); i++) - { - if (TestBit(folder_data->m_lpGameBits, i)) - fprintf(f, "%s\n", GetGameName(i).c_str()); - } - } + if (GetDisplayNoRomsGames()) + return true; + else + return false; } - fclose(f); - printf("SaveExternalFolders: Saved file %s.\n",filename.c_str()); + return IsAuditResultYes(GetRomAuditResults(driver_index)); } +#endif -/* End of source file */ |