随笔 - 132  文章 - 51  trackbacks - 0
<2011年4月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿(7)

随笔分类

随笔档案

文章分类

文章档案

cocos2d-x

OGRE

OPenGL

搜索

  •  

最新评论

阅读排行榜

评论排行榜


 关于文件版本块的结构定义方法。
 
×/

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

#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


 1JResult 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}

分成三个部分保存,header, grid ,sector,每个都有自己的版本控制,

 1size_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
20size_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
38size_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
56size_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;
    }


    
forint i=0;i<sector_count;i++ ){
        Sector
* ps = &sectors[ i ];
        
forint 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 风轻云淡 阅读(282) 评论(0)  编辑 收藏 引用 所属分类: GameDevelop

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理