#include "actor.h" #include #include "game.h" #include "player.h" #include "sdk/oam.h" #include "util.h" #define MAX_UNIQUE_MOBS 3 #define MAX_ACTORS 5 #define NUM_OAM_ENTRIES 40 #define TILE_WIDTH 8 #define FRAMES_PER_ANIM_FRAME 20 #define PLAYER_ACTOR_IDX 0 static actor_anim_state_t ANIM_TOTAL_FRAMES[] = {2, 1}; static uint8_t ANIM_OFFSETS[] = {0, 2 * 4}; static uint8_t mob_ids[MAX_UNIQUE_MOBS]; static uint8_t *mob_anim_data[MAX_UNIQUE_MOBS]; static actor_t all_actors[MAX_ACTORS]; static uint8_t actor_load_mob_anim_data(uint8_t mob_id); actor_t *PLAYER_ACTOR = &all_actors[PLAYER_ACTOR_IDX]; void actor_init(void) { actor_reset(); PLAYER_ACTOR->active = 1; PLAYER_ACTOR->flip = 0; PLAYER_ACTOR->anim = ANIM_STAND; PLAYER_ACTOR->frame_idx = 0; PLAYER_ACTOR->frame_counter = 0; PLAYER_ACTOR->x = PLAYER.x; PLAYER_ACTOR->y = PLAYER.y_hi; } void actor_reset(void) { for (uint8_t i = 0; i < ARRSIZE(mob_ids); ++i) { mob_ids[i] = 0xff; } for (uint8_t i = 0; i < ARRSIZE(all_actors); ++i) { all_actors[i].active = 0; } } actor_t *actor_create_mob(uint8_t id) { uint8_t mob_anim_idx = actor_load_mob_anim_data(id); if (mob_anim_idx == 0xff) { return NULL; } actor_t *a = NULL; for (uint8_t i = 0; i < ARRSIZE(all_actors); ++i) { if (all_actors[i].active) { continue; } a = &all_actors[i]; a->active = 1; a->flip = 0; a->mob_anim_idx = mob_anim_idx; a->anim = ANIM_STAND; a->frame_idx = 0; a->frame_counter = 0; break; } return a; } void actor_remove(actor_t *a) { a->active = 0; } void actor_update(void) { struct oam_entry *oam_ptr = &shadow_oam[0]; actor_t *a = &all_actors[0]; for (uint8_t i = 0; i < ARRSIZE(all_actors); ++i) { if (!a->active) { a++; continue; } a->frame_counter++; if (a->frame_counter == FRAMES_PER_ANIM_FRAME) { a->frame_counter = 0; a->frame_idx = (a->frame_idx + 1) % ANIM_TOTAL_FRAMES[a->anim]; } const uint8_t *anim_ptr; if (i == 0) { anim_ptr = &player_map[ANIM_OFFSETS[a->anim]]; } else { anim_ptr = mob_anim_data[a->mob_anim_idx]; } anim_ptr += a->frame_idx * 4; oam_ptr->y = a->y + 16; oam_ptr->x = a->x + 8; oam_ptr->tile = anim_ptr[a->flip] + TILE_INDEX_PLAYER; oam_ptr->attr = a->flip ? (1 << 5) : 0; oam_ptr++; oam_ptr->y = a->y + 16; oam_ptr->x = a->x + TILE_WIDTH + 8; oam_ptr->tile = anim_ptr[1 - a->flip] + TILE_INDEX_PLAYER; oam_ptr->attr = a->flip ? (1 << 5) : 0; oam_ptr++; oam_ptr->y = a->y + TILE_WIDTH + 16; oam_ptr->x = a->x + 8; oam_ptr->tile = anim_ptr[a->flip + 2] + TILE_INDEX_PLAYER; oam_ptr->attr = a->flip ? (1 << 5) : 0; oam_ptr++; oam_ptr->y = a->y + TILE_WIDTH + 16; oam_ptr->x = a->x + TILE_WIDTH + 8; oam_ptr->tile = anim_ptr[1 - a->flip + 2] + TILE_INDEX_PLAYER; oam_ptr->attr = a->flip ? (1 << 5) : 0; oam_ptr++; a++; } } static uint8_t actor_load_mob_anim_data(uint8_t mob_id) { uint8_t mob_anim_idx = 0xff; for (uint8_t i = 0; i < ARRSIZE(mob_ids); ++i) { if (mob_ids[i] == mob_id) { mob_anim_idx = i; break; } } if (mob_anim_idx == 0xff) { for (uint8_t i = 0; i < ARRSIZE(mob_ids); ++i) { if (mob_ids[i] == 0xff) { mob_ids[i] = mob_id; // TODO: Load data into mob_anim_data[i] mob_anim_idx = i; break; } } } return mob_anim_idx; }