网页功能: 加入收藏 设为首页 网站搜索  
《石器时代》《魔力宝贝》图像压缩格式的破解
发表日期:2007-01-18作者:[转贴] 出处:  

这两种游戏使用的是同一种压缩方式,都是RLE压缩方式,具体的压缩编码如下:
0a xx xx xx
a 个单独的颜色点

1a bb xx xx xx
abb 个单独的颜色点

Da bb
abb 个透明色

Ca
a 个透明色

8a xx
a 个颜色是XX的点

9a xx bb
abb 个颜色为xx的点

Aa xx bb cc
abbcc 个颜色为xx的点

其他情况,没有压缩

基本上超过3个点一样就用8a xx 了

然后,以魔力宝贝为例,graphics_10.bin是图像压缩数据文件,一幅图像的结构如下:

typedef struct
{
    WORD fmtflag;       //全部为"RD"
    WORD unknow;        //不知道什么用
    DWORD width;
    DWORD height;
    DWORD size;         // 整个结构大小,就是头+压缩数据
    unsigned char * pdata; // 大小为(size - 16)
}st_RDHeader;

另外还有一个GraphicInfo_10.bin的文件,里面是图片信息的数据,具体结构如下:

typedef struct
{
    int idx;            //索引号,基本上是按照顺序排列的
    DWORD fileptr;      //在数据文件中的偏移量
    DWORD size;         //大小,整个图像结构的大小,同上一个结构的SIZE
    int ofs_x;          //x偏移量
    int ofs_y;          //y偏移量,就是对齐点离坐上角的y 轴距离
    DWORD width;
    DWORD height;
    DWORD colorkey;     //随便猜得,不一定正确
    DWORD unuse1;
    DWORD unuse2;
}st_GrpInfo;            // 40 bytes

有了这3样资料,就可以从他们的数据文件里面解出我们需要的图片了。

一般来说,他们的图片都是256色的,调色板存储在相应的目录下,只要读出来就能够把颜色调整好。

但是魔力宝贝3。0增加了16位色的新资源,其实,压缩方法还是按照字节的方式来得。只不过,输出的缓存不再是高度* 宽度,而是高度* 宽度的2倍。
而且是两个字节描述一个点的16位色位图。具体是555,还是565模式的,我没有试验。


下面是我的8位解压函数,不过一些情况没有处理,比如说没有压缩的数据。而且写得很烂。。。。。-_-b

如果需要改成16位,需要送进的out_len 是 w * h *2。

int _core_uncompress_rle8( char * instream, int in_len, char * outstream, int out_len )
{
    char rle_code;
    int ptr_instream = 0, ptr_outstream = 0;
    int i = 0,loopcnt = 0;;

    if( instream == NULL || in_len == 0 || outstream == NULL || out_len == 0 || in_len > out_len )
        return 0;

    while( ptr_instream < in_len )
    {
        rle_code = instream[ptr_instream];
        ptr_instream ++;
        switch( rle_code & 0xf0 )
        {
        case 0x00:
            loopcnt = rle_code;
            for( i = 0;i < loopcnt;i ++ )
            {
                outstream[ptr_outstream] = instream[ptr_instream];
                ptr_instream ++;
                ptr_outstream ++;
            }
            break;

        case 0x10:
                loopcnt = (rle_code & 0xf) * 0x100 + instream[ptr_instream];
                ptr_instream ++;
                for( i = 0;i < loopcnt;i ++ )
                {
                    outstream[ptr_outstream] = instream[ptr_instream];
                    ptr_instream ++;
                    ptr_outstream ++;
                }
            break;

        case 0x80:
            loopcnt = rle_code & 0xf;
            rle_code = instream[ptr_instream];
            ptr_instream ++;
            for( i = 0;i < loopcnt;i ++ )
            {
                outstream[ptr_outstream] = rle_code;
                ptr_outstream ++;
            }
            break;

        case 0x90:
            loopcnt = (rle_code & 0xf) * 0x100 + instream[ptr_instream + 1];
            rle_code = instream[ptr_instream];
            ptr_instream += 2;
            for( i = 0;i < loopcnt;i++)
            {
                outstream[ptr_outstream] = rle_code;
                ptr_outstream ++;
            }
            break;

        case 0xa0:
            loopcnt = (rle_code & 0xf) * 0x10000 + instream[ptr_instream + 1] * 0x100 + instream[ptr_instream + 2];
            rle_code = instream[ptr_instream];
            ptr_instream += 3;
            for( i = 0;i < loopcnt;i ++ )
            {
                outstream[ptr_outstream] = rle_code;
                ptr_outstream ++;
            }
            break;

        case 0xc0:
            loopcnt = rle_code & 0xf;
            for( i = 0;i < loopcnt;i ++)
            {
                outstream[ptr_outstream] = (char)0xff;
                ptr_outstream ++;
            }
            break;

        case 0xd0:
            loopcnt = (rle_code & 0xf) * 0x100 + instream[ptr_instream];
            ptr_instream ++;
            for( i = 0;i < loopcnt;i ++ )
            {
                outstream[ptr_outstream] = (char)0xff;
                ptr_outstream ++;
            }
            break;
        }
        ptr_instream ++;
    }

    return 1;
}


终于写完了,希望能对别人有用。。。


《魔力宝贝》 《石器时代》 图片破解 补遗


上次分析得不够完善,一些情况没有分析出来,抱歉。下面是补充。

RLE压缩的地方多了几个:

0a xx xx xx
a 个单独的颜色点

1a bb xx xx xx
abb 个单独的颜色点
(添加)
2a bb cc xx xx xx
abbcc个单独的点


Ca
a 个透明色

Da bb
abb 个透明色
(添加)
Ea bb cc
abbcc个透明色

8a xx
a 个颜色是XX的点

9a xx bb
abb 个颜色为xx的点

Aa xx bb cc
abbcc 个颜色为xx的点

所有的a ,b ,c 都是表示单个十六进制数字

关于3。0的魔力宝贝添加的图片其实还是8位色的图片。按照8位色的图片解出来就是了,她不过是用了16位色的显示模式(其实是任何显示模式都可以)。

还有,《石器时代》的INFO的结构和魔力宝贝一样,不过,需要在后面添加一个40字节的数组,什么用都没有。只是结构增大为80字节。

另外,他们的调色板把前面的16个位置丢掉了,就是说实际上调色板是存储了后236个颜色的数值。所使用的时候要注意。

暂时就补充这些了。如果需要软件或者原码,请请联系我 johndragon@sohu.com。
我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 《石器时代》《魔力宝贝》图像压缩格式的破解
本类热点文章
  DirectShow应用——支持Windows Media格..
  DirectShow PIN 連接教學
  游戏UI设计1
  PSD格式文件的读取
  将RGB值转换为灰度值的简单算法
  貼圖 filtering 與 MIP map 簡介
  读取万能图片以及DShow的另类用法
  TGA图像文件格式资料
  DirectShow初探
  PNG格式
  DirectShow应用——支持DVD播放
  DirectShow的中文资料之建立一个捕捉程序
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00363