diff --git a/th01/main/boss/b20m.cpp b/th01/main/boss/b20m.cpp index babb6ca0..61432a44 100644 --- a/th01/main/boss/b20m.cpp +++ b/th01/main/boss/b20m.cpp @@ -3,18 +3,21 @@ extern "C" { #include +#include #include "platform.h" #include "pc98.h" #include "planar.h" #include "master.hpp" #include "th01/common.h" #include "th01/math/area.hpp" +#include "th01/math/overlap.hpp" #include "th01/math/subpixel.hpp" #include "th01/hardware/frmdelay.h" #include "th01/hardware/graph.h" #include "th01/hardware/egc.h" #include "th01/hardware/ptrans.hpp" #include "th01/hardware/scrollup.hpp" +#include "th01/hardware/input.hpp" #include "th01/snd/mdrv2.h" #include "th01/main/playfld.hpp" #include "th01/formats/pf.hpp" @@ -26,6 +29,7 @@ extern "C" { #include "th01/main/spawnray.hpp" #include "th01/main/vars.hpp" #include "th01/main/boss/entity_a.hpp" +#include "th01/main/player/player.hpp" } #include "th01/main/stage/stageobj.hpp" #include "th01/main/boss/boss.hpp" @@ -47,6 +51,10 @@ static const pixel_t WAND_W = 128; // That's 32 more than BOSS6_2.BOS is wide? static const pixel_t WAND_H = 96; // ----------- +enum sariel_colors_t { + COL_BIRD = 15, // Yes, just a single one, changed by the background image. +}; + #define pattern_state sariel_pattern_state #define flash_colors sariel_flash_colors #define invincible sariel_invincible @@ -108,6 +116,32 @@ inline void sariel_grc_free(void) { grc_free(GRC_SLOT_SPAWNCROSS); grc_free(GRC_SLOT_LEAFSPLASH); } + +// For some reason, all of this code assumes .GRC entities to be 48×32, rather +// than 32×32. Why?! +#define sloppy_unput_32x32(left, top) \ + egc_copy_rect_1_to_0_16(left, top, 48, 32); + +// Birds (BOSS6GR2.GRC) +// -------------------- + +static const pixel_t BIRD_W = 32; +static const pixel_t BIRD_H = 32; + +static const int BIRD_COUNT = 30; +static const int BIRD_HATCH_CELS = 5; +static const int BIRD_FLY_CELS = 2; + +enum bird_cel_t { + C_HATCH = 1, + C_HATCH_last = (C_HATCH + BIRD_HATCH_CELS - 1), + C_FLY, + C_FLY_last = (C_FLY + BIRD_FLY_CELS - 1), +}; + +#define bird_put_8(left, top, cel) \ + grc_put_8(left, top, GRC_SLOT_BIRD, cel, COL_BIRD); +// -------------------- /// ------------- // .PTN @@ -250,3 +284,165 @@ void pascal near spawnray_unput_and_put( #undef target_prev_x #undef target_prev_y } + +enum bird_pellet_group_t { + BPG_AIMED = 0, + BPG_6_RING = 1, + BPG_RANDOM_RAIN = 2, +}; + +static const int BF_UNPUT_UPDATE_RENDER = 0; +static const int BF_RESET = 1000; +static const int BF_FIRE = 1001; + +void pascal near birds_reset_fire_spawn_unput_update_render( + double func_or_left, + double top = 0.0f, + double velocity_x = 0.0f, + double velocity_y = 0.0f, + int8_t unknown = 0 +) +{ + extern char birds_alive[BIRD_COUNT]; // Should be bool. + extern struct { + double left[BIRD_COUNT]; + double top[BIRD_COUNT]; + double velocity_x[BIRD_COUNT]; + double velocity_y[BIRD_COUNT]; + int8_t unknown[BIRD_COUNT]; + char hatch_time[BIRD_COUNT]; + char hatch_duration[BIRD_COUNT]; + + double pellet_left(int i) { + return (left[i] + ((BIRD_W / 2) - (PELLET_W / 2))); + } + + double pellet_top(int i) { + return (top[i] + ((BIRD_H / 2) - (PELLET_H / 2))); + } + + // Yes, this is a genuine ZUN abstraction, nothing I refactored. + // Why would you not just have a per-instance spawn() method?! + void set_velocity_and_hatch_time( + const double velocity_x, const double velocity_y, + double& out_velocity_x, double& out_velocity_y, char& hatch_time + ) { + out_velocity_x = velocity_x; + out_velocity_y = velocity_y; + hatch_time = 25; + } + } birds; + + if(func_or_left == BF_RESET) { + for(int i = 0; i < BIRD_COUNT; i++) { + birds_alive[i] = false; + } + } else if(func_or_left == (BF_FIRE + BPG_AIMED)) { + for(int i = 0; i < BIRD_COUNT; i++) { + if(!birds_alive[i] || birds.hatch_time[i]) { + continue; + } + Pellets.add_group( + birds.pellet_left(i), + birds.pellet_top(i), + PG_1_AIMED, + to_sp(3.0f) + ); + } + } else if(func_or_left == (BF_FIRE + BPG_6_RING)) { + for(int i = 0; i < BIRD_COUNT; i++) { + if(!birds_alive[i] || birds.hatch_time[i]) { + continue; + } + for(int j = 0; j < 6; j++) { + Pellets.add_single( + birds.pellet_left(i), + birds.pellet_top(i), + (j * (0x100 / 6)), + to_sp(4.0f) + ); + } + } + } else if(func_or_left == (BF_FIRE + BPG_RANDOM_RAIN)) { + for(int i = 0; i < BIRD_COUNT; i++) { + if(!birds_alive[i] || birds.hatch_time[i]) { + continue; + } + Pellets.add_single( + birds.pellet_left(i), + birds.pellet_top(i), + ((rand() & 0x7F) + 0x80), + to_sp(4.0f), + PM_GRAVITY, + to_sp(0.1f) + ); + } + } else if(func_or_left != BF_UNPUT_UPDATE_RENDER) { + // (Yes, this prevents birds from being spawned at [left] == 0.) + for(int i = 0; i < BIRD_COUNT; i++) { + if(birds_alive[i] != true) { + birds_alive[i] = true; + birds.set_velocity_and_hatch_time( + velocity_x, + velocity_y, + birds.velocity_x[i], + birds.velocity_y[i], + birds.hatch_time[i] + ); + birds.left[i] = func_or_left; + birds.top[i] = top; + birds.unknown[i] = unknown; + birds.hatch_duration[i] = birds.hatch_time[i]; + return; + } + } + } else { + int i; + for(i = 0; i < BIRD_COUNT; i++) { + if(!birds_alive[i]) { + continue; + } + if(birds.hatch_time[i] > 0) { + bird_put_8(birds.left[i], birds.top[i], (( + (birds.hatch_duration[i] - birds.hatch_time[i]) / + (birds.hatch_duration[i] / BIRD_HATCH_CELS) + ) + C_HATCH)); + birds.hatch_time[i]--; + } else { + // ZUN bug: Shouldn't these be unblitted unconditionally? + // Because they aren't, each cel of the hatch animation is + // blitted on top of the previous one... + sloppy_unput_32x32(birds.left[i], birds.top[i]); + } + } + for(i = 0; i < BIRD_COUNT; i++) { + if(!birds_alive[i] || birds.hatch_time[i]) { + continue; + } + birds.left[i] += birds.velocity_x[i]; + birds.top[i] += birds.velocity_y[i]; + if(!overlap_xy_lrtb_le_ge( + birds.left[i], birds.top[i], 0, 0, (RES_X - 1), (RES_Y - 1) + )) { + sloppy_unput_32x32(birds.left[i], birds.top[i]); + birds_alive[i] = false; + continue; + } + bird_put_8(birds.left[i], birds.top[i], ( + C_FLY + ((boss_phase_frame / 5) % BIRD_FLY_CELS) + )); + // 14×38 pixels… still unfair given the shape of such a bird. + if( + !player_invincible && + (birds.left[i] > (player_left - (PLAYER_W / 4))) && + (birds.left[i] < (player_left + (PLAYER_W / 4))) && + (birds.top[i] > (player_top - (PLAYER_H / 2) - (BIRD_H / 4))) && + (birds.top[i] < (player_top + (PLAYER_H / 2))) + ) { + done = true; + delay(100); // ??? + return; + } + } + } +} diff --git a/th01/main_36_.cpp b/th01/main_36_.cpp index b43b9a01..0903cb44 100644 --- a/th01/main_36_.cpp +++ b/th01/main_36_.cpp @@ -1,15 +1,6 @@ // Temporary data storage // ---------------------- -float f1000_0 = 1000.0; -float f1001_0 = 1001.0; -float f12_0 = 12.0; -float f1002_0 = 1002.0; -float f1003_0 = 1003.0; -float f639_0 = 639.0; -float f399_0 = 399.0; -float f344_0 = 344.0; -float f384_0 = 384.0; float f8_0 = 8.0; float f80_0 = 80.0; double d0_1 = 0.1; diff --git a/th01_reiiden.asm b/th01_reiiden.asm index 41b7c356..d7df68e1 100644 --- a/th01_reiiden.asm +++ b/th01_reiiden.asm @@ -22434,6 +22434,7 @@ main_36_TEXT segment byte public 'CODE' use16 extern @sariel_free$qv:proc @SPAWNRAY_UNPUT_AND_PUT$QIIIII procdesc pascal near \ origin:Point, target_x:word, target_y:word, col:word + @BIRDS_RESET_FIRE_SPAWN_UNPUT_UPD$QDDDDC procdesc pascal near main_36_TEXT ends main_36__TEXT segment byte public 'CODE' use16 @@ -22447,522 +22448,6 @@ sariel_shield equ sariel_dress equ sariel_wand equ -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -; int __stdcall sub_289D0(char, double, double, double, double) -sub_289D0 proc near - -var_1E = qword ptr -1Eh -var_16 = qword ptr -16h -var_E = dword ptr -0Eh -var_A = dword ptr -0Ah -var_6 = dword ptr -6 -var_2 = word ptr -2 -arg_0 = byte ptr 4 -arg_2 = qword ptr 6 -arg_A = qword ptr 0Eh -arg_12 = qword ptr 16h -arg_1A = qword ptr 1Eh - - enter 1Eh, 0 - push si - push di - fld [bp+arg_1A] - fcomp _f1000_0 - fstsw [bp+var_2] - fwait - mov ax, [bp+var_2] - sahf - jnz short loc_289FD - xor si, si - jmp short loc_289F5 -; --------------------------------------------------------------------------- - -loc_289EF: - mov byte ptr [si+141Fh], 0 - inc si - -loc_289F5: - cmp si, 1Eh - jl short loc_289EF - jmp loc_28EA0 -; --------------------------------------------------------------------------- - -loc_289FD: - fld [bp+arg_1A] - fcomp _f1001_0 - fstsw [bp+var_2] - fwait - mov ax, [bp+var_2] - sahf - jnz short loc_28A69 - xor si, si - jmp short loc_28A61 -; --------------------------------------------------------------------------- - -loc_28A16: - cmp byte ptr [si+141Fh], 0 - jz short loc_28A60 - cmp byte ptr [si+61C0h], 0 - jnz short loc_28A60 - push PG_1_AIMED or ((3 shl 4) shl 16) - mov bx, si - shl bx, 3 - fld qword ptr [bx+5ED2h] - fadd _f12_0 - call ftol@ - push ax - mov bx, si - shl bx, 3 - fld qword ptr [bx+5DE2h] - fadd _f12_0 - call ftol@ - push ax - push ds - push offset _Pellets - call @CPellets@add_group$qii14pellet_group_ti - add sp, 0Ch - -loc_28A60: - inc si - -loc_28A61: - cmp si, 1Eh - jl short loc_28A16 - jmp loc_28EA0 -; --------------------------------------------------------------------------- - -loc_28A69: - fld [bp+arg_1A] - fcomp _f1002_0 - fstsw [bp+var_2] - fwait - mov ax, [bp+var_2] - sahf - jnz short loc_28AE7 - xor si, si - jmp short loc_28ADF -; --------------------------------------------------------------------------- - -loc_28A82: - cmp byte ptr [si+141Fh], 0 - jz short loc_28ADE - cmp byte ptr [si+61C0h], 0 - jnz short loc_28ADE - xor di, di - jmp short loc_28AD9 -; --------------------------------------------------------------------------- - -loc_28A94: - pushd 0 or (0 shl 16) - pushd PM_NORMAL or (0 shl 16) - push (4 shl 4) - mov ax, di - imul ax, 42 - push ax - mov bx, si - shl bx, 3 - fld qword ptr [bx+5ED2h] - fadd _f12_0 - call ftol@ - push ax - mov bx, si - shl bx, 3 - fld qword ptr [bx+5DE2h] - fadd _f12_0 - call ftol@ - push ax - push ds - push offset _Pellets - call @CPellets@add_single$qiiuci15pellet_motion_tiii - add sp, 14h - inc di - -loc_28AD9: - cmp di, 6 - jl short loc_28A94 - -loc_28ADE: - inc si - -loc_28ADF: - cmp si, 1Eh - jl short loc_28A82 - jmp loc_28EA0 -; --------------------------------------------------------------------------- - -loc_28AE7: - fld [bp+arg_1A] - fcomp _f1003_0 - fstsw [bp+var_2] - fwait - mov ax, [bp+var_2] - sahf - jnz short loc_28B62 - xor si, si - jmp short loc_28B5A -; --------------------------------------------------------------------------- - -loc_28B00: - cmp byte ptr [si+141Fh], 0 - jz short loc_28B59 - cmp byte ptr [si+61C0h], 0 - jnz short loc_28B59 - pushd 0 or (0 shl 16) - push PM_GRAVITY or (1 shl 16) - push (4 shl 4) - call IRand - and al, 7Fh - add al, 80h - push ax - mov bx, si - shl bx, 3 - fld qword ptr [bx+5ED2h] - fadd _f12_0 - call ftol@ - push ax - mov bx, si - shl bx, 3 - fld qword ptr [bx+5DE2h] - fadd _f12_0 - call ftol@ - push ax - push ds - push offset _Pellets - call @CPellets@add_single$qiiuci15pellet_motion_tiii - add sp, 14h - -loc_28B59: - inc si - -loc_28B5A: - cmp si, 1Eh - jl short loc_28B00 - jmp loc_28EA0 -; --------------------------------------------------------------------------- - -loc_28B62: - fld [bp+arg_1A] - fldz - fcompp - fstsw [bp+var_2] - fwait - mov ax, [bp+var_2] - sahf - jz loc_28C25 - xor si, si - jmp loc_28C1B -; --------------------------------------------------------------------------- - -loc_28B7F: - mov al, [si+141Fh] - cbw - cmp ax, 1 - jz loc_28C1A - mov byte ptr [si+141Fh], 1 - mov ax, si - add ax, 61C0h - mov word ptr [bp+var_6+2], ds - mov word ptr [bp+var_6], ax - mov ax, si - shl ax, 3 - add ax, 60B2h - mov word ptr [bp+var_A+2], ds - mov word ptr [bp+var_A], ax - mov ax, si - shl ax, 3 - add ax, 5FC2h - mov word ptr [bp+var_E+2], ds - mov word ptr [bp+var_E], ax - fld [bp+arg_2] - fstp [bp+var_16] - fld [bp+arg_A] - fstp [bp+var_1E] - fwait - les bx, [bp+var_E] - fld [bp+var_1E] - fstp qword ptr es:[bx] - fwait - les bx, [bp+var_A] - fld [bp+var_16] - fstp qword ptr es:[bx] - fwait - les bx, [bp+var_6] - mov byte ptr es:[bx], 19h - mov bx, si - shl bx, 3 - fld [bp+arg_1A] - fstp qword ptr [bx+5DE2h] - mov bx, si - shl bx, 3 - fld [bp+arg_12] - fstp qword ptr [bx+5ED2h] - fwait - mov al, [bp+arg_0] - mov [si+61A2h], al - mov al, [si+61C0h] - mov [si+61DEh], al - jmp loc_28EA0 -; --------------------------------------------------------------------------- - -loc_28C1A: - inc si - -loc_28C1B: - cmp si, 1Eh - jl loc_28B7F - jmp loc_28EA0 -; --------------------------------------------------------------------------- - -loc_28C25: - xor si, si - jmp loc_28CC1 -; --------------------------------------------------------------------------- - -loc_28C2A: - cmp byte ptr [si+141Fh], 0 - jz loc_28CC0 - mov al, [si+61C0h] - cbw - or ax, ax - jle short loc_28C92 - push 15 ; col - mov al, [si+61DEh] - cbw - push ax - mov al, [si+61C0h] - cbw - mov dx, ax - pop ax - sub ax, dx - push ax - mov al, [si+61DEh] - cbw - mov bx, 5 - cwd - idiv bx - mov bx, ax - pop ax - cwd - idiv bx - inc ax - push ax ; image - push GRC_SLOT_BOSS_2 ; slot - mov bx, si - shl bx, 3 - fld qword ptr [bx+5ED2h] - call ftol@ - push ax ; top - mov bx, si - shl bx, 3 - fld qword ptr [bx+5DE2h] - call ftol@ - push ax ; left - call _grc_put_8 - add sp, 0Ah - dec byte ptr [si+61C0h] - jmp short loc_28CC0 -; --------------------------------------------------------------------------- - -loc_28C92: - push (32 shl 16) or 48 - mov bx, si - shl bx, 3 - fld qword ptr [bx+5ED2h] - call ftol@ - push ax - mov bx, si - shl bx, 3 - fld qword ptr [bx+5DE2h] - call ftol@ - push ax - call _egc_copy_rect_1_to_0_16 - add sp, 8 - -loc_28CC0: - inc si - -loc_28CC1: - cmp si, 1Eh - jl loc_28C2A - xor si, si - jmp loc_28E99 -; --------------------------------------------------------------------------- - -loc_28CCD: - cmp byte ptr [si+141Fh], 0 - jz loc_28E98 - cmp byte ptr [si+61C0h], 0 - jnz loc_28E98 - mov bx, si - shl bx, 3 - fld qword ptr [bx+5FC2h] - mov bx, si - shl bx, 3 - fadd qword ptr [bx+5DE2h] - mov bx, si - shl bx, 3 - fstp qword ptr [bx+5DE2h] - mov bx, si - shl bx, 3 - fld qword ptr [bx+60B2h] - mov bx, si - shl bx, 3 - fadd qword ptr [bx+5ED2h] - mov bx, si - shl bx, 3 - fstp qword ptr [bx+5ED2h] - mov bx, si - shl bx, 3 - fld qword ptr [bx+5DE2h] - fldz - fcompp - fstsw [bp+var_2] - fwait - mov ax, [bp+var_2] - sahf - ja short loc_28D89 - mov bx, si - shl bx, 3 - fld qword ptr [bx+5DE2h] - fcomp _f639_0 - fstsw [bp+var_2] - fwait - mov ax, [bp+var_2] - sahf - ja short loc_28D89 - mov bx, si - shl bx, 3 - fld qword ptr [bx+5ED2h] - fldz - fcompp - fstsw [bp+var_2] - fwait - mov ax, [bp+var_2] - sahf - ja short loc_28D89 - mov bx, si - shl bx, 3 - fld qword ptr [bx+5ED2h] - fcomp _f399_0 - fstsw [bp+var_2] - fwait - mov ax, [bp+var_2] - sahf - jbe short loc_28DBF - -loc_28D89: - push (32 shl 16) or 48 - mov bx, si - shl bx, 3 - fld qword ptr [bx+5ED2h] - call ftol@ - push ax - mov bx, si - shl bx, 3 - fld qword ptr [bx+5DE2h] - call ftol@ - push ax - call _egc_copy_rect_1_to_0_16 - add sp, 8 - mov byte ptr [si+141Fh], 0 - jmp loc_28E98 -; --------------------------------------------------------------------------- - -loc_28DBF: - push 15 ; col - mov ax, _boss_phase_frame - mov bx, 5 - cwd - idiv bx - mov bx, 2 - cwd - idiv bx - add dx, 6 - push dx ; image - push GRC_SLOT_BOSS_2 ; slot - mov bx, si - shl bx, 3 - fld qword ptr [bx+5ED2h] - call ftol@ - push ax ; top - mov bx, si - shl bx, 3 - fld qword ptr [bx+5DE2h] - call ftol@ - push ax ; left - call _grc_put_8 - add sp, 0Ah - cmp _player_invincible, 0 - jnz loc_28E98 - mov bx, si - shl bx, 3 - fld qword ptr [bx+5DE2h] - mov ax, _player_left - add ax, -8 - mov [bp+var_2], ax - fild [bp+var_2] - fcompp - fstsw [bp+var_2] - fwait - mov ax, [bp+var_2] - sahf - jnb short loc_28E98 - mov bx, si - shl bx, 3 - fld qword ptr [bx+5DE2h] - mov ax, _player_left - add ax, 8 - mov [bp+var_2], ax - fild [bp+var_2] - fcompp - fstsw [bp+var_2] - fwait - mov ax, [bp+var_2] - sahf - jbe short loc_28E98 - mov bx, si - shl bx, 3 - fld qword ptr [bx+5ED2h] - fcomp _f344_0 - fstsw [bp+var_2] - fwait - mov ax, [bp+var_2] - sahf - jbe short loc_28E98 - mov bx, si - shl bx, 3 - fld qword ptr [bx+5ED2h] - fcomp _f384_0 - fstsw [bp+var_2] - fwait - mov ax, [bp+var_2] - sahf - jnb short loc_28E98 - mov _done, 1 - push 64h ; 'd' - call _delay - pop cx - jmp short loc_28EA0 -; --------------------------------------------------------------------------- - -loc_28E98: - inc si - -loc_28E99: - cmp si, 1Eh - jl loc_28CCD - -loc_28EA0: - pop di - pop si - leave - retn 22h -sub_289D0 endp - - ; =============== S U B R O U T I N E ======================================= ; Attributes: bp-based frame @@ -24159,7 +23644,7 @@ loc_29905: fstp [bp+var_2C] push 1 ; char fwait - call sub_289D0 + call @birds_reset_fire_spawn_unput_upd$qddddc dec si loc_2997F: @@ -24254,7 +23739,7 @@ loc_29A41: fstp [bp+var_2C] push 0 ; char fwait - call sub_289D0 + call @birds_reset_fire_spawn_unput_upd$qddddc jmp short loc_29A96 ; --------------------------------------------------------------------------- @@ -26110,7 +25595,7 @@ loc_2AD01: fstp [bp+var_2A] push 1 ; char fwait - call sub_289D0 + call @birds_reset_fire_spawn_unput_upd$qddddc mov ax, (RES_X - 1) sub ax, point_3B043.x mov [bp+var_A], ax @@ -26139,7 +25624,7 @@ loc_2AD01: fstp [bp+var_2A] push 1 ; char fwait - call sub_289D0 + call @birds_reset_fire_spawn_unput_upd$qddddc loc_2AE0C: mov ax, _boss_phase_frame @@ -26148,7 +25633,7 @@ loc_2AE0C: idiv bx or dx, dx jnz locret_2AECC - fld _f1003_0 + fld dword ptr ds:[15D6h] sub sp, 8 fstp [bp+var_12] fldz @@ -26165,7 +25650,7 @@ loc_2AE0C: fstp [bp+var_2A] push 0 ; char fwait - call sub_289D0 + call @birds_reset_fire_spawn_unput_upd$qddddc leave retn ; --------------------------------------------------------------------------- @@ -26192,7 +25677,7 @@ loc_2AE7A: idiv bx or dx, dx jnz short loc_2AEBE - fld _f1003_0 + fld dword ptr ds:[15D6h] sub sp, 8 fstp [bp+var_12] fldz @@ -26209,7 +25694,7 @@ loc_2AE7A: fstp [bp+var_2A] push 0 ; char fwait - call sub_289D0 + call @birds_reset_fire_spawn_unput_upd$qddddc loc_2AEBE: cmp _boss_phase_frame, 300 @@ -28252,7 +27737,7 @@ loc_2C2F2: call @wand_bg_snap$qv push 1 call sub_28F11 - fld _f1000_0 + fld dword ptr ds:[15C6h] sub sp, 8 fstp [bp+var_12] fldz @@ -28269,7 +27754,7 @@ loc_2C2F2: fstp [bp+var_2A] push 0 ; char fwait - call sub_289D0 + call @birds_reset_fire_spawn_unput_upd$qddddc jmp loc_2CDCE ; --------------------------------------------------------------------------- @@ -28318,7 +27803,7 @@ loc_2C3BE: fstp [bp+var_2A] push 0 ; char fwait - call sub_289D0 + call @birds_reset_fire_spawn_unput_upd$qddddc cmp word_35E95, 0 jnz short loc_2C40D call sub_2958C @@ -28650,7 +28135,7 @@ loc_2C6F2: fstp [bp+var_2A] push 0 ; char fwait - call sub_289D0 + call @birds_reset_fire_spawn_unput_upd$qddddc cmp word_35E95, 0 jnz short loc_2C751 call sub_2ABDC @@ -29863,15 +29348,11 @@ _BG_IMAGES label dword public _spawnray_target_prev_x, _spawnray_target_prev_y _spawnray_target_prev_x dw 999 _spawnray_target_prev_y dw 999 - dd 0 - dd 0 - dd 0 - dd 0 - dd 0 - dd 0 - dd 0 - db 0 - db 0 + +BIRD_COUNT = 30 + +public _birds_alive +_birds_alive db BIRD_COUNT dup(0) word_35DDD dw 0 word_35DDF dw 0 byte_35DE1 db 0 @@ -29953,15 +29434,6 @@ _sariel_invincibility_flash_colors db 3, 4, 5 extern _boss6_a2_grp:byte extern _boss6_a3_grp:byte extern _boss6_a4_grp:byte - extern _f1000_0:dword - extern _f1001_0:dword - extern _f12_0:dword - extern _f1002_0:dword - extern _f1003_0:dword - extern _f639_0:dword - extern _f399_0:dword - extern _f344_0:dword - extern _f384_0:dword extern _f8_0:dword extern _f80_0:dword extern _d0_1:qword @@ -30312,7 +29784,19 @@ _elis_initial_hp_rendered db ? public _sariel_pattern_state _sariel_pattern_state dw ? - db 1050 dup (?) + +CBirds struc + dq BIRD_COUNT dup(?) ; left + dq BIRD_COUNT dup(?) ; top + dq BIRD_COUNT dup(?) ; velocity_x + dq BIRD_COUNT dup(?) ; velocity_y + db BIRD_COUNT dup(?) ; unknown + db BIRD_COUNT dup(?) ; hatch_time + db BIRD_COUNT dup(?) ; hatch_duration +CBirds ends + +public _birds +_birds CBirds unk_3AB9C db ? ; db 3 dup(?) unk_3ABA0 db ? ;