]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - libs/picomodel/lwo/lwo2.c
Remove -Wno-pedantic
[xonotic/netradiant.git] / libs / picomodel / lwo / lwo2.c
index 1d72af7decf8754838300f24a82877f14c1f6e53..5299d29718b5fcaaa2bced92aac0d7353bf8ddd8 100644 (file)
-/*\r
-======================================================================\r
-lwo2.c\r
-\r
-The entry point for loading LightWave object files.\r
-\r
-Ernie Wright  17 Sep 00\r
-====================================================================== */\r
-\r
-#include "../picointernal.h"\r
-#include "lwo2.h"\r
-\r
-/* disable warnings */\r
-#ifdef _WIN32\r
-#pragma warning( disable:4018 )                /* signed/unsigned mismatch */\r
-#endif\r
-\r
-\r
-/*\r
-======================================================================\r
-lwFreeLayer()\r
-\r
-Free memory used by an lwLayer.\r
-====================================================================== */\r
-\r
-void lwFreeLayer( lwLayer *layer )\r
-{\r
-   if ( layer ) {\r
-      if ( layer->name ) _pico_free( layer->name );\r
-      lwFreePoints( &layer->point );\r
-      lwFreePolygons( &layer->polygon );\r
-      lwListFree( layer->vmap, lwFreeVMap );\r
-      _pico_free( layer );\r
-   }\r
-}\r
-\r
-\r
-/*\r
-======================================================================\r
-lwFreeObject()\r
-\r
-Free memory used by an lwObject.\r
-====================================================================== */\r
-\r
-void lwFreeObject( lwObject *object )\r
-{\r
-   if ( object ) {\r
-      lwListFree( object->layer, lwFreeLayer );\r
-      lwListFree( object->env, lwFreeEnvelope );\r
-      lwListFree( object->clip, lwFreeClip );\r
-      lwListFree( object->surf, lwFreeSurface );\r
-      lwFreeTags( &object->taglist );\r
-      _pico_free( object );\r
-   }\r
-}\r
-\r
-\r
-/*\r
-======================================================================\r
-lwGetObject()\r
-\r
-Returns the contents of a LightWave object, given its filename, or\r
-NULL if the file couldn't be loaded.  On failure, failID and failpos\r
-can be used to diagnose the cause.\r
-\r
-1.  If the file isn't an LWO2 or an LWOB, failpos will contain 12 and\r
-    failID will be unchanged.\r
-\r
-2.  If an error occurs while reading, failID will contain the most\r
-    recently read IFF chunk ID, and failpos will contain the value\r
-    returned by _pico_memstream_tell() at the time of the failure.\r
-\r
-3.  If the file couldn't be opened, or an error occurs while reading\r
-    the first 12 bytes, both failID and failpos will be unchanged.\r
-\r
-If you don't need this information, failID and failpos can be NULL.\r
-====================================================================== */\r
-\r
-lwObject *lwGetObject( char *filename, picoMemStream_t *fp, unsigned int *failID, int *failpos )\r
-{\r
-   lwObject *object;\r
-   lwLayer *layer;\r
-   lwNode *node;\r
-   unsigned int id, formsize, type, cksize;\r
-   int i, rlen;\r
-\r
-   /* open the file */\r
-\r
-   if ( !fp ) return NULL;\r
-\r
-   /* read the first 12 bytes */\r
-\r
-   set_flen( 0 );\r
-   id       = getU4( fp );\r
-   formsize = getU4( fp );\r
-   type     = getU4( fp );\r
-   if ( 12 != get_flen() ) {\r
-      return NULL;\r
-   }\r
-\r
-   /* is this a LW object? */\r
-\r
-   if ( id != ID_FORM ) {\r
-      if ( failpos ) *failpos = 12;\r
-      return NULL;\r
-   }\r
-\r
-   if ( type != ID_LWO2 ) {\r
-      if ( type == ID_LWOB )\r
-         return lwGetObject5( filename, fp, failID, failpos );\r
-      else {\r
-         if ( failpos ) *failpos = 12;\r
-         return NULL;\r
-      }\r
-   }\r
-\r
-   /* allocate an object and a default layer */\r
-\r
-   object = _pico_calloc( 1, sizeof( lwObject ));\r
-   if ( !object ) goto Fail;\r
-\r
-   layer = _pico_calloc( 1, sizeof( lwLayer ));\r
-   if ( !layer ) goto Fail;\r
-   object->layer = layer;\r
-\r
-   /* get the first chunk header */\r
-\r
-   id = getU4( fp );\r
-   cksize = getU4( fp );\r
-   if ( 0 > get_flen() ) goto Fail;\r
-\r
-   /* process chunks as they're encountered */\r
-\r
-   while ( 1 ) {\r
-      cksize += cksize & 1;\r
-\r
-      switch ( id )\r
-      {\r
-         case ID_LAYR:\r
-            if ( object->nlayers > 0 ) {\r
-               layer = _pico_calloc( 1, sizeof( lwLayer ));\r
-               if ( !layer ) goto Fail;\r
-               lwListAdd( &object->layer, layer );\r
-            }\r
-            object->nlayers++;\r
-\r
-            set_flen( 0 );\r
-            layer->index = getU2( fp );\r
-            layer->flags = getU2( fp );\r
-            layer->pivot[ 0 ] = getF4( fp );\r
-            layer->pivot[ 1 ] = getF4( fp );\r
-            layer->pivot[ 2 ] = getF4( fp );\r
-            layer->name = getS0( fp );\r
-\r
-            rlen = get_flen();\r
-            if ( rlen < 0 || rlen > cksize ) goto Fail;\r
-            if ( rlen <= cksize - 2 )\r
-               layer->parent = getU2( fp );\r
-            rlen = get_flen();\r
-            if ( rlen < cksize )\r
-               _pico_memstream_seek( fp, cksize - rlen, PICO_SEEK_CUR );\r
-            break;\r
-\r
-         case ID_PNTS:\r
-            if ( !lwGetPoints( fp, cksize, &layer->point ))\r
-               goto Fail;\r
-            break;\r
-\r
-         case ID_POLS:\r
-            if ( !lwGetPolygons( fp, cksize, &layer->polygon,\r
-               layer->point.offset ))\r
-               goto Fail;\r
-            break;\r
-\r
-         case ID_VMAP:\r
-         case ID_VMAD:\r
-            node = ( lwNode * ) lwGetVMap( fp, cksize, layer->point.offset,\r
-               layer->polygon.offset, id == ID_VMAD );\r
-            if ( !node ) goto Fail;\r
-            lwListAdd( &layer->vmap, node );\r
-            layer->nvmaps++;\r
-            break;\r
-\r
-         case ID_PTAG:\r
-            if ( !lwGetPolygonTags( fp, cksize, &object->taglist,\r
-               &layer->polygon ))\r
-               goto Fail;\r
-            break;\r
-\r
-         case ID_BBOX:\r
-            set_flen( 0 );\r
-            for ( i = 0; i < 6; i++ )\r
-               layer->bbox[ i ] = getF4( fp );\r
-            rlen = get_flen();\r
-            if ( rlen < 0 || rlen > cksize ) goto Fail;\r
-            if ( rlen < cksize )\r
-               _pico_memstream_seek( fp, cksize - rlen, PICO_SEEK_CUR );\r
-            break;\r
-\r
-         case ID_TAGS:\r
-            if ( !lwGetTags( fp, cksize, &object->taglist ))\r
-               goto Fail;\r
-            break;\r
-\r
-         case ID_ENVL:\r
-            node = ( lwNode * ) lwGetEnvelope( fp, cksize );\r
-            if ( !node ) goto Fail;\r
-            lwListAdd( &object->env, node );\r
-            object->nenvs++;\r
-            break;\r
-\r
-         case ID_CLIP:\r
-            node = ( lwNode * ) lwGetClip( fp, cksize );\r
-            if ( !node ) goto Fail;\r
-            lwListAdd( &object->clip, node );\r
-            object->nclips++;\r
-            break;\r
-\r
-         case ID_SURF:\r
-            node = ( lwNode * ) lwGetSurface( fp, cksize );\r
-            if ( !node ) goto Fail;\r
-            lwListAdd( &object->surf, node );\r
-            object->nsurfs++;\r
-            break;\r
-\r
-         case ID_DESC:\r
-         case ID_TEXT:\r
-         case ID_ICON:\r
-         default:\r
-            _pico_memstream_seek( fp, cksize, PICO_SEEK_CUR );\r
-            break;\r
-      }\r
-\r
-      /* end of the file? */\r
-\r
-      if ( formsize <= _pico_memstream_tell( fp ) - 8 ) break;\r
-\r
-      /* get the next chunk header */\r
-\r
-      set_flen( 0 );\r
-      id = getU4( fp );\r
-      cksize = getU4( fp );\r
-      if ( 8 != get_flen() ) goto Fail;\r
-   }\r
-\r
-   if ( object->nlayers == 0 )\r
-      object->nlayers = 1;\r
-\r
-   layer = object->layer;\r
-   while ( layer ) {\r
-      lwGetBoundingBox( &layer->point, layer->bbox );\r
-      lwGetPolyNormals( &layer->point, &layer->polygon );\r
-      if ( !lwGetPointPolygons( &layer->point, &layer->polygon )) goto Fail;\r
-      if ( !lwResolvePolySurfaces( &layer->polygon, &object->taglist,\r
-         &object->surf, &object->nsurfs )) goto Fail;\r
-      lwGetVertNormals( &layer->point, &layer->polygon );\r
-      if ( !lwGetPointVMaps( &layer->point, layer->vmap )) goto Fail;\r
-      if ( !lwGetPolyVMaps( &layer->polygon, layer->vmap )) goto Fail;\r
-      layer = layer->next;\r
-   }\r
-\r
-   return object;\r
-\r
-Fail:\r
-  if ( failID ) *failID = id;\r
-   if ( fp ) {\r
-      if ( failpos ) *failpos = _pico_memstream_tell( fp );\r
-   }\r
-   lwFreeObject( object );\r
-   return NULL;\r
-}\r
-\r
-int lwValidateObject( char *filename, picoMemStream_t *fp, unsigned int *failID, int *failpos )\r
-{\r
-   unsigned int id, formsize, type;\r
-\r
-   /* open the file */\r
-\r
-   if ( !fp ) return PICO_PMV_ERROR_MEMORY;\r
-\r
-   /* read the first 12 bytes */\r
-\r
-   set_flen( 0 );\r
-   id       = getU4( fp );\r
-   formsize = getU4( fp );\r
-   type     = getU4( fp );\r
-   if ( 12 != get_flen() ) {\r
-      return PICO_PMV_ERROR_SIZE;\r
-   }\r
-\r
-   /* is this a LW object? */\r
-\r
-   if ( id != ID_FORM ) {\r
-      if ( failpos ) *failpos = 12;\r
-      return PICO_PMV_ERROR_SIZE;\r
-   }\r
-\r
-   if ( type != ID_LWO2 ) {\r
-      if ( type == ID_LWOB )\r
-         return lwValidateObject5( filename, fp, failID, failpos );\r
-      else {\r
-         if ( failpos ) *failpos = 12;\r
-         return PICO_PMV_ERROR_IDENT;\r
-      }\r
-   }\r
-\r
-   return PICO_PMV_OK;\r
-}\r
+/*
+   ======================================================================
+   lwo2.c
+
+   The entry point for loading LightWave object files.
+
+   Ernie Wright  17 Sep 00
+   ====================================================================== */
+
+#include "../picointernal.h"
+#include "lwo2.h"
+
+/* disable warnings */
+#ifdef WIN32
+#pragma warning( disable:4018 )                /* signed/unsigned mismatch */
+#endif
+
+
+/*
+   ======================================================================
+   lwFreeLayer()
+
+   Free memory used by an lwLayer.
+   ====================================================================== */
+
+void lwFreeLayer( lwLayer *layer ){
+       if ( layer ) {
+               if ( layer->name ) {
+                       _pico_free( layer->name );
+               }
+               lwFreePoints( &layer->point );
+               lwFreePolygons( &layer->polygon );
+               lwListFree(layer->vmap, (void (*)(void *)) lwFreeVMap);
+               _pico_free( layer );
+       }
+}
+
+
+/*
+   ======================================================================
+   lwFreeObject()
+
+   Free memory used by an lwObject.
+   ====================================================================== */
+
+void lwFreeObject( lwObject *object ){
+       if ( object ) {
+               lwListFree(object->layer, (void (*)(void *)) lwFreeLayer);
+               lwListFree(object->env, (void (*)(void *)) lwFreeEnvelope);
+               lwListFree(object->clip, (void (*)(void *)) lwFreeClip);
+               lwListFree(object->surf, (void (*)(void *)) lwFreeSurface);
+               lwFreeTags( &object->taglist );
+               _pico_free( object );
+       }
+}
+
+
+/*
+   ======================================================================
+   lwGetObject()
+
+   Returns the contents of a LightWave object, given its filename, or
+   NULL if the file couldn't be loaded.  On failure, failID and failpos
+   can be used to diagnose the cause.
+
+   1.  If the file isn't an LWO2 or an LWOB, failpos will contain 12 and
+    failID will be unchanged.
+
+   2.  If an error occurs while reading, failID will contain the most
+    recently read IFF chunk ID, and failpos will contain the value
+    returned by _pico_memstream_tell() at the time of the failure.
+
+   3.  If the file couldn't be opened, or an error occurs while reading
+    the first 12 bytes, both failID and failpos will be unchanged.
+
+   If you don't need this information, failID and failpos can be NULL.
+   ====================================================================== */
+
+lwObject *lwGetObject( const char *filename, picoMemStream_t *fp, unsigned int *failID, int *failpos ){
+       lwObject *object;
+       lwLayer *layer;
+       lwNode *node;
+       unsigned int id, formsize, type;
+       int i, rlen, cksize;
+
+       /* open the file */
+
+       if ( !fp ) {
+               return NULL;
+       }
+
+       /* read the first 12 bytes */
+
+       set_flen( 0 );
+       id       = getU4( fp );
+       formsize = getU4( fp );
+       type     = getU4( fp );
+       if ( 12 != get_flen() ) {
+               return NULL;
+       }
+
+       /* is this a LW object? */
+
+       if ( id != ID_FORM ) {
+               if ( failpos ) {
+                       *failpos = 12;
+               }
+               return NULL;
+       }
+
+       if ( type != ID_LWO2 ) {
+               if ( type == ID_LWOB ) {
+                       return lwGetObject5( filename, fp, failID, failpos );
+               }
+               else {
+                       if ( failpos ) {
+                               *failpos = 12;
+                       }
+                       return NULL;
+               }
+       }
+
+       /* allocate an object and a default layer */
+
+       object = _pico_calloc( 1, sizeof( lwObject ) );
+       if ( !object ) {
+               goto Fail;
+       }
+
+       layer = _pico_calloc( 1, sizeof( lwLayer ) );
+       if ( !layer ) {
+               goto Fail;
+       }
+       object->layer = layer;
+
+       /* get the first chunk header */
+
+       id = getU4( fp );
+       cksize = getU4( fp );
+       if ( 0 > get_flen() ) {
+               goto Fail;
+       }
+
+       /* process chunks as they're encountered */
+
+       while ( 1 ) {
+               cksize += cksize & 1;
+
+               switch ( id )
+               {
+               case ID_LAYR:
+                       if ( object->nlayers > 0 ) {
+                               layer = _pico_calloc( 1, sizeof( lwLayer ) );
+                               if ( !layer ) {
+                                       goto Fail;
+                               }
+                               lwListAdd( (void **) &object->layer, layer );
+                       }
+                       object->nlayers++;
+
+                       set_flen( 0 );
+                       layer->index = getU2( fp );
+                       layer->flags = getU2( fp );
+                       layer->pivot[ 0 ] = getF4( fp );
+                       layer->pivot[ 1 ] = getF4( fp );
+                       layer->pivot[ 2 ] = getF4( fp );
+                       layer->name = getS0( fp );
+
+                       rlen = get_flen();
+                       if ( rlen < 0 || rlen > cksize ) {
+                               goto Fail;
+                       }
+                       if ( rlen <= cksize - 2 ) {
+                               layer->parent = getU2( fp );
+                       }
+                       rlen = get_flen();
+                       if ( rlen < cksize ) {
+                               _pico_memstream_seek( fp, cksize - rlen, PICO_SEEK_CUR );
+                       }
+                       break;
+
+               case ID_PNTS:
+                       if ( !lwGetPoints( fp, cksize, &layer->point ) ) {
+                               goto Fail;
+                       }
+                       break;
+
+               case ID_POLS:
+                       if ( !lwGetPolygons( fp, cksize, &layer->polygon,
+                                                                layer->point.offset ) ) {
+                               goto Fail;
+                       }
+                       break;
+
+               case ID_VMAP:
+               case ID_VMAD:
+                       node = ( lwNode * ) lwGetVMap( fp, cksize, layer->point.offset,
+                                                                                  layer->polygon.offset, id == ID_VMAD );
+                       if ( !node ) {
+                               goto Fail;
+                       }
+                       lwListAdd( (void **) &layer->vmap, node );
+                       layer->nvmaps++;
+                       break;
+
+               case ID_PTAG:
+                       if ( !lwGetPolygonTags( fp, cksize, &object->taglist,
+                                                                       &layer->polygon ) ) {
+                               goto Fail;
+                       }
+                       break;
+
+               case ID_BBOX:
+                       set_flen( 0 );
+                       for ( i = 0; i < 6; i++ )
+                               layer->bbox[ i ] = getF4( fp );
+                       rlen = get_flen();
+                       if ( rlen < 0 || rlen > cksize ) {
+                               goto Fail;
+                       }
+                       if ( rlen < cksize ) {
+                               _pico_memstream_seek( fp, cksize - rlen, PICO_SEEK_CUR );
+                       }
+                       break;
+
+               case ID_TAGS:
+                       if ( !lwGetTags( fp, cksize, &object->taglist ) ) {
+                               goto Fail;
+                       }
+                       break;
+
+               case ID_ENVL:
+                       node = ( lwNode * ) lwGetEnvelope( fp, cksize );
+                       if ( !node ) {
+                               goto Fail;
+                       }
+                       lwListAdd( (void **) &object->env, node );
+                       object->nenvs++;
+                       break;
+
+               case ID_CLIP:
+                       node = ( lwNode * ) lwGetClip( fp, cksize );
+                       if ( !node ) {
+                               goto Fail;
+                       }
+                       lwListAdd( (void **) &object->clip, node );
+                       object->nclips++;
+                       break;
+
+               case ID_SURF:
+                       node = ( lwNode * ) lwGetSurface( fp, cksize );
+                       if ( !node ) {
+                               goto Fail;
+                       }
+                       lwListAdd( (void **) &object->surf, node );
+                       object->nsurfs++;
+                       break;
+
+               case ID_DESC:
+               case ID_TEXT:
+               case ID_ICON:
+               default:
+                       _pico_memstream_seek( fp, cksize, PICO_SEEK_CUR );
+                       break;
+               }
+
+               /* end of the file? */
+
+               if ( formsize <= (unsigned int) ( _pico_memstream_tell( fp ) - 8 ) ) {
+                       break;
+               }
+
+               /* get the next chunk header */
+
+               set_flen( 0 );
+               id = getU4( fp );
+               cksize = getU4( fp );
+               if ( 8 != get_flen() ) {
+                       goto Fail;
+               }
+       }
+
+       if ( object->nlayers == 0 ) {
+               object->nlayers = 1;
+       }
+
+       layer = object->layer;
+       while ( layer ) {
+               lwGetBoundingBox( &layer->point, layer->bbox );
+               lwGetPolyNormals( &layer->point, &layer->polygon );
+               if ( !lwGetPointPolygons( &layer->point, &layer->polygon ) ) {
+                       goto Fail;
+               }
+               if ( !lwResolvePolySurfaces( &layer->polygon, &object->taglist,
+                                                                        &object->surf, &object->nsurfs ) ) {
+                       goto Fail;
+               }
+               lwGetVertNormals( &layer->point, &layer->polygon );
+               if ( !lwGetPointVMaps( &layer->point, layer->vmap ) ) {
+                       goto Fail;
+               }
+               if ( !lwGetPolyVMaps( &layer->polygon, layer->vmap ) ) {
+                       goto Fail;
+               }
+               layer = layer->next;
+       }
+
+       return object;
+
+Fail:
+       if ( failID ) {
+               *failID = id;
+       }
+       if ( fp ) {
+               if ( failpos ) {
+                       *failpos = _pico_memstream_tell( fp );
+               }
+       }
+       lwFreeObject( object );
+       return NULL;
+}
+
+int lwValidateObject( const char *filename, picoMemStream_t *fp, unsigned int *failID, int *failpos ){
+       unsigned int id, type;
+
+       /* open the file */
+
+       if ( !fp ) {
+               return PICO_PMV_ERROR_MEMORY;
+       }
+
+       /* read the first 12 bytes */
+
+       set_flen( 0 );
+       id       = getU4( fp );
+       /* formsize = */ getU4( fp );
+       type     = getU4( fp );
+       if ( 12 != get_flen() ) {
+               return PICO_PMV_ERROR_SIZE;
+       }
+
+       /* is this a LW object? */
+
+       if ( id != ID_FORM ) {
+               if ( failpos ) {
+                       *failpos = 12;
+               }
+               return PICO_PMV_ERROR_SIZE;
+       }
+
+       if ( type != ID_LWO2 ) {
+               if ( type == ID_LWOB ) {
+                       return lwValidateObject5( filename, fp, failID, failpos );
+               }
+               else {
+                       if ( failpos ) {
+                               *failpos = 12;
+                       }
+                       return PICO_PMV_ERROR_IDENT;
+               }
+       }
+
+       return PICO_PMV_OK;
+}