Changeset 559

Show
Ignore:
Timestamp:
04/11/08 00:25:47 (9 months ago)
Author:
phill
Message:

o Undid random loader crap.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/morph-targets/libx42/include/x42.h

    r558 r559  
    316316*/ 
    317317X42_EXPORT x42header_t* X42_CALL x42_LoadHeaderFromBuffer( void *out_buffer, const void **file_data ); 
    318 //X42_EXPORT x42header_t* X42_CALL x42_LoadHeaderFromStream( void *out_buffer, x42inStream_t *file_stream ); 
     318X42_EXPORT x42header_t* X42_CALL x42_LoadHeaderFromStream( void *out_buffer, x42inStream_t *file_stream ); 
    319319 
    320320/* 
     
    339339 
    340340X42_EXPORT x42data_t* X42_CALL x42_LoadDataFromBuffer( void *out_buffer, const x42header_t *h, uint persist_flags, const void *file_data ); 
    341 //X42_EXPORT x42data_t* X42_CALL x42_LoadDataFromStream( void *out_buffer, const x42header_t *h, uint persist_flags, x42inStream_t *file_stream ); 
     341X42_EXPORT x42data_t* X42_CALL x42_LoadDataFromStream( void *out_buffer, const x42header_t *h, uint persist_flags, x42inStream_t *file_stream ); 
    342342 
    343343/*********************************** 
  • branches/morph-targets/libx42/libx42.vcproj

    r558 r559  
    912912                </File> 
    913913                <File 
    914                         RelativePath=".\load-int1.inc.h" 
    915                         > 
    916                 </File> 
    917                 <File 
    918                         RelativePath=".\load-int2.inc.h" 
    919                         > 
    920                 </File> 
    921                 <File 
    922914                        RelativePath=".\load.c" 
    923                         > 
    924                         <FileConfiguration 
    925                                 Name="Debug (.NET)|Win32" 
    926                                 > 
    927                                 <Tool 
    928                                         Name="VCCLCompilerTool" 
    929                                         GeneratePreprocessedFile="1" 
    930                                 /> 
    931                         </FileConfiguration> 
    932                 </File> 
    933                 <File 
    934                         RelativePath=".\load_old.c" 
    935915                        > 
    936916                </File> 
     
    10201000                </File> 
    10211001                <File 
    1022                         RelativePath=".\persist-datatypes.inc.h" 
    1023                         > 
    1024                 </File> 
    1025                 <File 
    10261002                        RelativePath=".\pose.c" 
    10271003                        > 
  • branches/morph-targets/libx42/load.c

    r558 r559  
    3232ALWAYS_INLINE f32 swap_f32( f32 f ) { union { u32 i; f32 f; } u; u.f = f; u.i = swap_u32( u.i ); return u.f; } 
    3333 
    34 typedef struct bufSrc_t 
    35 { 
    36         byte                    *buf; 
    37         size_t                 pos
    38 } bufSrc_t; 
    39  
    40 static bool align_buf_ptr( bufSrc_t *src, size_t a
    41 
    42         if( a ) 
    43         { 
    44                size_t ofs = ((a - (src->pos % a)) % a); 
    45  
    46                if( ofs ) 
    47                 { 
    48                         src->buf += ofs; 
    49                        src->pos += ofs; 
    50                 } 
     34X42_EXPORT bool X42_CALL x42_ValidateIdent( const x42Header_ident_t *h ) 
     35{ 
     36#ifndef LIBX42_NO_PARAM_VALIDATION 
     37        demand_rf( h != NULL, X42_ERR_BADPTR, "Expected valid x42Header pointer, got NULL instead." )
     38#endif 
     39 
     40       if( h->ident != X42_IDENT
     41                return false; 
     42 
     43        switch( h->version ) 
     44        { 
     45        case X42_VER_V5: 
     46        case X42_VER_V6: 
     47                break;     
     48 
     49        default: 
     50                return false; 
    5151        } 
    5252 
     
    5454} 
    5555 
    56 typedef struct stmSrc_t 
    57 
    58         x42inStream_t   stm; 
    59         size_t                  pos; 
    60 } stmSrc_t; 
    61  
    62 static size_t read_n( void *buffer, size_t cb, stmSrc_t *source ) 
     56X42_EXPORT bool X42_CALL x42_ValidateHeader( const x42header_t *h ) 
     57
     58#ifndef LIBX42_NO_PARAM_VALIDATION 
     59        demand_rf( h != NULL, X42_ERR_BADPTR, "Expected valid x42Header pointer, got NULL instead." ); 
     60#endif 
     61 
     62        if( !x42_ValidateIdent( &h->ident ) ) 
     63                return false; 
     64 
     65        return true; 
     66
     67 
     68typedef struct bufStm_t 
     69
     70        const byte              *pBuf; 
     71        size_t                  cbRead; 
     72} bufStm_t; 
     73 
     74static size_t X42_CALL bufStm_read( void *buffer, size_t cb, void *baton ) 
     75
     76        bufStm_t *s = (bufStm_t*)baton; 
     77 
     78        memcpy( buffer, s->pBuf, cb ); 
     79 
     80        s->pBuf += cb; 
     81        s->cbRead += cb; 
     82 
     83        return cb; 
     84
     85 
     86static size_t read_n( void *buffer, size_t cb, x42inStream_t *file_stream ) 
    6387{ 
    6488        byte *buf = (byte*)buffer; 
     
    6791        while( cb ) 
    6892        { 
    69                 size_t cr = source->stm.read_fn( buf, cb, source->stm.baton ); 
     93                size_t cr = file_stream->read_fn( buf, cb, file_stream->baton ); 
    7094 
    7195                demand_rv( cr <= cb, X42_ERR_BADSTREAM, "stream returned more data than requested", cbRead ); 
     
    78102        } 
    79103 
    80         source->pos += cbRead; 
    81104        return cbRead; 
    82105} 
    83106 
    84 static bool align_stream( stmSrc_t *src, size_t a ) 
    85 
    86         byte tmp[128]; 
    87         assert( a < sizeof( tmp ), X42_ERR_INTERNAL, "crazy huge alignment value" ); 
    88  
     107static bool align_stream( x42inStream_t *file_stream, size_t *pos, size_t a ) 
     108
    89109        if( a ) 
    90110        { 
    91                 size_t ofs = ((a - (src->pos % a)) % a); 
     111                size_t ofs = ((a - (*pos % a)) % a); 
     112                 
     113#ifdef LIBX42_NO_ALLOCA 
     114                byte tmp[128]; 
     115                 
     116                assert( a < sizeof( tmp ), X42_ERR_INTERNAL, "crazy huge alignment value" ); 
     117#else 
     118                byte *tmp = ofs ? (byte*)_alloca( ofs ) : NULL; 
     119#endif 
    92120 
    93121                if( ofs ) 
    94                         src->pos += read_n( tmp, ofs, src ); 
    95  
    96                 demand_rf( src->pos % a == 0, X42_ERR_INTERNAL, "failed to align stream - EOF?" ); 
    97         } 
    98  
     122                        *pos += read_n( tmp, ofs, file_stream ); 
     123 
     124                demand_rf( *pos % a == 0, X42_ERR_INTERNAL, "failed to align stream - EOF?" ); 
     125        } 
    99126        return true; 
    100127} 
    101128 
    102 static bool skip_block( stmSrc_t *src, size_t cb ) 
     129static bool read_packed_floats( x42inStream_t *file_stream, size_t *inPos, 
     130        const vec2_t *bounds, uint components, float *dest, uint elements, 
     131        size_t elemStride ) 
     132
     133        uint i; 
     134        float scale[4], bias[4]; 
     135        size_t cbElem; 
     136 
     137        if( !elements ) 
     138                return true; 
     139 
     140        for( i = 0; i < components; i++ ) 
     141        { 
     142                bias[i] = bounds[i][0]; 
     143                scale[i] = (bounds[i][1] - bounds[i][0]) / 65530.0F; 
     144        } 
     145 
     146        cbElem = sizeof( u16 ) * components; 
     147 
     148        for( i = 0; i < elements; i++ ) 
     149        { 
     150                uint c; 
     151                u16 buf[4]; 
     152 
     153                if( read_n( buf, cbElem, file_stream ) != cbElem ) 
     154                        return false; 
     155 
     156                for( c = 0; c < components; c++ ) 
     157                        dest[c] = buf[c] * scale[c] + bias[c]; 
     158 
     159                dest = (float*)((byte*)dest + elemStride); 
     160        } 
     161 
     162        *inPos += cbElem * elements; 
     163        return true; 
     164
     165 
     166static bool read_packed_floats_swp( x42inStream_t *file_stream, size_t *inPos, 
     167        const vec2_t *bounds, uint components, float *dest, uint elements, 
     168        size_t elemStride ) 
     169
     170        uint i; 
     171        float scale[4], bias[4]; 
     172        size_t cbElem; 
     173 
     174        if( !elements ) 
     175                return true; 
     176 
     177        for( i = 0; i < components; i++ ) 
     178        { 
     179                bias[i] = bounds[i][0]; 
     180                scale[i] = (bounds[i][1] - bounds[i][0]) / 65530.0F; 
     181        } 
     182 
     183        cbElem = sizeof( u16 ) * components; 
     184 
     185        for( i = 0; i < elements; i++ ) 
     186        { 
     187                uint c; 
     188                u16 buf[4]; 
     189 
     190                if( read_n( buf, cbElem, file_stream ) != cbElem ) 
     191                        return false; 
     192 
     193                for( c = 0; c < components; c++ ) 
     194                        dest[c] = (float)(int)swap_u16( buf[c] ) * scale[c] + bias[c]; 
     195 
     196                dest = (float*)((byte*)dest + elemStride); 
     197        } 
     198 
     199        *inPos += cbElem * elements; 
     200        return true; 
     201
     202 
     203static bool read_packed_floats_s16n( x42inStream_t *file_stream, size_t *inPos, 
     204        uint components, float *dest, uint elements, 
     205        size_t elemStride ) 
     206
     207        uint i; 
     208        size_t cbElem; 
     209 
     210        if( !elements ) 
     211                return true; 
     212 
     213        cbElem = sizeof( s16 ) * components; 
     214 
     215        for( i = 0; i < elements; i++ ) 
     216        { 
     217                uint c; 
     218                s16 buf[4]; 
     219 
     220                if( read_n( buf, cbElem, file_stream ) != cbElem ) 
     221                        return false; 
     222 
     223                for( c = 0; c < components; c++ ) 
     224                        dest[c] = X42_FLOAT_S16N_UNPACK( buf[c] ); 
     225 
     226                dest = (float*)((byte*)dest + elemStride); 
     227        } 
     228 
     229        *inPos += cbElem * elements; 
     230        return true; 
     231
     232 
     233static bool read_packed_floats_s16n_swp( x42inStream_t *file_stream, size_t *inPos, 
     234        uint components, float *dest, uint elements, 
     235        size_t elemStride ) 
     236
     237        uint i; 
     238        size_t cbElem; 
     239 
     240        if( !elements ) 
     241                return true; 
     242 
     243        cbElem = sizeof( s16 ) * components; 
     244 
     245        for( i = 0; i < elements; i++ ) 
     246        { 
     247                uint c; 
     248                s16 buf[4]; 
     249 
     250                if( read_n( buf, cbElem, file_stream ) != cbElem ) 
     251                        return false; 
     252 
     253                for( c = 0; c < components; c++ ) 
     254                        dest[c] = X42_FLOAT_S16N_UNPACK( swap_s16( buf[c] ) ); 
     255 
     256                dest = (float*)((byte*)dest + elemStride); 
     257        } 
     258 
     259        *inPos += cbElem * elements; 
     260        return true; 
     261
     262 
     263static bool read_packed_floats_s8n( x42inStream_t *file_stream, size_t *inPos, 
     264        uint components, float *dest, uint elements, 
     265        size_t elemStride ) 
     266
     267        uint i; 
     268        size_t cbElem; 
     269 
     270        if( !elements ) 
     271                return true; 
     272 
     273        cbElem = sizeof( s8 ) * components; 
     274 
     275        for( i = 0; i < elements; i++ ) 
     276        { 
     277                uint c; 
     278                s8 buf[8]; 
     279 
     280                if( read_n( buf, cbElem, file_stream ) != cbElem ) 
     281                        return false; 
     282 
     283                for( c = 0; c < components; c++ ) 
     284                        dest[c] = X42_FLOAT_S8N_UNPACK( buf[c] ); 
     285 
     286                dest = (float*)((byte*)dest + elemStride); 
     287        } 
     288 
     289        *inPos += cbElem * elements; 
     290        return true; 
     291
     292 
     293#define read_packed_floats_s8n_swp read_packed_floats_s8n 
     294 
     295static bool skip_block( x42inStream_t *file_stream, size_t cb ) 
    103296{ 
    104297        size_t len; 
     
    114307                        len = sizeof( tmp ); 
    115308 
    116                 cbR = read_n( tmp, cbRq, src ); 
     309                cbR = read_n( tmp, cbRq, file_stream ); 
    117310 
    118311                demand_rf( cbR != 0, X42_ERR_INTERNAL, "failed to skip stream bytes - EOF?" ); 
     
    124317} 
    125318 
    126 /******************************************************** 
    127         Swapped/Unswapped loader routines. 
    128  
    129         Functions that vary only by whether they swap or not 
    130         are defined in load-int1.inc. 
    131  
    132         This file is included twice, once for unswapped 
    133         reading, and once for swapped. The macros around the 
    134         include site define the behavior. 
    135 ********************************************************/ 
    136  
    137 #define read_s16( l ) (l) 
    138 #define read_u16( l ) (l) 
    139 #define read_u32( l ) (l) 
    140 #define read_f32( f ) (f) 
    141  
    142 #define SWP_EXT dir 
    143  
    144 #include "load-int1.inc.h" 
    145  
    146 #undef SWP_EXT 
    147  
    148 #undef read_f32 
    149 #undef read_u32 
    150 #undef read_u16 
    151 #undef read_s16 
    152  
    153 #define read_s16( l ) swap_s16( l ) 
    154 #define read_u16( l ) swap_u16( l ) 
    155 #define read_u32( l ) swap_u32( l ) 
    156 #define read_f32( f ) swap_f32( f ) 
    157  
    158 #define SWP_EXT swp 
    159  
    160 #include "load-int1.inc.h" 
    161  
    162 #undef SWP_EXT 
    163  
    164 #undef read_f32 
    165 #undef read_u32 
    166 #undef read_u16 
    167 #undef read_s16 
    168  
    169 X42_EXPORT bool X42_CALL x42_ValidateIdent( const x42Header_ident_t *h ) 
    170 
     319X42_EXPORT x42header_t* X42_CALL x42_LoadHeaderFromStream( void *out_buffer, x42inStream_t *file_stream ) 
     320
     321        bool swap; 
     322 
     323        x42Header_ident_t ident; 
     324        x42header_t *ret; 
     325 
    171326#ifndef LIBX42_NO_PARAM_VALIDATION 
    172         demand_rf( h != NULL, X42_ERR_BADPTR, "Expected valid x42Header pointer, got NULL instead." ); 
     327        demand_rn( out_buffer != NULL, X42_ERR_BADPTR, "out_buffer is NULL" ); 
     328        demand_rn( file_stream != NULL, X42_ERR_BADPTR, "file_stream is NULL" ); 
    173329#endif 
    174330 
    175         if( h->ident != X42_IDENT ) 
    176                 return false; 
    177  
    178         switch( h->version ) 
     331#define read_check() demand_rn( stat, X42_ERR_INTERNAL, "failed to read from stream" ) 
     332#define checked_read( buf, size ) demand_rn( read_n( buf, size, file_stream ) == (size_t)(size), X42_ERR_INTERNAL, "failed to read from stream" ) 
     333 
     334        checked_read( &ident, sizeof( ident ) ); 
     335 
     336        swap = ident.ident == swap_u32( X42_IDENT ); 
     337        if( swap ) 
     338        { 
     339                ident.ident = swap_u32( ident.ident ); 
     340                ident.version = swap_u32( ident.version ); 
     341        } 
     342 
     343        demand_rn( x42_ValidateIdent( &ident ), X42_ERR_BADDATA, "invalid x42 data" ); 
     344 
     345        ret = (x42header_t*)out_buffer; 
     346        memset( ret, 0, sizeof( x42header_t ) ); 
     347 
     348        ret->ident = ident; 
     349        ret->runFlags = swap ? X42_RF_LOAD_SWAPPED : 0; 
     350 
     351        switch( ident.version ) 
    179352        { 
    180353        case X42_VER_V5: 
    181         case X42_VER_V6: 
    182                 break;      
    183  
    184         default: 
    185                 return false; 
    186         } 
     354                { 
     355                        x42Header_v5_t in; 
     356                        checked_read( &in, sizeof( in ) ); 
     357 
     358                        ret->modelFlags = in.modelFlags; 
     359                         
     360                        ret->baseFrame = in.baseFrame; 
     361                        ret->numFrames = in.numFrames; 
     362                         
     363                        ret->nameBlobLen = in.nameBlobLen; 
     364 
     365                        ret->numBones = in.numBones; 
     366                        ret->numAnimGroups = in.numAnimGroups; 
     367 
     368                        ret->numPosValues = in.numPosValues; 
     369                        ret->numScaleValues = in.numScaleValues; 
     370                        ret->numRotValues = in.numRotValues; 
     371 
     372                        ret->keyStreamLength = in.keyStreamLength; 
     373                        ret->numAnims = in.numAnims; 
     374 
     375                        ret->numTags = in.numTags; 
     376                        ret->numInfluences = in.numInfluences; 
     377 
     378                        ret->numLods = in.numLods; 
     379                        ret->numGroups = in.numGroups; 
     380                        ret->numMorphTargets = 0; 
     381 
     382                        ret->numVerts = in.numVerts; 
     383                        ret->numIndices = in.numIndices; 
     384                        ret->numMorphDeltas = 0; 
     385 
     386                        ret->boundingSphere = in.boundingSphere; 
     387                        ret->boundingBox = in.boundingBox; 
     388                } 
     389                break; 
     390 
     391                case X42_VER_V6: 
     392                { 
     393                        x42Header_v6_t in; 
     394                        checked_read( &in, sizeof( in ) ); 
     395 
     396                        ret->modelFlags = in.modelFlags; 
     397                         
     398                        ret->baseFrame = in.baseFrame; 
     399                        ret->numFrames = in.numFrames; 
     400                         
     401                        ret->nameBlobLen = in.nameBlobLen; 
     402 
     403                        ret->numBones = in.numBones; 
     404                        ret->numAnimGroups = in.numAnimGroups; 
     405 
     406                        ret->numPosValues = in.numPosValues; 
     407                        ret->numScaleValues = in.numScaleValues; 
     408                        ret->numRotValues = in.numRotValues; 
     409 
     410                        ret->keyStreamLength = in.keyStreamLength; 
     411                        ret->numAnims = in.numAnims; 
     412 
     413                        ret->numTags = in.numTags; 
     414                        ret->numInfluences = in.numInfluences; 
     415 
     416                        ret->numLods = in.numLods; 
     417                        ret->numGroups = in.numGroups; 
     418                        ret->numMorphTargets = in.numMorphTargets; 
     419 
     420                        ret->numVerts = in.numVerts; 
     421                        ret->numIndices = in.numIndices; 
     422                        ret->numMorphDeltas = in.numMorphDeltas; 
     423 
     424                        ret->boundingSphere = in.boundingSphere; 
     425                        ret->boundingBox = in.boundingBox; 
     426                } 
     427                break; 
     428 
     429        NO_DEFAULT; 
     430        } 
     431 
     432        if( swap ) 
     433        { 
     434                ret->modelFlags = swap_u16( ret->modelFlags ); 
     435 
     436                ret->baseFrame = swap_s16( ret->baseFrame ); 
     437                ret->numFrames = swap_u16( ret->numFrames ); 
     438 
     439                ret->nameBlobLen = swap_u16( ret->nameBlobLen ); 
     440 
     441                ret->numBones = swap_u16( ret->numBones ); 
     442                ret->numAnimGroups = swap_u16( ret->numAnimGroups ); 
     443 
     444                ret->numPosValues = swap_u16( ret->numPosValues ); 
     445                ret->numScaleValues = swap_u16( ret->numScaleValues ); 
     446                ret->numRotValues = swap_u16( ret->numRotValues ); 
     447 
     448                ret->keyStreamLength = swap_u16( ret->keyStreamLength ); 
     449                ret->numAnims = swap_u16( ret->numAnims ); 
     450 
     451                ret->numTags = swap_u16( ret->numTags ); 
     452                ret->numInfluences = swap_u16( ret->numInfluences ); 
     453 
     454                ret->numLods = swap_u16( ret->numLods ); 
     455                ret->numGroups = swap_u16( ret->numGroups ); 
     456                ret->numMorphTargets = swap_u16( ret->numMorphTargets ); 
     457 
     458                ret->numVerts = swap_u32( ret->numVerts ); 
     459                ret->numIndices = swap_u32( ret->numIndices ); 
     460                ret->numMorphDeltas = swap_u32( ret->numMorphDeltas ); 
     461 
     462                ret->boundingBox.mins[0] = swap_f32( ret->boundingBox.mins[0] ); 
     463                ret->boundingBox.mins[1] = swap_f32( ret->boundingBox.mins[1] ); 
     464                ret->boundingBox.mins[2] = swap_f32( ret->boundingBox.mins[2] ); 
     465 
     466                ret->boundingBox.maxs[0] = swap_f32( ret->boundingBox.maxs[0] ); 
     467                ret->boundingBox.maxs[1] = swap_f32( ret->boundingBox.maxs[1] ); 
     468                ret->boundingBox.maxs[2] = swap_f32( ret->boundingBox.maxs[2] ); 
     469 
     470                ret->boundingSphere.center[0] = swap_f32( ret->boundingSphere.center[0] ); 
     471                ret->boundingSphere.center[1] = swap_f32( ret->boundingSphere.center[1] ); 
     472                ret->boundingSphere.center[2] = swap_f32( ret->boundingSphere.center[2] ); 
     473 
     474                ret->boundingSphere.radius = swap_f32( ret->boundingSphere.radius ); 
     475        } 
     476 
     477#undef checked_read 
     478#undef read_check 
     479 
     480        return ret; 
     481
     482 
     483X42_EXPORT x42header_t* X42_CALL x42_LoadHeaderFromBuffer( void *out_buffer, const void **file_data ) 
     484
     485        bufStm_t s; 
     486        x42inStream_t stm; 
     487 
     488        x42header_t *ret; 
     489 
     490#ifndef LIBX42_NO_PARAM_VALIDATION 
     491        demand_rn( out_buffer != NULL, X42_ERR_BADPTR, "out_buffer is NULL" ); 
     492        demand_rn( file_data != NULL, X42_ERR_BADPTR, "file_data is NULL" ); 
     493        demand_rn( *file_data != NULL, X42_ERR_BADPTR, "*file_data is NULL" ); 
     494#endif 
     495 
     496        s.pBuf = (byte*)*file_data; 
     497        s.cbRead = 0; 
     498 
     499        stm.read_fn = bufStm_read; 
     500        stm.baton = &s; 
     501 
     502        ret = x42_LoadHeaderFromStream( out_buffer, &stm ); 
     503 
     504        *file_data = s.pBuf; 
     505 
     506        return ret; 
     507
     508 
     509static void fixup_persist_flags( uint *pf, const x42header_t *h ) 
     510
     511        if( !(h->modelFlags & X42_MF_HAS_NORMALS) ) 
     512                *pf &= ~X42_PERSIST_NORMALS; 
     513        if( !(h->modelFlags & X42_MF_HAS_TANGENT_BASIS) ) 
     514                *pf &= ~X42_PERSIST_TANGENT_BASIS; 
     515        if( !(h->modelFlags &X42_MF_HAS_TEXTURE_COORDINATES) ) 
     516                *pf &= ~X42_PERSIST_TEXTURE_COORDINATES; 
     517        if( !(h->modelFlags & X42_MF_HAS_COLORS) ) 
     518                *pf &= ~X42_PERSIST_COLORS; 
     519
     520 
     521//get the size of buffer a given x42 file (represented by its header) will use in memory 
     522X42_EXPORT size_t X42_CALL x42_GetLoadedSize( const x42header_t *h, uint persist_flags ) 
     523
     524        size_t ret; 
     525 
     526#ifndef LIBX42_NO_PARAM_VALIDATION 
     527        demand_rz( h != NULL, X42_ERR_BADPTR, "Expected valid x42Header pointer, got NULL instead." ); 
     528        demand_rz( x42_ValidateHeader( h ), X42_ERR_BADDATA, "Invalid x42 file header." ); 
     529#endif 
     530 
     531        fixup_persist_flags( &persist_flags, h ); 
     532 
     533        ret = sizeof( x42data_t ); 
     534 
     535        /* 
     536                The x42data_t struct always resides at the start 
     537                of the buffer. Sneak in 16 bytes so that the buffer 
     538                pointer can be pushed to a 16-byte boundary before 
     539                we lay out the rest of the data. 
     540        */ 
     541        ret += sizeof( float[4] ); 
     542 
     543        ret = align( ret, sizeof( void* ) )                     + sizeof( x42keyStreamEntry_t )         * h->keyStreamLength; 
     544        ret = align( ret, sizeof( void* ) )                     + sizeof( x42animation_t )                      * h->numAnims; 
     545         
     546        ret = align( ret, sizeof( float ) )                     + sizeof( vec3_t )                                      * h->numPosValues; 
     547        ret = align( ret, sizeof( float ) )                     + sizeof( vec3_t )                                      * h->numScaleValues; 
     548        ret = align( ret, sizeof( float ) )                     + sizeof( quat_t )                                      * h->numRotValues; 
     549         
     550        ret = align( ret, sizeof( void* ) )                     + sizeof( x42animGroup_t )                      * h->numAnimGroups; 
     551        ret = align( ret, sizeof( void* ) )                     + sizeof( x42bone_t )                           * h->numBones; 
     552        ret = align( ret, sizeof( void* ) )                     + sizeof( u8 )                                          * h->numBones; 
     553         
     554        ret = align( ret, sizeof( void* ) )                     + sizeof( x42influence_t )                      * h->numInfluences; 
     555        ret = align( ret, sizeof( void* ) )                     + sizeof( x42tag_t )                            * h->numTags; 
     556         
     557        ret = align( ret, sizeof( void* ) )                     + sizeof( x42lodRange_t )                       * h->numLods; 
     558        ret = align( ret, sizeof( void* ) )                     + sizeof( x42group_t )                          * h->numGroups; 
     559        ret = align( ret, sizeof( void* ) )                     + sizeof( x42morphTarget_t )            * h->numMorphTargets; 
     560         
     561        ret = align( ret, sizeof( float[4] ) )          + sizeof( x42vertAnim_t )                       * h->numVerts; 
     562        if( persist_flags & X42_PERSIST_NORMALS ) 
     563                ret = align( ret, sizeof( float[4] ) )  + sizeof( x42vertNormal_t )                     * h->numVerts; 
     564        if( persist_flags & X42_PERSIST_TANGENT_BASIS ) 
     565                ret = align( ret, sizeof( float[4] ) )  + sizeof( x42vertTangent_t )            * h->numVerts; 
     566        if( persist_flags & X42_PERSIST_TEXTURE_COORDINATES ) 
     567                ret = align( ret, sizeof( float ) )             + sizeof( vec2_t )                                      * h->numVerts; 
     568        if( persist_flags & X42_PERSIST_COLORS ) 
     569                ret = align( ret, sizeof( rgba_t ) )    + sizeof( rgba_t )                                      * h->numVerts; 
     570 
     571        ret = align( ret, sizeof( x42index_t ) )        + sizeof( x42index_t )                          * h->numIndices; 
     572         
     573        ret = align( ret, sizeof( x42index_t ) )        + sizeof( x42index_t )                          * h->numMorphDeltas; 
     574        ret = align( ret, sizeof( float[4] ) )          + sizeof( vec4_t )                                      * h->numMorphDeltas; 
     575        if( persist_flags & X42_PERSIST_NORMALS ) 
     576                ret = align( ret, sizeof( float[4] ) )  + sizeof( x42morphNormal_t )            * h->numMorphDeltas; 
     577        if( persist_flags & X42_PERSIST_TANGENT_BASIS ) 
     578                ret = align( ret, sizeof( float[4] ) )  + sizeof( x42morphTangent_t )           * h->numMorphDeltas; 
     579 
     580        ret += sizeof( char ) * h->nameBlobLen; 
     581 
     582        return ret; 
     583
     584 
     585ALWAYS_INLINE void* advance_out_internal( byte **out, size_t a, size_t cb ) 
     586
     587        void *ret; 
     588 
     589        *out = align_ptr( *out, a ); 
     590        ret = *out; 
     591 
     592        *out += cb; 
     593 
     594        return ret; 
     595
     596 
     597X42_EXPORT x42data_t* X42_CALL x42_SetupBufferPointers( void *out_buffer, const x42header_t *h, uint persist_flags ) 
     598
     599        byte *out; 
     600        x42data_t *ret; 
     601 
     602#ifndef LIBX42_NO_PARAM_VALIDATION 
     603        demand_rn( out_buffer != NULL, X42_ERR_BADPTR, "out_buffer is NULL" ); 
     604        demand_rn( h != NULL, X42_ERR_BADPTR, "Expected valid x42Header pointer, got NULL instead." ); 
     605        demand_rn( x42_ValidateHeader( h ), X42_ERR_BADDATA, "Invalid x42 file header." ); 
     606#endif 
     607 
     608        fixup_persist_flags( &persist_flags, h ); 
     609 
     610#define advance_out( a, cb ) advance_out_internal( &out, a, cb ) 
     611 
     612        ret = (x42data_t*)out_buffer; 
     613        memcpy( &ret->header, h, sizeof( x42header_t ) ); 
     614 
     615        out = (byte*)(ret + 1); 
     616        out = align_ptr( out, sizeof( float[4] ) ); 
     617 
     618        ret->keyStream          = (x42keyStreamEntry_t*)advance_out( sizeof( void* ),   sizeof( x42keyStreamEntry_t )*h->keyStreamLength ); 
     619        ret->animations         = (x42animation_t*)             advance_out( sizeof( void* ),   sizeof( x42animation_t )        * h->numAnims ); 
     620 
     621        ret->posValues          = (vec3_t*)                             advance_out( sizeof( float ),   sizeof( vec3_t )                        * h->numPosValues ); 
     622        ret->scaleValues        = (vec3_t*)                             advance_out( sizeof( float ),   sizeof( vec3_t )                        * h->numScaleValues ); 
     623        ret->rotValues          = (quat_t*)                             advance_out( sizeof( float ),   sizeof( quat_t )                        * h->numRotValues ); 
     624 
     625        ret->animGroups         = (x42animGroup_t*)             advance_out( sizeof( void* ),   sizeof( x42animGroup_t )        * h->numAnimGroups ); 
     626        ret->bones                      = (x42bone_t*)                  advance_out( sizeof( void* ),   sizeof( x42bone_t )                     * h->numBones ); 
     627        ret->boneGroups         = (u8*)                                 advance_out( sizeof( void* ),   sizeof( u8 )                            * h->numBones ); 
     628 
     629        ret->influences         = (x42influence_t*)             advance_out( sizeof( void* ),   sizeof( x42influence_t )        * h->numInfluences ); 
     630        ret->tags                       = (x42tag_t*)                   advance_out( sizeof( void* ),   sizeof( x42tag_t )                      * h->numTags ); 
     631 
     632        ret->lods                       = (x42lodRange_t*)              advance_out( sizeof( void* ),   sizeof( x42lodRange_t )         * h->numLods ); 
     633        ret->groups                     = (x42group_t*)                 advance_out( sizeof( void* ),   sizeof( x42group_t )            * h->numGroups ); 
     634        ret->morphTargets       = (x42morphTarget_t*)   advance_out( sizeof( void* ),   sizeof( x42morphTarget_t )      * h->numMorphTargets ); 
     635 
     636        ret->vertPos            = (x42vertAnim_t*)              advance_out( sizeof( float[4] ),sizeof( x42vertAnim_t )         * h->numVerts ); 
     637 
     638        if( persist_flags & X42_PERSIST_NORMALS ) 
     639                ret->vertNorm   = (x42vertNormal_t*)    advance_out( sizeof( float[4] ),sizeof( x42vertNormal_t )       * h->numVerts ); 
     640        else 
     641                ret->vertNorm = NULL; 
     642 
     643        if( persist_flags & X42_PERSIST_TANGENT_BASIS ) 
     644                ret->vertTan    = (x42vertTangent_t*)   advance_out( sizeof( float[4] ),sizeof( x42vertTangent_t )      * h->numVerts ); 
     645        else 
     646                ret->vertTan = NULL; 
     647 
     648        if( persist_flags & X42_PERSIST_TEXTURE_COORDINATES ) 
     649                ret->vertTc = (vec2_t*)                                 advance_out( sizeof( float ),           sizeof( vec2_t )                        * h->numVerts ); 
     650        else 
     651                ret->vertTc = NULL; 
     652 
     653        if( persist_flags & X42_PERSIST_COLORS ) 
     654                ret->vertCl = (rgba_t*)                                 advance_out( sizeof( rgba_t ),          sizeof( rgba_t )                        * h->numVerts ); 
     655        else 
     656                ret->vertCl = NULL; 
     657 
     658        ret->indices = (x42index_t*)                            advance_out( sizeof( x42index_t ),      sizeof( x42index_t )            * h->numIndices ); 
     659 
     660        ret->morphIndices       = (x42index_t*)                 advance_out( sizeof( x42index_t ),      sizeof( x42index_t )            * h->numMorphDeltas ); 
     661        ret->morphPos           = (vec4_t*)                             advance_out( sizeof( float[4] ),        sizeof( vec4_t )                        * h->numMorphDeltas ); 
     662 
     663        if( persist_flags & X42_PERSIST_NORMALS ) 
     664                ret->morphNorm  = (x42morphNormal_t*)   advance_out( sizeof( float[4] ),        sizeof( x42morphNormal_t )      * h->numMorphDeltas ); 
     665        else 
     666                ret->morphNorm = NULL; 
     667 
     668        if( persist_flags & X42_PERSIST_TANGENT_BASIS ) 
     669                ret->morphTan   = (x42morphTangent_t*)  advance_out( sizeof( float[4] ),        sizeof( x42morphTangent_t )     * h->numMorphDeltas ); 
     670        else 
     671                ret->morphTan = NULL; 
     672 
     673        ret->strings = (char*)                                          advance_out( sizeof( char ),            sizeof( char )                          * h->nameBlobLen ); 
     674 
     675        return ret; 
     676
     677 
     678X42_EXPORT x42data_t* x42_CopyRuntimeData( void *out_buffer, const x42data_t *src ) 
     679
     680        uint persist_flags; 
     681        const x42header_t *h; 
     682        x42data_t *ret; 
     683         
     684        x42data_t tmp; 
     685 
     686#ifndef LIBX42_NO_PARAM_VALIDATION 
     687        demand_rn( out_buffer != NULL, X42_ERR_BADPTR, "out_buffer is NULL" ); 
     688        demand_rn( src != NULL, X42_ERR_BADPTR, "Expected valid x42data_t pointer, got NULL instead." ); 
     689#endif 
     690 
     691        //src may be unaligned - copy it to stack before reading anything from it 
     692        memcpy( &tmp, src, sizeof( x42data_t ) ); 
     693        src = &tmp; 
     694 
     695#ifndef LIBX42_NO_PARAM_VALIDATION 
     696        demand_rn( x42_ValidateHeader( &src->header ), X42_ERR_BADDATA, "Invalid x42 file header." ); 
     697#endif 
     698 
     699        h = &src->header; 
     700 
     701        persist_flags = 0; 
     702        if( src->vertNorm ) 
     703                persist_flags |= X42_PERSIST_NORMALS; 
     704        if( src->vertTan ) 
     705                persist_flags |= X42_PERSIST_TANGENT_BASIS; 
     706        if( src->vertTc ) 
     707                persist_flags |= X42_PERSIST_TEXTURE_COORDINATES; 
     708        if( src->vertCl ) 
     709                persist_flags |= X42_PERSIST_COLORS; 
     710 
     711        ret = x42_SetupBufferPointers( out_buffer, h, persist_flags ); 
     712 
     713        memcpy( ret->keyStream,         src->keyStream,         sizeof( x42keyStreamEntry_t )   * h->keyStreamLength ); 
     714        memcpy( ret->animations,        src->animations,        sizeof( x42animation_t )                * h->numAnims ); 
     715         
     716        memcpy( ret->posValues,         src->posValues,         sizeof( vec3_t )                                * h->numPosValues ); 
     717        memcpy( ret->scaleValues,       src->scaleValues,       sizeof( vec3_t )                                * h->numScaleValues ); 
     718        memcpy( ret->rotValues,         src->rotValues,         sizeof( quat_t )                                * h->numRotValues ); 
     719 
     720        memcpy( ret->animGroups,        src->animGroups,        sizeof( x42animGroup_t )                * h->numAnimGroups ); 
     721        memcpy( ret->bones,                     src->bones,                     sizeof( x42bone_t )                             * h->numBones ); 
     722        memcpy( ret->boneGroups,        src->boneGroups,        sizeof( u8 )                                    * h->numBones ); 
     723         
     724        memcpy( ret->influences,        src->influences,        sizeof( x42influence_t )                * h->numInfluences ); 
     725        memcpy( ret->tags,                      src->tags,                      sizeof( x42tag_t )                              * h->numTags ); 
     726 
     727        memcpy( ret->lods,                      src->lods,                      sizeof( x42lodRange_t )                 * h->numLods ); 
     728        memcpy( ret->groups,            src->groups,            sizeof( x42group_t )                    * h->numGroups ); 
     729        memcpy( ret->morphTargets,      src->morphTargets,      sizeof( x42morphTarget_t )              * h->numMorphTargets ); 
     730 
     731        memcpy( ret->vertPos,           src->vertPos,           sizeof( x42vertAnim_t )                 * h->numVerts ); 
     732         
     733        if( src->vertNorm ) 
     734                memcpy( ret->vertNorm,  src->vertNorm,          sizeof( x42vertNormal_t )               * h->numVerts ); 
     735 
     736        if( src->vertTan ) 
     737                memcpy( ret->vertTan,   src->vertTan,           sizeof( x42vertTangent_t )              * h->numVerts ); 
     738 
     739        if( src->vertTc ) 
     740                memcpy( ret->vertTc,    src->vertTc,            sizeof( vec2_t )                                * h->numVerts ); 
     741 
     742        if( src->vertCl ) 
     743                memcpy( ret->vertCl,    src->vertCl,            sizeof( rgba_t )                                * h->numVerts ); 
     744 
     745        memcpy( ret->indices,           src->indices,           sizeof( x42index_t )                    * h->numIndices ); 
     746 
     747        memcpy( ret->morphIndices,      src->morphIndices,      sizeof( x42index_t )                    * h->numMorphDeltas ); 
     748        memcpy( ret->morphPos,          src->morphPos,          sizeof( vec4_t )                                * h->numMorphDeltas ); 
     749 
     750        if( src->morphNorm ) 
     751                memcpy( ret->morphNorm, src->morphNorm,         sizeof( x42morphNormal_t )              * h->numMorphDeltas ); 
     752 
     753        if( src->morphTan ) 
     754                memcpy( ret->morphTan,  src->morphTan,          sizeof( x42morphTangent_t )             * h->numMorphDeltas ); 
     755 
     756        memcpy( CONST_CAST( char, ret->strings ), src->strings,         sizeof( char )          * h->nameBlobLen ); 
     757 
     758        return ret; 
     759
     760 
     761static bool load_direct( x42data_t *ret, const x42header_t *h, 
     762        x42inStream_t *file_stream, size_t inPos ) 
     763
     764        uint i; 
     765 
     766        bool stat; 
     767        x42PackHeader_v6_t pack; 
     768 
     769        /* 
     770                Stream read helper macros begin here... 
     771        */ 
     772 
     773#define read_check() demand_rf( stat, X42_ERR_INTERNAL, "failed to read from stream" ) 
     774 
     775#define checked_read( buf, type, count )                                                                        \ 
     776        if( const_cond_true )                                                                                                   \ 
     777        {                                                                                                                                               \ 
     778                size_t cb = sizeof( type ) * count;                                                                     \ 
     779                stat = read_n( buf, cb, file_stream ) == cb;                                            \ 
     780                                                                                                        &nbs