unix.c
changeset 4221 bb06fe8dcce2
parent 4220 86ca889037b3
child 4222 951fbf19b1ad
equal deleted inserted replaced
4220:86ca889037b3 4221:bb06fe8dcce2
    47 		//the mac implementation needs this file included in the same file as main()
    47 		//the mac implementation needs this file included in the same file as main()
    48 		#include <SDL.h>
    48 		#include <SDL.h>
    49 	#endif
    49 	#endif
    50 #endif
    50 #endif
    51 extern char *_fios_path;
    51 extern char *_fios_path;
    52 static char *_fios_save_path;
       
    53 static char *_fios_scn_path;
       
    54 extern FiosItem *_fios_items;
    52 extern FiosItem *_fios_items;
    55 extern int _fios_count, _fios_alloc;
    53 extern int _fios_count, _fios_alloc;
    56 
    54 
    57 #if !defined(__MORPHOS__) && !defined(__AMIGAOS__)
    55 #if !defined(__MORPHOS__) && !defined(__AMIGAOS__)
    58 #define ISROOT(__p)  (__p[1] == '\0')
    56 #define ISROOT(__p)  (__p[1] == '\0')
    66 static bool __isroot; /* not very thread save, but will do in this case */
    64 static bool __isroot; /* not very thread save, but will do in this case */
    67 #define ISROOT(__p)  (__isroot = (__p[strlen(__p)-1] == ':'))
    65 #define ISROOT(__p)  (__isroot = (__p[strlen(__p)-1] == ':'))
    68 #define PATHTEMPLATE (__isroot ? "%s:%s" : "%s/%s")
    66 #define PATHTEMPLATE (__isroot ? "%s:%s" : "%s/%s")
    69 #endif
    67 #endif
    70 
    68 
    71 // Get a list of savegames
    69 bool FiosIsRoot(const char *path)
    72 FiosItem *FiosGetSavegameList(int *num, int mode)
    70 {
    73 {
    71 #if !defined(__MORPHOS__) && !defined(__AMIGAOS__)
    74 	FiosItem *fios;
    72 	return path[1] == '\0';
    75 	DIR *dir;
    73 #else
    76 	struct dirent *dirent;
    74 	/* On MorphOS or AmigaOS paths look like: "Volume:directory/subdirectory" */
    77 	struct stat sb;
    75 	const char *s = strchr(path, ':');
    78 	int sort_start;
    76 	return s[1] == '\0';
       
    77 #endif
       
    78 }
       
    79 
       
    80 void FiosGetDrives(void)
       
    81 {
       
    82 	return;
       
    83 }
       
    84 
       
    85 bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb)
       
    86 {
    79 	char filename[MAX_PATH];
    87 	char filename[MAX_PATH];
    80 
    88 
    81 	if (_fios_save_path == NULL) {
    89 #if defined(__MORPHOS__) || defined(__AMIGAOS__)
    82 		_fios_save_path = malloc(MAX_PATH);
    90 	/* On MorphOS or AmigaOS paths look like: "Volume:directory/subdirectory" */
    83 		strcpy(_fios_save_path, _path.save_dir);
    91 	if (FiosIsRoot(path)) {
    84 	}
    92 		snprintf(filename, lengthof(filename), "%s:%s", path, ent->d_name);
    85 
    93 	} else // XXX - only next line!
    86 	_fios_path = _fios_save_path;
    94 #endif
    87 
    95 	snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, ent->d_name);
    88 	// Parent directory, only if not in root already.
    96 
    89 	if (!ISROOT(_fios_path)) {
    97 	if (stat(filename, sb) != 0) return false;
    90 		fios = FiosAlloc();
    98 
    91 		fios->type = FIOS_TYPE_PARENT;
    99 	return (ent->d_name[0] != '.'); // hidden file
    92 		fios->mtime = 0;
       
    93 		strcpy(fios->name, "..");
       
    94 		strcpy(fios->title, ".. (Parent directory)");
       
    95 	}
       
    96 
       
    97 	// Show subdirectories first
       
    98 	dir = opendir(_fios_path);
       
    99 	if (dir != NULL) {
       
   100 		while ((dirent = readdir(dir)) != NULL) {
       
   101 			snprintf(filename, lengthof(filename), PATHTEMPLATE,
       
   102 				_fios_path, dirent->d_name);
       
   103 			if (!stat(filename, &sb) && S_ISDIR(sb.st_mode) &&
       
   104 					dirent->d_name[0] != '.') {
       
   105 				fios = FiosAlloc();
       
   106 				fios->type = FIOS_TYPE_DIR;
       
   107 				fios->mtime = 0;
       
   108 				ttd_strlcpy(fios->name, dirent->d_name, lengthof(fios->name));
       
   109 				snprintf(fios->title, lengthof(fios->title), "%s/ (Directory)", FS2OTTD(dirent->d_name));
       
   110 				str_validate(fios->title);
       
   111 			}
       
   112 		}
       
   113 		closedir(dir);
       
   114 	}
       
   115 
       
   116 	{
       
   117 		/* XXX ugly global variables ... */
       
   118 		byte order = _savegame_sort_order;
       
   119 		_savegame_sort_order = SORT_BY_NAME | SORT_ASCENDING;
       
   120 		qsort(_fios_items, _fios_count, sizeof(FiosItem), compare_FiosItems);
       
   121 		_savegame_sort_order = order;
       
   122 	}
       
   123 
       
   124 	// this is where to start sorting
       
   125 	sort_start = _fios_count;
       
   126 
       
   127 	/* Show savegame files
       
   128 	 * .SAV OpenTTD saved game
       
   129 	 * .SS1 Transport Tycoon Deluxe preset game
       
   130 	 * .SV1 Transport Tycoon Deluxe (Patch) saved game
       
   131 	 * .SV2 Transport Tycoon Deluxe (Patch) saved 2-player game
       
   132 	 */
       
   133 	dir = opendir(_fios_path);
       
   134 	if (dir != NULL) {
       
   135 		while ((dirent = readdir(dir)) != NULL) {
       
   136 			char *t;
       
   137 
       
   138 			snprintf(filename, lengthof(filename), PATHTEMPLATE,
       
   139 				_fios_path, dirent->d_name);
       
   140 			if (stat(filename, &sb) || S_ISDIR(sb.st_mode)) continue;
       
   141 
       
   142 			t = strrchr(dirent->d_name, '.');
       
   143 			if (t == NULL) continue;
       
   144 
       
   145 			if (strcasecmp(t, ".sav") == 0) { // OpenTTD
       
   146 				fios = FiosAlloc();
       
   147 				fios->type = FIOS_TYPE_FILE;
       
   148 				fios->mtime = sb.st_mtime;
       
   149 				ttd_strlcpy(fios->name, dirent->d_name, lengthof(fios->name));
       
   150 
       
   151 				*t = '\0'; // strip extension
       
   152 				ttd_strlcpy(fios->title, FS2OTTD(dirent->d_name), lengthof(fios->title));
       
   153 				str_validate(fios->title);
       
   154 			} else if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO) {
       
   155 				if (strcasecmp(t, ".ss1") == 0 ||
       
   156 						strcasecmp(t, ".sv1") == 0 ||
       
   157 						strcasecmp(t, ".sv2") == 0) { // TTDLX(Patch)
       
   158 					fios = FiosAlloc();
       
   159 					fios->type = FIOS_TYPE_OLDFILE;
       
   160 					fios->mtime = sb.st_mtime;
       
   161 					ttd_strlcpy(fios->name, dirent->d_name, lengthof(fios->name));
       
   162 					GetOldSaveGameName(fios->title, filename);
       
   163 				}
       
   164 			}
       
   165 		}
       
   166 		closedir(dir);
       
   167 	}
       
   168 
       
   169 	qsort(_fios_items + sort_start, _fios_count - sort_start, sizeof(FiosItem), compare_FiosItems);
       
   170 	*num = _fios_count;
       
   171 	return _fios_items;
       
   172 }
       
   173 
       
   174 // Get a list of scenarios
       
   175 // FIXME: Gross code duplication with FiosGetSavegameList()
       
   176 FiosItem *FiosGetScenarioList(int *num, int mode)
       
   177 {
       
   178 	FiosItem *fios;
       
   179 	DIR *dir;
       
   180 	struct dirent *dirent;
       
   181 	struct stat sb;
       
   182 	int sort_start;
       
   183 	char filename[MAX_PATH];
       
   184 
       
   185 	if (_fios_scn_path == NULL) {
       
   186 		_fios_scn_path = malloc(MAX_PATH);
       
   187 		strcpy(_fios_scn_path, _path.scenario_dir);
       
   188 	}
       
   189 
       
   190 	_fios_path = _fios_scn_path;
       
   191 
       
   192 	// Parent directory, only if not of the type C:\.
       
   193 	if ((!ISROOT(_fios_path)) && mode != SLD_NEW_GAME) {
       
   194 		fios = FiosAlloc();
       
   195 		fios->type = FIOS_TYPE_PARENT;
       
   196 		fios->mtime = 0;
       
   197 		strcpy(fios->title, ".. (Parent directory)");
       
   198 	}
       
   199 
       
   200 	// Show subdirectories first
       
   201 	dir = opendir(_fios_path);
       
   202 	if (dir != NULL) {
       
   203 		while ((dirent = readdir(dir)) != NULL) {
       
   204 			snprintf(filename, lengthof(filename), PATHTEMPLATE,
       
   205 				_fios_path, dirent->d_name);
       
   206 			if (!stat(filename, &sb) && S_ISDIR(sb.st_mode) &&
       
   207 					dirent->d_name[0] != '.') {
       
   208 				fios = FiosAlloc();
       
   209 				fios->type = FIOS_TYPE_DIR;
       
   210 				fios->mtime = 0;
       
   211 				ttd_strlcpy(fios->name, dirent->d_name, lengthof(fios->name));
       
   212 				snprintf(fios->title, lengthof(fios->title), "%s/ (Directory)", FS2OTTD(dirent->d_name));
       
   213 				str_validate(fios->title);
       
   214 			}
       
   215 		}
       
   216 		closedir(dir);
       
   217 	}
       
   218 
       
   219 	{
       
   220 		/* XXX ugly global variables ... */
       
   221 		byte order = _savegame_sort_order;
       
   222 		_savegame_sort_order = SORT_BY_NAME | SORT_ASCENDING;
       
   223 		qsort(_fios_items, _fios_count, sizeof(FiosItem), compare_FiosItems);
       
   224 		_savegame_sort_order = order;
       
   225 	}
       
   226 
       
   227 	// this is where to start sorting
       
   228 	sort_start = _fios_count;
       
   229 
       
   230 	/* Show scenario files
       
   231 	 * .SCN OpenTTD style scenario file
       
   232 	 * .SV0 Transport Tycoon Deluxe (Patch) scenario
       
   233 	 * .SS0 Transport Tycoon Deluxe preset scenario
       
   234 	 */
       
   235 	dir = opendir(_fios_path);
       
   236 	if (dir != NULL) {
       
   237 		while ((dirent = readdir(dir)) != NULL) {
       
   238 			char *t;
       
   239 
       
   240 			snprintf(filename, lengthof(filename), PATHTEMPLATE, _fios_path, dirent->d_name);
       
   241 			if (stat(filename, &sb) || S_ISDIR(sb.st_mode)) continue;
       
   242 
       
   243 			t = strrchr(dirent->d_name, '.');
       
   244 			if (t == NULL) continue;
       
   245 
       
   246 			if (strcasecmp(t, ".scn") == 0) { // OpenTTD
       
   247 				fios = FiosAlloc();
       
   248 				fios->type = FIOS_TYPE_SCENARIO;
       
   249 				fios->mtime = sb.st_mtime;
       
   250 				ttd_strlcpy(fios->name, dirent->d_name, lengthof(fios->name));
       
   251 
       
   252 				*t = '\0'; // strip extension
       
   253 				ttd_strlcpy(fios->title, FS2OTTD(dirent->d_name), lengthof(fios->title));
       
   254 				str_validate(fios->title);
       
   255 			} else if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO ||
       
   256 					mode == SLD_NEW_GAME) {
       
   257 				if (strcasecmp(t, ".sv0") == 0 ||
       
   258 						strcasecmp(t, ".ss0") == 0) { // TTDLX(Patch)
       
   259 					fios = FiosAlloc();
       
   260 					fios->type = FIOS_TYPE_OLD_SCENARIO;
       
   261 					fios->mtime = sb.st_mtime;
       
   262 					GetOldScenarioGameName(fios->title, filename);
       
   263 					ttd_strlcpy(fios->name, dirent->d_name, lengthof(fios->name));
       
   264 				}
       
   265 			}
       
   266 		}
       
   267 		closedir(dir);
       
   268 	}
       
   269 
       
   270 	qsort(_fios_items + sort_start, _fios_count - sort_start, sizeof(FiosItem), compare_FiosItems);
       
   271 	*num = _fios_count;
       
   272 	return _fios_items;
       
   273 }
   100 }
   274 
   101 
   275 // Browse to
   102 // Browse to
   276 char *FiosBrowseTo(const FiosItem *item)
   103 char *FiosBrowseTo(const FiosItem *item)
   277 {
   104 {