Fix issue in Rocket.lua script.
[Cafu-Engine.git] / Libs / SoundSystem / SoundShaderManagerImpl.cpp
blobc01824053ce7e64d2119d568a4ebc99ac6885670
1 /*
2 Cafu Engine, http://www.cafu.de/
3 Copyright (c) Carsten Fuchs and other contributors.
4 This project is licensed under the terms of the MIT license.
5 */
7 #include "SoundShaderManagerImpl.hpp"
8 #include "SoundShader.hpp"
10 #include "TextParser/TextParser.hpp"
11 #include "FileSys/FileMan.hpp"
12 #include "FileSys/File.hpp"
14 #ifdef _WIN32
15 #include <direct.h>
16 #if defined(_MSC_VER)
17 #define WIN32_LEAN_AND_MEAN
18 #include <windows.h>
19 #endif
20 #else
21 #include <cstring>
22 #include <dirent.h>
23 #endif
25 #include <iostream>
28 SoundShaderManagerImplT::SoundShaderManagerImplT()
33 SoundShaderManagerImplT::~SoundShaderManagerImplT()
35 for (std::map<std::string, SoundShaderT*>::const_iterator SoundShader=m_SoundShaders.begin(); SoundShader!=m_SoundShaders.end(); SoundShader++)
36 delete SoundShader->second;
37 m_SoundShaders.clear();
41 ArrayT<const SoundShaderT*> SoundShaderManagerImplT::RegisterSoundShaderScript(const std::string& ScriptFile, const std::string& ModDir)
43 ArrayT<const SoundShaderT*> NewSoundShaders;
45 // Check if script has already been loaded and return empty sound shader array if this is the case.
46 for (unsigned long Nr=0; Nr<m_SoundShaderScriptFiles.Size(); Nr++)
47 if (m_SoundShaderScriptFiles[Nr]==ScriptFile) return NewSoundShaders;
49 m_SoundShaderScriptFiles.PushBack(ScriptFile);
51 // Get sound shaders from the script.
52 TextParserT TextParser(ScriptFile.c_str(), "({[]}),");
54 try
56 while (!TextParser.IsAtEOF())
58 const std::string Token=TextParser.GetNextToken();
60 // If the sound shader cannot be parsed (e.g. due to a syntax error or unknown token),
61 // the parsing of the entire file is aborted - the file might be something else than a sound shader script.
62 // Even if it was, we cannot easily continue anyway.
64 SoundShaderT* NewSoundShader=new SoundShaderT(Token, TextParser, ModDir);
65 SoundShaderT*& TestShader =m_SoundShaders[NewSoundShader->Name];
67 // Check if sound shader with this name already exists.
68 if (TestShader==NULL)
70 TestShader=NewSoundShader;
71 NewSoundShaders.PushBack(NewSoundShader);
73 else
75 std::cout << "File '"<< ScriptFile << "' sound shader '" << NewSoundShader->Name << "' duplicate definition (ignored).\n";
76 delete NewSoundShader;
80 catch (const TextParserT::ParseError&)
82 std::cout << "Error parsing '" << ScriptFile << "' at input byte " << TextParser.GetReadPosByte() << "\n";
85 return NewSoundShaders;
89 ArrayT<const SoundShaderT*> SoundShaderManagerImplT::RegisterSoundShaderScriptsInDir(const std::string& Directory, const std::string& ModDir, bool Recurse)
91 ArrayT<const SoundShaderT*> NewSoundShaders;
93 if (Directory=="") return NewSoundShaders;
95 #ifdef _MSC_VER
96 WIN32_FIND_DATA FindFileData;
98 HANDLE hFind=FindFirstFile((Directory+"\\*").c_str(), &FindFileData);
100 // MessageBox(NULL, hFind==INVALID_HANDLE_VALUE ? "INV_VALUE!!" : FindFileData.cFileName, "Starting parsing.", MB_ICONINFORMATION);
101 if (hFind==INVALID_HANDLE_VALUE) return NewSoundShaders;
103 ArrayT<std::string> DirEntNames;
107 // MessageBox(NULL, FindFileData.cFileName, "Material Script Found", MB_ICONINFORMATION);
108 if (!_stricmp(FindFileData.cFileName, "." )) continue;
109 if (!_stricmp(FindFileData.cFileName, ".." )) continue;
110 if (!_stricmp(FindFileData.cFileName, "cvs")) continue;
112 DirEntNames.PushBack(Directory+"/"+FindFileData.cFileName);
113 } while (FindNextFile(hFind, &FindFileData)!=0);
115 if (GetLastError()==ERROR_NO_MORE_FILES) FindClose(hFind);
116 #else
117 DIR* Dir=opendir(Directory.c_str());
119 if (!Dir) return NewSoundShaders;
121 ArrayT<std::string> DirEntNames;
123 for (dirent* DirEnt=readdir(Dir); DirEnt!=NULL; DirEnt=readdir(Dir))
125 if (!strcasecmp(DirEnt->d_name, "." )) continue;
126 if (!strcasecmp(DirEnt->d_name, ".." )) continue;
127 if (!strcasecmp(DirEnt->d_name, "cvs")) continue;
129 // For portability, only the 'd_name' member of a 'dirent' may be accessed.
130 DirEntNames.PushBack(Directory+"/"+DirEnt->d_name);
133 closedir(Dir);
134 #endif
137 for (unsigned long DENr=0; DENr<DirEntNames.Size(); DENr++)
139 #ifdef _WIN32
140 bool IsDirectory=true;
142 FILE* TempFile=fopen(DirEntNames[DENr].c_str(), "r");
143 if (TempFile!=NULL)
145 // This was probably a file (instead of a directory).
146 fclose(TempFile);
147 IsDirectory=false;
149 #else
150 bool IsDirectory=false;
152 // Sigh. And this doesn't work under Win32... (opendir does not return NULL for files!?!)
153 DIR* TempDir=opendir(DirEntNames[DENr].c_str());
154 if (TempDir!=NULL)
156 // This was a directory.
157 closedir(TempDir);
158 IsDirectory=true;
160 #endif
162 if (IsDirectory)
164 if (Recurse)
165 NewSoundShaders.PushBack(RegisterSoundShaderScriptsInDir(DirEntNames[DENr], ModDir));
167 else
169 if (DirEntNames[DENr].length()>5)
170 if (std::string(DirEntNames[DENr].c_str()+DirEntNames[DENr].length()-5)==".caud")
171 NewSoundShaders.PushBack(RegisterSoundShaderScript(DirEntNames[DENr], ModDir));
175 return NewSoundShaders;
179 static bool IsFile(const std::string& Name)
181 cf::FileSys::InFileI* AudioFile=cf::FileSys::FileMan->OpenRead(Name);
183 if (AudioFile==NULL)
184 return false;
186 cf::FileSys::FileMan->Close(AudioFile);
187 return true;
191 static bool IsCapture(const std::string& Name)
193 return Name.find("capture")==0 && Name.length()>8;
197 const SoundShaderT* SoundShaderManagerImplT::GetSoundShader(const std::string& Name)
199 // Ignore empty names and just return NULL.
200 if (Name.empty()) return NULL;
202 // Note that I'm *not* just writing return SoundShaders[Name] here, because that
203 // would implicitly create a NULL entry for every Name that does not actually exist.
204 std::map<std::string, SoundShaderT*>::const_iterator It=m_SoundShaders.find(Name);
206 if (It!=m_SoundShaders.end()) return It->second;
208 // Sound shader not found, try to interpret the name as a filename or a "capture n" string.
209 if (IsFile(Name) || IsCapture(Name))
211 SoundShaderT* AutoShader=new SoundShaderT(Name);
212 AutoShader->AudioFile=Name;
214 // Add auto created shader to list of shaders.
215 m_SoundShaders[Name]=AutoShader;
217 return AutoShader;
220 std::cout << "Error auto creating sound shader: File '" << Name << "' not doesn't exist.\n";
221 return NULL;