刚开始接触OGRE, 看到网上关于天龙八部的文章比较多, 所以自己也从天龙八部着手学习OGRE开发. 关于天龙的AXP数据格式, 在网上已有很完整的解析, 这里就不累赘再说了.
截图:
使用QT来开发, 由于也是刚接触QT来开发界面, 渲染窗口和主窗口的位置没有调整好, 不过影响不大 :)
以下是对应Archive的代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1
#include
"
AxpArchive.h
"
2 // #include <stdlib.h>
3
4 namespace Ogre {
5
6 AxpArchive::AxpArchive( const String & name, const String & archType )
7 : Archive(name, archType)
8 , m_pAxpPak( 0 )
9 {
10 }
11
12 AxpArchive:: ~ AxpArchive( void )
13 {
14 unload();
15 }
16
17 bool AxpArchive::isCaseSensitive( void ) const
18 {
19 return false ;
20 }
21
22 void AxpArchive::load()
23 {
24 OGRE_LOCK_AUTO_MUTEX
25
26 if (m_pAxpPak != NULL)
27 {
28 return ;
29 }
30
31 m_pAxpPak = fopen( mName.c_str(), " rb " );
32 if ( ! m_pAxpPak )
33 {
34 OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, " File: " + mName + " not found. " , " AxpArchive::load " );
35 return ;
36 }
37
38 int pData[ 1 ];
39
40 // data begin address
41 fseek(m_pAxpPak, 0x10 , 0 );
42 fread(pData, sizeof ( int ), 1 , m_pAxpPak);
43 int address = pData[ 0 ];
44
45 // files count
46 fseek(m_pAxpPak, 0x14 , 0 );
47 fread(pData, sizeof ( int ), 1 , m_pAxpPak);
48 int count = pData[ 0 ];
49
50 // last file address
51 fseek(m_pAxpPak, address + (count - 1 ) * 0xC , 0 );
52 fread(pData, sizeof ( int ), 1 , m_pAxpPak);
53 int fileAddr = pData[ 0 ];
54
55 // last file size
56 fseek(m_pAxpPak, address + (count - 1 ) * 0xC + 0x4 , 0 );
57 fread(pData, sizeof ( int ), 1 , m_pAxpPak);
58 int fileLSize = pData[ 0 ];
59
60 // last file data
61 char * fileData = new char [fileLSize];
62 fseek(m_pAxpPak, fileAddr, 0 );
63 // fseek(m_pAxpPak, fileAddr + 0xD, 0);
64 fread(fileData, sizeof ( char ), fileLSize, m_pAxpPak);
65
66 LoadFileList(fileData);
67 delete []fileData;
68
69 // files
70 for ( int i = 0 ; i < (count - 1 ); i ++ )
71 {
72 // file address
73 fseek(m_pAxpPak, address + i * 0xC , 0 );
74 fread(pData, sizeof ( int ), 1 , m_pAxpPak);
75 mPackedFiles[i].uiFileAddr = pData[ 0 ];
76
77 // file size
78 fseek(m_pAxpPak, address + i * 0xC + 0x4 , 0 );
79 fread(pData, sizeof ( int ), 1 , m_pAxpPak);
80 mPackedFiles[i].dwSize = pData[ 0 ];
81 }
82 }
83
84 void AxpArchive::unload()
85 {
86 OGRE_LOCK_AUTO_MUTEX
87
88 mPackedFileMap.clear();
89 mPackedFiles.clear();
90
91 if (m_pAxpPak != 0 )
92 {
93 fclose(m_pAxpPak);
94 m_pAxpPak = 0 ;
95 }
96 }
97
98 DataStreamPtr AxpArchive::open( const String & filename, bool readOnly) const
99 {
100 OGRE_LOCK_AUTO_MUTEX
101
102 std::map < String, int > ::const_iterator itrPos = mPackedFileMap.find(filename);
103 if (itrPos == mPackedFileMap.end())
104 {
105 return DataStreamPtr();
106 }
107
108 const FILE_DESC & kFileDesc = mPackedFiles[itrPos -> second];
109
110 char * pFileData = new char [kFileDesc.dwSize];
111 fseek(m_pAxpPak, kFileDesc.uiFileAddr, 0 );
112 fread(pFileData, sizeof ( char ), kFileDesc.dwSize, m_pAxpPak);
113
114 return DataStreamPtr(OGRE_NEW MemoryDataStream(kFileDesc.szFileName, pFileData, kFileDesc.dwSize, false , true ));
115 }
116
117 StringVectorPtr AxpArchive::list( bool recursive, bool dirs)
118 {
119 OGRE_LOCK_AUTO_MUTEX
120
121 StringVectorPtr ret = StringVectorPtr(OGRE_NEW_T(StringVector, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T);
122 findFiles( "" , ret.getPointer(), 0 );
123
124 return ret;
125 }
126
127 FileInfoListPtr AxpArchive::listFileInfo( bool recursive, bool dirs)
128 {
129 OGRE_LOCK_AUTO_MUTEX
130
131 FileInfoListPtr fil = FileInfoListPtr(OGRE_NEW_T(FileInfoList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T);
132 findFiles( "" , 0 , fil.getPointer());
133
134 return fil;
135 }
136
137 StringVectorPtr AxpArchive::find( const String & pattern, bool recursive, bool dirs)
138 {
139 OGRE_LOCK_AUTO_MUTEX
140
141 StringVectorPtr ret = StringVectorPtr(OGRE_NEW_T(StringVector, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T);
142 findFiles(pattern, ret.getPointer(), 0 );
143
144 return ret;
145 }
146
147 FileInfoListPtr AxpArchive::findFileInfo( const String & pattern, bool recursive, bool dirs)
148 {
149 OGRE_LOCK_AUTO_MUTEX
150
151 FileInfoListPtr fil = FileInfoListPtr(OGRE_NEW_T(FileInfoList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T);
152 findFiles(pattern, 0 , fil.getPointer());
153
154 return fil;
155 }
156
157 bool AxpArchive::exists( const String & filename)
158 {
159 return (mPackedFileMap.find(filename) != mPackedFileMap.end());
160 }
161
162 time_t AxpArchive::getModifiedTime( const String & filename)
163 {
164 struct stat tagStat;
165 bool ret = (stat(mName.c_str(), & tagStat) == 0 );
166
167 if (ret)
168 {
169 return tagStat.st_mtime;
170 }
171 else
172 {
173 return 0 ;
174 }
175 }
176
177 //
178
179
180 void AxpArchive::findFiles( const String & pattern, StringVector * simpleList, FileInfoList * detailList)
181 {
182 OGRE_LOCK_AUTO_MUTEX
183
184 String pat = pattern;
185 if ( pat.empty() ) pat = " * " ;
186
187 for (size_t nIdx = 0 ; nIdx < mPackedFiles.size(); nIdx ++ )
188 {
189 const FILE_DESC & kFileDesc = mPackedFiles[nIdx];
190
191 if ( StringUtil::match( String(kFileDesc.szFileName), pat ) )
192 {
193 if ( simpleList )
194 {
195 simpleList -> push_back(kFileDesc.szFileName);
196 }
197 else if (detailList)
198 {
199 FileInfo fi;
200 fi.archive = this ;
201 fi.filename = kFileDesc.szFileName;
202
203 String basename = "" ;
204 String path = "" ;
205 StringUtil::splitFilename(kFileDesc.szFileName, basename, path);
206 fi.basename = basename;
207 fi.path = path;
208
209 fi.compressedSize = kFileDesc.dwSize;
210 fi.uncompressedSize = kFileDesc.dwSize;
211
212 detailList -> push_back(fi);
213 }
214 }
215 }
216 }
217
218 //
219
220 void AxpArchive::LoadFileList( char * fileData)
221 {
222 mPackedFiles.clear();
223 mPackedFileMap.clear();
224
225 int nBegI = 0 ;
226 int nEndI = 0 ;
227
228 char c = * (fileData + nEndI);
229 char LF = ( char ) 10 ;
230
231 int lineCount = 0 ;
232 while (c != ' \0 ' )
233 {
234 if (c == LF)
235 {
236 lineCount ++ ;
237 if (lineCount > 2 )
238 {
239 String line;
240 line.append(fileData, nBegI + 1 , (nEndI - nBegI));
241 vector < String > ::type lineParts = StringUtil::split(line, " | " );
242
243 FILE_DESC desc;
244 desc.szFileName = lineParts[ 0 ];
245 mPackedFiles.push_back(desc);
246 mPackedFileMap.insert(PACKED_FILE_PAIR(desc.szFileName, mPackedFiles.size() - 1 ));
247 }
248
249 nBegI = nEndI;
250 }
251
252 nEndI ++ ;
253 c = * (fileData + nEndI);
254 }
255 }
256 }
2 // #include <stdlib.h>
3
4 namespace Ogre {
5
6 AxpArchive::AxpArchive( const String & name, const String & archType )
7 : Archive(name, archType)
8 , m_pAxpPak( 0 )
9 {
10 }
11
12 AxpArchive:: ~ AxpArchive( void )
13 {
14 unload();
15 }
16
17 bool AxpArchive::isCaseSensitive( void ) const
18 {
19 return false ;
20 }
21
22 void AxpArchive::load()
23 {
24 OGRE_LOCK_AUTO_MUTEX
25
26 if (m_pAxpPak != NULL)
27 {
28 return ;
29 }
30
31 m_pAxpPak = fopen( mName.c_str(), " rb " );
32 if ( ! m_pAxpPak )
33 {
34 OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, " File: " + mName + " not found. " , " AxpArchive::load " );
35 return ;
36 }
37
38 int pData[ 1 ];
39
40 // data begin address
41 fseek(m_pAxpPak, 0x10 , 0 );
42 fread(pData, sizeof ( int ), 1 , m_pAxpPak);
43 int address = pData[ 0 ];
44
45 // files count
46 fseek(m_pAxpPak, 0x14 , 0 );
47 fread(pData, sizeof ( int ), 1 , m_pAxpPak);
48 int count = pData[ 0 ];
49
50 // last file address
51 fseek(m_pAxpPak, address + (count - 1 ) * 0xC , 0 );
52 fread(pData, sizeof ( int ), 1 , m_pAxpPak);
53 int fileAddr = pData[ 0 ];
54
55 // last file size
56 fseek(m_pAxpPak, address + (count - 1 ) * 0xC + 0x4 , 0 );
57 fread(pData, sizeof ( int ), 1 , m_pAxpPak);
58 int fileLSize = pData[ 0 ];
59
60 // last file data
61 char * fileData = new char [fileLSize];
62 fseek(m_pAxpPak, fileAddr, 0 );
63 // fseek(m_pAxpPak, fileAddr + 0xD, 0);
64 fread(fileData, sizeof ( char ), fileLSize, m_pAxpPak);
65
66 LoadFileList(fileData);
67 delete []fileData;
68
69 // files
70 for ( int i = 0 ; i < (count - 1 ); i ++ )
71 {
72 // file address
73 fseek(m_pAxpPak, address + i * 0xC , 0 );
74 fread(pData, sizeof ( int ), 1 , m_pAxpPak);
75 mPackedFiles[i].uiFileAddr = pData[ 0 ];
76
77 // file size
78 fseek(m_pAxpPak, address + i * 0xC + 0x4 , 0 );
79 fread(pData, sizeof ( int ), 1 , m_pAxpPak);
80 mPackedFiles[i].dwSize = pData[ 0 ];
81 }
82 }
83
84 void AxpArchive::unload()
85 {
86 OGRE_LOCK_AUTO_MUTEX
87
88 mPackedFileMap.clear();
89 mPackedFiles.clear();
90
91 if (m_pAxpPak != 0 )
92 {
93 fclose(m_pAxpPak);
94 m_pAxpPak = 0 ;
95 }
96 }
97
98 DataStreamPtr AxpArchive::open( const String & filename, bool readOnly) const
99 {
100 OGRE_LOCK_AUTO_MUTEX
101
102 std::map < String, int > ::const_iterator itrPos = mPackedFileMap.find(filename);
103 if (itrPos == mPackedFileMap.end())
104 {
105 return DataStreamPtr();
106 }
107
108 const FILE_DESC & kFileDesc = mPackedFiles[itrPos -> second];
109
110 char * pFileData = new char [kFileDesc.dwSize];
111 fseek(m_pAxpPak, kFileDesc.uiFileAddr, 0 );
112 fread(pFileData, sizeof ( char ), kFileDesc.dwSize, m_pAxpPak);
113
114 return DataStreamPtr(OGRE_NEW MemoryDataStream(kFileDesc.szFileName, pFileData, kFileDesc.dwSize, false , true ));
115 }
116
117 StringVectorPtr AxpArchive::list( bool recursive, bool dirs)
118 {
119 OGRE_LOCK_AUTO_MUTEX
120
121 StringVectorPtr ret = StringVectorPtr(OGRE_NEW_T(StringVector, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T);
122 findFiles( "" , ret.getPointer(), 0 );
123
124 return ret;
125 }
126
127 FileInfoListPtr AxpArchive::listFileInfo( bool recursive, bool dirs)
128 {
129 OGRE_LOCK_AUTO_MUTEX
130
131 FileInfoListPtr fil = FileInfoListPtr(OGRE_NEW_T(FileInfoList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T);
132 findFiles( "" , 0 , fil.getPointer());
133
134 return fil;
135 }
136
137 StringVectorPtr AxpArchive::find( const String & pattern, bool recursive, bool dirs)
138 {
139 OGRE_LOCK_AUTO_MUTEX
140
141 StringVectorPtr ret = StringVectorPtr(OGRE_NEW_T(StringVector, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T);
142 findFiles(pattern, ret.getPointer(), 0 );
143
144 return ret;
145 }
146
147 FileInfoListPtr AxpArchive::findFileInfo( const String & pattern, bool recursive, bool dirs)
148 {
149 OGRE_LOCK_AUTO_MUTEX
150
151 FileInfoListPtr fil = FileInfoListPtr(OGRE_NEW_T(FileInfoList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T);
152 findFiles(pattern, 0 , fil.getPointer());
153
154 return fil;
155 }
156
157 bool AxpArchive::exists( const String & filename)
158 {
159 return (mPackedFileMap.find(filename) != mPackedFileMap.end());
160 }
161
162 time_t AxpArchive::getModifiedTime( const String & filename)
163 {
164 struct stat tagStat;
165 bool ret = (stat(mName.c_str(), & tagStat) == 0 );
166
167 if (ret)
168 {
169 return tagStat.st_mtime;
170 }
171 else
172 {
173 return 0 ;
174 }
175 }
176
177 //
178
179
180 void AxpArchive::findFiles( const String & pattern, StringVector * simpleList, FileInfoList * detailList)
181 {
182 OGRE_LOCK_AUTO_MUTEX
183
184 String pat = pattern;
185 if ( pat.empty() ) pat = " * " ;
186
187 for (size_t nIdx = 0 ; nIdx < mPackedFiles.size(); nIdx ++ )
188 {
189 const FILE_DESC & kFileDesc = mPackedFiles[nIdx];
190
191 if ( StringUtil::match( String(kFileDesc.szFileName), pat ) )
192 {
193 if ( simpleList )
194 {
195 simpleList -> push_back(kFileDesc.szFileName);
196 }
197 else if (detailList)
198 {
199 FileInfo fi;
200 fi.archive = this ;
201 fi.filename = kFileDesc.szFileName;
202
203 String basename = "" ;
204 String path = "" ;
205 StringUtil::splitFilename(kFileDesc.szFileName, basename, path);
206 fi.basename = basename;
207 fi.path = path;
208
209 fi.compressedSize = kFileDesc.dwSize;
210 fi.uncompressedSize = kFileDesc.dwSize;
211
212 detailList -> push_back(fi);
213 }
214 }
215 }
216 }
217
218 //
219
220 void AxpArchive::LoadFileList( char * fileData)
221 {
222 mPackedFiles.clear();
223 mPackedFileMap.clear();
224
225 int nBegI = 0 ;
226 int nEndI = 0 ;
227
228 char c = * (fileData + nEndI);
229 char LF = ( char ) 10 ;
230
231 int lineCount = 0 ;
232 while (c != ' \0 ' )
233 {
234 if (c == LF)
235 {
236 lineCount ++ ;
237 if (lineCount > 2 )
238 {
239 String line;
240 line.append(fileData, nBegI + 1 , (nEndI - nBegI));
241 vector < String > ::type lineParts = StringUtil::split(line, " | " );
242
243 FILE_DESC desc;
244 desc.szFileName = lineParts[ 0 ];
245 mPackedFiles.push_back(desc);
246 mPackedFileMap.insert(PACKED_FILE_PAIR(desc.szFileName, mPackedFiles.size() - 1 ));
247 }
248
249 nBegI = nEndI;
250 }
251
252 nEndI ++ ;
253 c = * (fileData + nEndI);
254 }
255 }
256 }