From 5d6fabe47d4cce45d956fdfa4d4dba30e2f6ea06 Mon Sep 17 00:00:00 2001 From: lordhavoc Date: Mon, 25 Mar 2002 22:51:57 +0000 Subject: [PATCH] now loads gamedir/*.pak instead of gamedir/pak#.pak, sorted by ASCII value (note: lowercase overrides uppercase) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@1676 d7cf8633-e32d-0410-b094-e92efae38249 --- common.c | 32 ++++++++-- common.h | 10 ++++ filematch.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++ makefile | 2 +- 4 files changed, 205 insertions(+), 5 deletions(-) create mode 100644 filematch.c diff --git a/common.c b/common.c index 6eb69277..36d2920e 100644 --- a/common.c +++ b/common.c @@ -1728,10 +1728,11 @@ then loads and adds pak1.pak pak2.pak ... */ void COM_AddGameDirectory (char *dir) { - int i; - searchpath_t *search; - pack_t *pak; - char pakfile[MAX_OSPATH]; + //int i; + stringlist_t *list, *current; + searchpath_t *search; + pack_t *pak; + char pakfile[MAX_OSPATH]; strcpy (com_gamedir, dir); @@ -1743,6 +1744,28 @@ void COM_AddGameDirectory (char *dir) search->next = com_searchpaths; com_searchpaths = search; + // add any paks in the directory + list = listdirectory(dir); + for (current = list;current;current = current->next) + { + if (matchpattern(current->text, "*.pak")) + { + sprintf (pakfile, "%s/%s", dir, current->text); + pak = COM_LoadPackFile (pakfile); + if (pak) + { + search = Mem_Alloc(pak_mempool, sizeof(searchpath_t)); + search->pack = pak; + search->next = com_searchpaths; + com_searchpaths = search; + } + else + Con_Printf("unable to load pak \"%s\"\n", pakfile); + } + } + freedirectory(list); + + /* // // add any pak files in the format pak0.pak pak1.pak, ... // @@ -1757,6 +1780,7 @@ void COM_AddGameDirectory (char *dir) search->next = com_searchpaths; com_searchpaths = search; } + */ // // add the contents of the parms.txt file to the end of the command line diff --git a/common.h b/common.h index 9cb9b9b2..b4fcbab9 100644 --- a/common.h +++ b/common.h @@ -199,3 +199,13 @@ extern char *gamename; // LordHavoc: useful... extern void COM_ToLowerString(char *in, char *out); extern void COM_ToUpperString(char *in, char *out); + +typedef struct stringlist_s +{ + struct stringlist_s *next; + char *text; +} stringlist_t; + +int matchpattern(char *in, char *pattern); +stringlist_t *listdirectory(char *path); +void freedirectory(stringlist_t *list); diff --git a/filematch.c b/filematch.c new file mode 100644 index 00000000..996753c1 --- /dev/null +++ b/filematch.c @@ -0,0 +1,166 @@ + +#include "quakedef.h" + +// LordHavoc: some portable directory listing code I wrote for lmp2pcx, now used in darkplaces to load id1/*.pak and such... + +int matchpattern(char *in, char *pattern) +{ + while (*pattern) + { + switch (*pattern) + { + case '?': // match any single character + if (!*in) + return 0; // no match + in++; + pattern++; + break; + case '*': // match anything until following string + if (!*in) + return 1; // match + while (*pattern == '*') + pattern++; + if (*pattern == '?') + { + // *? (weird) + break; + } + else if (*pattern) + { + // *text (typical) + while (*in && *in != *pattern) + in++; + } + else + { + // *null (* at end of pattern) + return 1; + } + break; + default: + if (*in != *pattern) + return 0; // no match + in++; + pattern++; + break; + } + } + if (*in) + return 0; // reached end of pattern but not end of input + return 1; // success +} + +// a little chained strings system +stringlist_t *stringlistappend(stringlist_t *current, char *text) +{ + stringlist_t *newitem; + newitem = Z_Malloc(strlen(text) + 1 + sizeof(stringlist_t)); + newitem->next = NULL; + newitem->text = (char *)(newitem + 1); + strcpy(newitem->text, text); + if (current) + current->next = newitem; + return newitem; +} + +void stringlistfree(stringlist_t *current) +{ + stringlist_t *next; + while (current) + { + next = current->next; + Z_Free(current); + current = next; + } +} + +stringlist_t *stringlistsort(stringlist_t *start) +{ + int notdone; + stringlist_t *current, *previous, *temp2, *temp3, *temp4; + notdone = 1; + while (notdone) + { + current = start; + notdone = 0; + previous = NULL; + while (current && current->next) + { + if (strcmp(current->text, current->next->text) > 0) + { + // current is greater than next + notdone = 1; + temp2 = current->next; + temp3 = current; + temp4 = current->next->next; + if (previous) + previous->next = temp2; + else + start = temp2; + temp2->next = temp3; + temp3->next = temp4; + break; + } + previous = current; + current = current->next; + } + } + return start; +} + +// operating system specific code +#ifdef WIN32 +#include +stringlist_t *listdirectory(char *path) +{ + char pattern[4096]; + struct _finddata_t n_file; + long hFile; + stringlist_t *start, *current; + strcpy(pattern, path); + strcat(pattern, "\\*"); + // ask for the directory listing handle + hFile = _findfirst(pattern, &n_file); + if(hFile != -1) + { + // start a new chain with the the first name + start = current = stringlistappend(NULL, n_file.name); + // iterate through the directory + while (_findnext(hFile, &n_file) == 0) + current = stringlistappend(current, n_file.name); + _findclose(hFile); + // sort the list alphanumerically + return stringlistsort(start); + } + else + return NULL; +} +#else +#include +stringlist_t *listdirectory(char *path) +{ + DIR *dir; + struct dirent *ent; + stringlist_t *start, *current; + dir = opendir(path); + if (!dir) + return NULL; + ent = readdir(dir); + if (!ent) + { + closedir(dir); + return NULL; + } + start = current = stringlistappend(NULL, ent->d_name); + while((ent = readdir(dir))) + current = stringlistappend(current, ent->d_name); + closedir(dir); + // sort the list alphanumerically + return stringlistsort(start); +} +#endif + +void freedirectory(stringlist_t *list) +{ + stringlistfree(list); +} \ No newline at end of file diff --git a/makefile b/makefile index 371fca22..bd1a764a 100644 --- a/makefile +++ b/makefile @@ -9,7 +9,7 @@ SOUNDLIB=-lasound #SND=snd_oss.o #SOUNDLIB= -OBJECTS= builddate.o cd_linux.o chase.o cl_demo.o cl_input.o cl_main.o cl_parse.o cl_tent.o cmd.o common.o console.o crc.o cvar.o fractalnoise.o gl_draw.o r_sky.o gl_rmain.o gl_rsurf.o host.o host_cmd.o image.o keys.o mathlib.o menu.o model_alias.o model_brush.o model_shared.o model_sprite.o net_bsd.o net_udp.o net_dgrm.o net_loop.o net_main.o pr_cmds.o pr_edict.o pr_exec.o r_light.o r_explosion.o sbar.o snd_dma.o snd_mem.o snd_mix.o $(SND) sv_main.o sv_move.o sv_phys.o sv_user.o sv_light.o sys_linux.o transform.o view.o wad.o world.o zone.o vid_shared.o palette.o r_crosshairs.o gl_textures.o gl_models.o r_sprites.o r_modules.o r_explosion.o r_lerpanim.o protocol.o quakeio.o r_clip.o ui.o portals.o sys_shared.o cl_light.o gl_backend.o cl_particles.o cl_screen.o cgamevm.o cgame.o +OBJECTS= builddate.o cd_linux.o chase.o cl_demo.o cl_input.o cl_main.o cl_parse.o cl_tent.o cmd.o common.o console.o crc.o cvar.o fractalnoise.o gl_draw.o r_sky.o gl_rmain.o gl_rsurf.o host.o host_cmd.o image.o keys.o mathlib.o menu.o model_alias.o model_brush.o model_shared.o model_sprite.o net_bsd.o net_udp.o net_dgrm.o net_loop.o net_main.o pr_cmds.o pr_edict.o pr_exec.o r_light.o r_explosion.o sbar.o snd_dma.o snd_mem.o snd_mix.o $(SND) sv_main.o sv_move.o sv_phys.o sv_user.o sv_light.o sys_linux.o transform.o view.o wad.o world.o zone.o vid_shared.o palette.o r_crosshairs.o gl_textures.o gl_models.o r_sprites.o r_modules.o r_explosion.o r_lerpanim.o protocol.o quakeio.o r_clip.o ui.o portals.o sys_shared.o cl_light.o gl_backend.o cl_particles.o cl_screen.o cgamevm.o cgame.o filematch.o #K6/athlon optimizations CPUOPTIMIZATIONS=-march=k6 -- 2.39.2