⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lwreader.cpp

📁 赫赫大名的 OGRE 游戏引擎
💻 CPP
📖 第 1 页 / 共 4 页
字号:
*/

int lwReader::lwGetTHeader( int hsz, lwTexture &tex )
{
	unsigned int id;
	unsigned short sz;
	int pos, rlen;
	
	/* remember where we started */
	
	flen = 0;
	pos = is->tellg();
	
	/* ordinal string */
	
	tex.ord = getS0();
	
	/* first subchunk header */
	
	id = getU4();
	sz = getU2();
	if ( 0 > flen ) return 0;
	
	/* process subchunks as they're encountered */
	
	while ( 1 ) {
		sz += sz & 1;
		flen = 0;
		
		switch ( id ) {
		case ID_CHAN:
			tex.chan = getU4();
			break;
			
		case ID_OPAC:
			tex.opac_type = getU2();
			tex.opacity.val = getF4();
			tex.opacity.eindex = getVX();
			break;
			
		case ID_ENAB:
			tex.enabled = getU2();
			break;
			
		case ID_NEGA:
			tex.negative = getU2();
			break;
			
		case ID_AXIS:
			tex.axis = getU2();
			break;
			
		default:
			break;
		}
		
		/* error while reading current subchunk? */
		
		rlen = flen;
		if ( rlen < 0 || rlen > sz ) return 0;
		
		/* skip unread parts of the current subchunk */
		
		if ( rlen < sz )
			is->seekg(sz - rlen, ios_base::cur );
		
		/* end of the texture header subchunk? */
		
		int fpos = is->tellg();
		if ( fpos == -1 ) break;
		if ( hsz + pos <= fpos ) break;

//		if ( hsz + pos <= is->tellg())
//			break;
		
		/* get the next subchunk header */
		
		flen = 0;
		id = getU4();
		sz = getU2();
		if ( 6 != flen ) return 0;
	};
	
	int g = is->tellg(); 
	flen = g - pos;
	return 1;
}

/*======================================================================
lwGetTMap()

  Read a texture map from a SURF.BLOK in an LWO2 file.  The TMAP
  defines the mapping from texture to world or object coordinates.
====================================================================== */

int lwReader::lwGetTMap( int tmapsz, lwTMap &tmap )
{
	unsigned int id;
	unsigned short sz;
	int rlen, pos, i;
	
	pos = is->tellg();
	id = getU4();
	sz = getU2();
	if ( 0 > flen ) return 0;
	
	while ( 1 ) {
		sz += sz & 1;
		flen = 0;
		
		switch ( id ) {
		case ID_SIZE:
			for ( i = 0; i < 3; i++ )
				tmap.size.val[ i ] = getF4();
			tmap.size.eindex = getVX();
			break;
			
		case ID_CNTR:
			for ( i = 0; i < 3; i++ )
				tmap.center.val[ i ] = getF4();
			tmap.center.eindex = getVX();
			break;
			
		case ID_ROTA:
			for ( i = 0; i < 3; i++ )
				tmap.rotate.val[ i ] = getF4();
			tmap.rotate.eindex = getVX();
			break;
			
		case ID_FALL:
			tmap.fall_type = getU2();
			for ( i = 0; i < 3; i++ )
				tmap.falloff.val[ i ] = getF4();
			tmap.falloff.eindex = getVX();
			break;
			
		case ID_OREF:
			tmap.ref_object = getS0();
			break;
			
		case ID_CSYS:
			tmap.coord_sys = getU2();
			break;
			
		default:
			break;
		}
		
		/* error while reading the current subchunk? */
		
		rlen = flen;
		if ( rlen < 0 || rlen > sz ) return 0;
		
		/* skip unread parts of the current subchunk */
		
		if ( rlen < sz )
			is->seekg(sz - rlen, ios_base::cur );
		
		/* end of the TMAP subchunk? */
		int fpos = is->tellg();
		if ( fpos == -1 ) break;
		if ( tmapsz + pos <= fpos ) break;
		
//		if ( tmapsz + pos <= is->tellg() )
//			break;
		
		/* get the next subchunk header */
		
		flen = 0;
		id = getU4();
		sz = getU2();
		if ( 6 != flen ) return 0;
	};
	
	int g = is->tellg(); 
	flen = g - pos;
	return 1;
}

/*======================================================================
lwGetImageMap()

Read an lwImageMap from a SURF.BLOK in an LWO2 file.
====================================================================== */

lwImageMap *lwReader::lwGetImageMap( int rsz, lwTexture &tex )
{
	unsigned int id;
	unsigned short sz;
	int rlen, pos;
	
	pos = is->tellg();
	id = getU4();
	sz = getU2();
	if ( 0 > flen ) return 0;

	lwImageMap *imap = new lwImageMap;
	if (!imap) return NULL;

	while ( 1 ) {
		sz += sz & 1;
		flen = 0;
		
		switch ( id ) {
		case ID_TMAP:
			if ( !lwGetTMap( sz, tex.tmap )) return 0;
			break;
			
		case ID_PROJ:
			imap->projection = getU2();
			break;
			
		case ID_VMAP:
			imap->vmap_name = getS0();
			break;
			
		case ID_AXIS:
			imap->axis = getU2();
			break;
			
		case ID_IMAG:
			imap->cindex = getVX();
			break;
			
		case ID_WRAP:
			imap->wrapw_type = getU2();
			imap->wraph_type = getU2();
			break;
			
		case ID_WRPW:
			imap->wrapw.val = getF4();
			imap->wrapw.eindex = getVX();
			break;
			
		case ID_WRPH:
			imap->wraph.val = getF4();
			imap->wraph.eindex = getVX();
			break;
			
		case ID_AAST:
			imap->aas_flags = getU2();
			imap->aa_strength = getF4();
			break;
			
		case ID_PIXB:
			imap->pblend = getU2();
			break;
			
		case ID_STCK:
			imap->stck.val = getF4();
			imap->stck.eindex = getVX();
			break;
			
		case ID_TAMP:
			imap->amplitude.val = getF4();
			imap->amplitude.eindex = getVX();
			break;
			
		default:
			break;
		}
		
		/* error while reading the current subchunk? */
		
		rlen = flen;
		if ( rlen < 0 || rlen > sz ) return 0;
		
		/* skip unread parts of the current subchunk */
		
		if ( rlen < sz )
			is->seekg(sz - rlen, ios_base::cur );
		
		/* end of the image map? */
		
		int fpos = is->tellg();
		if ( fpos == -1 ) break;
		if ( rsz + pos <= fpos ) break;

//		if ( rsz + pos <= is->tellg() )
//			break;
		
		/* get the next subchunk header */
		
		flen = 0;
		id = getU4();
		sz = getU2();
		if ( 6 != flen ) return 0;
	};
	
	int g = is->tellg(); 
	flen = g - pos;
	return imap;
}


/*
======================================================================
lwGetProcedural()

Read an lwProcedural from a SURF.BLOK in an LWO2 file.
======================================================================
*/
  
lwProcedural *lwReader::lwGetProcedural( int rsz, lwTexture &tex )
{
	unsigned int id;
	unsigned short sz;
	int rlen, pos, fpos;
	
	pos = is->tellg();
	id = getU4();
	sz = getU2();
	if ( 0 > flen ) return 0;

  	lwProcedural *proc = new lwProcedural;
	if (!proc) return NULL;
	
	while ( 1 ) {
		sz += sz & 1;
		flen = 0;
		
		switch ( id ) {
		case ID_TMAP:
			if ( !lwGetTMap( sz, tex.tmap )) return 0;
			break;
			
		case ID_AXIS:
			proc->axis = getU2();
			break;
			
		case ID_VALU:
			proc->value[ 0 ] = getF4();
			if ( sz >= 8 ) proc->value[ 1 ] = getF4();
			if ( sz >= 12 ) proc->value[ 2 ] = getF4();
			break;
			
		case ID_FUNC:
			proc->name = getS0();
			rlen = flen;
			proc->data = getbytes( sz - rlen );
			break;
			
		default:
			break;
		}
		
		/* error while reading the current subchunk? */
		
		rlen = flen;
		if ( rlen < 0 || rlen > sz ) return 0;
		
		/* skip unread parts of the current subchunk */
		
		if ( rlen < sz )
			is->seekg(sz - rlen, ios_base::cur );
		
		/* end of the procedural block? */
		
		fpos = is->tellg();
		
		if (fpos == -1)
		{
			flen  = -pos;
			return proc;
		}
		
		if ( rsz + pos <= fpos )
			break;
		
		//		if ( rsz + pos <= is->tellg())
		//			break;
		
		/* get the next subchunk header */
		
		flen = 0;
		id = getU4();
		sz = getU2();
		if ( 6 != flen ) return 0;
	};
	
	int g = is->tellg(); 
	flen = g - pos;
	return proc;
}
  
  
/*
======================================================================
lwGetGradient()

Read an lwGradient from a SURF.BLOK in an LWO2 file.
====================================================================== */
  
lwGradient *lwReader::lwGetGradient( int rsz, lwTexture &tex )
{
	unsigned int id;
	unsigned short sz;
	int rlen, pos, i, j, nkeys;
	
	pos = is->tellg();
	id = getU4();
	sz = getU2();
	if ( 0 > flen ) return 0;

	lwGradient *grad = new lwGradient;
	if (!grad) return NULL;

	while ( 1 ) {
		sz += sz & 1;
		flen = 0;
		
		switch ( id ) {
		case ID_TMAP:
			if ( !lwGetTMap( sz, tex.tmap )) return 0;
			break;
			
		case ID_PNAM:
			grad->paramname = getS0();
			break;
			
		case ID_INAM:
			grad->itemname = getS0();
			break;
			
		case ID_GRST:
			grad->start = getF4();
			break;
			
		case ID_GREN:
			grad->end = getF4();
			break;
			
		case ID_GRPT:
			grad->repeat = getU2();
			break;
			
		case ID_FKEY:
			nkeys = sz / sizeof( lwGradKey );
			grad->key = (lwGradKey *)malloc(nkeys * sizeof(lwGradKey));
			if ( !grad->key ) return 0;
			for ( i = 0; i < nkeys; i++ ) {
				grad->key[ i ].value = getF4();
				for ( j = 0; j < 4; j++ )
					grad->key[ i ].rgba[ j ] = getF4();
			}
			break;
			
		case ID_IKEY:
			nkeys = sz / 2;
			grad->ikey = (short *)malloc(nkeys * sizeof(short));
			if ( !grad->ikey ) return 0;
			for ( i = 0; i < nkeys; i++ )
				grad->ikey[ i ] = getU2();
			break;
			
		default:
			break;
		}
		
		/* error while reading the current subchunk? */
		
		rlen = flen;
		if ( rlen < 0 || rlen > sz ) return 0;
		
		/* skip unread parts of the current subchunk */
		
		if ( rlen < sz )
			is->seekg(sz - rlen, ios_base::cur );
		
		/* end of the gradient? */
		
		int fpos = is->tellg();
		if ( fpos == -1 ) break;
		if ( rsz + pos <= fpos ) break;

//		if ( rsz + pos <= is->tellg() )
//			break;
		
		/* get the next subchunk header */
		
		flen = 0;
		id = getU4();
		sz = getU2();
		if ( 6 != flen ) return 0;
	};
	
	int g = is->tellg(); 
	flen = g - pos;
	return grad;
}


/*
======================================================================
lwGetTexture()

Read an lwTexture from a SURF.BLOK in an LWO2 file.
====================================================================== */
  
lwTexture *lwReader::lwGetTexture( int bloksz, unsigned int type )
{
	lwTexture *tex;
	unsigned short sz;
	bool ok;
	
	tex = new lwTexture;
	if ( !tex ) return NULL;
	
	tex->type = type;
	
	sz = getU2();
	if ( !lwGetTHeader( sz, *tex )) {
		delete tex;
		return NULL;
	}
	
	sz = bloksz - sz - 6;
	switch ( type ) {
	case ID_IMAP:
		tex->param.imap = lwGetImageMap( sz, *tex );
		ok = tex->param.imap!=0;
		break;
	case ID_PROC:
		tex->param.proc = lwGetProcedural( sz, *tex );
		ok = tex->param.proc!=0;
		break;
	case ID_GRAD:
		tex->param.grad = lwGetGradient( sz, *tex );
		ok = tex->param.grad!=0;
		break;
	default:
		ok = !is->seekg(sz, ios_base::cur );
	}
	
	if ( !ok )
	{
		delete tex;
		return NULL;
	}
	
	flen = bloksz;
	return tex;
}
  
/*
======================================================================
lwGetShader()

Read a shader record from a SURF.BLOK in an LWO2 file.
====================================================================== */

lwPlugin *lwReader::lwGetShader( int bloksz )
{
	lwPlugin *shdr;
	unsigned int id;
	unsigned short sz;
	int hsz, rlen, pos;
	int g = 0;
	
	shdr = new lwPlugin;
	if ( !shdr ) return NULL;
	
	pos = is->tellg();
	flen = 0;
	hsz = getU2();
	shdr->ord = getS0();
	id = getU4();
	sz = getU2();
	if ( 0 > flen ) goto Fail;
	
	while ( hsz > 0 )
	{
		sz += sz & 1;
		hsz -= sz;
		if ( id == ID_ENAB ) {
			shdr->flags = getU2();
			break;
		}
		else {
			is->seekg(sz, ios_base::cur );
			id = getU4();
			sz = getU2();
		}
	}
	
	id = getU4();
	sz = getU2();
	if ( 0 > flen ) goto Fail;
	
	while ( 1 )
	{
		sz += sz & 1;
		flen = 0;
		
		switch ( id ) {
		case ID_FUNC:
			shdr->name = getS0();
			rlen = flen;
			shdr->data = getbytes( sz - rlen );
			break;
			
		default:
			break;
		}
		
		/* error while reading the current subchunk? */
		
		rlen = flen;
		if ( rlen < 0 || rlen > sz ) goto Fail;
		
		/* skip unread parts of the current subchunk */
		
		if ( rlen < sz )
			is->seekg(sz - rlen, ios_base::cur );
		
		/* end of the shader block? */
		
		int fpos = is->tellg();
		if ( fpos == -1 ) break;
		if ( bloksz + pos <= fpos ) break;
		
		
		//		if ( bloksz + pos <= is->tellg() )
		//			break;
		
		/* get the next subchunk header */
		
		flen = 0;
		id = getU4();
		sz = getU2();
		if ( 6 != flen ) goto Fail;
	};
	
	g = is->tellg(); 
	flen = g - pos;
	return shdr;
	
Fail:
	delete shdr;
	return NULL;
}

/*======================================================================
add_clip()

Add a clip to the clip list. Used to store the contents of an RIMG or
TIMG surface subchunk.
======================================================================*/

int lwReader::add_clip( char *s, vclips &clips )
{
	lwClip *clip;
	char *p;

	clip = new lwClip;
	if ( !clip ) return 0;

	if ( p = strstr( s, "(sequence)" ))
	{
		p[ -1 ] = 0;
		clip->type = ID_ISEQ;
		lwClipSeq *seq = new lwClipSeq;
		seq->prefix = s;
		seq->digits = 3;
		clip->source.seq = seq;
	}
	else
	{
		clip->type = ID_STIL;
		lwClipStill *still = new lwClipStill;
		still->name = s;
		clip->source.still = still;
	}

	clips.push_back( clip );
	clip->index = clips.size()-1;

	return clip->index;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -