游戏开发论坛

 找回密码
 立即注册
搜索
查看: 12054|回复: 6

网易西游系列网游地图读取类(大话2 大话3 梦幻)

[复制链接]

32

主题

82

帖子

88

积分

注册会员

Rank: 2

积分
88
QQ
发表于 2007-12-12 11:19:00 | 显示全部楼层 |阅读模式
ReadGameMap.h

  1. /*********************************************************************************************
  2. *                                         网易公司西游系列
  3. *                《梦幻西游》《大话西游II》《大话西游3内测版》《大话西游3正式版》
  4. *                                        地图文件格式读取类
  5. *---------------------------------------------------------------------------------------------
  6. *
  7. *                                           版本 4.0.0
  8. *
  9. *                                     王大理 <wdl@sina.com>
  10. *                                            <QQ:598337462>
  11. *
  12. *---------------------------------------------------------------------------------------------
  13. * 声明:
  14. *     本源代码应用于网易公司的网络游戏:《梦幻西游》、《大话西游II》、《大话西游3内测版》和
  15. *《大话西游3正式版》地图文件格式的读取。与此源代码相应的文件格式版权属于网易公司所有。
  16. *     此源代码仅应用于教育目的,禁止用于商业目的,否则后果自负,本源代码作者不承担任何责任。
  17. * 如有异议或应用于其他目的请务使用本源代码,并永久删除此源代码。
  18. *---------------------------------------------------------------------------------------------
  19. *                         版权所有(c) 2003-2007 王大理,保留所有权利。
  20. *********************************************************************************************/
  21. #pragma once
  22. //=========== 包含文件 ============
  23. #include <stdio.h>
  24. #include <math.h>
  25. #include <iostream>
  26. #include <fstream>
  27. #include <string>
  28. //=================================

  29. //========= 定义数据类型 ==========
  30. typedef long long                        int64;
  31. typedef unsigned long long        uint64;
  32. typedef int                                        int32;
  33. typedef unsigned int                uint32;
  34. typedef short                                int16;
  35. typedef unsigned short                uint16;
  36. typedef char                                int8;
  37. typedef unsigned char                uint8;
  38. //=================================

  39. using namespace std; // 使用C++标准文件头

  40. namespace NetEase
  41. {
  42.         // 地图的文件头(梦幻、大话2)
  43.         class MapHeader1
  44.         {
  45.         public:
  46.                 uint32                Flag;                //文件标志
  47.                 uint32                Width;                //地图宽
  48.                 uint32                Height;                //地图高       
  49.         };

  50.         // 地图的文件头(大话3)
  51.         class MapHeader3
  52.         {
  53.         public:
  54.                 // 文件头结构共40字节
  55.                 uint32                Flag;                                // 文件标志 0.3M (M3.0) 0x524F4C30
  56.                 uint32                Reserved;                        // 保留(未知作用,应该都为0)
  57.                 uint32                Width;                                // 地图实际的宽度
  58.                 uint32                Height;                                // 地图实际的高度
  59.                 uint16                PointWidth;                        // 坐标的宽度(默认:20px)
  60.                 uint16                PointHeight;                // 坐标的高度(默认:20px)
  61.                 uint16                SubWidth;                        // 小地图的宽度(默认:400px)
  62.                 uint16                SubHeight;                        // 小地图的高度(默认:320px)
  63.                 uint32                UnitIndexOffset;        // 单元引索的位置
  64.                 uint32                UnitIndexNum;                // 单元引索的数量
  65.                 uint32                IndexOffset;                // 引索的位置(未知部分)
  66.                 uint32                IndexNum;                        // 引索的数量(未知部分)
  67.         };

  68.         // ROL0的文件头(大话3)
  69.         class Rol0Header
  70.         {
  71.         public:
  72.                 // 外文件头结构共24字节
  73.                 uint32                Flag;                                // 文件标志 0LOR (ROL0) 0x524F4C30
  74.                 uint32                Reserved;                        // 保留(未知作用,应该都为0)
  75.                 uint32                Width;                                // 地图实际的宽度
  76.                 uint32                Height;                                // 地图实际的高度
  77.                 uint16                SubWidth;                        // 小地图的宽度(默认:400px)
  78.                 uint16                SubHeight;                        // 小地图的高度(默认:320px)
  79.                 uint32                UnitIndexNum;                // 单元引索的数量
  80.         };

  81.         // 地图的单元头
  82.         class UnitHeader
  83.         {
  84.         public:
  85.                 uint32                Flag;                // 单元标志
  86.                 uint32                Size;                // 单元大小
  87.         };

  88.         // 地图的数据
  89.         class MapData
  90.         {
  91.         public:
  92.                 uint32                Size;                // 数据大小
  93.                 uint8                *Data;                // 数据内容
  94.         };

  95.         // 读取游戏地图类
  96.         class ReadGameMap
  97.         {
  98.         // 公有
  99.         public:
  100.                 ReadGameMap(void);
  101.                 ~ReadGameMap(void);

  102.                 bool LoadMap(string filename);                                        // 加载地图文件
  103.                 uint32 GetMapWidth();                                                        // 获得地图的宽度
  104.                 uint32 GetMapHeight();                                                        // 获得地图的高度
  105.                 uint32 GetSubMapWidth();                                                // 获得子地图的宽度(大话3为400px,其他为320px)
  106.                 uint32 GetSubMapHeight();                                                // 获得子地图的高度(大话3为300px,其他为240px)
  107.                 uint32 GetPointWidth();                                                        // 获得坐标的宽度(默认为20px)
  108.                 uint32 GetPointHeight();                                                // 获得坐标的高度(默认为20px)
  109.                 uint32 GetSubMapTotal();                                                // 获得子地图的总数
  110.                 uint32 GetMaskTotal();                                                        // 获得子地图中Mask的总数
  111.                 uint32 GetMapSize();                                                        // 获得地图文件的大小(字节)
  112.                 uint32 GetMapType();                                                        // 获得地图文件的类型(1为旧的,2为新的,3为大话3内测版,4为大话3正式版,5为大话3ROL文件)
  113.                 uint32 GetSubMapRowNum();                                                // 获得地图的行数
  114.                 uint32 GetSubMapColNum();                                                // 获得地图的列数

  115.                 bool ReadUnit(uint32 UnitNum);                                        // 读取地图的单元数据
  116.                 bool ReleaseUnit();                                                                // 释放地图单元的内存空间(每调用ReadUnit()都要释放)

  117.                 MapData GetJpghData();                                                        // 获得JPGH的数据
  118.                 MapData GetHeadData();                                                        // 获得HEAD的数据
  119.                 MapData GetImagData();                                                        // 获得IMAG的数据
  120.                 MapData GetJpegData();                                                        // 获得JPEG的数据
  121.                 MapData GetMaskData(uint8 ID);                                        // 获得MASK的数据
  122.                 MapData GetBlokData();                                                        // 获得BLOK的数据
  123.                 MapData GetCellData();                                                        // 获得CELL的数据
  124.                 MapData GetBrigData();                                                        // 获得BRIG的数据
  125.                 MapData GetRol0Data();                                                        // 获得ROL0的数据(只应用于大话3)
  126.                 MapData GetLigtData();                                                        // 获得LIGT的数据(只应用于大话3)

  127.         // 私有
  128.         private:

  129.                 bool m_isJpgh;                                                                        // 是否有此数据,则可释放此内存空间
  130.                 bool m_isHead;                                                                        // 是否有此数据,则可释放此内存空间
  131.                 bool m_isImag;                                                                        // 是否有此数据,则可释放此内存空间
  132.                 bool m_isJpeg;                                                                        // 是否有此数据,则可释放此内存空间
  133.                 bool m_isMask;                                                                        // 是否有此数据,则可释放此内存空间
  134.                 bool m_isBlok;                                                                        // 是否有此数据,则可释放此内存空间
  135.                 bool m_isCell;                                                                        // 是否有此数据,则可释放此内存空间
  136.                 bool m_isBrig;                                                                        // 是否有此数据,则可释放此内存空间
  137.                 bool m_isLigt;                                                                        // 是否有此数据,则可释放此内存空间

  138.                 bool ReadJPGH(ifstream &file);                                                                        // 读取地图JPGH的数据(只应用旧的)
  139.                 bool ReadHEAD(ifstream &file);                                                                        // 读取地图HEAD的数据(只应用新的)
  140.                 bool ReadIMAG(ifstream &file, uint32 Flag, uint32 Size);                // 读取地图IMAG的数据(只应用旧的)
  141.                 bool ReadJPEG(ifstream &file, uint32 Flag, uint32 Size);                // 读取地图JPEG的数据
  142.                 bool ReadMASK(ifstream &file, uint32 Flag, uint32 Size);                // 读取地图MASK的数据(只应用旧的)
  143.                 bool ReadBLOK(ifstream &file, uint32 Flag, uint32 Size);                // 读取地图BLOK的数据(只应用旧的)
  144.                 bool ReadCELL(ifstream &file, uint32 Flag, uint32 Size);                // 读取地图CELL的数据
  145.                 bool ReadBRIG(ifstream &file, uint32 Flag, uint32 Size);                // 读取地图BRIG的数据

  146.                 bool ReadROLO(ifstream &file, uint32 Size);                                                // 读取ROLO单元数据(只应用于大话3)
  147.                 bool ReadLIGT(ifstream &file, uint32 Flag, uint32 Size);                // 读取地图LIGT的数据(只应用于大话3)
  148.                 bool ReadEND (ifstream &file, uint32 Flag, uint32 Size);                // 读取地图END 的数据(只应用于大话3)

  149.                 uint32 m_FileFlag;                                                                // 文件标志
  150.                 string m_FileName;                                                                // 地图的文件名
  151.                 uint32 m_FileType;                                                                // 地图文件类型(1为旧的,2为新的,3为大话3内测版,4为大话3正式版,5为大话3ROL文件)

  152.                 float m_MapWidth;                                                                // 地图的宽度
  153.                 float m_MapHeight;                                                                // 地图的高度
  154.                 float m_SubMapWidth;                                                        // 子地图的宽度
  155.                 float m_SubMapHeight;                                                        // 子地图的高度
  156.                 uint32 m_PointWidth;                                                        // 坐标的宽度
  157.                 uint32 m_PointHeight;                                                        // 坐标的高度
  158.                 uint32 m_SubMapRowNum;                                                        // 子地图的行数量
  159.                 uint32 m_SubMapColNum;                                                        // 子地图的列数量
  160.                 uint32 m_SubMapTotal;                                                        // 子地图的总数
  161.                 uint32 m_MapSize;                                                                // 地图的大小

  162.                 uint32 m_Reserved;                                                                // 保留
  163.                 uint32 m_UnitIndexOffset;                                                // 单元的引索位置
  164.                 uint32 m_UnitIndexNum;                                                        // 单元的引索数量
  165.                 uint32 m_IndexOffset;                                                        // 引索位置(未知部分)
  166.                 uint32 m_IndexNum;                                                                // 引索数量(未知部分)

  167.                 uint32 *m_UnitOffsetList;                                                // 单元的偏移列表
  168.                 uint32 *m_OffsetList;                                                        // 未知部分的偏移列表

  169.                 uint32 m_MaskNum;                                                                // MASK 的数量
  170.                 uint32 m_MaskTemp;                                                                // MASK 临时变量
  171.                 uint32 *m_MaskList;                                                                // MASK 的列表

  172.                 MapData m_jpgh;                                                                        // JPGH 数据
  173.                 MapData m_head;                                                                        // HEAD 数据
  174.                 MapData m_imag;                                                                        // IMAG 数据
  175.                 MapData m_jpeg;                                                                        // JPEG 数据
  176.                 MapData m_mask[128];                                                        // MASK 数据
  177.                 MapData m_blok;                                                                        // BLOK 数据
  178.                 MapData m_cell;                                                                        // CELL 数据
  179.                 MapData m_brig;                                                                        // BRIG 数据
  180.                 MapData m_rol0;                                                                        // ROL0 数据
  181.                 MapData m_ligt;                                                                        // LIGT 数据

  182.                 UnitHeader m_ErrorUnit;                                                        // 错误单元的标志
  183.         };
  184. }

  185. /************************************************************************
  186. Map File Old Format
  187. Dali Wang <wdl@sina.com>
  188. 2004-05-09 起稿 @Changchun
  189. 2004-05-10 修改 @Changchun
  190. 2006-02-19 修改 @Haikou

  191. =======================MAP HEAD===============================
  192. 4字节 XPAM(MAPX)
  193. 4字节 地图的宽度
  194. 4字节 地图的高度

  195. 4*n字节 地图单元的引索 n=地图的宽度/640*2 * 地图高度/480*2
  196. 4字节 多出的一个地图单元引索,即结束引索,也就是文件的大小。

  197. 4字节 HGPJ (JPGH)
  198. 4字节 JPG头的大小
  199. n字节 数据内容 n=JPG头的大小,不包括前面8字节。

  200. ==============================================================

  201. 4字节 地图单元引索的开始位置,也是KSAM的数量。

  202. 4字节 GAMI (IMAG)
  203. 4字节 大小(153600),正好是320x240x2。
  204. n字节 数据,不包括前面8字节。

  205. 4字节 GEPJ (JPEG)
  206. 4字节 JPEG单元大小,不包括这8字节。
  207. 2字节 单元地图的宽度
  208. 2字节 单元地图的高度
  209. n字节 地图数据

  210. 4字节 KSAM (MASK)
  211. 4字节 大小(不定)
  212. n字节 数据,不包括前面8字节。
  213. :
  214. 4字节 KSAM (MASK)
  215. 4字节 大小(不定)
  216. n字节 数据,不包括前面8字节。


  217. 4字节 KOLB (BLOK)
  218. 4字节 大小(9600)
  219. n字节 数据,不包括前面8字节。

  220. 4字节 LLEC (CELL)
  221. 4字节 大小(192)
  222. n字节 数据,不包括前面8字节。

  223. 4字节 GIRB (BRIG)
  224. 4字节 大小(不定)
  225. n字节 数据,不包括前面8字节。

  226. 8字节 结束单元。

  227. ==============================================================

  228. XPAM (MAPX) 地图文件头
  229. Index       图象单元引索
  230. HGPJ (JPGH) 图象JPEG Head

  231. GAMI (IMAG) 只有1028.map地图含有这个单元。
  232. GEPJ (JPEG) 图象数据
  233. KSAM (MASK)
  234. :
  235. KSAM (MASK)
  236. KOLB (BLOK) 遮掩规则,一比特代表一个地图像素。
  237. LLEC (CELL) 地图规则,一字节代表一个游戏坐标。
  238. GIRB (BRIG) 光亮规则
  239. :
  240. :
  241. :
  242. GAMI (IMAG) 只有1028.map地图含有这个单元。
  243. GEPJ (JPEG) 图象数据
  244. KSAM (MASK)
  245. :
  246. KSAM (MASK)
  247. KOLB (BLOK) 遮掩规则,一比特代表一个地图像素。
  248. LLEC (CELL) 地图规则,一字节代表一个游戏坐标。
  249. GIRB (BRIG) 光亮规则
  250. ************************************************************************/

  251. /************************************************************************
  252. Map File New Format
  253. Dali Wang <wdl@sina.com>
  254. 2004-05-09 起稿 @Changchun
  255. 2006-02-16 整理 @Haikou
  256. 2006-02-20 整理 @Haikou

  257. ======================= MAP HEAD =============================
  258. 4字节 0.1M (M1.0) 0x302E314D
  259. 4字节 地图的宽度
  260. 4字节 地图的高度

  261. 4*n字节  地图单元的引索 n=地图的宽度/640*2 * 地图高度/480*2

  262. 4字节 文件头大小,包括这4字节,及以上的字节。
  263. ==============================================================

  264. ======================= Unknown ==============================
  265. n字节 未知用途,大小为:第一个单元引索值减去文件头大小。
  266. 注意:这个格式中还没有发现旧格式中的KOLB、GAMI和KSAM。
  267. 有可能和这些单元的用途相同。
  268. ==============================================================

  269. ======================= Unit Data ============================
  270. 4字节 地图单元引索的开始位置。
  271. n*4字节 n为上面的值,n为0时不存在。

  272. 4字节 GEPJ (JPEG)
  273. 4字节 大小
  274. n字节 数据

  275. 4字节 LLEC (CELL)
  276. 4字节 大小
  277. n字节 数据

  278. 4字节 BRIG (GIRB)
  279. 4字节 大小
  280. n字节 数据

  281. 4字节 结束单元。
  282. ==============================================================

  283. 0.1M                新地图文件头       
  284. Index                数据块引索

  285. Unknown         n字节,未知用途(暂称为HEAD)

  286. GEPJ(JPEG)        图象数据
  287. LLEC(CELL)        地图规则,一字节代表一个游戏坐标
  288. GIRB(BRIG)        光亮规则
  289. :
  290. :
  291. :
  292. GEPJ(JPEG)        图象数据
  293. LLEC(CELL)        地图规则,一字节代表一个游戏坐标
  294. GIRB(BRIG)        光亮规则

  295. ************************************************************************/

  296. /************************************************************************
  297. 大话西游3的MAP格式
  298. Dali Wang <wdl@sina.com>
  299. 2007-05-18

  300. =========== MAP HEAD ============
  301. 4字节 文件标志 0.3M (M3.0) 0x524F4C30
  302. 4字节 保留(未知作用,应该都为0)
  303. 4字节 地图实际的宽度
  304. 4字节 地图实际的高度
  305. 2字节 坐标的宽度(默认:20px)
  306. 2字节 坐标的高度(默认:20px)
  307. 2字节 小地图的宽度(默认:400px)
  308. 2字节 小地图的高度(默认:320px)
  309. 4字节 单元引索的位置
  310. 4字节 单元引索的数量
  311. 4字节 引索的位置(未知部分)
  312. 4字节 引索的数量(未知部分)

  313. =========== UNIT INDEX =========
  314. 4字节*n 单元的引索      

  315. ========== 未知数据 ============
  316. 可能是地图遮掩关系等数据

  317. ========== UNIT DATA ===========
  318. 4字节 MASK(KSAM) 遮掩关系
  319. 4字节 大小
  320. n字节 数据

  321. 4字节 JPEG(GEPJ) JPEG 图片数据
  322. 4字节 大小
  323. n字节 数据

  324. 4字节 CELL(LLEC) 地图行走规则
  325. 4字节 大小
  326. n字节 数据

  327. 4字节 LIGT(TGIL) 地图亮度规则
  328. 4字节 大小
  329. n字节 数据

  330. 4字节 END ( DNE) 单元结束标志
  331. 4字节 大小

  332. ////////////////////////////////
  333. HEADER 40字节

  334. INDEX
  335. ......
  336. INDEX

  337. 未知数据

  338. MASK (KSAM) 0x4D41534B
  339. MSK2 (2KSM) 0x4D534B32
  340. JPEG (GEPJ) 0x4A504547
  341. CELL (LLEC) 0x43454C4C
  342. LIGT (TGIL) 0x4C494754
  343. END  ( DNE) 0x454E4420
  344. :
  345. :
  346. :
  347. MASK (KSAM) 0x4D41534B
  348. MSK2 (2KSM) 0x4D534B32
  349. JPEG (GEPJ) 0x4A504547
  350. CELL (LLEC) 0x43454C4C
  351. LIGT (TGIL) 0x4C494754
  352. END  ( DNE) 0x454E4420
  353. ************************************************************************/

  354. /************************************************************************
  355. 大话3地图 ROL 文件格式
  356. Dali Wang<wdl@sina.com>
  357. 2007-05-18

  358. =========== FILE HEAD ==========
  359. 24字节
  360. 4字节 文件标志 0LOR(ROL0)
  361. 4字节 保留 (00 00 00 00)
  362. 4字节 大地图的宽度
  363. 4字节 大地图的高度
  364. 2字节 小地图的宽度
  365. 2字节 小地图的高度
  366. 4字节 引索的数量

  367. =========== JPEG INDEX =========
  368. n*4字节 引索列表

  369. =========== JPEG DATA ==========
  370. 4字节 47 45 50 4A 标志 GEPJ(JPEG)
  371. 4字节 B7 20 00 00 数据大小
  372. n字节 数据
  373. :
  374. :
  375. :
  376. 4字节 47 45 50 4A 标志 GEPJ(JPEG)
  377. 4字节 数据大小
  378. n字节 数据

  379. ************************************************************************/
复制代码


ReadGameMap.cpp

  1. /*********************************************************************************************
  2. *                                         网易公司西游系列
  3. *                《梦幻西游》《大话西游II》《大话西游3内测版》《大话西游3正式版》
  4. *                                        地图文件格式读取类
  5. *---------------------------------------------------------------------------------------------
  6. *
  7. *                                           版本 4.0.0
  8. *
  9. *                                     王大理 <wdl@sina.com>
  10. *                                            <QQ:598337462>
  11. *
  12. *---------------------------------------------------------------------------------------------
  13. * 声明:
  14. *     本源代码应用于网易公司的网络游戏:《梦幻西游》、《大话西游II》、《大话西游3内测版》和
  15. *《大话西游3正式版》地图文件格式的读取。与此源代码相应的文件格式版权属于网易公司所有。
  16. *     此源代码仅应用于教育目的,禁止用于商业目的,否则后果自负,本源代码作者不承担任何责任。
  17. * 如有异议或应用于其他目的请务使用本源代码,并永久删除此源代码。
  18. *---------------------------------------------------------------------------------------------
  19. *                         版权所有(c) 2003-2007 王大理,保留所有权利。
  20. *********************************************************************************************/
  21. #include "ReadGameMap.h"

  22. using namespace NetEase; // 使用NetEase命名空间

  23. ReadGameMap::ReadGameMap(void)
  24. {
  25.         m_MapWidth = 0;                                                                // 地图的宽度
  26.         m_MapHeight = 0;                                                        // 地图的高度
  27.         m_SubMapWidth = 0;                                                        // 子地图的宽度
  28.         m_SubMapHeight = 0;                                                        // 子地图的高度
  29.         m_PointWidth = 0;                                                        // 坐标的宽度
  30.         m_PointHeight = 0;                                                        // 坐标的高度
  31.         m_SubMapRowNum = 0;                                                        // 子地图的行数量
  32.         m_SubMapColNum = 0;                                                        // 子地图的列数量
  33.         m_SubMapTotal = 0;                                                        // 子地图的总数
  34.         m_MapSize = 0;                                                                // 地图的大小

  35.         m_Reserved = 0;                                                                // 保留
  36.         m_UnitIndexOffset = 0;                                                // 单元的引索位置
  37.         m_UnitIndexNum = 0;                                                        // 单元的引索数量
  38.         m_IndexOffset = 0;                                                        // 引索位置(未知部分)
  39.         m_IndexNum = 0;                                                                // 引索数量(未知部分)

  40.         m_MaskNum = 0;                                                                // MASK 的数量
  41.         m_MaskTemp = 0;                                                                // MASK 临时变量

  42.         m_isJpgh = false;
  43.         m_isHead = false;
  44.         m_isImag = false;
  45.         m_isJpeg = false;
  46.         m_isMask = false;
  47.         m_isBlok = false;
  48.         m_isCell = false;
  49.         m_isBrig = false;
  50.         m_isLigt = false;

  51. }

  52. ReadGameMap::~ReadGameMap(void)
  53. {
  54.         if (m_isJpgh)
  55.         {
  56.                 delete[] m_jpgh.Data;
  57.         }

  58.         if (m_isHead)
  59.         {
  60.                 delete[] m_head.Data;
  61.         }

  62. }

  63. // 加载地图文件
  64. bool ReadGameMap::LoadMap(string filename)
  65. {
  66.         m_FileName = filename;
  67.         ifstream infile;

  68.         // 打开地图文件
  69.         infile.open(filename.c_str(), ios::in|ios::binary);

  70.         // 判断文件是否存在
  71.         if(!infile)
  72.         {
  73.                 cerr << "不能打开地图文件 :" << filename << endl;
  74.                 exit(EXIT_FAILURE); // 退出
  75.         }

  76.         uint32 TempFlag; // 临时文件标志
  77.         infile.read((char*)&TempFlag,sizeof(uint32));
  78.         infile.seekg(0, ios_base::beg); // 跳到文件开头位置

  79.         // 文件标志
  80.         // 0x4D415058 (MAPX) 大话2旧地图
  81.         // 0x4D312E30 (M1.0) 大话2新地图 梦幻地图
  82.         // 0x4D322E35 (M2.5) 大话3内测版
  83.         // 0x4D332E30 (M3.0) 大话3正式版
  84.         // 0x524F4C30 (ROL0) 大话3地图背景文件
  85.         if ((TempFlag == 0x4D415058) | (TempFlag == 0x4D312E30) | (TempFlag == 0x4D322E35) | (TempFlag == 0x4D332E30) | (TempFlag == 0x524F4C30))
  86.         {
  87.                 switch(TempFlag)
  88.                 {
  89.                 case 0x4D415058:
  90.                         m_FileType = 1; // 大话2旧地图格式
  91.                         break;
  92.                 case 0x4D312E30:
  93.                         m_FileType = 2; // 大话2新地图、梦幻地图格式
  94.                         break;
  95.                 case 0x4D322E35:
  96.                         m_FileType = 3; // 大话3内测版地图格式
  97.                         break;
  98.                 case 0x4D332E30:
  99.                         m_FileType = 4; // 大话3正式版地图格式
  100.                         break;
  101.                 case 0x524F4C30:
  102.                         m_FileType = 5; // 大话3地图背景文件格式
  103.                         break;
  104.                 }

  105.                 if ((m_FileType == 1) | (m_FileType == 2))
  106.                 {
  107.                         MapHeader1 header;
  108.                         infile.read((char*)&header,sizeof(MapHeader1));
  109.                         m_FileFlag=header.Flag;                // 文件标志
  110.                         m_MapWidth = (float)header.Width;        // 地图的宽度
  111.                         m_MapHeight= (float)header.Height;        // 地图的高度

  112.                         m_SubMapWidth = 320;// 子地图的宽度
  113.                         m_SubMapHeight = 240;// 子地图的高度
  114.                         m_PointWidth = 20;// 坐标的宽度
  115.                         m_PointHeight = 20;// 坐标的高度
  116.                 }

  117.                 if ((m_FileType == 3) | (m_FileType == 4))
  118.                 {
  119.                         MapHeader3 header;
  120.                         infile.read((char*)&header,sizeof(MapHeader3));
  121.                         m_FileFlag=header.Flag;                                                // 文件标志
  122.                         m_MapWidth = (float)header.Width;                        // 地图的宽度
  123.                         m_MapHeight= (float)header.Height;                        // 地图的高度
  124.                         m_SubMapWidth = header.SubWidth;                        // 子地图的宽度
  125.                         m_SubMapHeight = header.SubHeight;                        // 子地图的高度
  126.                         m_PointWidth = header.PointWidth;                        // 坐标的宽度
  127.                         m_PointHeight = header.PointHeight;                        // 坐标的高度

  128.                         m_Reserved=header.Reserved;                                        // 保留
  129.                         m_UnitIndexOffset=header.UnitIndexOffset;        // 单元的引索位置
  130.                         m_UnitIndexNum=header.UnitIndexNum;                        // 单元的引索数量
  131.                         m_IndexOffset=header.IndexOffset;                        // 引索位置(未知部分)
  132.                         m_IndexNum=header.IndexNum;                                        // 引索数量(未知部分)
  133.                 }

  134.                 if (m_FileType == 5)
  135.                 {
  136.                         Rol0Header header;
  137.                         infile.read((char*)&header,sizeof(Rol0Header));
  138.                         m_FileFlag=header.Flag;                                                // 文件标志
  139.                         m_Reserved=header.Reserved;                                        // 保留
  140.                         m_MapWidth = (float)header.Width;                        // 地图的宽度
  141.                         m_MapHeight= (float)header.Height;                        // 地图的高度
  142.                         m_SubMapWidth = header.SubWidth;                        // 子地图的宽度
  143.                         m_SubMapHeight = header.SubHeight;                        // 子地图的高度
  144.                         m_UnitIndexNum=header.UnitIndexNum;                        // 单元的引索数量
  145.                 }

  146.                 // 注:因为有些地图的尺寸并一定可以被小地图尺寸整除,所以需要趋向最大取整
  147.                 m_SubMapRowNum=(uint32)ceil((float)(m_MapHeight/m_SubMapHeight)); // 计算行中子地图的数量
  148.                 m_SubMapColNum=(uint32)ceil((float)(m_MapWidth/m_SubMapWidth)); // 计算列中子地图的数量
  149.                 m_SubMapTotal=m_SubMapRowNum*m_SubMapColNum; // 计算地图中总的子地图数量

  150.                 // 读取单元偏移值列表
  151.                 m_UnitOffsetList=new uint32[m_SubMapTotal]; // 自动分配列表空间
  152.                 infile.read((char*)m_UnitOffsetList, sizeof(uint32) * m_SubMapTotal); // 读取列表

  153.                 // 仅大话3地图使用
  154.                 if ((m_FileType == 3) | (m_FileType == 4))
  155.                 {
  156.                         // 读取未知部分偏移值列表
  157.                         m_OffsetList=new uint32[m_IndexNum]; // 分配(未知部分)的列表空间
  158.                         infile.read((char*)&m_OffsetList, sizeof(uint32) * m_IndexNum); // 读取列表(未知部分)
  159.                 }
  160.         }
  161.         else
  162.         {
  163.                 cerr << filename << ": 地图文件格式错误!" << endl;
  164.                 exit(EXIT_FAILURE); // 退出
  165.         }

  166.         if (m_FileType == 1)
  167.         {
  168.                 infile.read((char*)&m_MapSize,sizeof(uint32)); // 获得地图文件的大小
  169.                 ReadJPGH(infile); // 读取JPGH的数据
  170.         }

  171.         if ((m_FileType == 2) | (m_FileType == 3) | (m_FileType == 4))
  172.         {
  173.                 ReadHEAD(infile); // 读取新地图的数据
  174.         }

  175.         if (m_FileType == 5)
  176.         {
  177.                 // 此格式无需处理
  178.         }
  179.         infile.close();
  180.         return true;
  181. }


  182. // 读取旧地图JPGH的数据
  183. bool ReadGameMap::ReadJPGH(ifstream &file)
  184. {       
  185.         m_isJpgh = true;
  186.         UnitHeader JpegHead;
  187.         file.read((char*)&JpegHead,sizeof(JpegHead)); // 读取单元头的数据

  188.         // 判断标志是否正确(HGPJ)
  189.         if (JpegHead.Flag!=0x4A504748)
  190.         {
  191.                 cerr << "JPEG HEADER 标志错误!" << endl;
  192.                 m_isJpgh = false;
  193.                 return false;
  194.         }
  195.         m_jpgh.Data = new uint8[JpegHead.Size]; // 分配单元数据的内存空间
  196.         m_jpgh.Size=JpegHead.Size;
  197.         file.read((char*)&m_jpgh.Data,JpegHead.Size); // 读取单元数据
  198.         return true;
  199. }

  200. // 读取新地图HEAD的数据
  201. bool ReadGameMap::ReadHEAD(ifstream &file)
  202. {       
  203.         m_isHead = true;
  204.         uint32 HeaderSize;

  205.         if (m_FileType == 2)
  206.         {
  207.                 file.read((char*)&m_MapSize,sizeof(uint32)); // 获得文件头的大小
  208.                 file.read((char*)&HeaderSize,sizeof(uint32)); // 获得HEAD的大小
  209.         }

  210.         if ((m_FileType == 3) | (m_FileType == 4))
  211.         {
  212.                 HeaderSize=m_UnitIndexOffset-m_IndexOffset; // 计算地图头数据的大小
  213.         }
  214.         m_head.Size=HeaderSize;
  215.         m_head.Data = new uint8[HeaderSize];
  216.         file.read((char*)m_head.Data,HeaderSize); // 读取地图头数据
  217.         return true;
  218. }

  219. // 读取地图的单元数据
  220. bool ReadGameMap::ReadUnit(uint32 UnitNum)
  221. {
  222.         ifstream file;
  223.         uint32 seek;                // 跳转地址
  224.         bool Result;                // 结果
  225.         bool loop=true;                // 是否循环
  226.         m_MaskTemp=1;

  227.         m_isMask=false;
  228.         m_isJpeg=false;
  229.         m_isCell=false;
  230.         m_isLigt=false;

  231.         // 打开文件流
  232.         file.open(m_FileName.c_str(), ios::in|ios::binary);
  233.         if(!file)
  234.         {
  235.                 cerr << "不能打开地图文件 :" << m_FileName << endl;
  236.                 return false;
  237.         }

  238.         seek=m_UnitOffsetList[UnitNum];
  239.         file.seekg(seek,ios_base::beg); // 跳转到单元开始的位置

  240.         if ((m_FileType == 1) | (m_FileType == 2))
  241.         {
  242.                 file.read((char*)&m_MaskNum,sizeof(uint32)); // 获得MASK的数量
  243.         }

  244.         if ((m_FileType == 2) && (m_MaskNum > 0))
  245.         {
  246.                 m_MaskList = new uint32[m_MaskNum];
  247.                 file.read((char*)m_MaskList,sizeof(uint32)*m_MaskNum);
  248.         }

  249.         UnitHeader unit;

  250.         while(loop)
  251.         {
  252.                 file.read((char*)&unit,sizeof(UnitHeader)); // 读取单元的头数据

  253.                 switch(unit.Flag)
  254.                 {

  255.                         // GAMI "47 41 4D 49"
  256.                 case 0x494D4147:
  257.                         Result=ReadIMAG(file,unit.Flag,unit.Size);
  258.                         break;

  259.                         // 2KSM "32 4B 53 4D"
  260.                 case 0x4D534B32:
  261.                         Result=ReadMASK(file,unit.Flag,unit.Size);
  262.                         break;
  263.                         // KSAM "4B 53 41 4D"
  264.                 case 0x4D41534B:
  265.                         Result=ReadMASK(file,unit.Flag,unit.Size);
  266.                         break;

  267.                         // GEPJ "47 45 50 4A"
  268.                 case 0x4A504547:
  269.                         Result=ReadJPEG(file,unit.Flag,unit.Size);

  270.                         if (m_FileFlag==0x524F4C30) // 是否为ROL文件
  271.                         {
  272.                                 loop=false;
  273.                         }

  274.                         break;

  275.                         // KOLB "4B 4F 4C 42"
  276.                 case 0x424C4F4B:
  277.                         Result=ReadBLOK(file,unit.Flag,unit.Size);
  278.                         break;

  279.                         // LLEC "4C 4C 45 43"
  280.                 case 0x43454C4C:
  281.                         Result=ReadCELL(file,unit.Flag,unit.Size);
  282.                         break;

  283.                         // GIRB "47 49 52 42"
  284.                 case 0x42524947:
  285.                         Result=ReadBRIG(file,unit.Flag,unit.Size);
  286.                         break;

  287.                         // TGIL "54 47 49 4C"
  288.                 case 0x4C494754:
  289.                         Result=ReadLIGT(file,unit.Flag,unit.Size);
  290.                         break;

  291.                         //  DNE "20 44 4E 45"
  292.                 case 0x454E4420:
  293.                         Result=ReadEND(file,unit.Flag,unit.Size);
  294.                         loop=false;
  295.                         break;

  296.                         // 默认处理
  297.                 default:
  298.                         // 错误标志
  299.                         m_ErrorUnit.Flag=unit.Flag;
  300.                         m_ErrorUnit.Size=unit.Size;
  301.                         loop=false;
  302.                         break;
  303.                 }
  304.         }
  305.         file.close();
  306.         return Result;
  307. }

  308. // 释放地图单元的内存空间
  309. bool ReadGameMap::ReleaseUnit()
  310. {
  311.         if (m_isImag)
  312.         {
  313.                 delete[] m_imag.Data;
  314.         }

  315.         if (m_isJpeg)
  316.         {
  317.                 delete[] m_jpeg.Data; // 释放JPEG的内存空间
  318.         }

  319.         if (m_isBlok)
  320.         {
  321.                 delete[] m_blok.Data;
  322.         }

  323.         if (m_isCell)
  324.         {
  325.                 delete[] m_cell.Data; // 释放CELL的内存空间
  326.         }

  327.         if (m_isBrig)
  328.         {
  329.                 delete[] m_brig.Data;
  330.         }

  331.         if (m_isLigt)
  332.         {
  333.                 delete[] m_ligt.Data; // 释放LIGT的内存空间
  334.         }
  335.        
  336.         if (m_FileType == 1)
  337.         {
  338.                 if (m_isMask)
  339.                 {
  340.                         //delete m_mask[0].Data;
  341.                 }
  342.         }

  343.         if (m_FileType == 2)
  344.         {
  345.                 delete[] m_MaskList;
  346.         }

  347.         if ((m_FileType == 3) | (m_FileType == 4))
  348.         {
  349.                 if (m_isMask)
  350.                 {
  351.                         //delete[] m_mask[m_MaskTemp].Data;
  352.                 }
  353.         }

  354.                
  355.         return true;
  356. }

  357. // 获得地图宽度
  358. uint32 ReadGameMap::GetMapWidth()
  359. {
  360.         return (uint32)m_MapWidth;
  361. }

  362. // 获得地图高度
  363. uint32 ReadGameMap::GetMapHeight()
  364. {
  365.         return (uint32)m_MapHeight;
  366. }

  367. // 获得子地图的宽度
  368. uint32 ReadGameMap::GetSubMapWidth()
  369. {
  370.         return (uint32)m_SubMapWidth;
  371. }

  372. // 获得子地图的高度
  373. uint32 ReadGameMap::GetSubMapHeight()
  374. {
  375.         return (uint32)m_SubMapHeight;
  376. }

  377. // 获得坐标的宽度
  378. uint32 ReadGameMap::GetPointWidth()
  379. {
  380.         return m_PointWidth;
  381. }

  382. // 获得坐标的高度
  383. uint32 ReadGameMap::GetPointHeight()
  384. {
  385.         return m_PointHeight;
  386. }

  387. // 获得地图的行数
  388. uint32 ReadGameMap::GetSubMapRowNum()
  389. {
  390.         return m_SubMapRowNum;
  391. }

  392. // 获得地图的列数
  393. uint32 ReadGameMap::GetSubMapColNum()
  394. {
  395.         return m_SubMapColNum;
  396. }

  397. // 获得子地图的总数量
  398. uint32 ReadGameMap::GetSubMapTotal()
  399. {
  400.         return m_SubMapTotal;
  401. }

  402. // 获得子地图中Mask的总数
  403. uint32 ReadGameMap::GetMaskTotal()
  404. {
  405.         return m_MaskNum;
  406. }

  407. // 获得地图的大小
  408. uint32 ReadGameMap::GetMapSize()
  409. {
  410.         return m_MapSize;
  411. }

  412. // 获得地图的类型
  413. uint32 ReadGameMap::GetMapType()
  414. {
  415.         return m_FileType;
  416. }

  417. // 读取ROL0单元数据
  418. bool ReadGameMap::ReadROLO(ifstream &file, uint32 Size)
  419. {
  420.         if (m_FileFlag==0x524F4C30) // 是否为ROL文件
  421.         {
  422.                 m_isJpeg = true;
  423.                 m_jpeg.Data = new uint8[Size]; // 分配单元数据的内存空间
  424.                 file.read((char*)m_jpeg.Data,Size); // 读取单元JPEG的数据
  425.                 m_jpeg.Size = Size;
  426.         }
  427.         else
  428.         {
  429.                 cerr << "ROL0标志错误!" << endl;
  430.                 m_isJpeg = false;
  431.                 return false;
  432.         }
  433.         return true;
  434. }

  435. // 读取地图IMAG的数据
  436. bool ReadGameMap::ReadIMAG(ifstream &file, uint32 Flag, uint32 Size)
  437. {
  438.         if (Flag==0x494D4147)
  439.         {
  440.                 m_isImag = true;
  441.                 m_imag.Data = new uint8[Size]; // 分配单元数据的内存空间
  442.                 file.read((char*)m_imag.Data,Size); // 读取单元IMAG的数据
  443.                 m_imag.Size = Size;
  444.         }
  445.         else
  446.         {
  447.                 cerr << "IMAG标志错误!" << endl;
  448.                 m_isImag = false;
  449.                 return false;
  450.         }
  451.         return true;
  452. }

  453. // 读取地图MASK的数据
  454. bool ReadGameMap::ReadMASK(ifstream &file, uint32 Flag, uint32 Size)
  455. {
  456.         // 这个处理可能存在问题
  457.         if (Flag==0x4D41534B || Flag==0x4D534B32)
  458.         {
  459.                 m_isMask = true;
  460.                 if (m_FileType == 1)
  461.                 {
  462.                         m_mask[0].Data = new uint8[Size];
  463.                         file.read((char*)m_mask[0].Data,Size);
  464.                         m_mask[0].Size = Size;
  465.                 }

  466.                 if ((m_FileType == 3) | (m_FileType == 4))
  467.                 {
  468.                         m_MaskNum = Size; // Mask的数量
  469.                         m_mask[m_MaskTemp].Data = new uint8[Size]; // 分配单元数据的内存空间
  470.                         for (uint32 i=0; i< Size; i++)
  471.                         {
  472.                                 file.read((char*)m_mask[m_MaskTemp].Data,4);
  473.                         }
  474.                 }
  475.         }
  476.         else
  477.         {
  478.                 cerr << "MASK标志错误!" << endl;
  479.                 m_isMask = false;
  480.                 return false;
  481.         }
  482.         return true;
  483. }

  484. // 读取地图JPEG的数据
  485. bool ReadGameMap::ReadJPEG(ifstream &file, uint32 Flag, uint32 Size)
  486. {
  487.         if (Flag==0x4A504547)
  488.         {
  489.                 m_isJpeg = true;
  490.                 m_jpeg.Data = new uint8[Size]; // 分配单元数据的内存空间
  491.                 file.read((char*)m_jpeg.Data,Size); // 读取单元JPEG的数据
  492.                 m_jpeg.Size=Size;
  493.         }
  494.         else
  495.         {
  496.                 cerr << "JPEG标志错误!" << endl;
  497.                 m_isJpeg = false;
  498.                 return false;
  499.         }
  500.         return true;
  501. }

  502. // 读取地图BLOK的数据
  503. bool ReadGameMap::ReadBLOK(ifstream &file, uint32 Flag, uint32 Size)
  504. {
  505.         if (Flag == 0x424C4F4B)
  506.         {
  507.                 m_isBlok = true;
  508.                 m_blok.Data = new uint8[Size]; // 分配单元数据的内存空间
  509.                 file.read((char*)m_blok.Data,Size); // 读取单元BLOK的数据
  510.                 m_blok.Size = Size;
  511.         }
  512.         else
  513.         {
  514.                 cerr << "BLOK标志错误!" << endl;
  515.                 m_isBlok = false;
  516.                 return false;

  517.         }
  518.         return true;
  519. }

  520. // 读取地图CELL的数据
  521. bool ReadGameMap::ReadCELL(ifstream &file, uint32 Flag, uint32 Size)
  522. {
  523.         if (Flag==0x43454C4C)
  524.         {
  525.                 m_isCell = true;
  526.                 m_cell.Data = new uint8[Size]; // 分配单元数据的内存空间
  527.                 file.read((char*)m_cell.Data,Size); // 读取单元CELL的数据
  528.                 m_cell.Size=Size;
  529.         }
  530.         else
  531.         {
  532.                 cerr << "CELL标志错误!" << endl;
  533.                 m_isCell = false;
  534.                 return false;
  535.         }
  536.         return true;
  537. }

  538. // 读取地图BRIG的数据
  539. bool ReadGameMap::ReadBRIG(ifstream &file, uint32 Flag, uint32 Size)
  540. {
  541.         if (Flag == 0x42524947)
  542.         {
  543.                 m_isBrig = true;
  544.                 m_brig.Data = new uint8[Size];
  545.                 file.read((char*)m_brig.Data,Size); // 分配单元数据的内存空间
  546.                 m_brig.Size;
  547.         }
  548.         else
  549.         {
  550.                 cerr << "BRIG标志错误!" << endl;
  551.                 m_isBrig = false;
  552.                 return false;
  553.         }
  554.         return true;
  555. }

  556. // 读取地图LIGT的数据
  557. bool ReadGameMap::ReadLIGT(ifstream &file, uint32 Flag, uint32 Size)
  558. {
  559.         if (Flag==0x4C494754)
  560.         {
  561.                 m_isLigt = true;
  562.                 m_ligt.Data = new uint8[Size]; // 分配单元数据的内存空间
  563.                 file.read((char*)m_ligt.Data,Size); // 读取单元JPEG的数据
  564.                 m_ligt.Size=Size;
  565.         }
  566.         else
  567.         {
  568.                 cerr << "LIGT标志错误!" << endl;
  569.                 m_isLigt = false;
  570.                 return false;
  571.         }
  572.         return true;
  573. }

  574. // 读取地图END 的数据
  575. bool ReadGameMap::ReadEND (ifstream &file, uint32 Flag, uint32 Size)
  576. {
  577.         if (Flag==0x454E4420)
  578.         {
  579.                 // 不需要处理数据
  580.         }
  581.         else
  582.         {
  583.                 cerr << "END 标志错误!" << endl;
  584.                 return false;
  585.         }
  586.         return true;
  587. }

  588. // 获得JPGH的数据
  589. MapData ReadGameMap::GetJpghData()
  590. {
  591.         return m_jpgh;
  592. }

  593. // 获得HEAD的数据
  594. MapData ReadGameMap::GetHeadData()
  595. {
  596.         return m_head;
  597. }

  598. // 获得IMAG的数据
  599. MapData ReadGameMap::GetImagData()
  600. {
  601.         return m_imag;
  602. }

  603. // 获得JPEG的数据
  604. MapData ReadGameMap::GetJpegData()
  605. {
  606.         return m_jpeg;
  607. }


  608. // 获得MASK的数据
  609. MapData ReadGameMap::GetMaskData(uint8 ID)
  610. {
  611.         return m_mask[ID];
  612. }

  613. // 获得BLOK的数据
  614. MapData ReadGameMap::GetBlokData()
  615. {
  616.         return m_blok;
  617. }

  618. // 获得CELL的数据
  619. MapData ReadGameMap::GetCellData()
  620. {
  621.         return m_cell;
  622. }

  623. // 获得BRIG的数据
  624. MapData ReadGameMap::GetBrigData()
  625. {
  626.         return m_brig;
  627. }

  628. // 获得LIGT的数据
  629. MapData ReadGameMap::GetLigtData()
  630. {
  631.         return m_ligt;
  632. }
复制代码

1

主题

5

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2009-4-17 21:11:00 | 显示全部楼层

Re:网易西游系列网游地图读取类(大话2 大话3 梦幻)

  能给个读显,WDF 或WDA文件吗,自己下了个MFC 的,现在可以在Win32里画固定1个动话,如果有发我下感激不尽啊,谢谢。

32

主题

82

帖子

88

积分

注册会员

Rank: 2

积分
88
QQ
 楼主| 发表于 2007-12-12 11:28:00 | 显示全部楼层

Re: 网易西游系列网游地图读取类(大话2 大话3 梦幻)

附件为代码文件。

仅供参考,此类没有深入的调试过,使用过程中可能会遇到问题。
我写这个类主要用于提取游戏地图中的背景图片,其他的都没怎么用。

感兴趣的朋友可以试试, 需要可以和我联系。(代码中有联系方式)

sf_20071212112814.rar

7.07 KB, 下载次数:

75

主题

385

帖子

400

积分

中级会员

Rank: 3Rank: 3

积分
400
发表于 2007-12-12 13:14:00 | 显示全部楼层

Re:网易西游系列网游地图读取类(大话2 大话3 梦幻)

有完整得地图工具么?

32

主题

82

帖子

88

积分

注册会员

Rank: 2

积分
88
QQ
 楼主| 发表于 2007-12-12 14:22:00 | 显示全部楼层

Re:网易西游系列网游地图读取类(大话2 大话3 梦幻)

有的,但目前不公布
解出来的地图下载地址:

http://www.dali.hi.cn:81/GameCG/游戏地图/梦幻西游地图全景.rar
http://www.dali.hi.cn:81/GameCG/游戏地图/大话西游2地图全景.rar
http://www.dali.hi.cn:81/GameCG/游戏地图/大话西游3地图全景.rar

30

主题

79

帖子

180

积分

版主

Rank: 7Rank: 7Rank: 7

积分
180
QQ
发表于 2008-3-13 17:21:00 | 显示全部楼层

Re:网易西游系列网游地图读取类(大话2 大话3 梦幻)

请教一下此地图文件:
这个文件我以前就可以解包出来..
生成每个JPGE的KEY.
但我通过这些KEY进行组装JPEG文件时.
组装好后发现里面的数据有些问题..
所以想请教一下.
我QQ:29774874

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2008-3-19 16:26:00 | 显示全部楼层

Re:网易西游系列网游地图读取类(大话2 大话3 梦幻)

有时间看这个不如自己写个
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-20 12:50

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表