@@ -76,12 +76,25 @@ int compare_FiosItems(const void *a, con
}
if (_savegame_sort_order & SORT_DESCENDING) r = -r;
return r;
#if !defined(__MORPHOS__) && !defined(__AMIGAOS__)
#define ISROOT(__p) (__p[1] == '\0')
#define PATHTEMPLATE "%s/%s"
#else
/* on MorphOS or AmigaOS paths look like: "Volume:directory/subdirectory".
* This is some evil magic which tries to handle this transparently w/o
* disturbing code with too much #ifdefs. It's not possible to switch the
* volume, but at least it doesn't crash :) (tokai)
*/
static bool __isroot; /* not very thread save, but will do in this case */
#define ISROOT(__p) (__isroot = (__p[strlen(__p)-1] == ':'))
#define PATHTEMPLATE (__isroot ? "%s:%s" : "%s/%s")
#endif
// Get a list of savegames
FiosItem *FiosGetSavegameList(int *num, int mode)
{
FiosItem *fios;
DIR *dir;
@@ -95,25 +108,25 @@ FiosItem *FiosGetSavegameList(int *num,
strcpy(_fios_save_path, _path.save_dir);
_fios_path = _fios_save_path;
// Parent directory, only if not in root already.
if (_fios_path[1] != '\0') {
if (!ISROOT(_fios_path)) {
fios = FiosAlloc();
fios->type = FIOS_TYPE_PARENT;
fios->mtime = 0;
strcpy(fios->name, "..");
strcpy(fios->title, ".. (Parent directory)");
// Show subdirectories first
dir = opendir(_fios_path);
if (dir != NULL) {
while ((dirent = readdir(dir)) != NULL) {
snprintf(filename, lengthof(filename), "%s/%s",
snprintf(filename, lengthof(filename), PATHTEMPLATE,
_fios_path, dirent->d_name);
if (!stat(filename, &sb) && S_ISDIR(sb.st_mode) &&
dirent->d_name[0] != '.') {
fios->type = FIOS_TYPE_DIR;
@@ -144,13 +157,13 @@ FiosItem *FiosGetSavegameList(int *num,
char *t;
if (stat(filename, &sb) || S_ISDIR(sb.st_mode)) continue;
t = strrchr(dirent->d_name, '.');
if (t == NULL) continue;
@@ -199,24 +212,24 @@ FiosItem *FiosGetScenarioList(int *num,
strcpy(_fios_scn_path, _path.scenario_dir);
_fios_path = _fios_scn_path;
// Parent directory, only if not of the type C:\.
if (_fios_path[1] != '\0' && mode != SLD_NEW_GAME) {
if ((!ISROOT(_fios_path)) && mode != SLD_NEW_GAME) {
@@ -246,13 +259,13 @@ FiosItem *FiosGetScenarioList(int *num,
snprintf(filename, lengthof(filename), "%s/%s", _fios_path, dirent->d_name);
snprintf(filename, lengthof(filename), PATHTEMPLATE, _fios_path, dirent->d_name);
if (strcasecmp(t, ".scn") == 0) { // OpenTTD
@@ -298,22 +311,31 @@ char *FiosBrowseTo(const FiosItem *item)
char *path = _fios_path;
char *s;
switch (item->type) {
case FIOS_TYPE_PARENT:
s = strrchr(path, '/');
if (s != path) {
s[0] = '\0';
} else {
s[1] = '\0';
/* Check for possible NULL ptr (not required for UNIXes, but AmigaOS-alikes) */
if ((s = strrchr(path, '/'))) {
#if defined(__MORPHOS__) || defined(__AMIGAOS__)
else {
if ((s = strrchr(path, ':'))) {
break;
case FIOS_TYPE_DIR:
if (path[1] != '\0') strcat(path, "/");
if (!ISROOT(path)) strcat(path, "/");
strcat(path, item->name);
case FIOS_TYPE_DIRECT:
sprintf(path, "%s/", item->name);
@@ -323,13 +345,17 @@ char *FiosBrowseTo(const FiosItem *item)
case FIOS_TYPE_FILE:
case FIOS_TYPE_OLDFILE:
case FIOS_TYPE_SCENARIO:
case FIOS_TYPE_OLD_SCENARIO: {
static char str_buffr[512];
sprintf(str_buffr, "%s/%s", path, item->name);
ISROOT(path); /* init __isroot for PATHTEMPLATE */
sprintf(str_buffr, PATHTEMPLATE, path, item->name);
return str_buffr;
return NULL;
Status change: