基於StormLib, 參考N3的ZipFileSystem實現了一個MpqFileSystem
有一點要注意, 檔案路徑裡不能用'/', 都要用'//' @_@
mpq檔案包裡的檔案是不儲存檔案名稱(或目錄名)的, 也就是說打包後的檔案是無法復原的. 但是在每個檔案包的根目錄下都有一個(listfile)檔案, 裡麵包含了檔案包中的檔案名稱列表
(為什麼listfile檔案最後有一段Null 字元串呢???)
沒有去實現寫入的功能, 雖然StormLib可以添加檔案, 不過對於遊戲只需要讀就可以了
mpq有一點比zip有優勢, 那就是可以進行Seek...這樣就支援流式的檔案載入了.
而且對於wav可以採用特殊的壓縮演算法來增大壓縮率. 不過我對wav沒好印象的說...
用XACT可以播放xWMA, 用DirectShow可以播放WMV(我暈, 我怎麼又跟著M$混了. 沒辦法啊, 誰叫fmod之類的商用收費來著)
嗯...寫完記得要測試.....(BOSS說這才是專業的一種表現-_-)
//------------------------------------------------------------------------------<br />/**<br />*/<br />void<br />MpqFileSystemTest::Run()<br />{<br /> Ptr<IoServer> ioServer = IoServer::Create();<br /> Ptr<MpqFileSystem> mpqFileSystem = MpqFileSystem::Create();<br /> Ptr<MpqArchive> patch2 = mpqFileSystem->Mount("file:///e:/World of Warcraft/Data/patch-2.MPQ");<br /> n_assert(patch2.isvalid());<br /> const Array<String>& fileList = patch2->GetFileList();<br /> n_assert(!fileList.IsEmpty());<br /> for (IndexT i = 0; i < fileList.Size(); ++i)<br /> {<br /> n_printf("%s/n", fileList[i].AsCharPtr());<br /> }<br /> n_assert(patch2->IsFileExsit("Creature/Ogre/Ogre.M2"));<br /> Array<String> spellFiles = patch2->ListFiles("Spells", "*.*");<br /> for (IndexT i = 0; i < spellFiles.Size(); ++i)<br /> {<br /> n_printf("%s/n", spellFiles[i].AsCharPtr());<br /> }<br /> Array<String> creatureDirs = patch2->ListDirectories("Creature", "*");<br /> for (IndexT i = 0; i < creatureDirs.Size(); ++i)<br /> {<br /> n_printf("%s/n", creatureDirs[i].AsCharPtr());<br /> }<br /> URI uri = "file:///e:/World of Warcraft/Data/Shaders/Vertex/snowpoint.bls";<br /> Ptr<MpqArchive> archive = mpqFileSystem->FindMpqArchiveWithFile(uri);<br /> n_assert(archive == patch2);<br /> Ptr<MpqFileStream> snowpoint = MpqFileStream::Create();<br /> uri = "mpq:///e:/World of Warcraft/Data/patch-2.MPQ?file=Shaders/Vertex/snowpoint.bls";<br /> snowpoint->SetURI(uri);<br /> snowpoint->Open();<br /> Array<char> buffer(snowpoint->GetSize(), 0, 0);<br /> snowpoint->Read(&buffer.Front(), snowpoint->GetSize());<br /> snowpoint->Close();<br />}<br />
嗯, 為了比較方便, 把檔案名稱都轉換成小寫了....不過linux下不是大小寫區分的麼, 那linux程式員寫的打包程式會不會也區別檔案名稱的大小寫, HOHO~