about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authoroy <Tom_Adams@web.de>2011-02-21 11:23:30 +0100
committeroy <Tom_Adams@web.de>2011-02-21 11:23:30 +0100
commit088ec3e2f3ba0419612846db8f3687f5e2de1348 (patch)
treef12d7d6a55a7ef668dcc58ee64d0869ea7434e21 /src
parent4f91026a01436d95cb20b3a994e96dce5072544e (diff)
downloadzcatch-088ec3e2f3ba0419612846db8f3687f5e2de1348.tar.gz
zcatch-088ec3e2f3ba0419612846db8f3687f5e2de1348.zip
made the client's map search work with sub folders. Closes #254
Diffstat (limited to 'src')
-rw-r--r--src/base/system.c6
-rw-r--r--src/base/system.h2
-rw-r--r--src/engine/client/client.cpp15
-rw-r--r--src/engine/client/client.h2
-rw-r--r--src/engine/shared/storage.cpp63
-rw-r--r--src/engine/storage.h1
-rw-r--r--src/game/client/components/menus.h2
-rw-r--r--src/game/client/components/menus_demo.cpp6
-rw-r--r--src/game/client/components/skins.cpp8
-rw-r--r--src/game/client/components/skins.h2
-rw-r--r--src/game/editor/ed_editor.cpp6
11 files changed, 98 insertions, 15 deletions
diff --git a/src/base/system.c b/src/base/system.c
index 81c43869..0f0aaf70 100644
--- a/src/base/system.c
+++ b/src/base/system.c
@@ -884,7 +884,8 @@ int fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, int type, void *user)
 	do
 	{
 		str_copy(buffer+length, finddata.cFileName, (int)sizeof(buffer)-length);
-		cb(finddata.cFileName, fs_is_dir(buffer), type, user);
+		if(cb(finddata.cFileName, fs_is_dir(buffer), type, user))
+			break;
 	}
 	while (FindNextFileA(handle, &finddata));
 
@@ -905,7 +906,8 @@ int fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, int type, void *user)
 	while((entry = readdir(d)) != NULL)
 	{
 		str_copy(buffer+length, entry->d_name, (int)sizeof(buffer)-length);
-		cb(entry->d_name, fs_is_dir(buffer), type, user);
+		if(cb(entry->d_name, fs_is_dir(buffer), type, user))
+			break;
 	}
 
 	/* close the directory and return */
diff --git a/src/base/system.h b/src/base/system.h
index b3beb056..725f3008 100644
--- a/src/base/system.h
+++ b/src/base/system.h
@@ -942,7 +942,7 @@ void str_timestamp(char *buffer, int buffer_size);
 	Returns:
 		Always returns 0.
 */
-typedef void (*FS_LISTDIR_CALLBACK)(const char *name, int is_dir, int dir_type, void *user);
+typedef int (*FS_LISTDIR_CALLBACK)(const char *name, int is_dir, int dir_type, void *user);
 int fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, int type, void *user);
 
 /*
diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp
index 850c1d52..67f954dd 100644
--- a/src/engine/client/client.cpp
+++ b/src/engine/client/client.cpp
@@ -378,19 +378,21 @@ void CFileCollection::AddEntry(int64 Timestamp)
 	}
 }
 
-void CFileCollection::FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser)
+int CFileCollection::FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser)
 {
 	CFileCollection *pThis = static_cast<CFileCollection *>(pUser);
 
 	// check for valid file name format
 	if(IsDir || !pThis->IsFilenameValid(pFilename))
-		return;
+		return 0;
 
 	// extract the timestamp
 	int64 Timestamp = pThis->ExtractTimestamp(pFilename+pThis->m_FileDescLength+1);
 
 	// add the entry
 	pThis->AddEntry(Timestamp);
+
+	return 0;
 }
 
 
@@ -991,6 +993,15 @@ const char *CClient::LoadMapSearch(const char *pMapName, int WantedCrc)
 	// try the downloaded maps
 	str_format(aBuf, sizeof(aBuf), "downloadedmaps/%s_%08x.map", pMapName, WantedCrc);
 	pError = LoadMap(pMapName, aBuf, WantedCrc);
+	if(!pError)
+		return pError;
+
+	// search for the map within subfolders
+	char aFilename[128];
+	str_format(aFilename, sizeof(aFilename), "%s.map", pMapName);
+	if(Storage()->FindFile(aFilename, "maps", IStorage::TYPE_ALL, aBuf, sizeof(aBuf)));
+		pError = LoadMap(pMapName, aBuf, WantedCrc);
+
 	return pError;
 }
 
diff --git a/src/engine/client/client.h b/src/engine/client/client.h
index c073139a..8768f23a 100644
--- a/src/engine/client/client.h
+++ b/src/engine/client/client.h
@@ -99,7 +99,7 @@ public:
 	void Init(IStorage *pStorage, const char *pPath, const char *pFileDesc, const char *pFileExt, int MaxEntries);
 	void AddEntry(int64 Timestamp);
 
-	static void FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser);
+	static int FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser);
 };
 
 
diff --git a/src/engine/shared/storage.cpp b/src/engine/shared/storage.cpp
index ffbd3aff..3d7257f4 100644
--- a/src/engine/shared/storage.cpp
+++ b/src/engine/shared/storage.cpp
@@ -282,6 +282,69 @@ public:
 		return 0;		
 	}
  	
+	struct CFindCBData
+	{
+		CStorage *pStorage;
+		const char *pFilename;
+		const char *pPath;
+		char *pBuffer;
+		int BufferSize;
+	};
+
+	static int FindFileCallback(const char *pName, int IsDir, int Type, void *pUser)
+	{
+		CFindCBData Data = *static_cast<CFindCBData *>(pUser);
+		if(IsDir)
+		{
+			if(pName[0] == '.')
+				return 0;
+
+			// search within the folder
+			char aBuf[MAX_PATH_LENGTH];
+			char aPath[MAX_PATH_LENGTH];
+			str_format(aPath, sizeof(aPath), "%s/%s", Data.pPath, pName);
+			Data.pPath = aPath;
+			fs_listdir(Data.pStorage->GetPath(Type, aPath, aBuf, sizeof(aBuf)), FindFileCallback, Type, &Data);
+		}
+		else if(!str_comp(pName, Data.pFilename))
+		{
+			// found the file = end
+			str_format(Data.pBuffer, Data.BufferSize, "%s/%s", Data.pPath, Data.pFilename);
+			return 1;
+		}
+
+		return 0;
+	}
+
+	virtual bool FindFile(const char *pFilename, const char *pPath, int Type, char *pBuffer, int BufferSize)
+	{
+		if(BufferSize < 1)
+			return false;
+		
+		pBuffer[0] = 0;
+		char aBuf[MAX_PATH_LENGTH];
+		CFindCBData Data;
+		Data.pStorage = this;
+		Data.pFilename = pFilename;
+		Data.pPath = pPath;
+		Data.pBuffer = pBuffer;
+		Data.BufferSize = BufferSize;
+
+		if(Type == TYPE_ALL)
+		{
+			// search within all available directories
+			for(int i = 0; i < m_NumPaths; ++i)
+				fs_listdir(GetPath(i, pPath, aBuf, sizeof(aBuf)), FindFileCallback, i, &Data);
+		}
+		else if(Type >= 0 && Type < m_NumPaths)
+		{
+			// search within wanted directory
+			fs_listdir(GetPath(Type, pPath, aBuf, sizeof(aBuf)), FindFileCallback, Type, &Data);
+		}
+
+		return pBuffer[0] != 0;
+	}
+
 	virtual bool RemoveFile(const char *pFilename, int Type)
 	{
 		if(Type < 0 || Type >= m_NumPaths)
diff --git a/src/engine/storage.h b/src/engine/storage.h
index 7ac9feff..e0cab12f 100644
--- a/src/engine/storage.h
+++ b/src/engine/storage.h
@@ -17,6 +17,7 @@ public:
 	
 	virtual void ListDirectory(int Type, const char *pPath, FS_LISTDIR_CALLBACK pfnCallback, void *pUser) = 0;
 	virtual IOHANDLE OpenFile(const char *pFilename, int Flags, int Type, char *pBuffer = 0, int BufferSize = 0) = 0;
+	virtual bool FindFile(const char *pFilename, const char *pPath, int Type, char *pBuffer, int BufferSize) = 0;
 	virtual bool RemoveFile(const char *pFilename, int Type) = 0;
 	virtual bool RenameFile(const char* pOldFilename, const char* pNewFilename, int Type) = 0;
 	virtual bool CreateFolder(const char *pFoldername, int Type) = 0;
diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h
index 35a9918f..59b3f159 100644
--- a/src/game/client/components/menus.h
+++ b/src/game/client/components/menus.h
@@ -187,7 +187,7 @@ class CMenus : public CComponent
 	
 	void DemolistOnUpdate(bool Reset);
 	void DemolistPopulate();
-	static void DemolistFetchCallback(const char *pName, int IsDir, int StorageType, void *pUser);
+	static int DemolistFetchCallback(const char *pName, int IsDir, int StorageType, void *pUser);
 	
 	// found in menus.cpp
 	int Render();
diff --git a/src/game/client/components/menus_demo.cpp b/src/game/client/components/menus_demo.cpp
index 5663bd85..92dd381d 100644
--- a/src/game/client/components/menus_demo.cpp
+++ b/src/game/client/components/menus_demo.cpp
@@ -427,14 +427,14 @@ int CMenus::UiDoListboxEnd(float *pScrollValue, bool *pItemActivated)
 	return gs_ListBoxNewSelected;
 }
 
-void CMenus::DemolistFetchCallback(const char *pName, int IsDir, int StorageType, void *pUser)
+int CMenus::DemolistFetchCallback(const char *pName, int IsDir, int StorageType, void *pUser)
 {
 	CMenus *pSelf = (CMenus *)pUser;
 	int Length = str_length(pName);
 	if((pName[0] == '.' && (pName[1] == 0 ||
 		(pName[1] == '.' && pName[2] == 0 && !str_comp(pSelf->m_aCurrentDemoFolder, "demos")))) ||
 		(!IsDir && (Length < 5 || str_comp(pName+Length-5, ".demo"))))
-		return;
+		return 0;
 	
 	CDemoItem Item;
 	str_copy(Item.m_aFilename, pName, sizeof(Item.m_aFilename));
@@ -452,6 +452,8 @@ void CMenus::DemolistFetchCallback(const char *pName, int IsDir, int StorageType
 	Item.m_IsDir = IsDir != 0;
 	Item.m_StorageType = StorageType;
 	pSelf->m_lDemos.add(Item);
+
+	return 0;
 }
 
 void CMenus::DemolistPopulate()
diff --git a/src/game/client/components/skins.cpp b/src/game/client/components/skins.cpp
index d24e36f0..d27f34eb 100644
--- a/src/game/client/components/skins.cpp
+++ b/src/game/client/components/skins.cpp
@@ -11,12 +11,12 @@
 
 #include "skins.h"
 
-void CSkins::SkinScan(const char *pName, int IsDir, int DirType, void *pUser)
+int  CSkins::SkinScan(const char *pName, int IsDir, int DirType, void *pUser)
 {
 	CSkins *pSelf = (CSkins *)pUser;
 	int l = str_length(pName);
 	if(l < 4 || IsDir || str_comp(pName+l-4, ".png") != 0)
-		return;
+		return 0;
 		
 	char aBuf[512];
 	str_format(aBuf, sizeof(aBuf), "skins/%s", pName);
@@ -25,7 +25,7 @@ void CSkins::SkinScan(const char *pName, int IsDir, int DirType, void *pUser)
 	{
 		str_format(aBuf, sizeof(aBuf), "failed to load skin from %s", pName);
 		pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf);
-		return;
+		return 0;
 	}
 	
 	CSkin Skin;
@@ -107,6 +107,8 @@ void CSkins::SkinScan(const char *pName, int IsDir, int DirType, void *pUser)
 	str_format(aBuf, sizeof(aBuf), "load skin %s", Skin.m_aName);
 	pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf);
 	pSelf->m_aSkins.add(Skin);
+
+	return 0;
 }
 
 
diff --git a/src/game/client/components/skins.h b/src/game/client/components/skins.h
index 5305fa2b..d76ad85b 100644
--- a/src/game/client/components/skins.h
+++ b/src/game/client/components/skins.h
@@ -31,6 +31,6 @@ public:
 private:
 	sorted_array<CSkin> m_aSkins;
 
-	static void SkinScan(const char *pName, int IsDir, int DirType, void *pUser);
+	static int SkinScan(const char *pName, int IsDir, int DirType, void *pUser);
 };
 #endif
diff --git a/src/game/editor/ed_editor.cpp b/src/game/editor/ed_editor.cpp
index a4ec3556..bf122bfa 100644
--- a/src/game/editor/ed_editor.cpp
+++ b/src/game/editor/ed_editor.cpp
@@ -2153,7 +2153,7 @@ void CEditor::RenderImages(CUIRect ToolBox, CUIRect ToolBar, CUIRect View)
 }
 
 
-static void EditorListdirCallback(const char *pName, int IsDir, int StorageType, void *pUser)
+static int EditorListdirCallback(const char *pName, int IsDir, int StorageType, void *pUser)
 {
 	CEditor *pEditor = (CEditor*)pUser;
 	int Length = str_length(pName);
@@ -2161,7 +2161,7 @@ static void EditorListdirCallback(const char *pName, int IsDir, int StorageType,
 		(pName[1] == '.' && pName[2] == 0 && (!str_comp(pEditor->m_pFileDialogPath, "maps") || !str_comp(pEditor->m_pFileDialogPath, "mapres"))))) ||
 		(!IsDir && ((pEditor->m_FileDialogFileType == CEditor::FILETYPE_MAP && (Length < 4 || str_comp(pName+Length-4, ".map"))) ||
 		(pEditor->m_FileDialogFileType == CEditor::FILETYPE_IMG && (Length < 4 || str_comp(pName+Length-4, ".png"))))))
-		return;
+		return 0;
 
 	CEditor::CFilelistItem Item;
 	str_copy(Item.m_aFilename, pName, sizeof(Item.m_aFilename));
@@ -2173,6 +2173,8 @@ static void EditorListdirCallback(const char *pName, int IsDir, int StorageType,
 	Item.m_IsLink = false;
 	Item.m_StorageType = StorageType;
 	pEditor->m_FileList.add(Item);
+
+	return 0;
 }
 
 void CEditor::AddFileDialogEntry(int Index, CUIRect *pView)