#include "load_anim_data.h" #include static uint32_t s_num_entries = 0; static struct Animation *s_libsm64_mario_animations = NULL; #define ANIM_DATA_ADDRESS 0x004EC000 static uint16_t read_u16_be( uint8_t *p ) { return (uint32_t)p[0] << 8 | (uint32_t)p[1]; } static uint16_t read_s16_be( uint8_t *p ) { return (int16_t)read_u16_be( p ); } static uint32_t read_u32_be( uint8_t *p ) { return (uint32_t)p[0] << 24 | (uint32_t)p[1] << 16 | (uint32_t)p[2] << 8 | (uint32_t)p[3]; } void load_mario_anims_from_rom( uint8_t *rom ) { #define GET_OFFSET( n ) (read_u32_be(&((struct OffsetSizePair*)( rom + ANIM_DATA_ADDRESS + 8 + (n)*8 ))->offset)) #define GET_SIZE( n ) (read_u32_be(&((struct OffsetSizePair*)( rom + ANIM_DATA_ADDRESS + 8 + (n)*8 ))->size )) uint8_t *read_ptr = rom + ANIM_DATA_ADDRESS; s_num_entries = read_u32_be( read_ptr ); s_libsm64_mario_animations = malloc( s_num_entries * sizeof( struct Animation )); struct Animation *anims = s_libsm64_mario_animations; for( int i = 0; i < s_num_entries; ++i ) { read_ptr = rom + ANIM_DATA_ADDRESS + GET_OFFSET(i); anims[i].flags = read_s16_be( read_ptr ); read_ptr += 2; anims[i].animYTransDivisor = read_s16_be( read_ptr ); read_ptr += 2; anims[i].startFrame = read_s16_be( read_ptr ); read_ptr += 2; anims[i].loopStart = read_s16_be( read_ptr ); read_ptr += 2; anims[i].loopEnd = read_s16_be( read_ptr ); read_ptr += 2; anims[i].unusedBoneCount = read_s16_be( read_ptr ); read_ptr += 2; uint32_t values_offset = read_u32_be( read_ptr ); read_ptr += 4; uint32_t index_offset = read_u32_be( read_ptr ); read_ptr += 4; uint32_t end_offset = read_u32_be( read_ptr ); read_ptr = rom + ANIM_DATA_ADDRESS + GET_OFFSET(i) + index_offset; uint8_t *values_ptr = rom + ANIM_DATA_ADDRESS + GET_OFFSET(i) + values_offset; uint8_t *end_ptr = rom + ANIM_DATA_ADDRESS + GET_OFFSET(i) + end_offset; anims[i].index = malloc( values_offset - index_offset ); anims[i].values = malloc( end_offset - values_offset ); int j = 0; while( read_ptr < values_ptr ) { anims[i].index[j++] = read_u16_be( read_ptr ); read_ptr += 2; } j = 0; while( read_ptr < end_ptr ) { anims[i].values[j++] = read_u16_be( read_ptr ); read_ptr += 2; } } #undef GET_OFFSET #undef GET_SIZE } void load_mario_animation(struct MarioAnimation *a, u32 index) { if ((u32)a->currentAnimAddr != 1 + index) { a->currentAnimAddr = (u8*)(1 + index); a->targetAnim = &s_libsm64_mario_animations[index]; } } void unload_mario_anims( void ) { for( int i = 0; i < s_num_entries; ++i ) { free( s_libsm64_mario_animations[i].index ); free( s_libsm64_mario_animations[i].values ); } free( s_libsm64_mario_animations ); s_libsm64_mario_animations = NULL; s_num_entries = 0; }