/×
關(guān)于文件版本塊的結(jié)構(gòu)定義方法。
×/
struct chunk{
JDWORD type;
JDWORD version;
JDWORD size;
}
通過 type 來識(shí)別這個(gè) chunk 的類型,如果是已知的類型就按照其對應(yīng)的版本號(hào) Version 來讀取數(shù)據(jù)
如果不是則跳過該 chunk 并給出一定的警告信息。
size 保存了這個(gè) chunk 的實(shí)際長度,通常情況下不包含自己的長度。
可以通過和實(shí)際加載的數(shù)據(jù)長度進(jìn)行對比,如果兩個(gè)值不行等,就說明其版本或者數(shù)據(jù)存在錯(cuò)誤~無法繼續(xù)加載。
舉個(gè)例子。
我們有一個(gè)結(jié)構(gòu)體。
struct MapInfo{
int width;
int height;
int mapdata[100];
// 下面兩個(gè)變量是在 2.0 版本之后才會(huì)出現(xiàn)的。
int posX;
int posY;
};
現(xiàn)在要把這個(gè)結(jié)構(gòu)體按照我們的保存結(jié)構(gòu)進(jìn)行保存。
首先給這個(gè)結(jié)構(gòu)定義一種chunk類型,以確保他在程序中是唯一的標(biāo)志。
例如。 我們定義
#define MAP_INFO_CHUNK_TYPE 0x1000
#define MAP_INFO_CHUNK_VERSION 0x0010 //表示 1.0
保存函數(shù):
JResult saveMapInfo( JIStream* pStream , const MapInfo* mi ){
chunk c;
c.type = MAP_INFO_CHUNK_TYPE;
c.version = MAP_INFO_CHUNK_VERSION; //根據(jù)不同的版本。進(jìn)行寫入。
c.size = 0;
JDWORD cur_pos = pStream->getPos();
pStream->write( c ); //先把數(shù)據(jù)寫入文件緩沖。(占位置)
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數(shù)據(jù)。
return JROK;
}
讀取函數(shù):
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 ){ //未來各個(gè)版本之間的控制。 向下兼容。
size += pStream->read( mi->posX );
size += pStream->read( mi->posY );
}
//檢查數(shù)據(jù)讀取長度是否和chunk中記錄的相同!
if( size != c.size ){
JSetLastErrorEx( "data chunk have a error existed!\n" );
return size;
}
return size; //這里應(yīng)該返回該函數(shù)總共在這個(gè)過程中讀取的字節(jié)長度。
//以便以后在多層次的嵌套或者遞歸式可以很方便的求出下一個(gè)chunk的位置。
}
大概就是如此。
另外很多情況下一個(gè)chunk中可以包含很多子chunk以實(shí)現(xiàn)嵌套
#define SCENE_VERSION_V1 100
#define SCENE_VERSION_V2 200
#define SCENE_VERSION_V3 300

#define SCENE_CURRENT_VERSION SCENE_VERSION_V3

#define HEADER_VERSION_V1 100
#define HEADER_VERSION_V2 200
#define HEADER_VERSION_V3 300

#define HEADER_CURRENT_VERSION HEADER_VERSION_V3

#define GRID_VERSION_V1 100
#define GRID_VERSION_V2 200
#define GRID_VERSION_V3 300

#define GRID_CURRENT_VERSION GRID_VERSION_V3
1
JResult GridDisplacement::saveMap( JIStream* pStream )
2

{
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
11
SAVECHUNK( save_header( &chunk , pStream ) );
12
SAVECHUNK( save_grid( &chunk , pStream ) );
13
SAVECHUNK( save_sector( &chunk , pStream ) );
14
15
#undef SAVECHUNCK
16
return JR_OK;
17
}
分成三個(gè)部分保存,header, grid ,sector,每個(gè)都有自己的版本控制,
1
size_t GridDisplacement::load_header( chunk_t* pc , JIStream* pStream )
2

{
3
size_t size = 0;
4
if( pc->version >= HEADER_VERSION_V1 )
{
5
size = pStream->read( name , sizeof( name ) );
6
}
7
8
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
17
return size;
18
}
19
20
size_t GridDisplacement::save_header( chunk_t* pc , JIStream* pStream )
21

{
22
pc->version = HEADER_CURRENT_VERSION;
23
pc->name = MF_HEADER;
24
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
34
//size += pStream->write( pitch );
35
return size;
36
}
37
38
size_t GridDisplacement::load_grid( chunk_t* pc , JIStream* pStream )
39

{
40
size_t size = 0;
41
42
size += pStream->read( width );
43
size += pStream->read( height );
44
size += pStream->read( pitch );
45
46
if( JROK( generate_maze( width , height ) ) )
{
47
r_setLastErrorMsg( "load_grid error ! generate_maze" ) ;
48
return 0;
49
}
50
51
// size += pStream->read( grids , pitch * height );
52
53
return size;
54
}
55
56
size_t GridDisplacement::save_grid( chunk_t* pc , JIStream* pStream )
57

{
58
pc->version = GRID_CURRENT_VERSION;
59
pc->name = MF_GRIDS;
60
61
size_t size = 0;
62
size += pStream->write( width );
63
size += pStream->write( height );
64
size += pStream->write( pitch );
65
66
// size += pStream->write( grids , pitch * height );
67
68
return size;
69
}
LoadMap分別加載
JResult GridDisplacement::loadMap( JIStream* pStream )


{
chunk_t chunk;
//JResult result = JR_OK;
const char* lpszErrorPos = NULL;

// while( !pStream->eof() )

{
#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
}

_END:

if( lpszErrorPos )
{
//JNOTE( "GD_load_map_error! pos:%s <%s>\n" , lpszErrorPos , r_getLastErrorMsg() );
return JR_FAILED;
}


for( int i=0;i<sector_count;i++ )
{
Sector* ps = §ors[ i ];

for( int j=0;j<ps->obj_list.count();j++ )
{
IObject* pi = ps->obj_list[ j ];

if( pi && pi->getType() == IObject::LIGHT )
{
GLight* light = (GLight*)pi;

if( light->light_ptr )
{
light->light_ptr->need_update_static_UT = JTRUE;
light->light_ptr->need_update = JTRUE;
}
}
}
}

return JR_OK;
}
posted on 2010-05-20 15:46
風(fēng)輕云淡 閱讀(288)
評論(0) 編輯 收藏 引用 所屬分類:
GameDevelop