aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CWADReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CWADReader.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CWADReader.cpp263
1 files changed, 263 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CWADReader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CWADReader.cpp
new file mode 100644
index 0000000..9945fc8
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CWADReader.cpp
@@ -0,0 +1,263 @@
1// Copyright (C) 2002-2012 Thomas Alten
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4// Code contributed by skreamz
5
6#include "IrrCompileConfig.h"
7
8#ifdef __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_
9
10#include "CWADReader.h"
11#include "os.h"
12#include "coreutil.h"
13
14namespace irr
15{
16namespace io
17{
18
19//! Constructor
20CArchiveLoaderWAD::CArchiveLoaderWAD( io::IFileSystem* fs)
21: FileSystem(fs)
22{
23 #ifdef _DEBUG
24 setDebugName("CArchiveLoaderWAD");
25 #endif
26}
27
28
29//! returns true if the file maybe is able to be loaded by this class
30bool CArchiveLoaderWAD::isALoadableFileFormat(const io::path& filename) const
31{
32 return core::hasFileExtension ( filename, "wad" );
33}
34
35
36//! Creates an archive from the filename
37/** \param file File handle to check.
38\return Pointer to newly created archive, or 0 upon error. */
39IFileArchive* CArchiveLoaderWAD::createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const
40{
41 IFileArchive *archive = 0;
42 io::IReadFile* file = FileSystem->createAndOpenFile(filename);
43
44 if (file)
45 {
46 archive = createArchive ( file, ignoreCase, ignorePaths );
47 file->drop ();
48 }
49
50 return archive;
51}
52
53//! creates/loads an archive from the file.
54//! \return Pointer to the created archive. Returns 0 if loading failed.
55IFileArchive* CArchiveLoaderWAD::createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const
56{
57 IFileArchive *archive = 0;
58 if ( file )
59 {
60 file->seek ( 0 );
61 archive = new CWADReader(file, ignoreCase, ignorePaths);
62 }
63 return archive;
64}
65
66
67//! Check if the file might be loaded by this class
68/** Check might look into the file.
69\param file File handle to check.
70\return True if file seems to be loadable. */
71bool CArchiveLoaderWAD::isALoadableFileFormat(io::IReadFile* file) const
72{
73 SWADFileHeader header;
74 memset(&header, 0, sizeof(header));
75
76 file->read( &header.tag, 4 );
77
78 return !strncmp ( header.tag, "WAD2", 4 ) || !strncmp ( header.tag, "WAD3", 4 );
79}
80
81//! Check to see if the loader can create archives of this type.
82bool CArchiveLoaderWAD::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const
83{
84 return fileType == EFAT_WAD;
85}
86
87void createDir ( const c8 *full );
88
89
90/*!
91 WAD Reader
92*/
93CWADReader::CWADReader(IReadFile* file, bool ignoreCase, bool ignorePaths)
94: CFileList((file ? file->getFileName() : io::path("")), ignoreCase, ignorePaths), File(file)
95{
96 #ifdef _DEBUG
97 setDebugName("CWADReader");
98 #endif
99
100 if (File)
101 {
102 File->grab();
103
104 Base = File->getFileName();
105 Base.replace ( '\\', '/' );
106
107 // scan local headers
108 scanLocalHeader();
109
110 sort();
111 }
112
113#if 0
114 for ( u32 i = 0; i < FileList.size(); ++i )
115 {
116 SWADFileEntry &e = FileList[i];
117 char buf[128];
118 snprintf ( buf, 128, "c:\\h2\\%s", e.wadFileName.c_str() );
119
120 createDir ( buf );
121 FILE * f = fopen ( buf, "wb" );
122 if ( 0 == f )
123 continue;
124
125 u8 * mem = new u8 [ e.header.disksize ];
126 File->seek ( e.header.filepos );
127 File->read ( mem, e.header.disksize );
128 fwrite ( mem, e.header.disksize, 1, f );
129 delete [] mem;
130 fclose ( f );
131 }
132#endif
133
134}
135
136
137CWADReader::~CWADReader()
138{
139 if (File)
140 File->drop();
141}
142
143
144//! return the id of the file Archive
145const io::path& CWADReader::getArchiveName () const
146{
147 return Base;
148}
149
150const IFileList* CWADReader::getFileList() const
151{
152 return this;
153}
154
155
156//! scans for a local header, returns false if there is no more local file header.
157bool CWADReader::scanLocalHeader()
158{
159 SWADFileEntryOriginal entry;
160 SWADFileEntry save;
161
162 memset(&Header, 0, sizeof(SWADFileHeader));
163 File->read(&Header, sizeof(SWADFileHeader));
164
165 if ( 0 == strncmp ( Header.tag, "WAD2", 4 ) )
166 WadType = WAD_FORMAT_QUAKE2;
167 else
168 if ( 0 == strncmp ( Header.tag, "WAD3", 4 ) )
169 WadType = WAD_FORMAT_HALFLIFE;
170 else
171 WadType = WAD_FORMAT_UNKNOWN;
172
173 if ( WadType == WAD_FORMAT_UNKNOWN )
174 return false;
175
176#ifdef __BIG_ENDIAN__
177 Header.numlumps = os::Byteswap::byteswap(Header.numlumps);
178 Header.infotableofs = os::Byteswap::byteswap(Header.infotableofs);
179#endif
180
181 File->seek ( Header.infotableofs );
182
183 c8 buf[16];
184 for ( u32 i = 0; i < Header.numlumps; ++i )
185 {
186 // read entry
187 File->read(&entry, sizeof ( SWADFileEntryOriginal ));
188 entry.name[ sizeof ( entry.name ) - 1 ] = 0;
189
190 save.header = entry;
191 save.wadFileName = "/";
192 save.wadFileName += entry.name;
193
194 if ( WadType == WAD_FORMAT_HALFLIFE )
195 {
196 // don't know about the types! i'm guessing
197 switch ( entry.type )
198 {
199 case WAD_TYP_MIPTEX_HALFLIFE:
200 save.wadFileName += ".wal2";
201 break;
202 default:
203 snprintf ( buf, 16, ".%02d", entry.type );
204 save.wadFileName += buf;
205 break;
206 }
207 }
208 else
209 if ( WadType == WAD_FORMAT_QUAKE2 )
210 {
211 switch ( entry.type )
212 {
213 case WAD_TYP_MIPTEX: save.wadFileName += ".miptex"; break;
214 case WAD_TYP_SOUND: save.wadFileName += ".sound"; break;
215 case WAD_TYP_PALETTE: save.wadFileName += ".palette"; break;
216 case WAD_TYP_QTEX: save.wadFileName += ".qtex"; break;
217 case WAD_TYP_QPIC: save.wadFileName += ".qpic"; break;
218 case WAD_TYP_FONT: save.wadFileName += ".font"; break;
219 default:
220 snprintf ( buf, 16, ".%02d", entry.type );
221 save.wadFileName += buf;
222 break;
223 }
224 }
225
226 // add file to list
227 addItem(save.wadFileName,save.header.filepos, save.header.disksize, false );
228 //FileInfo.push_back(save);
229 }
230 return true;
231}
232
233
234//! opens a file by file name
235IReadFile* CWADReader::createAndOpenFile(const io::path& filename)
236{
237 s32 index = findFile(filename, false);
238
239 if (index != -1)
240 return createAndOpenFile(index);
241
242 return 0;
243}
244
245
246//! opens a file by index
247IReadFile* CWADReader::createAndOpenFile(u32 index)
248{
249 if (index >= Files.size() )
250 return 0;
251
252 const SFileListEntry &entry = Files[index];
253 return createLimitReadFile( entry.FullName, File, entry.Offset, entry.Size );
254}
255
256
257
258} // end namespace io
259} // end namespace irr
260
261
262#endif // __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_
263