// B4 - Enemy instructions, sets, drop chances, resistances (complete) #include "ida_types.h" #include "variables.h" #include "funcs.h" #include "enemy_types.h" #define kCreateSprite_Ilists ((uint16*)RomFixedPtr(0xb4bda8)) uint16 CreateSpriteAtPos(uint16 x_r18, uint16 y_r20, uint16 ilist_r22, uint16 pal_r24) { // 0xB4BC26 int v0 = 62; while (sprite_instr_list_ptrs[v0 >> 1]) { v0 -= 2; if ((v0 & 0x8000) != 0) return 0xffff; } int v1 = v0 >> 1; sprite_palettes[v1] = 0; sprite_x_subpos[v1] = 0; sprite_y_subpos[v1] = 0; sprite_disable_flag[v1] = 0; sprite_x_pos[v1] = x_r18; sprite_y_pos[v1] = y_r20; sprite_palettes[v1] = pal_r24; uint16 v2 = kCreateSprite_Ilists[ilist_r22]; sprite_instr_list_ptrs[v1] = v2; sprite_instr_timer[v1] = *(uint16 *)RomPtr_B4(v2); // R18 = v0; return v0; } void CallSpriteObjectInstr(uint32 ea) { switch (ea) { case fnSpriteObject_Instr_RepeatLast: SpriteObject_Instr_RepeatLast(); return; // 0xb4bcf0 case fnSpriteObject_Instr_Terminate: SpriteObject_Instr_Terminate(); return; // 0xb4bd07 case fnSpriteObject_Instr_Goto: SpriteObject_Instr_Goto(); return; // 0xb4bd12 default: Unreachable(); } } void HandleSpriteObjects(void) { // 0xB4BC82 uint16 v1; if (debug_time_frozen_for_enemies | time_is_frozen_flag) return; sprite_object_index = 62; do { int v0; v0 = sprite_object_index >> 1; if (!sprite_instr_list_ptrs[v0] || (sprite_disable_flag[v0] & 1) != 0) continue; v1 = sprite_instr_timer[v0]; if (sign16(v1)) { BREAKLABEL: CallSpriteObjectInstr(v1 | 0xB40000); continue; } sprite_instr_timer[v0] = v1 - 1; if (v1 == 1) { uint16 v3 = sprite_instr_list_ptrs[v0] + 4; sprite_instr_list_ptrs[v0] = v3; v1 = *(uint16 *)RomPtr_B4(v3); if (sign16(v1)) goto BREAKLABEL; sprite_instr_timer[sprite_object_index >> 1] = v1; } } while (!sign16(sprite_object_index -= 2)); } void SpriteObject_Instr_RepeatLast(void) { // 0xB4BCF0 int v2 = sprite_object_index >> 1; sprite_instr_list_ptrs[v2] -= 4; sprite_instr_timer[v2] = 0x7FFF; } void SpriteObject_Instr_Terminate(void) { // 0xB4BD07 sprite_instr_list_ptrs[sprite_object_index >> 1] = 0; } void SpriteObject_Instr_Goto(void) { // 0xB4BD12 uint16 v2 = GET_WORD(RomPtr_B4(sprite_instr_list_ptrs[sprite_object_index >> 1]) + 2); sprite_instr_list_ptrs[sprite_object_index >> 1] = v2; sprite_instr_timer[sprite_object_index >> 1] = GET_WORD(RomPtr_B4(v2)); } void DrawSpriteObjects(void) { // 0xB4BD32 for (int i = 62; i >= 0; i -= 2) { int v1 = i >> 1; if (sprite_instr_list_ptrs[v1]) { uint16 x = sprite_x_pos[v1] - layer1_x_pos; if ((int16)(x + 16) >= 0) { if (sign16(x - 272)) { int16 y = sprite_y_pos[v1] - layer1_y_pos; if (y >= 0) { if (sign16(y - 272)) { uint16 r3 = sprite_palettes[v1] & 0xE00; uint16 r0 = sprite_palettes[v1] & 0x1FF; const uint8 *v3 = RomPtr_B4(sprite_instr_list_ptrs[v1]); DrawSpritemapWithBaseTile(0xB4, GET_WORD(v3 + 2), x, y, r3, r0); } } } } } } } void ClearSpriteObjects(void) { // 0xB4BD97 int v0 = 1022; do { sprite_instr_list_ptrs[v0 >> 1] = 0; v0 -= 2; } while (v0); }