文章目录

  • 资源分类bin目录
  • 调色板格式
  • 索引格式
  • 图库格式
  • 取图步骤
  • 最终效果

20来年前很喜欢魔力宝贝,最高才到达过40多级。后来陆陆续续玩过怀旧。毕竟游戏过于古老,很多不方便的地方。
4年前想着高清化,只不过领导不支持。官方手游也很不满意。
这一次,准备自己制作一下高清单机版,能够把剧情完整走一遍,也算是完成一个小小的愿望。

非营利项目,代码全部开源。
git地址:https://github.com/mversace/CrossGateRemastered.git

感谢先行者对文件格式的研究。
参考文档:https://tieba.baidu.com/p/976827378?red_tag=0672897547&traceid=
参考文档:https://blog.csdn.net/crossgate7/article/details/82430624
下载SEE4CGW来查看图片,与程序生成的对比,来确定对错

资源分类bin目录

本文解析的是图库类型,配置没什么必要性,在做特效时自行修改就可以了。图库总共7个(有一个重复,实际只有6个)

类型 名字 对应索引
动画配置 Anime_3 AnimeInfo_3
动画配置 Anime_Joy_13 AnimeInfo_Joy_13
动画配置 AnimeEx_1 AnimeInfoEx_1
动画配置 AnimeV3_7 AnimeInfoV3_7
动画配置 Puk2\Anime_PUK2_4 Puk2\AnimeInfo_PUK2_4
动画配置 Puk3\Anime_PUK3_2 Puk3\AnimeInfo_PUK3_2
??动画配置 AnimeAp AnimeApdd
??战斗调色板 battle_4 battletxt_4
坐标信息 coordinatev3_2 coordinateinfov3_2
声音配置 sound_1 soundaddr_1
图库 Graphic_20 GraphicInfo_20
图库 GraphicEx_4 GraphicInfoEx_4
图库 Graphic_Joy_22 GraphicInfo_20
图库 GraphicV3_18 GraphicInfoV3_18
图库 Puk2\Graphic_PUK2_2 Puk2\GraphicInfo_PUK2_2
图库同Puk2 Puk3\Graphic_PUK2_2 Puk3\GraphicInfo_PUK2_2
图库 Puk3\Graphic_PUK3_1 Puk3\GraphicInfo_PUK3_1
调色板 bin\pal\*.cgp

调色板格式

调色板文件固定长度708字节,每个颜色3个字节,总共236个颜色。
游戏中0-15号,240-255号颜色有固定的默认值。调色板实际占据的是16-239号
例如图片使用的调色板为16号颜色,也就是对应调色板文件中的0号颜色。取出字节1(Blue)、字节2(Green)、字节3(Red),自行拼配颜色即可。

本程序默认使用palet_08调色板。

索引格式

// 索引文件数据块
struct imgInfoHead
{unsigned int id;unsigned int addr;  // 在图像文件中的偏移unsigned int len;  // 长度long xOffset;      // 在游戏内的偏移量xlong yOffset;       // 在游戏内的偏移量yunsigned int width;unsigned int height;unsigned char tileEast;  // 地图上横向几格unsigned char tileSouth;// 竖向几格unsigned char flag;unsigned char unKnow[5];long tileId;            // 所属的地图tile的id
};

索引文件每一张图片包含40个字节的字段。索引文件/40就是总图片数。实际上读取这个索引文件对图片提取没有太大意义,里面的几个字段主要是用于地图的拼接。

图库格式

// 图像bin 文件格式
struct imgData
{unsigned char cName[2];unsigned char cVer; // 1压缩unsigned char cUnknow;unsigned int width;unsigned int height;unsigned int len;    // 包含自身头的总长度,后续跟char数组
}; // + char* len = size - 16

每一张图片都有数据头,而且因为是顺序存储,实际上可以不使用索引文件的。
一张完整的图片包含 数据头+图片数据。
cVer说明:
0:未压缩,后续的数据就是图片数据
1:压缩,需要对后续数据进行解压
3:带调色板的压缩。在读取文件头后,还需要再读入4个字节,这4个字节代表调色板解压后的长度。

取图步骤

  1. 读取索引数据

    FILE *pFile = nullptr;
    std::string strPath = _strPath + "\\bin\\";
    if (0 == fopen_s(&pFile, (strPath + strInfo).c_str(), "rb"))
    {imgInfoHead tHead = { 0 };int len = sizeof(imgInfoHead);while (len == fread_s(&tHead, len, 1, len, pFile))_vecImginfo.push_back(tHead);
    }
    if (pFile) fclose(pFile);
    
  2. 遍历索引读取对应图库数据头
    imgData tHead = { 0 };
    int len = sizeof(imgData);if (len == fread_s(&tHead, len, 1, len, pFile))
    {// 这种是错误的图if (tHead.width > 5000 || tHead.height > 5000){saveLog(LOG_ERROR, strErrorFile, strName, "img w or h error", imgHead, tHead);return false;}_cgpLen = 0; // 调色板长度if (tHead.cVer == 3){// 多读取4个字节,代表的是调色板的长度if (4 != fread_s(&_cgpLen, 4, 1, 4, pFile)){saveLog(LOG_ERROR, strErrorFile, strName, "read cgpLen error", imgHead, tHead);return false;}len += 4;}....
    }
    
  3. 解密后续数据
    if (imgLen == fread_s(_imgEncode, imgLen, 1, imgLen, pFile))
    {if (tHead.cVer == 0){// 未压缩图片 _imgDataIdx = imgLen;memcpy(_imgData, _imgEncode, imgLen);}else if (tHead.cVer == 1 || tHead.cVer == 3){// 压缩的图片_imgDataIdx = decodeImgData(_imgEncode, imgLen);if (_imgDataIdx != tHead.width * tHead.height + _cgpLen){// 这种情况按说是错的if (_imgDataIdx < tHead.width * tHead.height + _cgpLen){saveLog(LOG_ERROR, strErrorFile, strName, "decode len more", imgHead, tHead);return false;}else{// 大于的话应该算是不够严谨saveLog(LOG_INFO, strErrorFile, strName, "decode len less", imgHead, tHead);}}}
    }
    
  4. 填充像素
    // 默认使用palet_08.cgp(白天) 调色版
    unsigned char *pCgp = _uMapCgp.begin()->second.data();
    strCgpName = _uMapCgp.begin()->first;
    // 使用图片自带调色板
    if (_cgpLen > 0 && (int)_imgDataIdx >= w * h + _cgpLen)
    {pCgp = _imgData + (_imgDataIdx - _cgpLen);strCgpName = "self";
    }// 图片数据,竖向方向是反的,从最后一行开始
    int imgLen = w * h;
    for (int i = 0; i < imgLen; ++i)
    {// 调色板编号int cIdx = _imgData[i] * 3;int idx = (h - i / w - 1) * w + i % w;_imgPixel[idx] = (pCgp[cIdx]) + (pCgp[cIdx + 1] << 8) + (pCgp[cIdx + 2] << 16);if (pCgp[cIdx] != 0 || pCgp[cIdx + 1] != 0 || pCgp[cIdx + 2] != 0)_imgPixel[idx] |= 0xff000000;
    }
    

    这里需要注意,存储的图片实际上是从下往上存储的,需要自行修正。

  5. 生成图片
    Gdiplus::Bitmap bmp(w, h, PixelFormat32bppARGB);
    int idx = 0;
    for (int row = 0; row < h; ++row)
    {for (int col = 0; col < w; ++col){bmp.SetPixel(col, row, p[idx++]);}
    }CLSID encoderClsid;
    std::wstring s = L"image/" + wstrExt;
    if (!GetEncoderClsid(s.c_str(), &encoderClsid))
    {return false;
    }std::wstring sName = wstrName + L"." + wstrExt;
    bmp.Save(sName.c_str(), &encoderClsid, nullptr);
    

最终效果

放上我最爱的黄螳螂

魔力宝贝高清单机计划(一) 图库提取相关推荐

  1. 魔力宝贝高清单机计划(二) 地图转为tiled map

    文章目录 地图格式 tiled map格式学习 转换步骤 代码地址: https://github.com/mversace/CrossGateRemastered 地图格式 地图文件头: #prag ...

  2. 优酷上线4K修复版经典剧漫 高清修复计划5年焕新5000部经典

    3月3日消息,日前,优酷上线一批经过4K修复的经典国产内容,既有<潜伏>.<少年包青天>等经典国产剧集.也有<宝莲灯>.<哪吒闹海>等经典国漫.也包括& ...

  3. 魔力宝贝 6.0 linux 一键端,魔力宝贝单机版6.0下载_魔力宝贝单机版下载-游戏下载...

    游戏简介 <魔力宝贝单机版>是一款玩家自制的<魔力宝贝>的单机作品,今天小编给大家带来的是该游戏的6.0版本,现在就来体验这款回忆满满的作品吧!这款游戏自带架设教程,十分详细, ...

  4. 模糊视频如何修复高清?这个方法教给你

    目前,视频行业已经进入所谓的"超高清时代",清晰度和画质是影响老剧观感的最大.最难的问题.在没有高清电视的年代,没有人觉得标清画质模糊,而现在,有些简直是"奔跑的马赛克& ...

  5. 网站选择按钮点击无反应?_实用图片素材网站推荐,高清、免费、无版权!

    本文作者:果青奕奕 相信很多媒体和设计工作者,平时的工作任务之一就是寻找各种各样的素材,若是随便在搜索引擎上面找找就使用,就有可能侵权.碰到友好的版权方,会让你删除了事,要是运气差一点的,就有可能因版 ...

  6. 10 个免费的高清图库网站,强烈推荐

    转自:https://zhuanlan.zhihu.com/p/23411438 写东西找配图,真的很揪心,虽然从搜索引擎可以搜索很多,但是可能不是免费使用的,今天为大家介绍的这是个网站,所有的图片都 ...

  7. 6个免费高清图库素材库,设计师、自媒体都在用~

    免费高清图片素材分享,建议收藏起来. 1.菜鸟图库 https://www.sucai999.com/pic.html?v=NTYxMjky 超大图库网站,含有几百万张图片素材,自然.植物.人物.日常 ...

  8. 分享20个无版权的高清无码图库站

    今天这组网站比较有特色,有专门分享美食图片的,有专门分享复古图片的,各领风骚,质量都是一顶一的棒.下面就是20个无版权的高清无码图库站,记得收藏啊. 您可能感兴趣的相关文章 35款精致的 CSS3 和 ...

  9. 分享20个无版权的高清无 码图库站

    今天这组网站比较有特色,有专门分享美食图片的,有专门分享复古图片的,各领风骚,质量都是一顶一的棒.下面就是20个无版权的高清**图库站,记得收藏啊. Compfight Compfight 是一个图片 ...

最新文章

  1. LoadRunner中log的使用总结
  2. 3ds max 把模型放置到坐标系中心(原点)
  3. IPV6在WINXP、WIN2003、WIN7下的网络配置
  4. Spring.Net学习
  5. code Gym 100500D T-shirts(暴力)
  6. python常用_Python常用小技巧
  7. http反向代理之haproxy详解
  8. 前端学习(3050):vue+element今日头条管理-表格组件基本使用
  9. IDEA无法导入HttpServlet包解决方法
  10. Vmware报错:此主机支持IntelVTx 但IntelVTx处于禁用状态
  11. Flex读取非UTF-8中文数据乱码问题的解决方案
  12. Python——语言基础
  13. 浅谈分类与标签机制的特色
  14. Windows 安装kafka-python库
  15. 可视化信息论(2015年10月14日)
  16. 闪讯共享上网教程简单教程
  17. uniapp同目录的相对地址_如何修改手机MAC地址?
  18. phpnow升级mysql_PHPnow更新PHP版本后连接数据库错误(mysql_connect报错)
  19. 月饼,有毒 | 2016 影响因子
  20. win10系统服务器的ip地址,win10系统查看电脑IP地址和默认网关的操作方法

热门文章

  1. 校园网连不上ipv6问题
  2. 多目标优化之帕累托最优
  3. 思岚科技机器人避障方案解读
  4. win10创建Ubuntu16.04子系统,安装常用软件以及图形界面(包括win10远程桌面连接Ubuntu)
  5. Logism · 汉字字库存储芯片扩展 实验
  6. IE主页无法修改的办法
  7. 二极管 三极管 MOS管的区别
  8. 计算机网络——网络基础_网络命令的使用(配置主机IP、ipconfig、ping、tracert、arp实战)
  9. 用高德地图实现点击地图添加标记点,获取该点的经纬度,详细地址,通过输入框进行地址搜索自动定位到输入框地址
  10. Java中double类型输出小数点后两位