/×
关于文件版本块的结构定义方法。
×/
struct chunk{
JDWORD type;
JDWORD version;
JDWORD size;
}
通过 type 来识别这个 chunk 的类型,如果是已知的类型就按照其对应的版本号 Version 来读取数据
如果不是则跳过该 chunk 并给出一定的警告信息。
size 保存了这个 chunk 的实际长度,通常情况下不包含自己的长度。
可以通过和实际加载的数据长度进行对比,如果两个值不行等,就说明其版本或者数据存在错误~无法继续加载。
举个例子。
我们有一个结构体。
struct MapInfo{
int width;
int height;
int mapdata[100];
// 下面两个变量是在 2.0 版本之后才会出现的。
int posX;
int posY;
};
现在要把这个结构体按照我们的保存结构进行保存。
首先给这个结构定义一种chunk类型,以确保他在程序中是唯一的标志。
例如。 我们定义
#define MAP_INFO_CHUNK_TYPE 0x1000
#define MAP_INFO_CHUNK_VERSION 0x0010 //表示 1.0
保存函数:
JResult saveMapInfo( JIStream* pStream , const MapInfo* mi ){
chunk c;
c.type = MAP_INFO_CHUNK_TYPE;
c.version = MAP_INFO_CHUNK_VERSION; //根据不同的版本。进行写入。
c.size = 0;
JDWORD cur_pos = pStream->getPos();
pStream->write( c ); //先把数据写入文件缓冲。(占位置)
if( c.version >= 0x0010 ){
c.size += pStream->write( mi->width );
c.size += pStream->write( mi->height );
c.size += pStream->write( mi->mapdata );
}
if( c.version >= 0x0020 ){ //
c.size += pStream->write( mi->posX );
c.size += pStream->write( mi->posY );
}
pStream->setPos( TPOS_SET , cur_pos );
pStream->write( c ); //回写chunk数据。
return JROK;
}
读取函数:
JDWORD loadMapInfo( JIStream* pStream , const MapInfo* mi ){
chunk c;
JDWORD size = 0;
size += pStream->read( &c );
if( c.type != MAP_INFO_CHUNK_TYPE ){
JSetLastErrorEx( "error chunk type!\n" );
return size;
}
if( c.version >= 0x0010 ){
size += pStream->read( mi->width );
size += pStream->read( mi->height );
size += pStream->read( mi->mapdata );
}
if( c.version >= 0x0020 ){ //未来各个版本之间的控制。 向下兼容。
size += pStream->read( mi->posX );
size += pStream->read( mi->posY );
}
//检查数据读取长度是否和chunk中记录的相同!
if( size != c.size ){
JSetLastErrorEx( "data chunk have a error existed!\n" );
return size;
}
return size; //这里应该返回该函数总共在这个过程中读取的字节长度。
//以便以后在多层次的嵌套或者递归式可以很方便的求出下一个chunk的位置。
}
大概就是如此。
另外很多情况下一个chunk中可以包含很多子chunk以实现嵌套
#define SCENE_VERSION_V1 100
#define SCENE_VERSION_V2 200
#define SCENE_VERSION_V3 300
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#define SCENE_CURRENT_VERSION SCENE_VERSION_V3
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#define HEADER_VERSION_V1 100
#define HEADER_VERSION_V2 200
#define HEADER_VERSION_V3 300
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#define HEADER_CURRENT_VERSION HEADER_VERSION_V3
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#define GRID_VERSION_V1 100
#define GRID_VERSION_V2 200
#define GRID_VERSION_V3 300
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#define GRID_CURRENT_VERSION GRID_VERSION_V3
1
JResult GridDisplacement::saveMap( JIStream* pStream )
2![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
3
#define SAVECHUNK( func ) { \
4
chunk_t chunk; \
5
JIStream::tPos cpos = write_chunk( pStream , chunk ); \
6
chunk.size =(JDWORD)(func); \
7
JIStream::tPos tcurrent = pStream->getPos(); \
8
write_chunk( pStream , chunk , cpos ); \
9
pStream->setPos( tcurrent , JIStream::TPOS_SET ); }
10![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
11
SAVECHUNK( save_header( &chunk , pStream ) );
12
SAVECHUNK( save_grid( &chunk , pStream ) );
13
SAVECHUNK( save_sector( &chunk , pStream ) );
14![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
15
#undef SAVECHUNCK
16
return JR_OK;
17
}
分成三个部分保存,header, grid ,sector,每个都有自己的版本控制,
1
size_t GridDisplacement::load_header( chunk_t* pc , JIStream* pStream )
2![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
3
size_t size = 0;
4![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if( pc->version >= HEADER_VERSION_V1 )
{
5
size = pStream->read( name , sizeof( name ) );
6
}
7
8![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if( pc->version >= HEADER_VERSION_V1+1 )
{
9
size += pStream->read( &player_info.start_point , sizeof( vec3 ) );
10
}
11
12
//if( pc->version >= HEADER_VERSION_V4 ){
13
// size += pStream->read( width );
14
// size += pStream->read( height );
15
//}
16![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
17
return size;
18
}
19![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
20
size_t GridDisplacement::save_header( chunk_t* pc , JIStream* pStream )
21![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
22
pc->version = HEADER_CURRENT_VERSION;
23
pc->name = MF_HEADER;
24![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
25
size_t size = 0;
26
size += pStream->write( name , sizeof(name) );
27
size += pStream->write( &player_info.start_point , sizeof( vec3 ) );
28
29
//if( HEADER_CURRENT_VERSION >= HEADER_VERSION_V3 ){
30
// size += pStream->write( width ); //HEADER_VERSION_V4 added
31
// size += pStream->write( height );
32
//}
33![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
34
//size += pStream->write( pitch );
35
return size;
36
}
37![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
38
size_t GridDisplacement::load_grid( chunk_t* pc , JIStream* pStream )
39![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
40
size_t size = 0;
41![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
42
size += pStream->read( width );
43
size += pStream->read( height );
44
size += pStream->read( pitch );
45![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
46![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if( JROK( generate_maze( width , height ) ) )
{
47
r_setLastErrorMsg( "load_grid error ! generate_maze" ) ;
48
return 0;
49
}
50![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
51
// size += pStream->read( grids , pitch * height );
52![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
53
return size;
54
}
55![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
56
size_t GridDisplacement::save_grid( chunk_t* pc , JIStream* pStream )
57![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
58
pc->version = GRID_CURRENT_VERSION;
59
pc->name = MF_GRIDS;
60![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
61
size_t size = 0;
62
size += pStream->write( width );
63
size += pStream->write( height );
64
size += pStream->write( pitch );
65![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
66
// size += pStream->write( grids , pitch * height );
67![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
68
return size;
69
}
LoadMap分别加载
JResult GridDisplacement::loadMap( JIStream* pStream )
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
chunk_t chunk;
//JResult result = JR_OK;
const char* lpszErrorPos = NULL;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
// while( !pStream->eof() )
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
#define LOADCHUNK( func ) if( chunk.size != (func) ){ lpszErrorPos=#func; goto _END; }
// switch( chunk.name )
// {
// case MF_HEADER:
pStream->read( &chunk , sizeof( chunk_t ) );
LOADCHUNK( load_header( &chunk , pStream ) );
// break;
// case MF_GRIDS:
pStream->read( &chunk , sizeof( chunk_t ) );
LOADCHUNK( load_grid( &chunk , pStream ) );
// break;
// case MF_SECTOR:
pStream->read( &chunk , sizeof( chunk_t ) );
LOADCHUNK( load_sector( &chunk , pStream ) );
// break;
// default:
// JNOTE( "GD_load_map_warning! unknow chunk%x\n" , chunk.name );
// pStream->setPos( chunk.size , JIStream::TPOS_CUR );
// break;
// }
#undef LOADCHUNK
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
_END:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if( lpszErrorPos )
{
//JNOTE( "GD_load_map_error! pos:%s <%s>\n" , lpszErrorPos , r_getLastErrorMsg() );
return JR_FAILED;
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for( int i=0;i<sector_count;i++ )
{
Sector* ps = §ors[ i ];
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for( int j=0;j<ps->obj_list.count();j++ )
{
IObject* pi = ps->obj_list[ j ];
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if( pi && pi->getType() == IObject::LIGHT )
{
GLight* light = (GLight*)pi;
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if( light->light_ptr )
{
light->light_ptr->need_update_static_UT = JTRUE;
light->light_ptr->need_update = JTRUE;
}
}
}
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return JR_OK;
}
posted on 2010-05-20 15:46
风轻云淡 阅读(271)
评论(0) 编辑 收藏 引用 所属分类:
GameDevelop