﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-&lt;font size=5&gt;俊的blog&lt;/font&gt;-随笔分类-资源压缩打包</title><link>http://www.cppblog.com/mybios/category/3086.html</link><description>游戏开发 C++ DirectX 数学 计算机图形学 SQL Server
&lt;BR&gt;
&lt;BR&gt;
&lt;a href="http://www.cppblog.com/mybios" style="font-size:14px;color:#FFFFFF"&gt;返回我的Blog首页&lt;/a&gt;</description><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 18:01:43 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 18:01:43 GMT</pubDate><ttl>60</ttl><item><title>【转贴】数据打包格式</title><link>http://www.cppblog.com/mybios/archive/2006/11/19/15416.html</link><dc:creator>李锦俊</dc:creator><author>李锦俊</author><pubDate>Sun, 19 Nov 2006 00:17:00 GMT</pubDate><guid>http://www.cppblog.com/mybios/archive/2006/11/19/15416.html</guid><wfw:comment>http://www.cppblog.com/mybios/comments/15416.html</wfw:comment><comments>http://www.cppblog.com/mybios/archive/2006/11/19/15416.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mybios/comments/commentRss/15416.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mybios/services/trackbacks/15416.html</trackback:ping><description><![CDATA[
		<div align="left">　　游戏运行和显示的速度固然重要，不过我认为，在游戏中另外一个速度：游戏装入的速度也同样不可轻视。试想一个游戏，动不动就要装入数据，而且每次装入的时间都令人等到“心越来越慌”的地步，我想恐怕也没有什么人愿意玩下去的。<br /><br />　　选择一个好的打包数据格式，对于编程人员来说，是一件很重要的事情。一般来说，一个游戏的文件个数太多，并不是一件好事情，不光占用的硬盘空间大，而且严重的影响装入速度。不过这样做的优点也很明显：可以很详细的分类，可以大大的减小编程人员的工作量。另外一种做法是，把所有的数据全部放在一个文件里面，这样的做法和上面一种做法的优缺点正好相反，装入速度比较快（因为只要做一次文件打开的操作），但是由于所有数据都放在一起，文件数据的组织比较复杂，要求编程人员花费大量的精力去定位数据的格式和存放位置。因此，选择一个合适的数据打包格式，实际上就是在这两种情况之间选择一个平衡点，使它既不会对游戏的装入速度造成明显的影响，也不会给编程人员带来额外的负担。<br /><br />　　那么，对于一个游戏来说，数据应该怎么组织呢？其实现在有很多好的游戏，参考一下他们的数据文件就会发现这个平衡点其实很好找。现在大多数的游戏，基本上把游戏需要用到的数据分门别类的存放，每一类数据放在一个文件里面。比如说音乐放在一个文件里面，地形图素放在一个文件里面，精灵造型、动画放在一个文件里面，游戏需要用到的图片放在一个文件里面，人物的对话、事件说明放在一个文件里面……那么这些数据在文件里面怎么组织呢？<br /><br />　　还是一句话：分门别类。下面以游戏最基本的地形图素为例，说明数据的组织形式。一般说来，游戏的地图由很多大大小小的“图素”组成的，这些图素分为几层，每一层的图素基本上可以算作一类：比如说地面层可以算作一类，地上层可以算作一类，然后天空层（背景层）可以算作一类，部队、物品可以算作一类。而在地面层里面，又可以进一步的分类，比如说地形有山地，沙漠，草原，森林，河流，海洋……在游戏中，是可以分为场景的，一般的情况下，每个场景所涉及到的地形不会很多，总是以某一类典型地行为主，然后加入少量其他的地形作为点缀。针对这种情况，我们可以把同一类的地形连续的放在文件的某一个位置，这样我们在装入场景的时候，只要在这个位置一次读取这种地形的数据就可以了。一般游戏在制作的过程中都有一个场景生成器，或者叫作拚图器，它的作用就是生成地图——或者说生成场景。这个拚图器在初期的时候读人的数据肯定不是已经打包了的，因为美术还要对地形的基本图素进行某些修改。<br /><br />　　所以我认为，好的数据打包格式应该是基于拚图器的，他把每一种数据分门别类的连续存放在某一个文件之中或者文件的某一个位置，这样能够大大的加快程序读取数据的速度。这样几能够使游戏文件看起来很简洁，也会大大的有利于程序的开发。<br /></div>
<img src ="http://www.cppblog.com/mybios/aggbug/15416.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mybios/" target="_blank">李锦俊</a> 2006-11-19 08:17 <a href="http://www.cppblog.com/mybios/archive/2006/11/19/15416.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转贴】游戏中如何读取压缩包文件</title><link>http://www.cppblog.com/mybios/archive/2006/11/19/15414.html</link><dc:creator>李锦俊</dc:creator><author>李锦俊</author><pubDate>Sun, 19 Nov 2006 00:16:00 GMT</pubDate><guid>http://www.cppblog.com/mybios/archive/2006/11/19/15414.html</guid><wfw:comment>http://www.cppblog.com/mybios/comments/15414.html</wfw:comment><comments>http://www.cppblog.com/mybios/archive/2006/11/19/15414.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mybios/comments/commentRss/15414.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mybios/services/trackbacks/15414.html</trackback:ping><description><![CDATA[
		<font size="2">　　我们在市场上买了一个游戏，很少会轻易的看到游戏目录里一堆的BMP，PCX资源图片。难道他们不使用BMP之类的文件作为图片资源吗？非也，其实他们把这些资源图片进行了打包、压缩。<br /><br />　　举几个游戏的例子吧，大名鼎鼎westernwood的《红色警戒》的.mix文件就是一种压缩包，里面包含了一堆堆的游戏图片，声音等资源。还有blizzard的《星际争霸》、《暗黑破坏神》、《魔兽系列》的.mpq文件也是一种压缩包，里面包含了各种游戏使用的资源。几乎所有的游戏都用到了压缩包。<br /><br />　　那么为什么要使用这种压缩包呢？原因很多，首先就是压缩，游戏中使用的图片等资源都是极其适合压缩的，这样就减小了游戏的体积。如果把《红色警戒2》的资源全部解开相信会超过3G。其次压缩后文件体积的减小会带来读盘速度的显著提高。通常一个2M的BMP文件可以被压缩到700K以内，读取一个2M的文件和读取一个700K的文件然后再内存中解压的速度对比是可想而知的。最后，将大量的资源文件打包能使得游戏目录清晰，而不是一堆堆的文件夹和文件，这样能减少磁盘空间的浪费，也减少了磁盘碎片。<br /><br />说了那么多压缩包的好处，我们在游戏中到底怎么使用压缩包呢？<br />　　1．我们需要定义我们自己的压缩包文件存储格式。<br />　　2．根据1我们写一个压缩工具来对游戏中的资源进行压缩存储。<br />　　3．根据1我们写一个解压缩的库以便我们游戏中使用。<br />　　4．在游戏的代码中，我们调用这个库，来读取我们包中的文件。<br /><br />　　看到这儿，似乎我们需要做的工作还是很多、很复杂的。要定义一个文件结构，又要写压缩工具、还要写解压库。而我们真正使用确实在最后一步，而且是简单的调用一个库而已。似乎有点得不偿失了。好了，我们现在要找一条捷径来完成我们游戏使用压缩包的问题，对于1和2来说其实很好办，现成的就有很多压缩软件可以生成压缩包，winzip,winrar,winace ……都是非常好的压缩工具，这样我们不用定义压缩包的存储格式，也不用编写压缩工具。不费任何力气就完成了1和2两步。那么第3步又如何呢？文件存储格式不是我们设计的，我们无法知道文件是如何组织、如何压缩的，跟不用说知道如何压缩了。不过上网搜索一下，我们还是能得到一些winzip，winrar格式的解压缩源代码的。不过研究起这些代码来又是件痛苦的事情，更何况还要用在自己的游戏里。<br /><br />　　到这里，我们又遇到了严峻的考验，现在我向大家隆重介绍我们的压轴法宝：</font>
		<a href="http://www.gameres.com/Articles/Program/Other/MDFile.zip">
				<font size="2">MDFile文件系统</font>
		</a>
		<font size="2">。那么，MDFile是个什么东东呢？MDFile是一个可扩展的文件操作库，可以用最最简单的方法实现对任意压缩包格式内文件的读取。那么到此，我们的3和4也都可以实现了。下面我们就以MDFile为例来说以下怎么使用它来读取我们包中的文件。<br /><br />　　首先我们先获取我们需要的</font>
		<a href="http://www.gameres.com/Articles/Program/Other/MDFile.zip">
				<font size="2">MDFile</font>
		</a>
		<font size="2">库，到中国游戏开发技术咨询网上下载</font>
		<a href="http://www.gameres.com/Articles/Program/Other/MDFile.zip">
				<font size="2">MDFile库</font>
		</a>
		<font size="2">，点击本站原创，找到</font>
		<a href="http://www.gameres.com/Articles/Program/Other/MDFile.zip">
				<font size="2">MDFile</font>
		</a>
		<font size="2">并下载下来。<br /><br />　　将库放到你的工程中，并设置好，这里我就不详细说如何设置一个外部的库了，如果不会的话你可以参考相关的书。好了，下面我们就开始我们的代码了，这里以读取test.zip中的一个test.txt文件为例：<br /><br />我们在程序中添加一个LoadFile的函数来载入一个包里的文件。<br /></font>
		<font face="宋体" size="2">bool LoadFile(char* filename,char* packfile)<br />{<br />    BYTE* buf=NULL; // 用来存放读取出的文件的内容<br />    </font>
		<font face="宋体" size="2">CMD_File cmdfile(“ZipExt.dll”); // 我们先生成一个实例<br />    </font>
		<font face="宋体" size="2">cmdfile.Open(“test.zip”,true,true); // 打开test.zip这个压缩包<br />    </font>
		<font face="宋体" size="2">cmdfile.Locate(“test.txt”); // 定位到test.txt文件<br />    </font>
		<font face="宋体" size="2">buf=new BYTE[cmdfile.GetLength()];// 根据test.txt的大小分配内存<br />    </font>
		<font face="宋体" size="2">cmdfile.Read(buf); // 读取文件到我们的内存中<br />    </font>
		<font face="宋体" size="2">// 至此，buf中已经存储了我们需要的test.zip中的test.txt文件的内容了<br />    </font>
		<font face="宋体" size="2">// 是不是很简单呢？<br />}</font>
		<font face="Arial">
				<br />
				<br />
				<font size="2">细心的朋友可能已经注意到了，</font>
		</font>
		<font face="宋体" size="2">CMD_File cmdfile(“ZipExt.dll”);</font>
		<font face="Arial">
				<br />
				<br />
				<font size="2">　　这个初始化是什么意思呢？就是用ZipExt.dll这个扩展库来打开我们的test.zip文件，因为MDFile本身并不支持Zip格式，他支持内部的一种叫epk的压缩包格式，为了让他支持Zip你必须获得ZipExt.dll这个扩展库，同样的如果你需要Rar支持你需要获得RarExt.dll这个扩展库。好在我们刚下载的MDFile包中已经包括了一个ZipExt.dll（在Sample\Sample4\Release中），也好在@J--S Studio在不停的开发MDFile的扩展库，以便我们能够使用更多的压缩包格式。<br /><br />　　需要一提的是：使用这些现成的压缩软件制作文件包虽然简单，但是也有很多问题，例如安全性，有时候我们不想被其他人看到游戏中用到的资源，这时如果我们用的是Zip格式，那就可能轻易的被别人解开并修改了。这时，其实使用MDFile内部的epk格式就比较好，他使用动态加密技术，同时epk格式不被其他压缩软件支持，另外他的其他一些特性都是非常不错的。同时为了支持epk格式，他还提供了一个JSFilePacker程序用来打包需要的文件并存成epk格式。所有的这些都可以在我们下载的MDFile中得到。  (JSFilePacker在tools下)</font>
		</font>
		<font face="Arial">
				<br />
				<font size="2">
						<br />　　<a href="http://www.gameres.com/Articles/Program/Other/MDFile.zip">立即下载MDFile库</a></font>
		</font>
<img src ="http://www.cppblog.com/mybios/aggbug/15414.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mybios/" target="_blank">李锦俊</a> 2006-11-19 08:16 <a href="http://www.cppblog.com/mybios/archive/2006/11/19/15414.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转贴】游戏中的资源打包技术</title><link>http://www.cppblog.com/mybios/archive/2006/11/19/15413.html</link><dc:creator>李锦俊</dc:creator><author>李锦俊</author><pubDate>Sun, 19 Nov 2006 00:14:00 GMT</pubDate><guid>http://www.cppblog.com/mybios/archive/2006/11/19/15413.html</guid><wfw:comment>http://www.cppblog.com/mybios/comments/15413.html</wfw:comment><comments>http://www.cppblog.com/mybios/archive/2006/11/19/15413.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mybios/comments/commentRss/15413.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mybios/services/trackbacks/15413.html</trackback:ping><description><![CDATA[
		<div align="left">打包，很形象的，就是把零散的东西转换为单一的东西。常用的压缩软件就可以说是给文件打包。</div>
		<div align="left">那么，在游戏中为什么要打包？有什么意义么？个人认为，有以下几个意义：</div>
		<div align="left"> 　　1.安全性。</div>
		<div align="left"> 　　如果你的游戏重要数据以文本文件的形式保存在某些文件中，然而你又不希望玩家随意修改这些数据。（比如某些ini文件之类的）把他们和其他2进制文件全部打包在一起的话，这个问题就可以避免了。</div>
		<div align="left"> 　　2.节约磁盘空间。</div>
		<div align="left"> 　　文件太多的话，很容易产生“碎片”。比如一个1个字节的文件，占用空间就高达8Kb。（这个是由windows文件管理系统决定的），如果是很多这样的文件，就可能会发生这种情况：xxxxx个文件，实际大小1xxMb,占用空间3xxMB，（这里只是打一个比方，实际相差不会那么多）。这也许会让人感觉不舒服。</div>
		<div align="left"> 　　3.美观</div>
		<div align="left"> 　　简单的少量文件总比一大堆乱七八糟的东西更让人觉得舒服。</div>
		<div align="left"> 　　4.还没想到...... </div>
		<div align="left">　　下面说说我的设计思路。</div>
		<div align="left"> 　　打包后的文件该是怎样一种结构呢?</div>
		<div align="left"> 　　我想到的有以下几种结构:</div>
		<div align="left"> 　　1. 　　{ 文件标示信息 //判断是否是正确的打包文件 文件的个数,文件索引表大小 各个文件的一个索引表.里面包含每个文件的偏移,大小.类似这种结构:文件名 偏移 大小. 各个文件内容 　　} </div>
		<div align="left">　　2. 　　{ 文件标示信息 第一个文件信息: 文件名长度,文件名,文件长度 第二个文件信息: 文件名长度,文件名,文件长度 ...... 第n个文件信息: 文件名长度,文件名,文件长度 (文件计数) 　　}</div>
		<div align="left"> 　　3. 　　{ 打包成两个文件,一个负责方式1的索引表.另外一个只负责文件内容 　　} 　　这里第1种和第三种方式必须要得到索引表信息后才能填充文件,不如方式2直截了当.所以我在程序设计的时候采用的是方式2.当然方式1,3也有他们的好处,比如查找文件比2要方便一点. </div>
		<div align="left">　　需要压缩么?</div>
		<div align="left"> 　　解压缩是要花费时间的.你可以从速度和容量方面做一个折中.我在设计的时候,没有考虑压缩. 　　怎样在游戏中从已经打包了的文件读取需要的文件?</div>
		<div align="left"> 　　最简单的方法,得到需要的文件信息,从打包文件中读取出来,放到一个临时文件中.读取这个临时文件即可, </div>
		<div align="left">　　游戏结束之前,从程序中删除这个临时文件即可.这里就带来了一个问题:性能.每次都要进行I/O操作.如果每个文件都不是非常大的文件的话,这个办法还是可以的.或则你需要高性能的东西,那就只有一个办法:把你的程序中所有对文件操作都改到对内存进行操作.这样只要把需要的文件从打包文件中读取到内存中即可.或者还有另外的方法,直接在打包文件中读取(这个我还不知道怎么实现,盼望高手赐教之) 　　在制作游戏过程中,当然不用打包,只是在正式版发布后,把所有已经做好了的资源(比如图片,一些数据文件,脚本文件等)打包再一起就可以了.类似如下结构</div>
		<div align="left"> 　　//假设这个是一个打包类的一个成员函数, </div>
		<div align="left">BOOL CPackFile::GetPackFileFromPacker(char*szFindFile,char*szTempFile) { #ifndef PACKER strcpy(y,x); return true; #else </div>
		<div align="left">　　在打包文件中查找szFindFile,如果找到,创建文件名为szTempFile的文件,返回true </div>
		<div align="left">　　否则,返回false #endif } </div>
		<div align="left">　　程序中应该有如下片断 char szFile[256]; CPackFile packer; packer.OpenPackFile("somefile.pak"); ................ if(packer.GetPackFileFromPacker("resource.bmp",szFile)) do something.... 　　</div>
		<div align="left">下面看看我的具体程序吧!</div>
		<div align="left"> 　　<a href="http://www.gamego.cn/download/kaifajishu/packer.rar">程序下载</a> 　　</div>
		<div align="left">欢迎和我交流 　　E-mail:game-diy@163.com 　　OICQ:30784290(难得糊涂) 　　<a href="http://gameplusplus.yeah.net/" target="_blank">http://GamePlusPlus.yeah.net</a></div>
		<br />
		<br />
<img src ="http://www.cppblog.com/mybios/aggbug/15413.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mybios/" target="_blank">李锦俊</a> 2006-11-19 08:14 <a href="http://www.cppblog.com/mybios/archive/2006/11/19/15413.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转贴】PNG文件结构分析</title><link>http://www.cppblog.com/mybios/archive/2006/11/19/15411.html</link><dc:creator>李锦俊</dc:creator><author>李锦俊</author><pubDate>Sun, 19 Nov 2006 00:11:00 GMT</pubDate><guid>http://www.cppblog.com/mybios/archive/2006/11/19/15411.html</guid><wfw:comment>http://www.cppblog.com/mybios/comments/15411.html</wfw:comment><comments>http://www.cppblog.com/mybios/archive/2006/11/19/15411.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mybios/comments/commentRss/15411.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mybios/services/trackbacks/15411.html</trackback:ping><description><![CDATA[
		<span class="content">
				<strong>前言</strong>
				<p>PNG是20世纪90年代中期开始开发的图像文件存储格式，其目的是企图替代GIF和TIFF文件格式，同时增加一些GIF文件格式所不具备的特性。流式网络图形格式(Portable Network Graphic Format，PNG)名称来源于非官方的“PNG's Not GIF”，是一种位图文件(bitmap file)存储格式，读成“ping”。PNG用来存储灰度图像时，灰度图像的深度可多到16位，存储彩色图像时，彩色图像的深度可多到48位，并且还可存储多到16位的α通道数据。PNG使用从LZ77派生的无损数据压缩算法。</p>
				<p>
						<strong>PNG数据块（Chunk）</strong>
				</p>
				<p>PNG定义了两种类型的数据块，一种是称为关键数据块(critical chunk)，这是标准的数据块，另一种叫做辅助数据块(ancillary chunks)，这是可选的数据块。关键数据块定义了4个标准数据块，每个PNG文件都必须包含它们，PNG读写软件也都必须要支持这些数据块。虽然PNG文件规范没有要求PNG编译码器对可选数据块进行编码和译码，但规范提倡支持可选数据块。</p>
				<p>下表就是PNG中数据块的类别，其中，关键数据块部分我们使用深色背景加以区分。</p>
				<table class="text" cellspacing="1" cellpadding="3" align="center" bgcolor="#000000" border="0">
						<tbody>
								<tr bgcolor="#ffffff">
										<td colspan="5">
												<div align="center">
														<strong>PNG文件格式中的数据块</strong>
												</div>
										</td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>
												<div align="center">
														<b>数据块符号</b>
												</div>
										</td>
										<td>
												<div align="center">
														<b>数据块名称 </b>
												</div>
										</td>
										<td>
												<div align="center">
														<b>多数据块 </b>
												</div>
										</td>
										<td>
												<div align="center">
														<b>可选否 </b>
												</div>
										</td>
										<td>
												<div align="center">
														<b>位置限制 </b>
												</div>
										</td>
								</tr>
								<tr bgcolor="#cccccc">
										<td>IHDR </td>
										<td>文件头数据块 </td>
										<td>否 </td>
										<td>否 </td>
										<td>第一块 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>cHRM </td>
										<td>基色和白色点数据块 </td>
										<td>否 </td>
										<td>是</td>
										<td>在PLTE和IDAT之前</td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>gAMA </td>
										<td>图像γ数据块 </td>
										<td>否 </td>
										<td>是</td>
										<td>在PLTE和IDAT之前 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>sBIT </td>
										<td>样本有效位数据块 </td>
										<td>否 </td>
										<td>是</td>
										<td>在PLTE和IDAT之前 </td>
								</tr>
								<tr bgcolor="#cccccc">
										<td>PLTE </td>
										<td>调色板数据块 </td>
										<td>否 </td>
										<td>是</td>
										<td>在IDAT之前 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>bKGD </td>
										<td>背景颜色数据块 </td>
										<td>否 </td>
										<td>是</td>
										<td>在PLTE之后IDAT之前 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>hIST </td>
										<td>图像直方图数据块 </td>
										<td>否 </td>
										<td>是</td>
										<td>在PLTE之后IDAT之前 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>tRNS </td>
										<td>图像透明数据块 </td>
										<td>否 </td>
										<td>是</td>
										<td>在PLTE之后IDAT之前 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>oFFs </td>
										<td>(专用公共数据块) </td>
										<td>否 </td>
										<td>是</td>
										<td>在IDAT之前 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>pHYs </td>
										<td>物理像素尺寸数据块 </td>
										<td>否 </td>
										<td>是</td>
										<td>在IDAT之前 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>sCAL </td>
										<td>(专用公共数据块) </td>
										<td>否 </td>
										<td>是</td>
										<td>在IDAT之前 </td>
								</tr>
								<tr bgcolor="#cccccc">
										<td>IDAT </td>
										<td>图像数据块 </td>
										<td>是</td>
										<td>否 </td>
										<td>与其他IDAT连续</td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>tIME </td>
										<td>图像最后修改时间数据块 </td>
										<td>否 </td>
										<td>是</td>
										<td>无限制 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>tEXt </td>
										<td>文本信息数据块 </td>
										<td>是</td>
										<td>是</td>
										<td>无限制 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>zTXt </td>
										<td>压缩文本数据块 </td>
										<td>是</td>
										<td>是</td>
										<td>无限制 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>fRAc </td>
										<td>(专用公共数据块) </td>
										<td>是</td>
										<td>是</td>
										<td>无限制 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>gIFg </td>
										<td>(专用公共数据块) </td>
										<td>是</td>
										<td>是</td>
										<td>无限制 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>gIFt </td>
										<td>(专用公共数据块) </td>
										<td>是</td>
										<td>是</td>
										<td class="text">无限制 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>gIFx </td>
										<td>(专用公共数据块) </td>
										<td>是</td>
										<td>是</td>
										<td>无限制 </td>
								</tr>
								<tr bgcolor="#cccccc">
										<td>IEND </td>
										<td>图像结束数据 </td>
										<td>否 </td>
										<td>否 </td>
										<td>最后一个数据块 </td>
								</tr>
						</tbody>
				</table>
				<p>为了简单起见，我们假设在我们使用的PNG文件中，这4个数据块按以上先后顺序进行存储，并且都只出现一次。</p>
				<p>
						<strong>数据块结构</strong>
				</p>
				<p>PNG文件中，每个数据块由4个部分组成，如下：</p>
				<table class="text" cellspacing="1" cellpadding="3" align="center" bgcolor="#000000" border="0">
						<tbody>
								<tr bgcolor="#ffffff">
										<td>
												<b>名称 </b>
										</td>
										<td>
												<b>字节数 </b>
										</td>
										<td>
												<b>说明 </b>
										</td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>Length (长度) </td>
										<td>4字节 </td>
										<td>指定数据块中数据域的长度，其长度不超过(2<sup>31</sup>－1)字节 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>Chunk Type Code (数据块类型码) </td>
										<td>4字节 </td>
										<td>数据块类型码由ASCII字母(A-Z和a-z)组成 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>Chunk Data (数据块数据) </td>
										<td>可变长度 </td>
										<td>存储按照Chunk Type Code指定的数据 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>CRC (循环冗余检测) </td>
										<td>4字节 </td>
										<td>存储用来检测是否有错误的循环冗余码 </td>
								</tr>
						</tbody>
				</table>
				<p>CRC(cyclic redundancy check)域中的值是对Chunk Type Code域和Chunk Data域中的数据进行计算得到的。CRC具体算法定义在ISO 3309和ITU-T V.42中，其值按下面的CRC码生成多项式进行计算：</p>
				<p>x<sup>32</sup>+x<sup>26</sup>+x<sup>23</sup>+x<sup>22</sup>+x<sup>16</sup>+x<sup>12</sup>+x<sup>11</sup>+x<sup>10</sup>+x<sup>8</sup>+x<sup>7</sup>+x<sup>5</sup>+x<sup>4</sup>+x<sup>2</sup>+x+1</p>
				<p>下面，我们依次来了解一下各个关键数据块的结构吧。</p>
				<p>
						<strong>IHDR</strong>
				</p>
				<p>文件头数据块IHDR(header chunk)：它包含有PNG文件中存储的图像数据的基本信息，并要作为第一个数据块出现在PNG数据流中，而且一个PNG数据流中只能有一个文件头数据块。</p>
				<p>文件头数据块由13字节组成，它的格式如下表所示。</p>
				<table class="text" cellspacing="1" cellpadding="3" align="center" bgcolor="#000000" border="0">
						<tbody>
								<tr bgcolor="#ffffff">
										<td>
												<div align="center">
														<b>域的名称 </b>
												</div>
										</td>
										<td>
												<div align="center">
														<b>字节数 </b>
												</div>
										</td>
										<td>
												<div align="center">
														<b>说明 </b>
												</div>
										</td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>Width </td>
										<td>4 bytes </td>
										<td>图像宽度，以像素为单位 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>Height </td>
										<td>4 bytes </td>
										<td>图像高度，以像素为单位 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>Bit depth </td>
										<td>1 byte </td>
										<td>图像深度： <br />索引彩色图像：1，2，4或8 <br />灰度图像：1，2，4，8或16 <br />真彩色图像：8或16 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>ColorType </td>
										<td>1 byte </td>
										<td>颜色类型：<br />0：灰度图像, 1，2，4，8或16 <br />2：真彩色图像，8或16 <br />3：索引彩色图像，1，2，4或8 <br />4：带α通道数据的灰度图像，8或16 <br />6：带α通道数据的真彩色图像，8或16 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>Compression method </td>
										<td>1 byte </td>
										<td>压缩方法(LZ77派生算法) </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>Filter method </td>
										<td>1 byte </td>
										<td>滤波器方法 </td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>Interlace method </td>
										<td>1 byte </td>
										<td>隔行扫描方法：<br />0：非隔行扫描 <br />1： Adam7(由Adam M. Costello开发的7遍隔行扫描方法) </td>
								</tr>
						</tbody>
				</table>
				<p>由于我们研究的是手机上的PNG，因此，首先我们看看MIDP1.0对所使用PNG图片的要求吧：</p>
				<ul>
						<li>在MIDP1.0中，我们只可以使用1.0版本的PNG图片。并且，所以的PNG关键数据块都有特别要求：<br />IHDR 
</li>
						<li>文件大小：MIDP支持任意大小的PNG图片，然而，实际上，如果一个图片过大，会由于内存耗尽而无法读取。 
</li>
						<li>颜色类型：所有颜色类型都有被支持，虽然这些颜色的显示依赖于实际设备的显示能力。同时，MIDP也能支持alpha通道，但是，所有的alpha通道信息都会被忽略并且当作不透明的颜色对待。 
</li>
						<li>色深：所有的色深都能被支持。 
</li>
						<li>压缩方法：仅支持压缩方式0（deflate压缩方式），这和jar文件的压缩方式完全相同，所以，PNG图片数据的解压和jar文件的解压可以使用相同的代码。（其实这也就是为什么J2ME能很好的支持PNG图像的原因：）） 
</li>
						<li>滤波器方法：尽管在PNG的白皮书中仅定义了方法0，然而所有的5种方法都被支持！ 
</li>
						<li>隔行扫描：虽然MIDP支持0、1两种方式，然而，当使用隔行扫描时，MIDP却不会真正的使用隔行扫描方式来显示。 
</li>
						<li>PLTE chunk：支持 
</li>
						<li>IDAT chunk：图像信息必须使用5种过滤方式中的方式0 (None, Sub, Up, Average, Paeth) 
</li>
						<li>IEND chunk：当IEND数据块被找到时，这个PNG图像才认为是合法的PNG图像。 
</li>
						<li>可选数据块：MIDP可以支持下列辅助数据块，然而，这却不是必须的。 
<blockquote><p>bKGD cHRM gAMA hIST iCCP iTXt pHYs<br />sBIT sPLT sRGB tEXt tIME tRNS zTXt</p></blockquote></li>
				</ul>
				<p>关于更多的信息，可以参考<a href="http://www.w3.org/TR/REC-png.html" target="_blank"><font color="#000000"><a href="http://www.w3.org/TR/REC-png.html" target="_blank">http://www.w3.org/TR/REC-png.html</a></font></a></p>
				<p>
						<strong>PLTE</strong>
				</p>
				<p>调色板数据块PLTE(palette chunk)包含有与索引彩色图像(indexed-color image)相关的彩色变换数据，它仅与索引彩色图像有关，而且要放在图像数据块(image data chunk)之前。</p>
				<p>PLTE数据块是定义图像的调色板信息，PLTE可以包含1~256个调色板信息，每一个调色板信息由3个字节组成：</p>
				<table class="text" cellspacing="1" cellpadding="3" align="center" bgcolor="#000000" border="0">
						<tbody>
								<tr bgcolor="#ffffff">
										<td>
												<p align="center">
														<strong>颜色</strong>
												</p>
										</td>
										<td>
												<p align="center">
														<strong>字节</strong>
												</p>
										</td>
										<td>
												<p align="center">
														<strong>意义</strong>
												</p>
										</td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>
												<p>Red</p>
										</td>
										<td>
												<p>1 byte</p>
										</td>
										<td>
												<p>0 = 黑色, 255 = 红</p>
										</td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>
												<p>Green</p>
										</td>
										<td>
												<p>1 byte</p>
										</td>
										<td>
												<p>0 = 黑色, 255 = 绿色</p>
										</td>
								</tr>
								<tr bgcolor="#ffffff">
										<td>
												<p>Blue</p>
										</td>
										<td>
												<p>1 byte</p>
										</td>
										<td>
												<p>0 = 黑色, 255 = 蓝色 </p>
										</td>
								</tr>
						</tbody>
				</table>
				<p>因此，调色板的长度应该是3的倍数，否则，这将是一个非法的调色板。</p>
				<p>对于索引图像，调色板信息是必须的，调色板的颜色索引从0开始编号，然后是1、2……，调色板的颜色数不能超过色深中规定的颜色数（如图像色深为4的时候，调色板中的颜色数不可以超过2^4=16），否则，这将导致PNG图像不合法。</p>
				<p>真彩色图像和带α通道数据的真彩色图像也可以有调色板数据块，目的是便于非真彩色显示程序用它来量化图像数据，从而显示该图像。</p>
				<p>
						<strong>IDAT</strong>
				</p>
				<p>图像数据块IDAT(image data chunk)：它存储实际的数据，在数据流中可包含多个连续顺序的图像数据块。</p>
				<p>IDAT存放着图像真正的数据信息，因此，如果能够了解IDAT的结构，我们就可以很方便的生成PNG图像。</p>
				<p>
						<strong>IEND</strong>
				</p>
				<p>图像结束数据IEND(image trailer chunk)：它用来标记PNG文件或者数据流已经结束，并且必须要放在文件的尾部。</p>
				<p>如果我们仔细观察PNG文件，我们会发现，文件的结尾12个字符看起来总应该是这样的：</p>
				<p>00 00 00 00 49 45 4E 44 AE 42 60 82</p>
				<p>不难明白，由于数据块结构的定义，IEND数据块的长度总是0（00 00 00 00，除非人为加入信息），数据标识总是IEND（49 45 4E 44），因此，CRC码也总是AE 42 60 82。</p>
				<p>
						<strong>实例研究PNG</strong>
				</p>
				<p>以下是由Fireworks生成的一幅图像，图像大小为8*8，为了方便大家观看，我们将图像放大：</p>
				<p>
						<img hspace="0" src="http://svcdn.blogbus.com/files/1114048547.jpg" align="baseline" border="0" />
				</p>
				<p>使用UltraEdit32打开该文件，如下：<br /><strong>00000000~00000007：</strong></p>
				<p>
						<strong>
						</strong>
				</p>
				<p>
						<img hspace="0" src="http://svcdn.blogbus.com/files/1114048623.jpg" align="baseline" border="0" />
				</p>
				<p>可以看到，选中的头8个字节即为PNG文件的标识。</p>
				<p>接下来的地方就是IHDR数据块了：</p>
				<p>
						<strong>00000008~00000020：</strong>
				</p>
				<p>
						<img hspace="0" src="http://svcdn.blogbus.com/files/1114048677.jpg" align="baseline" border="0" />
				</p>
				<ul>
						<li>00 00 00 0D 说明IHDR头块长为13 
</li>
						<li>49 48 44 52 IHDR标识 
</li>
						<li>00 00 00 08 图像的宽，8像素 
</li>
						<li>00 00 00 08 图像的高，8像素 
</li>
						<li>04 色深，2^4=16，即这是一个16色的图像（也有可能颜色数不超过16，当然，如果颜色数不超过8，用03表示更合适） 
</li>
						<li>03 颜色类型，索引图像 
</li>
						<li>00 PNG Spec规定此处总为0（非0值为将来使用更好的压缩方法预留），表示使压缩方法(LZ77派生算法) 
</li>
						<li>00 同上 
</li>
						<li>00 非隔行扫描 
</li>
						<li>36 21 A3 B8 CRC校验</li>
				</ul>
				<p>
						<strong>00000021~0000002F：</strong>
				</p>
				<p>
						<img hspace="0" src="http://svcdn.blogbus.com/files/1114048728.jpg" align="baseline" border="0" />
				</p>
				<p>可选数据块sBIT，颜色采样率，RGB都是256（2^8=256）</p>
				<p>
						<strong>00000030~00000062：</strong>
				</p>
				<p>
						<img hspace="0" src="http://svcdn.blogbus.com/files/1114048773.jpg" align="baseline" border="0" />
				</p>
				<p>这里是调色板信息</p>
				<ul>
						<li>00 00 00 27 说明调色板数据长为39字节，既13个颜色数 
</li>
						<li>50 4C 54 45 PLTE标识 
</li>
						<li>FF FF 00 颜色0 
</li>
						<li>FF ED 00 颜色1 
</li>
						<li>…… …… 
</li>
						<li>09 00 B2 最后一个颜色，12 
</li>
						<li>5F F5 BB DD CRC校验</li>
				</ul>
				<p>
						<strong>00000063~000000C5：</strong>
				</p>
				<p>
						<img hspace="0" src="http://svcdn.blogbus.com/files/1114048823.jpg" align="baseline" border="0" />
				</p>
				<p>这部分包含了pHYs、tExt两种类型的数据块共3块，由于并不太重要，因此也不再详细描述了。<br /><br /><strong>000000C0~000000F8：</strong></p>
				<p>
						<img hspace="0" src="http://svcdn.blogbus.com/files/1114048862.jpg" align="baseline" border="0" />
				</p>
				<p>以上选中部分是IDAT数据块</p>
				<ul>
						<li>00 00 00 27 数据长为39字节 
</li>
						<li>49 44 41 54 IDAT标识 
</li>
						<li>78 9C…… 压缩的数据，LZ77派生压缩方法 
</li>
						<li>DA 12 06 A5 CRC校验</li>
				</ul>
				<p>IDAT中压缩数据部分在后面会有详细的介绍。</p>
				<p>
						<strong>000000F9~00000104：</strong>
				</p>
				<p>
						<img hspace="0" src="http://svcdn.blogbus.com/files/1114048896.jpg" align="baseline" border="0" />
				</p>
				<p>IEND数据块，这部分正如上所说，通常都应该是</p>
				<p>00 00 00 00 49 45 4E 44 AE 42 60 82</p>
				<p>至此，我们已经能够从一个PNG文件中识别出各个数据块了。由于PNG中规定除关键数据块外，其它的辅助数据块都为可选部分，因此，有了这个标准后，我们可以通过删除所有的辅助数据块来减少PNG文件的大小。（当然，需要注意的是，PNG格式可以保存图像中的层、文字等信息，一旦删除了这些辅助数据块后，图像将失去原来的可编辑性。）</p>
				<p>
						<img hspace="0" src="http://svcdn.blogbus.com/files/1114048924.jpg" align="baseline" border="0" />
				</p>
				<p>删除了辅助数据块后的PNG文件，现在文件大小为147字节，原文件大小为261字节，文件大小减少后，并不影响图像的内容。</p>
				<p>如上说过，IDAT数据块是使用了LZ77压缩算法生成的，由于受限于手机处理器的能力，因此，如果我们在生成IDAT数据块时仍然使用LZ77压缩算法，将会使效率大打折扣，因此，为了效率，只能使用无压缩的LZ77算法，关于LZ77算法的具体实现，此文不打算深究，如果你对LZ77算法的JAVA实现有兴趣，可以参考以下两个站点：</p>
				<ul>
						<li>
								<a href="http://jazzlib.sourceforge.net/" target="_blank">
										<font color="#000000">
												<a href="http://jazzlib.sourceforge.net/" target="_blank">http://jazzlib.sourceforge.net/</a>
										</font>
								</a>
						</li>
						<li>
								<a href="http://www.jcraft.com/jzlib/index.html" target="_blank">
										<font color="#000000">
												<a href="http://www.jcraft.com/jzlib/index.html" target="_blank">http://www.jcraft.com/jzlib/index.html</a>
										</font>
								</a>
						</li>
				</ul>
				<p>
						<strong>参考资料：</strong>
				</p>
				<p>PNG文件格式白皮书：<a href="http://www.w3.org/TR/REC-png.html" target="_blank"><font color="#000000"><a href="http://www.w3.org/TR/REC-png.html" target="_blank">http://www.w3.org/TR/REC-png.html</a></font></a><br />为数不多的中文PNG格式说明：<a href="http://dev.gameres.com/Program/Visual/Other/PNGFormat.htm" target="_blank"><font color="#000000"><a href="http://dev.gameres.com/Program/Visual/Other/PNGFormat.htm" target="_blank">http://dev.gameres.com/Program/Visual/Other/PNGFormat.htm</a></font></a><br />RFC-1950(ZLIB Compressed Data Format Specification)：<a href="ftp://ds.internic.net/rfc/rfc1950.txt" target="_blank"><font color="#000000"><a href="ftp://ds.internic.net/rfc/rfc1950.txt" target="_blank">ftp://ds.internic.net/rfc/rfc1950.txt</a></font></a><br />RFC-1950(DEFLATE Compressed Data Format Specification)：<a href="ftp://ds.internic.net/rfc/rfc1951.txt" target="_blank"><font color="#000000"><a href="ftp://ds.internic.net/rfc/rfc1951.txt" target="_blank">ftp://ds.internic.net/rfc/rfc1951.txt</a></font></a><br />LZ77算法的JAVA实现：<a href="http://jazzlib.sourceforge.net/" target="_blank"><font color="#000000"><a href="http://jazzlib.sourceforge.net/" target="_blank">http://jazzlib.sourceforge.net/</a></font></a><br />LZ77算法的JAVA实现，包括J2ME版本：<a href="http://www.jcraft.com/jzlib/index.html" target="_blank"><font color="#000000"><a href="http://www.jcraft.com/jzlib/index.html" target="_blank">http://www.jcraft.com/jzlib/index.html</a></font></a></p>
		</span>
<img src ="http://www.cppblog.com/mybios/aggbug/15411.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mybios/" target="_blank">李锦俊</a> 2006-11-19 08:11 <a href="http://www.cppblog.com/mybios/archive/2006/11/19/15411.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转贴】游戏中的资源打包</title><link>http://www.cppblog.com/mybios/archive/2006/11/19/15412.html</link><dc:creator>李锦俊</dc:creator><author>李锦俊</author><pubDate>Sun, 19 Nov 2006 00:11:00 GMT</pubDate><guid>http://www.cppblog.com/mybios/archive/2006/11/19/15412.html</guid><wfw:comment>http://www.cppblog.com/mybios/comments/15412.html</wfw:comment><comments>http://www.cppblog.com/mybios/archive/2006/11/19/15412.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/mybios/comments/commentRss/15412.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mybios/services/trackbacks/15412.html</trackback:ping><description><![CDATA[
		<span class="content">　　本人正在准备做一个游戏引擎（你就当我准备产生垃圾好了~呵呵！），准备写文档，就顺便把这篇文章写出来了，初次发稿，写得可能不是很好，请多多包涵~谢谢！~~<br /><br />　　资源打包就是将一些零碎资源（如图片，音乐文件）。打包的好处有哪些呢？<br /><br />　　1、减少碎片。因为WINDOWS的文件管理系统的原因，将这些资源按原样放在硬盘里，会产生“碎片”。比如1个字节的文件，占用的空间就高达8KB。这样，资源可以说“膨胀”了。<br /><br />　　2、安全。将这些数据集合起来打包的话，就可以隐藏这些文件，让用户不能修改（如果某位高手破解了文件结构并提取出来了的话你当我没说~）<br /><br />　　我想到的只有这些，如果哪位大虾认为还可以补充的，请联系我：）<br /><br />　　好了！我们现在来构造一个结构来储存这些文件吧！在这里因为我准备写的是只储存图形的游戏引擎，所以我想到的只是图片的储存，其他文件的储存，这里没有涉及。<br />　　<br />　　我们先构造一个文件头，这个文件头描述了一些基本的信息，有长度，文件版本，压缩类型，还有储存的图片总数。现在详细的说一下，长度就不用说了吧，文件头的大小。文件版本是给打包工具看的东东，游戏引擎里也可以使用，根据版本来用不同的方法打开文件（不同的结构，或者其他的）。压缩类型是一个以备扩展用的东东，根据标识来使用不同的压缩方法解压缩，在这里可以选一个速度和容量折中的压缩方法。图片总数说的不是单个图片的总数，而是静态图片和动态图片的总数，静态图片可以理解成一个图片，动态图片就是一系列静态图片的集合，这个在后面会说到。讲一个文件头就说了这么多话。我讲得是太详细了还是太水了？<br /><br />　　struct FileHeader<br /><br />　　{<br /><br />　　unsigned long headsize; //文件头长度<br /><br />　　int Version; //文件版本<br /><br />　　int Compress; //压缩类型<br /><br />　　int AllNumber; //图片总数<br /><br />　　}<br /><br />　　然后紧跟一个结构数组，这个结构描述了每个图片的起始偏移量，这个偏移量是以文件头的长度+索引结构数组的长度+1为基址的，还描述了图片的帧数，为1则表示为静态图片，大于1则表示动态图片（动态图片很有用处，比如海面，被风吹动的树，这些就可以很容易的表示出来）<br /><br />　　struct PicIndex<br /><br />　　{<br /><br />　　int offset; //图片偏移量<br /><br />　　unsigned long PicSize //图片长度（如果是多帧的则代表这个图片集的总共长度）<br /><br />　　int nFrameNumber; //图片帧数<br /><br />　　unsigned long nFrameSize[nFrameNumber]; //每一帧的偏移量，这里的偏移量就是基址+offset+这一个偏移量。。#··%…！天书？<br /><br />　　//当然上面这个数组定义编译时不能这样写<br /><br />　　}<br /><br />　　PicIndex结构是一个数组，它的下标为AllNumber个。例如：<br /><br />　　PicIndex Index[AllNumber];<br /><br />　　然后剩下的就是一些数据了，这些数据已经被压缩了，压缩方式通过文件头的AllNumber变量来获得。<br /><br />　　<br /><br />　　下标n其实就是AllNumber，这里为了省空间：）<br /><br />　　值得注意的是后面的压缩数据不是整块压缩的，而是单个图片的压缩，然后放在一起而已，我这样做是为了读取方便，就不用读取一个数据还要把整个文件再解压缩一道了，这样压缩率可能也会降低，不知道是否还有更好的办法，如果有，请联系我~谢谢！<br /><br />　　除了我写的这种结构方式来储存文件以外，还有其他的实现方案，但是我觉得这个好一点。<br /><br />　　代码我刚写一半，还不完全，所以这里就不放上来了。<br /><br />　　我的QQ：393277421<br /><br />　　我再说一句最重要的话：有空常联系~~~~~~~~<br /></span>
<img src ="http://www.cppblog.com/mybios/aggbug/15412.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mybios/" target="_blank">李锦俊</a> 2006-11-19 08:11 <a href="http://www.cppblog.com/mybios/archive/2006/11/19/15412.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转贴】通用型游戏资源提取工具介绍 （推荐）</title><link>http://www.cppblog.com/mybios/archive/2006/11/19/15410.html</link><dc:creator>李锦俊</dc:creator><author>李锦俊</author><pubDate>Sun, 19 Nov 2006 00:09:00 GMT</pubDate><guid>http://www.cppblog.com/mybios/archive/2006/11/19/15410.html</guid><wfw:comment>http://www.cppblog.com/mybios/comments/15410.html</wfw:comment><comments>http://www.cppblog.com/mybios/archive/2006/11/19/15410.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mybios/comments/commentRss/15410.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mybios/services/trackbacks/15410.html</trackback:ping><description><![CDATA[
		<span class="content">游戏资源包括了游戏的图片、文字、音乐、动画和其他数据资源。虽然很多游戏的资源都是开放的或者采用通用格式压缩的，但也不少游戏是经特殊格式打包过了，要想得到这些资源可以寻找专用的资源提取工具。但并非所有游戏都有专门的提取工具。这时可以尝试寻找一些通用的游戏资源提取工具。一般来说这样的工具都能支持大量的游戏文件格式，而且有些工具还有一个强大的功能就是可以分析未知的压缩格式并提取出里面的图片、音乐、动画等资源。同时，一些工具提供的写入功能也能令许多玩家在制作MOD、汉化游戏时事半功倍。一款能解包英雄无敌、FIFA、模拟城市、海商王、铁路大亨、极品飞车、模拟人生、古墓丽影等众多游戏资源的工具绝对是值得收藏的。<br /><br />在向大家介绍这些工具之前先说一下采用通用ZIP压缩资源的游戏，也就是说要打开它们时，可用winzip,winrar等软件直接打开。以下收录如有遗漏，欢迎补充。<br /><br />　　游戏名　　　　　　　　　　　　　　文件后缀名<br />18 Wheels Of Steel: Across America　　　ZIPFS<br />18 Wheels Of Steel: Pedal To The Metal　ZIPFS<br />Against Rome　　　　　　　　　　　　　 DAT<br />Alpha Black Zero　　　　　　　　　　　　 ABZ <br />American McGee's Alice　　　　　　　　　 PK3<br />Battlefield 2　　　　　　　　　　　　　　 ZIP<br />Blitzkrieg　　　　　　　　　　　　　　　　PAK<br />Brothers Pilots 4　　　　　　　　　　　　 PAK<br />Call of Duty　　　　　　　　　　　　　　　PK3<br />Cellblock Squadrons　　　　　　　　　　 BOX<br />Civilization: Call To Power　　　　　　　　CTP<br />Deadly Dozen　　　　　　　　　　　　　　ZA<br />Deadly Dozen 2 Pacific Theater　　　　　 ZIP<br />Defiance　　　　　　　　　　　　　　　　 DAT <br />Desperados: Wanted Dead or Alive　　　 PAC <br />Dethkarz　　　　　　　　　　　　　　　　ZIP <br />Duke Nukem Manhatten Project　　　　　ZIPFS <br />El Airplane　　　　　　　　　　　　　　　 ARH <br />Empire Earth 2　　　　　　　　　　　　　 ZIP <br />Falcon 4　　　　　　　　　　　　　　　　 ZIP <br />Fallout Tactics　　　　　　　　　　　　　 BOS <br />Far Cry　　　　　　　　　　　　　　　　 PAK<br />Fire Starter　　　　　　　　　　　　　　 ZIP <br />Freedom Fighters　　　　　　　　　　　 ZIP <br />Freedom Force vs The 3rd Reich　　　　　FF <br />Freelancer　　　　　　　　　　　　　　　 FLMOD <br />Great Battles of WWII - Stalingrad　　　 PAK <br />Hard Truck: 18 Wheels Of Steel　　　　　 ZIPFS<br />Heavy Metal FAKK 2　　　　　　　　　　 ZIP<br />Hellhog XP　　　　　　　　　　　　　　　 A <br />Hitman Contracts　　　　　　　　　　　 ZIP <br />Hitman 2 Silent Assasin　　　　　　　　 ZIP <br />Hot Rod American Street Drag　　　　　 ROD<br />Hunting Unlimited　　　　　　　　　　　 ZIP<br />Imperial Glory　　　　　　　　　　　　　 ZIP<br />Itch　　　　　　　　　　　　　　　　　　 PSH<br />Jedi Knight / JK Mysteries Of The Sith　　 ZIP<br />Jedi Academy / Outcast　　　　　　　　 PK3 <br />Law And Order 3　　　　　　　　　　　 ZIP<br />Lionheart　　　　　　　　　　　　　　　 DAT <br />Master of Orion 3　　　　　　　　　　　 MOD <br />Medal Of Honor: Allied Assult　　　　　　PK3<br />Monte Christo　　　　　　　　　　　　　ZIP<br />Outfront　　　　　　　　　　　　　　　　PAK <br />Packmania 2　　　　　　　　　　　　　　ARF <br />Perimeter　　　　　　　　　　　　　　　 PAK <br />Quake 3　　　　　　　　　　　　　　　　PK3 <br />Return To Castle Wolfenstein　　　　　　PK3 <br />Revenant　　　　　　　　　　　　　　　 RVI RVM RVR<br />Richard Burns Rally　　　　　　　　　　　RBZ <br />Ricochet / Ricochet Xtreme　　　　　　　 ZIP DAT<br />Sabotain　　　　　　　　　　　　　　　　ZIP<br />Serious Sam　　　　　　　　　　　　　　GRO<br />Shadow Warrior　　　　　　　　　　　　SHR<br />Shark: Hunting The Great White　　　　 ZIPFS <br />Soldier Of Fortune 2　　　　　　　　　　 PK3 <br />Swarm　　　　　　　　　　　　　　　　 DAT <br />S.W.A.T 3　　　　　　　　　　　　　　　 RES <br />System Shock 2　　　　　　　　　　　　CRF <br />Terminator 3　　　　　　　　　　　　　 POD <br />The Fall - Last Days Of Gaia　　　　　　 UBN<br />Thief: The Dark Age　　　　　　　　　　 CRF<br />Thief 2: The Metal Age　　　　　　　　　CRF<br />Transport Tycoon　　　　　　　　　　　 001<br />Tribes 2　　　　　　　　　　　　　　　　ZIP<br />Uplink　　　　　　　　　　　　　　　　　DAT<br />Vietnam: Line Of Sight　　　　　　　　　ZA<br />Vampire: The Masquerade　　　　　　　NOB<br />Xpand Rally　　　　　　　　　　　　　　PAK <br />XS Mark　　　　　　　　　　　　　　　　PK1 PK2<br />Zoo Tycoon　　　　　　　　　　　　　　ZTD<br /><br /><br />以下就简单介绍一些通用的游戏资源提取工具。<br /><br />1、Magic Extractor<br /><br />——游戏资源提取工具。适用于Windows XP/98，支持将近200个游戏。界面直观，简便易用。要查询它所支持的游戏和文件格式请查询：<a href="http://magicteam.ag.ru/formats.html" target="_blank"><a href="http://magicteam.ag.ru/formats.html" target="_blank">http://magicteam.ag.ru/formats.html</a></a>。它还有其他的配套工具如：Magic Viewer、Magic Packer。其中Magic Packer用来将游戏资源打包压缩回去。缺点就是Magic Packer支持的游戏比Magic Extractor少了很多，并且针对每个支持的游戏要下载专门的支持文件。<br /><br /><div align="center"><img onclick="function anonymous()&#xD;{&#xD;if(this.width&gt;screen.width-461) window.open('http://193.60.77.232/cg304/bl/MagicE.gif');&#xD;}" src="http://193.60.77.232/cg304/bl/MagicE.gif" border="0" /></div><br /><br />2、MultiEx Commander<br /><br />——游戏资源提取、编辑工具。适用于Windows XP/98，支持将近200个游戏，有图片、声音、文本的预览功能。要查询它所支持的游戏和文件格式请查询：<a href="http://multiex.xentax.com/gameslist.html" target="_blank"><a href="http://multiex.xentax.com/gameslist.html" target="_blank">http://multiex.xentax.com/gameslist.html</a></a>。其中白色字体表示该游戏的资源可以被写入。<br /><br /><div align="center"><img onclick="function anonymous()&#xD;{&#xD;if(this.width&gt;screen.width-461) window.open('http://multiex.xentax.com/popups/pics/popupsc39_3.jpg');&#xD;}" src="http://multiex.xentax.com/popups/pics/popupsc39_3.jpg" border="0" /></div><br /><br />3、Game Extractor<br /><br />——游戏资源提取、编辑工具。适用于Windows/Mac OS/Linux/Unix/Solaris等各种环境。运行时需要Java Runtime Environment的支持。该工具支持约800多个游戏，提供多种格式文件的预览。完全版还有写入功能，并提供了分析工具用于分析并提取未知格式的游戏文件中的图片、声音、动画等资源。要查询它所支持的游戏和文件格式请查询：<a href="http://www.watto.org/extract/games.html#games" target="_blank"><a href="http://www.watto.org/extract/games.html#games" target="_blank">http://www.watto.org/extract/games.html#games</a></a>。<br /><br /><div align="center"><img onclick="function anonymous()&#xD;{&#xD;if(this.width&gt;screen.width-461) window.open('http://193.60.77.232/cg304/bl/screen02.gif');&#xD;}" src="http://193.60.77.232/cg304/bl/screen02.gif" border="0" /></div><br /><br />4、Dragon Unpacker<br /><br />——游戏资源提取工具。适用于Windows XP/98，支持将近130个游戏。提供图片、声音的预览和转换（特殊格式转通用格式）。要查询它所支持的游戏和文件格式请查询：<a href="http://www.elberethzone.net/index.php?page=dup5&amp;language=en#formats" target="_blank"><a href="http://www.elberethzone.net/index.php?page=dup5&amp;language=en#formats" target="_blank">http://www.elberethzone.net/index.php?page=dup5&amp;language=en#formats</a></a> 。它同时提供了一个扫描分析工具用于分析未知格式的游戏文件中的图片、声音、动画等资源。该工具没有写入功能。<br /><br /><div align="center"><img onclick="function anonymous()&#xD;{&#xD;if(this.width&gt;screen.width-461) window.open('http://www.elberethzone.net/gfx/dup5/fr-dup2.gif');&#xD;}" src="http://www.elberethzone.net/gfx/dup5/fr-dup2.gif" border="0" /></div><br /><br />5、Game Archive UnPacker<br /><br />——游戏资源提取工具，用于Total Commander（类似于Windows资源管理器的工具）的插件。必须先安装Total Commander，网上有中文版，适用于Windows XP/98。安装时有些麻烦，实际上它的使用是最方便的。大家知道XP系统引入了ZIP压缩文件夹的功能，打开ZIP文件就像打开普通文件夹一样，且在ZIP文件夹里可以直接进行各种操作。比任何压缩软件都要方便。Game Archive UnPacker插件同样可以让Total Commander实现这种功能。打开游戏资源文件就像打开普通文件夹那样简单，要提取资源，只要像平常那样copy文件就可以了。该插件支持约120个游戏，要查询它所支持的游戏和文件格式请查询：<a href="http://forrox.narod.ru/gaup_en.htm#supform" target="_blank"><a href="http://forrox.narod.ru/gaup_en.htm#supform" target="_blank">http://forrox.narod.ru/gaup_en.htm#supform</a></a>。对部分游戏该工具提供了文件格式转换的功能，例如将游戏特殊格式的图片转换为通用格式的图片。该工具没有写入功能。<br /><br /><br />6、Game File Explorer<br /><br />——游戏资源提取工具，提供声音、图片的预览和图片转换功能，支持约70个游戏，没有什么突出的特点。相关信息请查询：<a href="http://www.geocities.com/TimesSquare/8271/index.html" target="_blank"><a href="http://www.geocities.com/TimesSquare/8271/index.html" target="_blank">http://www.geocities.com/TimesSquare/8271/index.html</a></a><br /><br /><br />7、Wombat Game Tools<br /><br />——游戏资源提取、编辑工具。支持的游戏较少，只有约50个，主要是老游戏，较新的也只有《席德梅尔的海盗》。该工具算然有文件预览、写入功能。但仍然支持的不是很好。具体请查询：<a href="http://www.szevvy.com/content.php?content.1" target="_blank"><a href="http://www.szevvy.com/content.php?content.1" target="_blank">http://www.szevvy.com/content.php?content.1</a></a><br /><br />* 以上有的工具提供了扫描分析未知游戏文件压缩格式的功能。但其并非万能，成百上千个游戏能自动分析出来10几个就很不错了。而且有时只能分析出文件的一部分而已。使用时不要抱太大期望。<br /><br />* 有些工具可以很好的识别同一系列游戏文件的压缩格式。例如MultiEx Commander、Game Extractor和Dragon Unpacker都支持Port Royale（海商王）的.cpr文件，它们同样也能很好的支持游戏列表中没有的Port Royale 2的.cpr文件。但Magic Extractor就不行，它可以支持Port Royale，却不能很好的支持Port Royale 2（可以打开资源文件，但不能识别完整），因此选用时应注意。<br /><br /><br /><br />            若大家还知道哪些通用型的游戏资源提取工具，欢迎补上来。<br /></span>
<img src ="http://www.cppblog.com/mybios/aggbug/15410.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mybios/" target="_blank">李锦俊</a> 2006-11-19 08:09 <a href="http://www.cppblog.com/mybios/archive/2006/11/19/15410.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>