Exemplo n.º 1
0
lwSurface *lwGetSurface( picoMemStream_t *fp, int cksize ){
	lwSurface *surf;
	lwTexture *tex;
	lwPlugin *shdr;
	unsigned int id, type;
	unsigned short sz;
	int pos, rlen;


	/* allocate the Surface structure */

	surf = _pico_calloc( 1, sizeof( lwSurface ) );
	if ( !surf ) {
		goto Fail;
	}

	/* non-zero defaults */

	surf->color.rgb[ 0 ] = 0.78431f;
	surf->color.rgb[ 1 ] = 0.78431f;
	surf->color.rgb[ 2 ] = 0.78431f;
	surf->diffuse.val    = 1.0f;
	surf->glossiness.val = 0.4f;
	surf->bump.val       = 1.0f;
	surf->eta.val        = 1.0f;
	surf->sideflags      = 1;

	/* remember where we started */

	set_flen( 0 );
	pos = _pico_memstream_tell( fp );

	/* names */

	surf->name = getS0( fp );
	surf->srcname = getS0( fp );

	/* first subchunk header */

	id = getU4( fp );
	sz = getU2( fp );
	if ( 0 > get_flen() ) {
		goto Fail;
	}

	/* process subchunks as they're encountered */

	while ( 1 ) {
		sz += sz & 1;
		set_flen( 0 );

		switch ( id ) {
		case ID_COLR:
			surf->color.rgb[ 0 ] = getF4( fp );
			surf->color.rgb[ 1 ] = getF4( fp );
			surf->color.rgb[ 2 ] = getF4( fp );
			surf->color.eindex = getVX( fp );
			break;

		case ID_LUMI:
			surf->luminosity.val = getF4( fp );
			surf->luminosity.eindex = getVX( fp );
			break;

		case ID_DIFF:
			surf->diffuse.val = getF4( fp );
			surf->diffuse.eindex = getVX( fp );
			break;

		case ID_SPEC:
			surf->specularity.val = getF4( fp );
			surf->specularity.eindex = getVX( fp );
			break;

		case ID_GLOS:
			surf->glossiness.val = getF4( fp );
			surf->glossiness.eindex = getVX( fp );
			break;

		case ID_REFL:
			surf->reflection.val.val = getF4( fp );
			surf->reflection.val.eindex = getVX( fp );
			break;

		case ID_RFOP:
			surf->reflection.options = getU2( fp );
			break;

		case ID_RIMG:
			surf->reflection.cindex = getVX( fp );
			break;

		case ID_RSAN:
			surf->reflection.seam_angle = getF4( fp );
			break;

		case ID_TRAN:
			surf->transparency.val.val = getF4( fp );
			surf->transparency.val.eindex = getVX( fp );
			break;

		case ID_TROP:
			surf->transparency.options = getU2( fp );
			break;

		case ID_TIMG:
			surf->transparency.cindex = getVX( fp );
			break;

		case ID_RIND:
			surf->eta.val = getF4( fp );
			surf->eta.eindex = getVX( fp );
			break;

		case ID_TRNL:
			surf->translucency.val = getF4( fp );
			surf->translucency.eindex = getVX( fp );
			break;

		case ID_BUMP:
			surf->bump.val = getF4( fp );
			surf->bump.eindex = getVX( fp );
			break;

		case ID_SMAN:
			surf->smooth = getF4( fp );
			break;

		case ID_SIDE:
			surf->sideflags = getU2( fp );
			break;

		case ID_CLRH:
			surf->color_hilite.val = getF4( fp );
			surf->color_hilite.eindex = getVX( fp );
			break;

		case ID_CLRF:
			surf->color_filter.val = getF4( fp );
			surf->color_filter.eindex = getVX( fp );
			break;

		case ID_ADTR:
			surf->add_trans.val = getF4( fp );
			surf->add_trans.eindex = getVX( fp );
			break;

		case ID_SHRP:
			surf->dif_sharp.val = getF4( fp );
			surf->dif_sharp.eindex = getVX( fp );
			break;

		case ID_GVAL:
			surf->glow.val = getF4( fp );
			surf->glow.eindex = getVX( fp );
			break;

		case ID_LINE:
			surf->line.enabled = 1;
			if ( sz >= 2 ) {
				surf->line.flags = getU2( fp );
			}
			if ( sz >= 6 ) {
				surf->line.size.val = getF4( fp );
			}
			if ( sz >= 8 ) {
				surf->line.size.eindex = getVX( fp );
			}
			break;

		case ID_ALPH:
			surf->alpha_mode = getU2( fp );
			surf->alpha = getF4( fp );
			break;

		case ID_AVAL:
			surf->alpha = getF4( fp );
			break;

		case ID_BLOK:
			type = getU4( fp );

			switch ( type ) {
			case ID_IMAP:
			case ID_PROC:
			case ID_GRAD:
				tex = lwGetTexture( fp, sz - 4, type );
				if ( !tex ) {
					goto Fail;
				}
				if ( !add_texture( surf, tex ) ) {
					lwFreeTexture( tex );
				}
				set_flen( 4 + get_flen() );
				break;
			case ID_SHDR:
				shdr = lwGetShader( fp, sz - 4 );
				if ( !shdr ) {
					goto Fail;
				}
				lwListInsert( (void **) &surf->shader, shdr, (void *) compare_shaders );
				++surf->nshaders;
				set_flen( 4 + get_flen() );
				break;
			}
			break;

		default:
			break;
		}

		/* error while reading current subchunk? */

		rlen = get_flen();
		if ( rlen < 0 || rlen > sz ) {
			goto Fail;
		}

		/* skip unread parts of the current subchunk */

		if ( rlen < sz ) {
			_pico_memstream_seek( fp, sz - rlen, PICO_SEEK_CUR );
		}

		/* end of the SURF chunk? */

		if ( cksize <= _pico_memstream_tell( fp ) - pos ) {
			break;
		}

		/* get the next subchunk header */

		set_flen( 0 );
		id = getU4( fp );
		sz = getU2( fp );
		if ( 6 != get_flen() ) {
			goto Fail;
		}
	}

	return surf;

Fail:
	if ( surf ) {
		lwFreeSurface( surf );
	}
	return NULL;
}
Exemplo n.º 2
0
lwSurface *lwGetSurface5( picoMemStream_t *fp, int cksize, lwObject *obj )
{
   lwSurface *surf;
   lwTexture *tex;
   lwPlugin *shdr;
   char *s;
   float v[ 3 ];
   unsigned int id, flags;
   unsigned short sz;
   int pos, rlen, i;

   tex = NULL;
   shdr = NULL;

   /* allocate the Surface structure */

   surf = _pico_calloc( 1, sizeof( lwSurface ));
   if ( !surf ) goto Fail;

   /* non-zero defaults */

   surf->color.rgb[ 0 ] = 0.78431f;
   surf->color.rgb[ 1 ] = 0.78431f;
   surf->color.rgb[ 2 ] = 0.78431f;
   surf->diffuse.val    = 1.0f;
   surf->glossiness.val = 0.4f;
   surf->bump.val       = 1.0f;
   surf->eta.val        = 1.0f;
   surf->sideflags      = 1;

   /* remember where we started */

   set_flen( 0 );
   pos = _pico_memstream_tell( fp );

   /* name */

   surf->name = getS0( fp );

   /* first subchunk header */

   id = getU4( fp );
   sz = getU2( fp );
   if ( 0 > get_flen() ) goto Fail;

   /* process subchunks as they're encountered */

   while ( 1 ) {
      sz += sz & 1;
      set_flen( 0 );

      switch ( id ) {
         case ID_COLR:
            surf->color.rgb[ 0 ] = getU1( fp ) / 255.0f;
            surf->color.rgb[ 1 ] = getU1( fp ) / 255.0f;
            surf->color.rgb[ 2 ] = getU1( fp ) / 255.0f;
            break;

         case ID_FLAG:
            flags = getU2( fp );
            if ( flags &   4 ) surf->smooth = 1.56207f;
            if ( flags &   8 ) surf->color_hilite.val = 1.0f;
            if ( flags &  16 ) surf->color_filter.val = 1.0f;
            if ( flags & 128 ) surf->dif_sharp.val = 0.5f;
            if ( flags & 256 ) surf->sideflags = 3;
            if ( flags & 512 ) surf->add_trans.val = 1.0f;
            break;

         case ID_LUMI:
            surf->luminosity.val = getI2( fp ) / 256.0f;
            break;

         case ID_VLUM:
            surf->luminosity.val = getF4( fp );
            break;

         case ID_DIFF:
            surf->diffuse.val = getI2( fp ) / 256.0f;
            break;

         case ID_VDIF:
            surf->diffuse.val = getF4( fp );
            break;

         case ID_SPEC:
            surf->specularity.val = getI2( fp ) / 256.0f;
            break;

         case ID_VSPC:
            surf->specularity.val = getF4( fp );
            break;

         case ID_GLOS:
            surf->glossiness.val = ( float ) log( getU2( fp )) / 20.7944f;
            break;

         case ID_SMAN:
            surf->smooth = getF4( fp );
            break;

         case ID_REFL:
            surf->reflection.val.val = getI2( fp ) / 256.0f;
            break;

         case ID_RFLT:
            surf->reflection.options = getU2( fp );
            break;

         case ID_RIMG:
            s = getS0( fp );
            surf->reflection.cindex = add_clip( s, &obj->clip, &obj->nclips );
            surf->reflection.options = 3;
            break;

         case ID_RSAN:
            surf->reflection.seam_angle = getF4( fp );
            break;

         case ID_TRAN:
            surf->transparency.val.val = getI2( fp ) / 256.0f;
            break;

         case ID_RIND:
            surf->eta.val = getF4( fp );
            break;

         case ID_BTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->bump.tex, tex );
            break;

         case ID_CTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->color.tex, tex );
            break;

         case ID_DTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->diffuse.tex, tex );
            break;

         case ID_LTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->luminosity.tex, tex );
            break;

         case ID_RTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->reflection.val.tex, tex );
            break;

         case ID_STEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->specularity.tex, tex );
            break;

         case ID_TTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->transparency.val.tex, tex );
            break;

         case ID_TFLG:
            flags = getU2( fp );

			i = 0; // greebo: initialise to fix compiler warnings

            if ( flags & 1 ) i = 0;
            if ( flags & 2 ) i = 1;
            if ( flags & 4 ) i = 2;
            tex->axis = i;
            if ( tex->type == ID_IMAP )
               tex->param.imap.axis = i;
            else
               tex->param.proc.axis = i;

            if ( flags &  8 ) tex->tmap.coord_sys = 1;
            if ( flags & 16 ) tex->negative = 1;
            if ( flags & 32 ) tex->param.imap.pblend = 1;
            if ( flags & 64 ) {
               tex->param.imap.aa_strength = 1.0f;
               tex->param.imap.aas_flags = 1;
            }
            break;

         case ID_TSIZ:
            for ( i = 0; i < 3; i++ )
               tex->tmap.size.val[ i ] = getF4( fp );
            break;

         case ID_TCTR:
            for ( i = 0; i < 3; i++ )
               tex->tmap.center.val[ i ] = getF4( fp );
            break;

         case ID_TFAL:
            for ( i = 0; i < 3; i++ )
               tex->tmap.falloff.val[ i ] = getF4( fp );
            break;

         case ID_TVEL:
            for ( i = 0; i < 3; i++ )
               v[ i ] = getF4( fp );
            tex->tmap.center.eindex = add_tvel( tex->tmap.center.val, v,
               &obj->env, &obj->nenvs );
            break;

         case ID_TCLR:
            if ( tex->type == ID_PROC )
               for ( i = 0; i < 3; i++ )
                  tex->param.proc.value[ i ] = getU1( fp ) / 255.0f;
            break;

         case ID_TVAL:
            tex->param.proc.value[ 0 ] = getI2( fp ) / 256.0f;
            break;

         case ID_TAMP:
            if ( tex->type == ID_IMAP )
               tex->param.imap.amplitude.val = getF4( fp );
            break;

         case ID_TIMG:
            s = getS0( fp );
            tex->param.imap.cindex = add_clip( s, &obj->clip, &obj->nclips );
            break;

         case ID_TAAS:
            tex->param.imap.aa_strength = getF4( fp );
            tex->param.imap.aas_flags = 1;
            break;

         case ID_TREF:
            tex->tmap.ref_object = getbytes( fp, sz );
            break;

         case ID_TOPC:
            tex->opacity.val = getF4( fp );
            break;

         case ID_TFP0:
            if ( tex->type == ID_IMAP )
               tex->param.imap.wrapw.val = getF4( fp );
            break;

         case ID_TFP1:
            if ( tex->type == ID_IMAP )
               tex->param.imap.wraph.val = getF4( fp );
            break;

         case ID_SHDR:
            shdr = _pico_calloc( 1, sizeof( lwPlugin ));
            if ( !shdr ) goto Fail;
            shdr->name = getbytes( fp, sz );
            lwListAdd( (void *) &surf->shader, shdr );
            surf->nshaders++;
            break;

         case ID_SDAT:
            shdr->data = getbytes( fp, sz );
            break;

         default:
            break;
      }

      /* error while reading current subchunk? */

      rlen = get_flen();
      if ( rlen < 0 || rlen > sz ) goto Fail;

      /* skip unread parts of the current subchunk */

      if ( rlen < sz )
         _pico_memstream_seek( fp, sz - rlen, PICO_SEEK_CUR );

      /* end of the SURF chunk? */

      if ( cksize <= _pico_memstream_tell( fp ) - pos )
         break;

      /* get the next subchunk header */

      set_flen( 0 );
      id = getU4( fp );
      sz = getU2( fp );
      if ( 6 != get_flen() ) goto Fail;
   }

   return surf;

Fail:
   if ( surf ) lwFreeSurface( surf );
   return NULL;
}