/×
 关于文件版本块的结构定义方法。 
 
×/
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_V1    100
 #define SCENE_VERSION_V2    200
#define SCENE_VERSION_V2    200
 #define SCENE_VERSION_V3    300
#define SCENE_VERSION_V3    300

 #define SCENE_CURRENT_VERSION    SCENE_VERSION_V3
#define SCENE_CURRENT_VERSION    SCENE_VERSION_V3

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

 #define HEADER_CURRENT_VERSION    HEADER_VERSION_V3
#define HEADER_CURRENT_VERSION    HEADER_VERSION_V3

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

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

 {
{    
 3 #define    SAVECHUNK( func ) {    \
#define    SAVECHUNK( func ) {    \
 4 chunk_t chunk;    \
    chunk_t chunk;    \
 5 JIStream::tPos cpos = write_chunk( pStream , chunk );    \
    JIStream::tPos cpos = write_chunk( pStream , chunk );    \
 6 chunk.size =(JDWORD)(func);    \
    chunk.size =(JDWORD)(func);    \
 7 JIStream::tPos tcurrent = pStream->getPos();    \
    JIStream::tPos tcurrent = pStream->getPos();    \
 8 write_chunk( pStream , chunk , cpos );    \
    write_chunk( pStream , chunk , cpos );    \
 9 pStream->setPos( tcurrent , JIStream::TPOS_SET ); }
    pStream->setPos( tcurrent , JIStream::TPOS_SET ); }
10
11 SAVECHUNK( save_header( &chunk , pStream ) );
    SAVECHUNK( save_header( &chunk , pStream ) );
12 SAVECHUNK( save_grid( &chunk , pStream ) );
    SAVECHUNK( save_grid( &chunk , pStream ) );
13 SAVECHUNK( save_sector( &chunk , pStream ) );
    SAVECHUNK( save_sector( &chunk , pStream ) );
14
15 #undef SAVECHUNCK
#undef SAVECHUNCK
16 return JR_OK;
    return JR_OK;
17 }
} 
分成三个部分保存,header, grid ,sector,每个都有自己的版本控制,
 1 size_t GridDisplacement::load_header( chunk_t* pc , JIStream* pStream )
size_t GridDisplacement::load_header( chunk_t* pc , JIStream* pStream )
 2

 {
{
 3 size_t size = 0;
    size_t size = 0;
 4
 if( pc->version >= HEADER_VERSION_V1 )
    if( pc->version >= HEADER_VERSION_V1 ) {
{
 5 size = pStream->read( name , sizeof( name ) );
        size = pStream->read( name , sizeof( name ) );
 6 }
    }
 7 
    
 8
 if( pc->version >= HEADER_VERSION_V1+1 )
    if( pc->version >= HEADER_VERSION_V1+1 ) {
{
 9 size += pStream->read( &player_info.start_point , sizeof( vec3 ) );
        size += pStream->read( &player_info.start_point , sizeof( vec3 ) );
10 }
    }
11 
    
12 //if( pc->version >= HEADER_VERSION_V4 ){
    //if( pc->version >= HEADER_VERSION_V4 ){
13 //    size += pStream->read( width );
    //    size += pStream->read( width );
14 //    size += pStream->read( height );
    //    size += pStream->read( height );
15 //}
    //}
16
17 return size;
    return size;
18 }
}
19
20 size_t GridDisplacement::save_header( chunk_t* pc , JIStream* pStream )
size_t GridDisplacement::save_header( chunk_t* pc , JIStream* pStream )
21

 {
{
22 pc->version = HEADER_CURRENT_VERSION;
    pc->version = HEADER_CURRENT_VERSION;
23 pc->name = MF_HEADER;
    pc->name = MF_HEADER;
24
25 size_t size = 0;
    size_t size = 0;
26 size += pStream->write( name , sizeof(name) );
    size += pStream->write( name , sizeof(name) );
27 size += pStream->write( &player_info.start_point , sizeof( vec3 ) );
    size += pStream->write( &player_info.start_point , sizeof( vec3 ) );
28 
    
29 //if( HEADER_CURRENT_VERSION >= HEADER_VERSION_V3 ){
    //if( HEADER_CURRENT_VERSION >= HEADER_VERSION_V3 ){
30 //    size += pStream->write( width );                                        //HEADER_VERSION_V4 added
    //    size += pStream->write( width );                                        //HEADER_VERSION_V4 added
31 //    size += pStream->write( height );
    //    size += pStream->write( height );
32 //}
    //}
33
34 //size += pStream->write( pitch );
    //size += pStream->write( pitch );
35 return size;
    return size;
36 }
}
37
38 size_t GridDisplacement::load_grid( chunk_t* pc , JIStream* pStream )
size_t GridDisplacement::load_grid( chunk_t* pc , JIStream* pStream )
39

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

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


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

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

 
     {
{
 #define LOADCHUNK( func ) if( chunk.size != (func) ){ lpszErrorPos=#func;  goto _END; }
#define LOADCHUNK( func ) if( chunk.size != (func) ){ lpszErrorPos=#func;  goto _END; }
 //        switch( chunk.name )
//        switch( chunk.name )
 //        {
//        {
 //        case MF_HEADER:
//        case MF_HEADER:
 pStream->read( &chunk , sizeof( chunk_t ) );
            pStream->read( &chunk , sizeof( chunk_t ) );
 LOADCHUNK( load_header( &chunk , pStream ) );
            LOADCHUNK( load_header( &chunk , pStream ) );
 //            break;
//            break;
 //        case MF_GRIDS:
//        case MF_GRIDS:
 pStream->read( &chunk , sizeof( chunk_t ) );
            pStream->read( &chunk , sizeof( chunk_t ) );
 LOADCHUNK( load_grid( &chunk , pStream ) );
            LOADCHUNK( load_grid( &chunk , pStream ) );
 //            break;
//            break;
 //        case MF_SECTOR:
//        case MF_SECTOR:
 pStream->read( &chunk , sizeof( chunk_t ) );
            pStream->read( &chunk , sizeof( chunk_t ) );
 LOADCHUNK( load_sector( &chunk , pStream ) );
            LOADCHUNK( load_sector( &chunk , pStream ) );
 //            break;
//            break;
 //        default:
//        default:
 //            JNOTE( "GD_load_map_warning! unknow chunk%x\n" , chunk.name );
//            JNOTE( "GD_load_map_warning! unknow chunk%x\n" , chunk.name );
 //            pStream->setPos( chunk.size , JIStream::TPOS_CUR );
//            pStream->setPos( chunk.size , JIStream::TPOS_CUR );
 //            break;
//            break;
 //        }
//        }
 #undef LOADCHUNK
#undef LOADCHUNK
 }
    }

 _END:
_END:

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


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

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

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

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

 return JR_OK;
    return JR_OK;
 }
}posted on 2010-05-20 15:46 
风轻云淡 阅读(303) 
评论(0)  编辑 收藏 引用  所属分类: 
GameDevelop