diff --git a/filesel/modlist.c b/filesel/modlist.c index 1426a8ac..7250e232 100644 --- a/filesel/modlist.c +++ b/filesel/modlist.c @@ -456,6 +456,46 @@ static int mlecmp (const void *a, const void *b) return strcasecmp(n1, n2); } +static int mlecmp_filesonly_groupdir (const void *a, const void *b) +{ + int _1 = *(int *)a; + int _2 = *(int *)b; + const struct modlistentry *e1 = &sorting->files[_1]; + const struct modlistentry *e2 = &sorting->files[_2]; + + int i1 = mlecmp_score (e1); + int i2 = mlecmp_score (e2); + + const char *n1, *n2; + + int retval; + + if (i1 != i2) + { + return i2 - i1; + } + + if (e1->flags & MODLIST_FLAG_DRV) + { + return 0; + } + if (!e1->file->parent) + { + return 0; + } + + retval = (int)((int32_t)e1->file->parent->dirdb_ref - (int32_t)e2->file->parent->dirdb_ref); + if (retval) + { + return retval; + } + + dirdbGetName_internalstr (e1->file->dirdb_ref, &n1); + dirdbGetName_internalstr (e2->file->dirdb_ref, &n2); + + return strcasecmp(n1, n2); +} + void modlist_sort (struct modlist *modlist) { sorting = modlist; /* dirty HACK that is not thread-safe / reentrant what so ever */ @@ -463,6 +503,19 @@ void modlist_sort (struct modlist *modlist) sorting = 0; } +void modlist_subsort_filesonly_groupdir (struct modlist *modlist, unsigned int pos, unsigned int length) +{ + if ((pos >= modlist->num) || + (length > modlist->num) || + ((pos + length) > modlist->num)) + { + return; + } + sorting = modlist; /* dirty HACK that is not thread-safe / reentrant what so ever */ + qsort(modlist->sortindex + pos, length, sizeof(modlist->sortindex[0]), mlecmp_filesonly_groupdir); + sorting = 0; +} + struct modlist *modlist_create (void) { /* TODO ARCS */ diff --git a/filesel/modlist.h b/filesel/modlist.h index cc570c76..c01c798c 100644 --- a/filesel/modlist.h +++ b/filesel/modlist.h @@ -37,6 +37,7 @@ struct dmDrive; struct modlist *modlist_create(void); void modlist_free(struct modlist *modlist); void modlist_sort(struct modlist *modlist); +void modlist_subsort_filesonly_groupdir (struct modlist *modlist, unsigned int pos, unsigned int length); /* sorts a slice of the list */ void modlist_append(struct modlist *modlist, struct modlistentry *entry); void modlist_append_dir (struct modlist *modlist, struct ocpdir_t *dir); void modlist_append_dotdot (struct modlist *modlist, struct ocpdir_t *dir); diff --git a/filesel/pfilesel.c b/filesel/pfilesel.c index 5efda6b1..a7b9d756 100644 --- a/filesel/pfilesel.c +++ b/filesel/pfilesel.c @@ -310,6 +310,12 @@ int fsReadDir (struct modlist *ml, struct ocpdir_t *dir, const char *mask, unsig { struct fsReadDir_token_t token; ocpdirhandle_pt dh; + unsigned int prenum = 0; + + if (opt & RD_SUBSORT) + { + prenum = ml->num; + } if (opt & RD_PUTDRIVES) { @@ -335,7 +341,7 @@ int fsReadDir (struct modlist *ml, struct ocpdir_t *dir, const char *mask, unsig #else token.mask = (char *)mask; #endif - token.opt = opt; + token.opt = opt & ~(RD_SUBSORT); if ((opt & RD_PUTRSUBS) && dir->readflatdir_start) { @@ -371,6 +377,12 @@ int fsReadDir (struct modlist *ml, struct ocpdir_t *dir, const char *mask, unsig #ifndef FNM_CASEFOLD free (token.mask); #endif + + if (opt & RD_SUBSORT) + { + modlist_subsort_filesonly_groupdir (ml, prenum, ml->num - prenum); + } + return 1; } @@ -3726,7 +3738,7 @@ signed int fsFileSelect(void) } else { if (m->dir) { - if (!(fsReadDir (playlist, m->dir, curmask, RD_PUTRSUBS | RD_ISMODONLY))) + if (!(fsReadDir (playlist, m->dir, curmask, RD_PUTRSUBS | RD_ISMODONLY | RD_SUBSORT))) { return -1; } diff --git a/filesel/pfilesel.h b/filesel/pfilesel.h index 47786f83..a4994ceb 100644 --- a/filesel/pfilesel.h +++ b/filesel/pfilesel.h @@ -89,6 +89,7 @@ void plFindInterface(struct moduletype modtype, const struct interfacestruct **i #define RD_PUTDRIVES 8 #define RD_PUTRSUBS 16 #define RD_ISMODONLY 32 +#define RD_SUBSORT 64 int fsMatchFileName12(const char *a, const char *b);