北京老时时彩|重庆老时时彩开奖号码
歡迎您,請 登錄 或 注冊會員

偶久網

搜索
偶久網 首頁 改圖教學 查看內容

魔獸改圖MPQ技術內幕

2016-6-5 01:40| 查看: 12308 |原作者: 邪惡叔

MPQ,也稱MoPaQ,是Mike O'Brien發明的一種壓縮文件格式。 
在1996作為,MPQ應用在Diablo(暗黑破壞神)游戲中。 
然而它的版權屬于 Blizzard 的父公司 Havas Interactive,并且在Mike O'Brien離開暴雪后繼續使用。 正是MPQs由于在Diablo(暗黑破壞神)中的出色表現,使其繼續應用在Starcraft(星際爭霸), Warcraft 2(魔獸爭霸2), Diablo 2(暗黑破壞神2), Lords of Magic(魔法大帝)中。 

第二章 關于MPQ的介紹 


MPQ內部包含了許多文件,包括坐標算法、聲音、動畫、字符串、數字數據和故事情節信息。 
明顯地,MPQ的潛力很大。要想利用MPQ,那么您就需要了解它。 

在有MPQ格式之前,一直使用的是WAR格式,在Warcraft 2,甚至在Warcraft1中存放游戲數據。然而WAR格式是簡單的,不精制的,是由缺乏經驗的程序員所編寫的文件格式(相信我,我知道)。文件在檔案中僅使用參考序數和是否被壓縮做為唯一可選擇調用的方法。 
盡管如此它仍然完成了它的任務。它提供了壓縮格式下的文件調用。但是,很快缺點開始出現。調用時使用參考序數,意味著一長傳文件接口的名單必須被保留和被咨詢,當程序員需要使用其中一個文件,那么則需要級長的時間,工作變得越來越繁瑣。 
當時這些問題并沒有那么嚴重,所以有人堅持使用WAR格式,但是一切在使用Battle.net(網絡對戰)后,問題變得不能接受。 


MPQ的特點 
如被提及以前,MPQ格式一直被用做修正WAR的設計缺陷。但是現在他們也想增加一些全新的特點到MPQ。在暴雪的游戲中,MPQ格式的特點總結為以下幾點: 

Security. 安全 

暴雪一定不希望在游戲中玩家可以修改數據。或許他們提早知道MPQ格式可以為Starcraft使用。 不管怎樣,安全是最重要的,由此他們顯然做了級大的努力去維護游戲的安全性。 

Efficiency. 效率 

MPQs要求執行時先簡單預先輸入的各種各樣的任務數據然后實時放出。對于預先輸入數據,時間并不重要。 但是實時放出就是另一件事了,其中的數據必須快速地被解壓使用。 

Multilinguality.多語言的計算機處理 

在最開始的時候,暴雪就計劃發布其游戲在全球游戲市場,因此他們盡可能的做到多語言。 在創新時,他們決定設計多語種能寫入MPQ格式。 
。 
Expandability.擴展 

顯然的,在游戲中需要使用獨立的數據。太大的數據不僅是效率低并且減慢游戲速度,如果補丁修改了,也是很麻煩的。暴雪明白這個道理,因而MPQ格式的要求就是有能力完全,高效率的,從多個檔案數據中調用需要的數據。 


什么是strom 
相比在程序模塊中復制函數,多數程序員喜歡把相同代碼放到shared libraries(共享程序庫)里。shared libraries是包含了任意程序功能的函數模塊。不僅能避免多余,并且能縮小程序大小。 
正因為如此,暴雪使用一個稱為Storm的共享程序庫(PC機上為Storm.dll,MAC機為Storm.bin)。 
所有現代的暴雪游戲中都使用strom存放重要功能,比如讀取MPQ,Battle.net和一些圖形化例程。 
當暴雪要發布新版本的游戲,只需要增加功能到strom,無需改變原有功能。 這意味著舊版本的游戲只用升級新版本strom就可以了,這就是我們俗稱的安裝補丁。 
就像所有共享程序庫,任何想使用它的程序都可以訪問到它的函數。這就是為什么strom只包含MPQ讀取功能。 


什么是 MPQ API Library DLL 

雖然 Storm 沒有包含任何編寫MPQ的功能。 
但是 StarEdit 包含,因為 SCM/SCX 文件也是 MoPaQ文件。 
但是這些函數被加密了,所以只有知識淵博的黑客們才可以使用。 
對于Blizzard 來說不幸的是,有一個這樣的黑客,他的名字是 Andrey Lelikov(aka Lelik)。 
他發現了一種訪問這些寶貴的函數的途徑,并把這個復雜的過程封裝在 
LMPQAPI.DLL(Lelik's MPQ API Library DLL)文件中。該文件自動破解 
StarEdit,將這些函數展示在所有的程序員面前。
第三章 MPQ的基本原理 

通過整個計算機發展史來看,絕大多數的進步都是在求解問題中發生的。 
那么在這一章中,我們將采取看看一些涉及到MPQ的問題及其解決辦法。 

HASH (散列或哈希) 

問題:你有一個非常大的字符串數組,和一個字符串 
怎么知道字符串是否在數組中? 

你可能會開始在數組中與其他字符串比較每個字符串,但是,當進行應用后,你會發現,這種方法在實際使用時是特別慢的。在此之前,你又怎能在沒有與其他字符串比較的情況下,確定這個字符串是否存在? 

解決方法:hash 
hash是規模較小的數據類型(例如數字)能指向其他較大的數據類型(通常是字符串) 。在這種情況下,您可以在數組中先存儲hash。然后再計算其他字符串的hash,并比較它存儲的hash。通過字符串比較,如果hash在數組相匹配的新的hash,就可以核實存在。這就是所謂的索引查找,可以加快對于不同大小的數組和平均長度的字符串的搜索速度約100倍。 

unsigned long HashString(char *lpszString) 
{
unsigned long ulHash = 0xf1e2d3c4; 

while (*lpszString != 0) 
{
ulHash <<= 1; 
ulHash += *lpszString++;

return ulHash;
}

搜索
北京老时时彩