学习OGRE - 载入天龙八部AXP文件

刚开始接触OGRE, 看到网上关于天龙八部的文章比较多, 所以自己也从天龙八部着手学习OGRE开发. 关于天龙的AXP数据格式, 在网上已有很完整的解析, 这里就不累赘再说了.

 

截图:

 

使用QT来开发, 由于也是刚接触QT来开发界面, 渲染窗口和主窗口的位置没有调整好, 不过影响不大 :)

 

以下是对应Archive的代码:

Archive代码
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 }

 

 

posted @ 2010-10-05 07:46  vibilin  阅读(2841)  评论(0编辑  收藏  举报