热血传奇资源文件wzl、wzx解析
盛大传奇客户端的图片资源都保存在data目录下的wzl文件中,wzl文件结构比较简单,由一个文件头结构和若干图片数据组成。
找了个最小的wzl文件作为例子
蓝色高亮部分就是文件头,其中只有ImageCount有意义,其他的字段不清楚是做什么的,也不用关心,因为不会影响图片解析。
ImageCount表示该文件中一共有多少张图片,但是研究后发现,后面出现的图片数量不一定就是这个总数,因为有空图存在。就好比你有一个数组int arr[10],但是只用到5个元素一样。
接着后面就是若干个IMAGE结构了
typedef struct {byte pixelFormat; // 图片位深byte compressed; // 表示图片数据是否经过gzip压缩byte reserve;byte compressLevel; // 如果图片数据是压缩过,这个就表示压缩的等级short width; // 图片宽度short height; // 图片高度short x;short y;int size; // 图片数据长度
} IMAGE;
结构后面紧跟着就是图片的原始数据,根据compressed可以得知这段数据是不是zlib压缩过的数据,如果是的则需要解压。
而PixelFormat指明了这张图片的位深度,它的值对应Delphi中的TPixelFormat枚举类型(因为传奇就是Delphi开发的)。
因为历史原因,传奇的图片资源基本都是8bit或16bit的位图。
bmp文件格式规定,8bit的图片颜色是由调色板来指定的,调色板是一个包含256个元素的RGBQuad数组
MirPalette: array[0..255] of TRGBQuad;
传奇使用的调色板数据如下(这里用C#来表示,看上去舒服点)
private static readonly Color[] MirPalette =
{Color.FromArgb(0, 0, 0),Color.FromArgb(128, 0, 0),Color.FromArgb(0, 128, 0),Color.FromArgb(128, 128, 0),Color.FromArgb(0, 0, 128),Color.FromArgb(128, 0, 128),Color.FromArgb(0, 128, 128),Color.FromArgb(192, 192, 192),Color.FromArgb(85, 128, 151),Color.FromArgb(157, 185, 200),Color.FromArgb(123, 115, 115),Color.FromArgb(45, 41, 41),Color.FromArgb(90, 82, 82),Color.FromArgb(99, 90, 90),Color.FromArgb(66, 57, 57),Color.FromArgb(29, 24, 24),Color.FromArgb(24, 16, 16),Color.FromArgb(41, 24, 24),Color.FromArgb(16, 8, 8),Color.FromArgb(242, 121, 113),Color.FromArgb(225, 103, 95),Color.FromArgb(255, 90, 90),Color.FromArgb(255, 49, 49),Color.FromArgb(214, 90, 82),Color.FromArgb(148, 16, 0),Color.FromArgb(148, 41, 24),Color.FromArgb(57, 8, 0),Color.FromArgb(115, 16, 0),Color.FromArgb(181, 24, 0),Color.FromArgb(189, 99, 82),Color.FromArgb(66, 24, 16),Color.FromArgb(255, 170, 153),Color.FromArgb(90, 16, 0),Color.FromArgb(115, 57, 41),Color.FromArgb(165, 74, 49),Color.FromArgb(148, 123, 115),Color.FromArgb(189, 82, 49),Color.FromArgb(82, 33, 16),Color.FromArgb(123, 49, 24),Color.FromArgb(45, 24, 16),Color.FromArgb(140, 74, 49),Color.FromArgb(148, 41, 0),Color.FromArgb(189, 49, 0),Color.FromArgb(198, 115, 82),Color.FromArgb(107, 49, 24),Color.FromArgb(198, 107, 66),Color.FromArgb(206, 74, 0),Color.FromArgb(165, 99, 57),Color.FromArgb(90, 49, 24),Color.FromArgb(42, 16, 0),Color.FromArgb(21, 8, 0),Color.FromArgb(58, 24, 0),Color.FromArgb(8, 0, 0),Color.FromArgb(41, 0, 0),Color.FromArgb(74, 0, 0),Color.FromArgb(157, 0, 0),Color.FromArgb(220, 0, 0),Color.FromArgb(222, 0, 0),Color.FromArgb(251, 0, 0),Color.FromArgb(156, 115, 82),Color.FromArgb(148, 107, 74),Color.FromArgb(115, 74, 41),Color.FromArgb(82, 49, 24),Color.FromArgb(140, 74, 24),Color.FromArgb(136, 68, 17),Color.FromArgb(74, 33, 0),Color.FromArgb(33, 24, 16),Color.FromArgb(214, 148, 90),Color.FromArgb(198, 107, 33),Color.FromArgb(239, 107, 0),Color.FromArgb(255, 119, 0),Color.FromArgb(165, 148, 132),Color.FromArgb(66, 49, 33),Color.FromArgb(24, 16, 8),Color.FromArgb(41, 24, 8),Color.FromArgb(33, 16, 0),Color.FromArgb(57, 41, 24),Color.FromArgb(140, 99, 57),Color.FromArgb(66, 41, 16),Color.FromArgb(107, 66, 24),Color.FromArgb(123, 74, 24),Color.FromArgb(148, 74, 0),Color.FromArgb(140, 132, 123),Color.FromArgb(107, 99, 90),Color.FromArgb(74, 66, 57),Color.FromArgb(41, 33, 24),Color.FromArgb(70, 57, 41),Color.FromArgb(181, 165, 148),Color.FromArgb(123, 107, 90),Color.FromArgb(206, 177, 148),Color.FromArgb(165, 140, 115),Color.FromArgb(140, 115, 90),Color.FromArgb(181, 148, 115),Color.FromArgb(214, 165, 115),Color.FromArgb(239, 165, 74),Color.FromArgb(239, 198, 140),Color.FromArgb(123, 99, 66),Color.FromArgb(107, 86, 57),Color.FromArgb(189, 148, 90),Color.FromArgb(99, 57, 0),Color.FromArgb(214, 198, 173),Color.FromArgb(82, 66, 41),Color.FromArgb(148, 99, 24),Color.FromArgb(239, 214, 173),Color.FromArgb(165, 140, 99),Color.FromArgb(99, 90, 74),Color.FromArgb(189, 165, 123),Color.FromArgb(90, 66, 24),Color.FromArgb(189, 140, 49),Color.FromArgb(53, 49, 41),Color.FromArgb(148, 132, 99),Color.FromArgb(123, 107, 74),Color.FromArgb(165, 140, 90),Color.FromArgb(90, 74, 41),Color.FromArgb(156, 123, 57),Color.FromArgb(66, 49, 16),Color.FromArgb(239, 173, 33),Color.FromArgb(24, 16, 0),Color.FromArgb(41, 33, 0),Color.FromArgb(156, 107, 0),Color.FromArgb(148, 132, 90),Color.FromArgb(82, 66, 24),Color.FromArgb(107, 90, 41),Color.FromArgb(123, 99, 33),Color.FromArgb(156, 123, 33),Color.FromArgb(222, 165, 0),Color.FromArgb(90, 82, 57),Color.FromArgb(49, 41, 16),Color.FromArgb(206, 189, 123),Color.FromArgb(99, 90, 57),Color.FromArgb(148, 132, 74),Color.FromArgb(198, 165, 41),Color.FromArgb(16, 156, 24),Color.FromArgb(66, 140, 74),Color.FromArgb(49, 140, 66),Color.FromArgb(16, 148, 41),Color.FromArgb(8, 24, 16),Color.FromArgb(8, 24, 24),Color.FromArgb(8, 41, 16),Color.FromArgb(24, 66, 41),Color.FromArgb(165, 181, 173),Color.FromArgb(107, 115, 115),Color.FromArgb(24, 41, 41),Color.FromArgb(24, 66, 74),Color.FromArgb(49, 66, 74),Color.FromArgb(99, 198, 222),Color.FromArgb(68, 221, 255),Color.FromArgb(140, 214, 239),Color.FromArgb(115, 107, 57),Color.FromArgb(247, 222, 57),Color.FromArgb(247, 239, 140),Color.FromArgb(247, 231, 0),Color.FromArgb(107, 107, 90),Color.FromArgb(90, 140, 165),Color.FromArgb(57, 181, 239),Color.FromArgb(74, 156, 206),Color.FromArgb(49, 132, 181),Color.FromArgb(49, 82, 107),Color.FromArgb(222, 222, 214),Color.FromArgb(189, 189, 181),Color.FromArgb(140, 140, 132),Color.FromArgb(247, 247, 222),Color.FromArgb(0, 8, 24),Color.FromArgb(8, 24, 57),Color.FromArgb(8, 16, 41),Color.FromArgb(8, 24, 0),Color.FromArgb(8, 41, 0),Color.FromArgb(0, 82, 165),Color.FromArgb(0, 123, 222),Color.FromArgb(16, 41, 74),Color.FromArgb(16, 57, 107),Color.FromArgb(16, 82, 140),Color.FromArgb(33, 90, 165),Color.FromArgb(16, 49, 90),Color.FromArgb(16, 66, 132),Color.FromArgb(49, 82, 132),Color.FromArgb(24, 33, 49),Color.FromArgb(74, 90, 123),Color.FromArgb(82, 107, 165),Color.FromArgb(41, 57, 99),Color.FromArgb(16, 74, 222),Color.FromArgb(41, 41, 33),Color.FromArgb(74, 74, 57),Color.FromArgb(41, 41, 24),Color.FromArgb(74, 74, 41),Color.FromArgb(123, 123, 66),Color.FromArgb(156, 156, 74),Color.FromArgb(90, 90, 41),Color.FromArgb(66, 66, 20),Color.FromArgb(57, 57, 0),Color.FromArgb(89, 89, 0),Color.FromArgb(202, 53, 44),Color.FromArgb(107, 115, 33),Color.FromArgb(41, 49, 0),Color.FromArgb(49, 57, 16),Color.FromArgb(49, 57, 24),Color.FromArgb(66, 74, 0),Color.FromArgb(82, 99, 24),Color.FromArgb(90, 115, 41),Color.FromArgb(49, 74, 24),Color.FromArgb(24, 33, 0),Color.FromArgb(24, 49, 0),Color.FromArgb(24, 57, 16),Color.FromArgb(99, 132, 74),Color.FromArgb(107, 189, 74),Color.FromArgb(99, 181, 74),Color.FromArgb(99, 189, 74),Color.FromArgb(90, 156, 74),Color.FromArgb(74, 140, 57),Color.FromArgb(99, 198, 74),Color.FromArgb(99, 214, 74),Color.FromArgb(82, 132, 74),Color.FromArgb(49, 115, 41),Color.FromArgb(99, 198, 90),Color.FromArgb(82, 189, 74),Color.FromArgb(16, 255, 0),Color.FromArgb(24, 41, 24),Color.FromArgb(74, 136, 74),Color.FromArgb(74, 231, 74),Color.FromArgb(0, 90, 0),Color.FromArgb(0, 136, 0),Color.FromArgb(0, 148, 0),Color.FromArgb(0, 222, 0),Color.FromArgb(0, 238, 0),Color.FromArgb(0, 251, 0),Color.FromArgb(74, 90, 148),Color.FromArgb(99, 115, 181),Color.FromArgb(123, 140, 214),Color.FromArgb(107, 123, 214),Color.FromArgb(119, 136, 255),Color.FromArgb(198, 198, 206),Color.FromArgb(148, 148, 156),Color.FromArgb(156, 148, 198),Color.FromArgb(49, 49, 57),Color.FromArgb(41, 24, 132),Color.FromArgb(24, 0, 132),Color.FromArgb(74, 66, 82),Color.FromArgb(82, 66, 123),Color.FromArgb(99, 90, 115),Color.FromArgb(206, 181, 247),Color.FromArgb(140, 123, 156),Color.FromArgb(119, 34, 204),Color.FromArgb(221, 170, 255),Color.FromArgb(240, 180, 42),Color.FromArgb(223, 0, 159),Color.FromArgb(227, 23, 179),Color.FromArgb(255, 251, 240),Color.FromArgb(160, 160, 164),Color.FromArgb(128, 128, 128),Color.FromArgb(255, 0, 0),Color.FromArgb(0, 255, 0),Color.FromArgb(255, 255, 0),Color.FromArgb(0, 0, 255),Color.FromArgb(255, 0, 255),Color.FromArgb(0, 255, 255),Color.FromArgb(255, 255, 255)
};
而对于16bit的图片来说,又有几种颜色模式之分,我们这里只需要知道,传奇的16bit图是用的RGB565模式。
至此,wzl文件差不多就这样了,是不是可以解析了?不是,因为上面说过,图片和图片之间可能存在空图,而空图不仅只是一个image header而已,后面可能跟着若干字节数据(不清楚这个数据有什么用),而这个长度也没办法知道,所以单单靠wzl一个文件想提取图片和其对应的索引号是不可能的,于是wzx文件诞生了。
wzx文件非常简单,就是一个索引数组,记录每张图片在wzl文件中的偏移量
非常简单,除了file header外剩下的数据就是一个偏移量数组。
正确提取图片的方法是:
1、读取wzx文件,取出偏移量数组
2、读取wzl文件中对应的image struct
3、解压图片数据
4、根据image struct中记录的图片位深、宽高信息导出图片
热血传奇资源文件wzl、wzx解析相关推荐
- 【Cocos2d-x】模仿热血传奇开门动画
一.准备素材 传奇登录场景背景资源在ChrSel.wzl文件中,背景图索引是22号,开门动画是24~32号(共9张). 至于图片提取,可以参考之前写过的一篇关于热血传奇资源文件的文章https://b ...
- 《热血传奇2》wix、wil文件解析Java实现
在百度上搜索java+wil只有iteye上一篇有丁点儿内容,不过他说的是错的!或者说是不完整的,我个人认为我对于热血传奇客户端解析还是有一定研究的,请移步: <JMir--Java版热血传奇2 ...
- javascript高仿热血传奇游戏
前言 游戏的第一个版本开发于14年,浏览器端使用html+css+js,服务端使用asp+php,通讯采用ajax,数据存储使用access+mySql.不过由于一些问题(当时还不会用node,用as ...
- [Python]:热血传奇-Wzl,Wzx的解析
首先我们要了解,wzl与wzx的对应关系,wzx里面存的是每张二进制图片数据在wzl中的偏移量,所以取到wzx中的偏移数据就可以取到wzl每张图片数据,其实就这么简单. 1[取wzx中偏移量数据]:以 ...
- 《热血传奇》wix、wil文件解析Java实现
解析的教程在网络上一抓一大把,我都分不清那个是原创了.不过有一点肯定的是,目前都没有Java版本,恩恩:),处于好奇,我稍稍用Java写了一个以供消遣. 写的过程中发现,其实教程有部分是错误的.而且很 ...
- springboot配置国际化资源文件 使用themself模板进行解析
2019独角兽企业重金招聘Python工程师标准>>> @ConfigurationProperties(prefix = "spring.messages") ...
- Symbian 资源文件解析
一.何为资源文件:<?XML:NAMESPACE PREFIX = O /> 在symbian应用程序中,资源文件指的是后缀名为.rss的文件,每个应用程序至少要有一个与之关联的资源文件. ...
- PHP下载m3u8视频及解析下载ts资源文件
上一篇写了PHP生成合并ts脚本,后来又想直接下载m3u8里面的ts,又码了一段. <?php /** PHP下载m3u8视频和及解析下载ts资源文件** @file m3u8download. ...
- Java笔记-读取资源文件应该注意的问题(大文件解析、\r\n分割相关的)
目前在弄一个模拟程序,数据是从XXXXXXX里XXXXX获取的,也算是真实的把,将其放到资源文件中. 如下代码在IDEA开发环境里面是正常的: byte[] bytesxxx = new byte[i ...
最新文章
- 31万奖金算法赛事来了!
- mysql groupby having_mysql group by having的使用方法
- ng-repeat支持的输入种类
- Python应用与实践【转】
- SVN 放弃修改或撤销删除
- 【建议收藏】这个工具专门用于寻找路由器中的安全漏洞
- poj1061-青蛙的约会(拓展欧几里得java)
- C++选择排序(附完整源码)
- ASA/PIX: Load balancing between two ISP - options
- 对计算机组装和维护课的总结,计算机组装与维护教师工作总结
- 10个你必须知道的jQueryMobile代码片段
- java程序开发个人笔记_Java程序开发入门笔记
- 论文笔记:Few-Shot Segmentation Without Meta-Learning : A Good Transductive Inference Is All You Need
- Ubuntu 18.04 通过 ufw route 配置网关服务器
- CFS调度主要代码分析一
- 田字格写汉字word模板下载可打印【教程】
- 【生信可视化】ChemDraw基础操作教程
- Fork\Join分而治之--RecursiveTask和RecursiveAction(一)
- JAVA使用wkhtmltopdf 将Html 导出PDF
- Google Guava 的 5 个鲜为人知的特性
热门文章
- 复数的加法(友元函数)
- 【Windows11】【3050Ti显卡】下进行PaddleDetetion安装指南
- excel爬虫相关学习1:简单的excel爬虫
- 如何调试Pro/TOOLKIT程序
- cannot open https //centos7.iuscommunity.org/ius-release.rpm. skipping
- web平台安装程序_Galaxy 生信平台(一):安装
- 500 字写一篇程序员的个人发展计划
- Qt中Widget Aplication项目的文件内容介绍
- Error type 3 Error: Activity class {com.xxx/com.xxx.MainActivity} does not
- 读书/观影-《红箭 红箭》话剧-观后感/我的第一篇的博文