| 102 | | static bool skip_block( stmSrc_t *src, size_t cb ) |
|---|
| | 129 | static 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 | |
|---|
| | 166 | static 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 | |
|---|
| | 203 | static 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 | |
|---|
| | 233 | static 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 | |
|---|
| | 263 | static 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 | |
|---|
| | 295 | static bool skip_block( x42inStream_t *file_stream, size_t cb ) |
|---|
| 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 | |
|---|
| | 483 | X42_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 | |
|---|
| | 509 | static 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 |
|---|
| | 522 | X42_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 | |
|---|
| | 585 | ALWAYS_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 | |
|---|
| | 597 | X42_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 | |
|---|
| | 678 | X42_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 | |
|---|
| | 761 | static 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 |
|---|