Files
libsm64/src/load_anim_data.c
T
2020-10-27 15:11:12 -06:00

102 lines
3.1 KiB
C

#include "load_anim_data.h"
#include <stdlib.h>
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;
}