Example #1
0
/*
=====================
SV_WipeSavegame

Delete save/<XXX>/
=====================
*/
void SV_WipeSavegame (char *savename)
{
	char	name[MAX_OSPATH];
	char	*s;

	Com_DPrintf("SV_WipeSaveGame(%s)\n", savename);

	Com_sprintf (name, sizeof(name), "%s/save/%s/server.ssv", FS_Gamedir (), savename);
	remove (name);
	Com_sprintf (name, sizeof(name), "%s/save/%s/game.ssv", FS_Gamedir (), savename);
	remove (name);
	// Knightmare- delete screenshot
	Com_sprintf (name, sizeof(name), "%s/save/%s/shot.png", FS_Gamedir (), savename);
	remove (name);

	Com_sprintf (name, sizeof(name), "%s/save/%s/*.sav", FS_Gamedir (), savename);
	s = Sys_FindFirst( name, 0, 0 );
	while (s)
	{
		remove (s);
		s = Sys_FindNext( 0, 0 );
	}
	Sys_FindClose ();
	Com_sprintf (name, sizeof(name), "%s/save/%s/*.sv2", FS_Gamedir (), savename);
	s = Sys_FindFirst(name, 0, 0 );
	while (s)
	{
		remove (s);
		s = Sys_FindNext( 0, 0 );
	}
	Sys_FindClose ();
}
Example #2
0
/*
=====================
SV_WipeSavegame

Delete save/<XXX>/
=====================
*/
static void SV_WipeSavegame (const char *savename)
{
	char	name[MAX_OSPATH];
	char	*s;

	Com_DPrintf("SV_WipeSaveGame(%s)\n", savename);

	Com_sprintf (name, sizeof(name), "%s/save/%s/server.ssv", FS_Gamedir (), savename);
	FS_RemoveFile(name);
	Com_sprintf (name, sizeof(name), "%s/save/%s/game.ssv", FS_Gamedir (), savename);
	FS_RemoveFile(name);

	Com_sprintf (name, sizeof(name), "%s/save/%s/*.sav", FS_Gamedir (), savename);
	s = Sys_FindFirst( name, 0, 0 );
	while (s)
	{
		FS_RemoveFile(s);
		s = Sys_FindNext( 0, 0 );
	}
	Sys_FindClose ();
	Com_sprintf (name, sizeof(name), "%s/save/%s/*.sv2", FS_Gamedir (), savename);
	s = Sys_FindFirst(name, 0, 0 );
	while (s)
	{
		FS_RemoveFile(s);
		s = Sys_FindNext( 0, 0 );
	}
	Sys_FindClose ();
}
void CASW_Mission_Chooser_Source_Local::BuildSavedCampaignList()
{
	// don't start searching for saves until we've loaded in all the campaigns
	if (!m_bBuiltCampaignList)
	{
		BuildCampaignList();
		return;
	}
	if (m_bBuildingSavedCampaignList || m_bBuiltSavedCampaignList)
		return;

	ClearSavedCampaignList();

	m_bBuildingSavedCampaignList = true;

	if (m_CampaignList.Count() <= 0)
	{
		//Msg("Error: Cannot build saved campaign list until the campaign list is built\n");
		return;
	}

	// Search the directory structure for save games
	char mapwild[MAX_QPATH];
	Q_strncpy(mapwild,"save/*.campaignsave", sizeof( mapwild ) );
	m_pszSavedFind = Sys_FindFirst( g_hsavedfind, mapwild, NULL, 0 );
	// think will continue the search
}
Example #4
0
void
FS_ExecAutoexec(void)
{
	char *dir;
	char name[MAX_QPATH];

	dir = (char *)Cvar_VariableString("gamedir");

	if (dir[0] != '\0')
	{
		Com_sprintf(name, sizeof(name), "%s/%s/autoexec.cfg",
				fs_basedir->string, dir);
	}
	else
	{
		Com_sprintf(name, sizeof(name), "%s/%s/autoexec.cfg",
				fs_basedir->string, BASEDIRNAME);
	}

	if (Sys_FindFirst(name, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM) != NULL)
	{
		Cbuf_AddText("exec autoexec.cfg\n");
	}

	Sys_FindClose();
}
Example #5
0
// Loads in all level themes found in tilegen/themes/
void CLevelTheme::LoadLevelThemes()
{
	if ( s_bLoadedThemes )
		return;

	s_pCurrentTheme = NULL;
	s_LevelThemes.PurgeAndDeleteElements();
	s_bLoadedThemes = true;

	// Search the directory structure.
	char mapwild[MAX_PATH];
	Q_strncpy(mapwild,"tilegen/themes/*.theme", sizeof( mapwild ) );
	char const *filename;
	filename = Sys_FindFirst( g_hthemefind, mapwild, NULL, 0 );

	while (filename)
	{
		// load the level theme
		char szFullFileName[256];
		Q_snprintf(szFullFileName, sizeof(szFullFileName), "tilegen/themes/%s", filename);
		KeyValues *pThemeKeyValues = new KeyValues( filename );
		if (pThemeKeyValues->LoadFromFile(g_pFullFileSystem, szFullFileName, "GAME"))
		{
			//CLevelTheme* pTheme = new CLevelTheme(pThemeKeyValues->GetString("ThemeName"),
			//									pThemeKeyValues->GetString("ThemeDescription"),
			//									pThemeKeyValues->GetInt("VMFTweak", 0) > 0 );
			//pTheme->m_bSkipErrorCheck = ( pThemeKeyValues->GetInt( "SkipErrorCheck", 0 ) > 0 );
			//sscanf( pThemeKeyValues->GetString( "AmbientLight" ) , "%f %f %f", &pTheme->m_vecAmbientLight.x, &pTheme->m_vecAmbientLight.y, &pTheme->m_vecAmbientLight.z );
			//// temp to avoid the 0,0,0 losing ambient light bug
			//if ( pTheme->m_vecAmbientLight == vec3_origin )
			//{
			//	pTheme->m_vecAmbientLight.x = 1;
			//	pTheme->m_vecAmbientLight.y = 1;
			//	pTheme->m_vecAmbientLight.z = 1;
			//}
			//pTheme->LoadRoomTemplates();
			//s_LevelThemes.AddToTail(pTheme);
			//if (!Q_stricmp(pTheme->m_szName, asw_tilegen_theme.GetString()))	// default to the Rydberg theme
			//	SetCurrentTheme(pTheme);
		}
		else
		{
			Msg("Error: failed to load theme %s\n", szFullFileName);
		}
		pThemeKeyValues->deleteThis();
		filename = Sys_FindNext(g_hthemefind, NULL, 0);
	}

	if ( s_pCurrentTheme == NULL && s_LevelThemes.Count() > 0 )
	{
		SetCurrentTheme( s_LevelThemes[0] );
	}
		
	Sys_FindClose(g_hthemefind);
}
Example #6
0
/*
================
SV_CopySaveGame
================
*/
void SV_CopySaveGame (char *src, char *dst)
{
	char	name[MAX_OSPATH], name2[MAX_OSPATH];
	int		l, len;
	char	*found;

	Com_DPrintf("SV_CopySaveGame(%s, %s)\n", src, dst);

	SV_WipeSavegame (dst);

	// copy the savegame over
	Com_sprintf (name, sizeof(name), "%s/save/%s/server.ssv", FS_Gamedir(), src);
	Com_sprintf (name2, sizeof(name2), "%s/save/%s/server.ssv", FS_Gamedir(), dst);
	FS_CreatePath (name2);
	CopyFile (name, name2);

	Com_sprintf (name, sizeof(name), "%s/save/%s/game.ssv", FS_Gamedir(), src);
	Com_sprintf (name2, sizeof(name2), "%s/save/%s/game.ssv", FS_Gamedir(), dst);
	CopyFile (name, name2);

	// Knightmare- copy screenshot
	if (strcmp(dst, "kmq2save0")) // no screenshot for start of level autosaves
	{
		Com_sprintf (name, sizeof(name), "%s/save/%s/shot.jpg", FS_Gamedir(), src);
		Com_sprintf (name2, sizeof(name2), "%s/save/%s/shot.jpg", FS_Gamedir(), dst);
		CopyFile (name, name2);
	}

	Com_sprintf (name, sizeof(name), "%s/save/%s/", FS_Gamedir(), src);
	len = strlen(name);
	Com_sprintf (name, sizeof(name), "%s/save/%s/*.sav", FS_Gamedir(), src);
	found = Sys_FindFirst(name, 0, 0 );
	while (found)
	{
	//	strncpy (name+len, found+len);
		Q_strncpyz (name+len, found+len, sizeof(name)-len);
		Com_sprintf (name2, sizeof(name2), "%s/save/%s/%s", FS_Gamedir(), dst, found+len);
		CopyFile (name, name2);

		// change sav to sv2
		l = strlen(name);
	//	strncpy (name+l-3, "sv2");
		Q_strncpyz (name+l-3, "sv2", sizeof(name)-l+3);
		l = strlen(name2);
	//	strncpy (name2+l-3, "sv2");
		Q_strncpyz (name2+l-3, "sv2", sizeof(name2)-l+3);
		CopyFile (name, name2);

		found = Sys_FindNext( 0, 0 );
	}
	Sys_FindClose ();
}
Example #7
0
File: files.c Project: Slipyx/r1q2
/*
=============
FS_ExecConfig
=============
*/
void FS_ExecConfig (const char *filename)
{
	const char	*dir;
	char		name [MAX_QPATH];

	dir = Cvar_VariableString("gamedir");
	if (dir[0])
		Com_sprintf(name, sizeof(name), "%s/%s/%s", fs_basedir->string, dir, filename); 
	else
		Com_sprintf(name, sizeof(name), "%s/%s/%s", fs_basedir->string, BASEDIRNAME, filename); 
	if (Sys_FindFirst(name, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM))
		Cbuf_AddText (va ("exec %s\n", filename));
	Sys_FindClose();
}
Example #8
0
static int CDAudio_GetAudioDiskInfo(void)
{
	char* t;

	cdValid = false;

	if(trackList != NULL)
	{
		CDAudio_DeleteTracks(trackList);
		free(trackList);
		trackList = NULL;
	};
	maxTrack = 0;

	sprintf(trackDir, cd_tracks.string, com_gamedir);
	sprintf(tracks, "%s/*.ogg", trackDir);
	t = Sys_FindFirst(tracks, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM);
	if(t == NULL)
	{
		Sys_FindClose();
		return -1;
	}

	cdValid = true;

	do
	{
		if(trackList == NULL)
		{
			trackList = Sys_Malloc(sizeof(trackinfo_t), "CDAudio_GetAudioDiskInfo");
			trackList->track = Sys_Malloc(strlen(t) + 1, "CDAudio_GetAudioDiskInfo");
			strcpy(trackList->track, t);
			trackList->prev = NULL;
			trackList->next = NULL;
		} else
		{
			CDAudio_AddTrack(trackList, t);
		};
		maxTrack++;
		t = Sys_FindNext(0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM);
	} while(t != NULL);

	if(cd_nofirst.value)
		maxTrack++;

	Sys_FindClose();

	return 0;
}
void CASW_Mission_Chooser_Source_Local::BuildCampaignList()
{
	if (m_bBuildingCampaignList || m_bBuiltCampaignList)	// already building
		return;

	ClearCampaignList();

	m_bBuildingCampaignList= true;

	// Search the directory structure.
	char mapwild[MAX_QPATH];
	Q_strncpy(mapwild,"resource/campaigns/*.txt", sizeof( mapwild ) );
	m_pszCampaignFind = Sys_FindFirst( g_hcampaignfind, mapwild, NULL, 0 );
	// think will continue the search
}
void CASW_Mission_Chooser_Source_Local::BuildMapList()
{
	if (m_bBuildingMapList || m_bBuiltMapList)	// already building
		return;

	ClearMapList();

	m_bBuildingMapList = true;

	// Search the directory structure.
	char mapwild[MAX_QPATH];
	Q_strncpy(mapwild,"maps/*.bsp", sizeof( mapwild ) );
	m_pszMapFind = Sys_FindFirst( g_hmapfind, mapwild, NULL, 0 );
	// think will continue the search
}
Example #11
0
void
SV_CopySaveGame(char *src, char *dst)
{
	char name[MAX_OSPATH], name2[MAX_OSPATH];
	size_t l, len;
	char *found;

	Com_DPrintf("SV_CopySaveGame(%s, %s)\n", src, dst);

	SV_WipeSavegame(dst);

	/* copy the savegame over */
	Com_sprintf(name, sizeof(name), "%s/save/%s/server.ssv", FS_Gamedir(), src);
	Com_sprintf(name2, sizeof(name2), "%s/save/%s/server.ssv", FS_Gamedir(), dst);
	FS_CreatePath(name2);
	CopyFile(name, name2);

	Com_sprintf(name, sizeof(name), "%s/save/%s/game.ssv", FS_Gamedir(), src);
	Com_sprintf(name2, sizeof(name2), "%s/save/%s/game.ssv", FS_Gamedir(), dst);
	CopyFile(name, name2);

	Com_sprintf(name, sizeof(name), "%s/save/%s/", FS_Gamedir(), src);
	len = strlen(name);
	Com_sprintf(name, sizeof(name), "%s/save/%s/*.sav", FS_Gamedir(), src);
	found = Sys_FindFirst(name, 0, 0);

	while (found)
	{
		strcpy(name + len, found + len);

		Com_sprintf(name2, sizeof(name2), "%s/save/%s/%s",
					FS_Gamedir(), dst, found + len);
		CopyFile(name, name2);

		/* change sav to sv2 */
		l = strlen(name);
		strcpy(name + l - 3, "sv2");
		l = strlen(name2);
		strcpy(name2 + l - 3, "sv2");
		CopyFile(name, name2);

		found = Sys_FindNext(0, 0);
	}

	Sys_FindClose();
}
Example #12
0
void CLevelTheme::LoadRoomTemplatesInFolder( const char *szPath )
{
	char mapwild[MAX_PATH];
	Q_snprintf( mapwild, sizeof( mapwild ), "%s/*", szPath );
	char const *filename;
	FileFindHandle_t	hRoomfind = FILESYSTEM_INVALID_FIND_HANDLE;
	filename = Sys_FindFirst( hRoomfind, mapwild, NULL, 0 );
	while ( filename )
	{
		if ( g_pFullFileSystem->FindIsDirectory( hRoomfind ) )
		{
			if ( Q_strcmp( filename, "." ) && Q_strcmp( filename, ".." ) )
			{
				char subfolder[MAX_PATH];
				Q_snprintf( subfolder, sizeof( subfolder ), "%s/%s", szPath, filename );
				LoadRoomTemplatesInFolder( subfolder );
			}
		}
		else
		{	
			const char *pExt = Q_GetFileExtension( filename );
			if ( pExt && !Q_stricmp( pExt, "roomtemplate" ) )
			{
				// load the room template
				char szFullFileName[256];
				Q_snprintf(szFullFileName, sizeof(szFullFileName), "%s/%s", szPath, filename);
				KeyValues *pRoomTemplateKeyValues = new KeyValues( filename );
				if (pRoomTemplateKeyValues->LoadFromFile(g_pFullFileSystem, szFullFileName, "GAME"))
				{
					CRoomTemplate* pRoomTemplate = new CRoomTemplate(this);
					pRoomTemplate->LoadFromKeyValues( szFullFileName + Q_strlen( ROOMTEMPLATES_FOLDER ) + 1 + Q_strlen( m_szName ), pRoomTemplateKeyValues );		// sets the room templates properties based on these keyvalues
					m_RoomTemplates.Insert(pRoomTemplate);
				}
				else
				{
					Msg("Error: failed to load room template %s\n", szFullFileName);
				}
				pRoomTemplateKeyValues->deleteThis();
			}
		}
		filename = Sys_FindNext(hRoomfind, NULL, 0);
	}
		
	Sys_FindClose(hRoomfind);
}
void CASW_KeyValuesDatabase::LoadFilesInFolder( const char *pPath )
{
	FileFindHandle_t tagsfind = FILESYSTEM_INVALID_FIND_HANDLE;

	// Search the directory structure.
	char mapwild[MAX_PATH];
	Q_snprintf( mapwild, sizeof( mapwild ), "%s*", pPath );
	char const *filename;
	filename = Sys_FindFirst( tagsfind, mapwild, NULL, 0 );

	while (filename)
	{
		if ( g_pFullFileSystem->FindIsDirectory( tagsfind ) )
		{
			if ( Q_strcmp( filename, "." ) && Q_strcmp( filename, ".." ) )
			{
				char subfolder[MAX_PATH];
				Q_snprintf( subfolder, sizeof( subfolder ), "%s%s/", pPath, filename );
				LoadFilesInFolder( subfolder );
			}
		}
		else
		{
			const char *pExt = Q_GetFileExtension( filename );
			if ( pExt && !Q_stricmp( pExt, "txt" ) )
			{
				// load the mission spec
				char fullFileName[256];
				Q_snprintf(fullFileName, sizeof(fullFileName), "%s%s", pPath, filename);
				KeyValues *pKeyValues = new KeyValues( filename );
				if (pKeyValues->LoadFromFile(g_pFullFileSystem, fullFileName, "GAME"))
				{
					AddFile( pKeyValues, fullFileName );
				}
				else
				{
					Msg( "Error: failed to load file: %s\n", fullFileName );
				}
			}
		}
		filename = Sys_FindNext(tagsfind, NULL, 0);
	}

	Sys_FindClose( tagsfind );
}
Example #14
0
/* DESCRIPTION: COM_ListMaps
// LOCATION: As other names I think.  Too messy to bother though.
// PATH: console command 'maps'
//
// Prints out map names.  I don't know if the string has the /maps appended
// to it or not yet; we'll work that out later, as well as extensions, gamedir,
// etc.
*/
int COM_ListMaps(const char * wildcards) {

   int i = 0;
   const char * filename;

   Con_Printf("COM_ListMaps \"%s\":\n", wildcards);

   filename = Sys_FindFirst(wildcards, NULL);
   while(filename != NULL) {
      i++;
      Con_Printf(" %s\n", filename);
      filename = Sys_FindNext(NULL);
   }
   Sys_FindClose();

   Con_Printf("%u matches found.\n", wildcards);
   return(i);
}
//-----------------------------------------------------------------------------
// Purpose: Fills buffer with list of maps from this mod
//-----------------------------------------------------------------------------
void CServerRemoteAccess::GetMapList(CUtlBuffer &value)
{
	// search the directory structure.
	char mapwild[MAX_QPATH];
	char friendly_com_gamedir[ MAX_OSPATH ];
	strcpy(mapwild, "maps/*.bsp");
	Q_strncpy( friendly_com_gamedir, com_gamedir, sizeof(friendly_com_gamedir) );
	Q_strlower( friendly_com_gamedir );
	
	char const *findfn = Sys_FindFirst( mapwild, NULL, 0 );
	while ( findfn )
	{
		char curDir[MAX_PATH];
		_snprintf(curDir, MAX_PATH, "maps/%s", findfn);
		g_pFileSystem->GetLocalPath(curDir, curDir, MAX_PATH);
		
		// limit maps displayed to ones for the mod only
		if (strstr(curDir, friendly_com_gamedir))
		{
			// clean up the map name
			char mapName[MAX_PATH];
			strcpy(mapName, findfn);
			char *extension = strstr(mapName, ".bsp");
			if (extension)
			{
				*extension = 0;
			}

			// write into buffer
			value.PutString(mapName);
			value.PutString("\n");
		}
		findfn = Sys_FindNext( NULL, 0 );
	}

	Sys_FindClose();
	value.PutChar(0);
}
Example #16
0
void CServerRemoteAccess::GetMapList(CUtlBuffer &value)
{
	const char *findfn;
	char *extension;
	char curDir[MAX_PATH];
	char mapName[MAX_PATH];
	char mapwild[64];

	Q_strcpy(mapwild, "maps/*.bsp");
	for (findfn = Sys_FindFirst(mapwild, 0); findfn; findfn = Sys_FindNext(0))
	{
		Q_snprintf(curDir, ARRAYSIZE(curDir), "maps/%s", findfn);
#ifdef REHLDS_CHECKS
		curDir[ARRAYSIZE(curDir) - 1] = 0;
#endif

		FS_GetLocalPath(curDir, curDir, ARRAYSIZE(curDir));
		if (Q_strstr(curDir, com_gamedir))
		{
#ifdef REHLDS_CHECKS
			Q_strncpy(mapName, findfn, ARRAYSIZE(mapName));
			mapName[ARRAYSIZE(mapName) - 1] = 0;
#else
			Q_strcpy(mapName, findfn);
#endif
			extension = Q_strstr(mapName, ".bsp");
			if (extension)
				*extension = 0;

			value.PutString(mapName);
			value.PutString("\n");
		}
	}
	Sys_FindClose();

	value.PutChar(0);
}
Example #17
0
File: files.c Project: Slipyx/r1q2
static void FS_LoadPaks (const char *dir, const char *ext)
{
	int				i;
	int				total;
	int				totalpaks;
	size_t			pakmatchlen;

	char			pakfile[MAX_OSPATH];
	char			pakmatch[MAX_OSPATH];
	char			*s;

	char			*filenames[4096];
	int				pakfiles[1024];

	pack_t			*pak;
	searchpath_t	*search;

	//r1: load all *.pak files
	Com_sprintf (pakfile, sizeof(pakfile), "%s/*.%s", dir, ext);
	Com_sprintf (pakmatch, sizeof(pakmatch), "%s/pak", dir);
	pakmatchlen = strlen(pakmatch);

	total = 0;
	totalpaks = 0;

	if ((s = Sys_FindFirst (pakfile, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM)) != NULL)
	{
		while (s)
		{
			i = (int)strlen (s);
			if (*(s+(i-4)) == '.' && !Q_stricmp (s+(i-3), ext))
			{
				if (!Q_strncasecmp (s, pakmatch, pakmatchlen))
				{
					pakfiles[totalpaks++] = atoi(s+pakmatchlen);
				}
				else
				{
					filenames[total++] = strdup(s);
					//filenames[total] = alloca(strlen(s)+1);
					//strcpy (filenames[total], s);
					//total++;
				}
			}

			s = Sys_FindNext (0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM);
		}
	}

	Sys_FindClose ();

	//sort for filenames designed to override earlier pak files
	qsort (filenames, total, sizeof(filenames[0]), filecmp);
	qsort (pakfiles, totalpaks, sizeof(pakfiles[0]), pakcmp);

	//r1: load pak*.pak first
	for (i = 0; i < totalpaks; i++)
	{
		Com_sprintf (pakfile, sizeof(pakfile), "%s/pak%d.%s", dir, pakfiles[i], ext);
		pak = FS_LoadPackFile (pakfile, ext);
		if (pak)
		{
			search = Z_TagMalloc (sizeof(searchpath_t), TAGMALLOC_SEARCHPATH);
			search->pack = pak;
			search->filename[0] = 0;
			search->next = fs_searchpaths;
			fs_searchpaths = search;
		}
	}

	//now the rest of them
	for (i = 0; i < total; i++)
	{
		pak = FS_LoadPackFile (filenames[i], ext);
		if (pak)
		{
			search = Z_TagMalloc (sizeof(searchpath_t), TAGMALLOC_SEARCHPATH);
			search->pack = pak;
			search->filename[0] = 0;
			search->next = fs_searchpaths;
			fs_searchpaths = search;
		}
		free (filenames[i]);
	}
}
Example #18
0
static qboolean PlayerConfig_ScanDirectories (void)
{
	char findname[1024];
	char scratch[1024];
	int ndirs = 0, npms = 0;
	char **dirnames;
	char *path = NULL;
	int i;

	//extern char **FS_ListFiles (char *, int *, unsigned, unsigned);

	s_numplayermodels = 0;

	// loop back to here if there were no valid player models found in the selected path
	do
	{
		//
		// get a list of directories
		//
		do 
		{
			path = FS_NextPath(path);
			Com_sprintf( findname, sizeof(findname), "%s/players/*.*", path );

			if ( (dirnames = FS_ListFiles(findname, &ndirs, SFF_SUBDIR, 0)) != 0 )
				break;
		} while (path);

		if (!dirnames)
			return false;

		//
		// go through the subdirectories
		//
		npms = ndirs;
		if (npms > MAX_PLAYERMODELS)
			npms = MAX_PLAYERMODELS;
		if ( (s_numplayermodels + npms) > MAX_PLAYERMODELS )
			npms = MAX_PLAYERMODELS - s_numplayermodels;

		for (i = 0; i < npms; i++)
		{
			int			k, s;
			char		*a, *b, *c;
			char		**skinnames;
			char		**imagenames;
			int			nimagefiles;
			int			nskins = 0;
			qboolean	already_added = false;	

			if (dirnames[i] == 0)
				continue;

			// check if dirnames[i] is already added to the s_pmi[i].directory list
			a = strrchr(dirnames[i], '/');
			b = strrchr(dirnames[i], '\\');
			c = (a > b) ? a : b;
			for (k=0; k < s_numplayermodels; k++)
				if (!strcmp(s_pmi[k].directory, c+1))
				{	already_added = true;	break;	}
			if (already_added)
			{	// todo: add any skins for this model not already listed to skindisplaynames
				continue;
			}

			// verify the existence of tris.md2
		//	strncpy(scratch, dirnames[i]);
		//	strncat(scratch, "/tris.md2");
			Q_strncpyz(scratch, dirnames[i], sizeof(scratch));
			Q_strncatz(scratch, "/tris.md2", sizeof(scratch));
			if ( !Sys_FindFirst(scratch, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM) )
			{
				free(dirnames[i]);
				dirnames[i] = 0;
				Sys_FindClose();
				continue;
			}
			Sys_FindClose();

			// verify the existence of at least one skin
		//	strncpy(scratch, va("%s%s", dirnames[i], "/*.*")); // was "/*.pcx"
			Q_strncpyz(scratch, va("%s%s", dirnames[i], "/*.*"), sizeof(scratch)); // was "/*.pcx"
			imagenames = FS_ListFiles (scratch, &nimagefiles, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM);

			if (!imagenames)
			{
				free(dirnames[i]);
				dirnames[i] = 0;
				continue;
			}

			// count valid skins, which consist of a skin with a matching "_i" icon
			for (k = 0; k < nimagefiles-1; k++)
				if ( IsValidSkin(imagenames, nimagefiles, k) )
					nskins++;

			if (!nskins)
				continue;

			skinnames = malloc(sizeof(char *) * (nskins+1));
			memset(skinnames, 0, sizeof(char *) * (nskins+1));

			// copy the valid skins
			if (nimagefiles)
				for (s = 0, k = 0; k < nimagefiles-1; k++)
				{
					char *a, *b, *c;
					if ( IsValidSkin(imagenames, nimagefiles, k) )
					{
						a = strrchr(imagenames[k], '/');
						b = strrchr(imagenames[k], '\\');

						c = (a > b) ? a : b;

					//	strncpy(scratch, c+1);
						Q_strncpyz(scratch, c+1, sizeof(scratch));

						if ( strrchr(scratch, '.') )
							*strrchr(scratch, '.') = 0;

						skinnames[s] = strdup(scratch);
						s++;
					}
				}

			// at this point we have a valid player model
			s_pmi[s_numplayermodels].nskins = nskins;
			s_pmi[s_numplayermodels].skindisplaynames = skinnames;

			// make short name for the model
			a = strrchr(dirnames[i], '/');
			b = strrchr(dirnames[i], '\\');

			c = (a > b) ? a : b;

			strncpy(s_pmi[s_numplayermodels].displayname, c+1, MAX_DISPLAYNAME-1);
		//	strncpy(s_pmi[s_numplayermodels].directory, c+1);
			Q_strncpyz(s_pmi[s_numplayermodels].directory, c+1, sizeof(s_pmi[s_numplayermodels].directory));

			FS_FreeFileList (imagenames, nimagefiles);

			s_numplayermodels++;
		}
		
		if (dirnames)
			FS_FreeFileList (dirnames, ndirs);

	// if no valid player models found in path,
	// try next path, if there is one
	} while (path);	// (s_numplayermodels == 0 && path);

	return true;	//** DMP warning fix
}