找回密码
 register

QQ登录

只需一步,快速开始

查看: 625|回复: 0

[游戏教程] 学习OGRE - 载入天龙八部AXP文件

[复制链接]

[游戏教程] 学习OGRE - 载入天龙八部AXP文件

[复制链接]
  • 打卡等级:热心大叔
  • 打卡总天数:95
  • 打卡月天数:18
  • 打卡总奖励:95
  • 最近打卡:2025-01-20 23:11:04
Waylee

主题

0

回帖

1万

积分

仙帝

积分
12398
Waylee 2024-2-29 21:10 | 显示全部楼层 |阅读模式

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

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

2010100507414626.png

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


以下是对应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:pen(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:oadFileList(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 }



您需要登录后才可以回帖 登录 | register

本版积分规则

雪舞知识库 | 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 |天天打卡

GMT+8, 2025-1-21 05:46 , Processed in 0.100688 second(s), 10 queries , Redis On.

Powered by XueWu Licensed

Copyright © Tencent Cloud.

快速回复 返回顶部 返回列表