金庸群侠传是智冠科技90年代出品的精品DOS游戏,
其资源压缩包格式紧凑而科学,这里我们一起学习一下其数据结构。并且编写一个能够读取解析它的程序,
以下是我对 Hdgrp资源文件解包的运行结果展示
下面我们看一下资源类型:
其资源包括 idx和grp文件,idx记录了各个资源的索引、grp(group pictures?)存储了具体数据。
另外以Mmap.col作为整体的调色板,存储各种颜色数据。
idx文件每4个byte为一个section,每个section记录一个资源图片的endoffset,即又是下一个资源图片的startoffset。
----------
int32 | endoffset
grp文件,以idx文件为基准,按offset区间划分存储图片,每个图片资源:
---------
int16 | w
int16 | h
int16 | x (不知道有什么用)
int16 | y(不知道有什么用)
以下h行,每行支持多个section,每个section数据结构
----------
int8 | 该行字节数
[section]
int8 | t 透明像素点个数
int8 | nt 非透明像素点个数
nt * int8 | 该点对应调色板数据,如1,则对应调色板第一个颜色值
调色板文件Mmap.col
一共256*3 byte,256色,每个颜色按rgb 除以4存放,按顺序存放
----------
byte | r
byte | g
byte | b
这样就可以解每个资源文件了。下面是部分核心的C#代码,我使用WPF的bitmapimage进行渲染。
class GameResource
{
#region 单例
static public GameResource Instance
{
get
{
if(_instance==null){
_instance = new GameResource();
}
return _instance;
}
}
static GameResource _instance = null;
private GameResource()
{
ImageFiles = new Dictionary<string, List<Image>>();
}
#endregion
public Dictionary<string, List<Image>> ImageFiles;
}
.............
/// <summary>
/// 初始化调色板
/// </summary>
public void InitColors()
{
FileStream f = new FileStream("data/Mmap.col", FileMode.Open);
BinaryReader reader = new BinaryReader(f);
for (int i = 0; i < 256; ++i)
{
byte[] color = reader.ReadBytes(3);
for (int j = 0; j < color.Length; ++j)
{
color[j] = (byte)((int)color[j] * 4);
}
colorMap[i] = color;
}
reader.Close();
f.Close();
}
Dictionary<int, byte[]> colorMap = new Dictionary<int, byte[]>();
private BitmapImage ReadImage(BinaryReader reader, int length)
{
int w = reader.ReadInt16();
int h = reader.ReadInt16();
int x = reader.ReadInt16();
int y = reader.ReadInt16();
List<System.Windows.Media.Color> colors = new List<System.Windows.Media.Color>();
colors.Add(System.Windows.Media.Colors.Blue);
colors.Add(System.Windows.Media.Colors.Green);
colors.Add(System.Windows.Media.Colors.Red);
BitmapPalette palette = new BitmapPalette(colors);
PixelFormat pf = PixelFormats.Bgra32;
int stride = (w * pf.BitsPerPixel + 7) / 8;
byte[] pixels = new byte[h * stride];
for (int i = 0; i < pixels.Length; ++i)
{
pixels[i] = 0x00;
}
int p = 0;
try
{
for (int i = 0; i < h; ++i) //H行
{
p = i * w * pf.BitsPerPixel / 8;
int count = reader.ReadByte(); //该行字节数
int offset = 0;
while (offset < count)
{
int transparentPixs = reader.ReadByte(); //透明像素个数
offset++;
p += transparentPixs * pf.BitsPerPixel / 8;
int nonTransPix = reader.ReadByte(); //非透明像素个数
offset++;
for (int j = 0; j < nonTransPix; ++j)
{
int colorKey = reader.ReadByte();
pixels[p] = colorMap[colorKey][2]; //b
p++;
pixels[p] = colorMap[colorKey][1]; //g
p++;
pixels[p] = colorMap[colorKey][0]; //r
p++;
pixels[p] = 0xFF; //a
p++;
offset++;
}
}
}
}
catch (Exception e)
{
MessageBox.Show(p.ToString());
}
BitmapSource image = BitmapSource.Create(
w,
h,
96,
96,
pf,
palette,
pixels,
stride);
PngBitmapEncoder encoder = new PngBitmapEncoder();
MemoryStream memoryStream = new MemoryStream();
BitmapImage bImg = new BitmapImage();
encoder.Frames.Add(BitmapFrame.Create(image));
encoder.Save(memoryStream);
bImg.BeginInit();
bImg.StreamSource = new MemoryStream(memoryStream.ToArray());
bImg.EndInit();
memoryStream.Close();
return bImg;
}
public List<Image> LoadImages(string filename)
{
List<Image> rst = new List<Image>();
FileStream f = new FileStream(filename + ".idx", FileMode.Open);
BinaryReader reader = new BinaryReader(f);
FileStream gf = new FileStream(filename + ".grp", FileMode.Open);
BinaryReader greader = new BinaryReader(gf);
try
{
int startOffset = 0;
while (f.CanRead)
{
int endOffset = reader.ReadInt32();
Image image = new Image();
image.Source = ReadImage(greader, endOffset-startOffset);
rst.Add(image);
startOffset = endOffset;
}
}
catch (Exception e)
{
}
greader.Close();
gf.Close();
reader.Close();
f.Close();
return rst;
}
public void LoadResource(string filename)
{
GameResource.Instance.ImageFiles.Add(filename, LoadImages(filename));
}
..................
- 大小: 126.6 KB
分享到:
相关推荐
金庸群侠传OL1.0易语言服务端模拟器+所需模块+开发资料+所需工具等 本模拟器理论支持 所有金庸群侠传OL1.0版客户端 简繁体。 本模拟器为【半成品】 本模拟器目前底层基础开发完毕,可以登陆游戏,其他还未开发,有...
本人用Delphi+SDL编写的Windows版《金庸群侠传》。含源代码。
金庸群侠传X Silverlight版
金庸群侠传X完整攻略,让你重新找回当年玩金庸群侠传,武林群侠传的感动。有些特殊的剧情或场景只能依靠特定的人物或某些不太强力的队友来闯,所以插科打诨的小宝可能也需要上战场噢,所以努力的练好每一个队友吧。
C++程序设计:C++复刻金庸群侠传以SDL2为基础实现的2D游戏引擎 这是一个以SDL2为基础实现的2D游戏框架,同时相当于提供了一个使用该框架制作DOS游戏金庸群侠传移植版的范例。有问题先看根目录说明。
金庸群侠源码
金庸群侠传架设视频教程
自己也难怪c写的一段游戏,先传一个资源,再贴代码上来。
自己写的,里面有附代码,可以参考着看看。
jy3-mirror:金庸群侠传3重制版代码库替代
kys-cpp:《金庸群侠传》 c ++复刻版,已完工
金庸群侠改版攻略,用户小伙伴能迅速打怪,且能知道在哪里能升级
重新实现DOS游戏The legend of Jin Yong Heroes(金庸群侠传) 如何建造 安装cmake和C ++编译器(GCC / Clang或MSVC) 第一次您需要克隆项目: git clone --recurse-submodules ...
循环结构:游戏使用 while 循环,直到玩家猜对为止。玩家每次猜测后,根据猜测的数字与目标数字的大小关系,给出相应的提示,并根据猜测结果决定下一步的操作。 用户输入处理:通过 Console.ReadLine() 获取用户...
侠客行MRP格式山寨软件!!帮你们提供优质的服务!!
易语言内网聊天工具源码,内网聊天工具,界面初始化,全局_客户_处理函数,清空内容,添加文本,文本向下滚动,取源文件,显示收到的内容,意外中断,启动窗口通用事件_左键单击,配置程序,读一段,删一段,表情通用事件_左键单击...
0基础易语言之易语言的认识
腾讯软件管家(纯净版),因为网上搜到的软件管家总是与很多其他软件捆绑,一下一大堆,这个是软件管家纯净版。可以用它更新下软件啥的,下软件也更方便了。