[Maintenance] [th01] Boss entrance rings: Move main code into a macro

Part of P0198, funded by Lmocinemod and Ember2528.
This commit is contained in:
nmlgc 2022-06-11 21:37:14 +02:00
parent c3572c62a9
commit dd8461e0bc
2 changed files with 56 additions and 31 deletions

View File

@ -36,12 +36,44 @@ inline long entrance_ring_radius(pixel_t base, unsigned int square_i) {
for( \
square_i = (1 * ENTRANCE_RING_SQUARES); \
square_i < ((1 + ENTRANCE_RING_STACK) * ENTRANCE_RING_SQUARES); \
i++ \
square_i++ \
) { \
invert_lhs entrance_ring_invert(square_i, radius_base); \
} \
}
#define entrance_rings_done(squares_offscreen) \
(squares_offscreen >= (ENTRANCE_RING_STACK * ENTRANCE_RING_SQUARES))
// Well, well, we'd *really* like call sites to use this macro within an `if`
// statement. That makes it looks as if this macro is actually a function that
// returns whether the animation is done or not. Unfortunately, the completion
// condition is itself nested within a conditional branch. This only leaves
// ugly workarounds:
//
// 1) Forcing calling sites to close a block they didn't open
// 2) A fake lambda function in another macro parameter
// 3) Using `goto` and jumping to a label (`entrance_rings_still_active`) that
// we force the call site to define
//
// Option 3) doesn't introduce weird syntax and thus feels like the most
// natural choice.
#define entrance_rings_update_and_render( \
radius_base, i, squares_offscreen, frame, radius_base_initial, frame_first \
) \
frame == frame_first) { \
radius_base = radius_base_initial; \
goto entrance_rings_still_active; \
} else if(frame == (frame_first + 1)) { \
entrance_rings_invert(i, {}, radius_base); \
goto entrance_rings_still_active; \
} else if((frame > (frame_first + 1)) && ((frame % 4) == 0)) { \
/* "Un-invert" the previous frame */ \
entrance_rings_invert(i, {}, radius_base); \
\
radius_base += 16; \
squares_offscreen = 0; \
\
entrance_rings_invert(i, squares_offscreen +=, radius_base); \
} else { \
goto entrance_rings_still_active; \
} \
if(squares_offscreen >= (ENTRANCE_RING_STACK * ENTRANCE_RING_SQUARES)
/// ------------------------------------------------

View File

@ -2648,39 +2648,32 @@ void sariel_main(void)
random_seed = frame_rand;
while(1) {
boss_phase_frame++;
if(boss_phase_frame == 1) {
entrance_ring_radius_base = 16;
} else if(boss_phase_frame == 2) {
entrance_rings_invert(i, {}, entrance_ring_radius_base);
} else if((boss_phase_frame > 2) && ((boss_phase_frame % 4) == 0)) {
// "Un-invert" the previous frame
entrance_rings_invert(i, {}, entrance_ring_radius_base);
#define frame_half boss_phase_frame
entrance_ring_radius_base += 16;
unsigned int squares_offscreen = 0;
unsigned int tmp;
entrance_rings_invert(
i, squares_offscreen +=, entrance_ring_radius_base
);
if(entrance_rings_done(squares_offscreen)) {
boss_phase = 1;
phase.pattern_cur = 0;
phase.ax.patterns_done = 0;
phase.patterns_until_next = ((rand() % 6) + 1);
boss_phase_frame = 0;
initial_hp_rendered = 0;
boss_palette_show(); // Unnecessary.
ent_shield.pos_cur_set(SHIELD_LEFT, SHIELD_TOP);
wand_lowered_snap();
wand_render_raise_both(true);
birds_reset();
return;
}
frame_half++;
if(entrance_rings_update_and_render(
entrance_ring_radius_base, i, tmp, frame_half, 16, 1
)) {
boss_phase = 1;
phase.pattern_cur = 0;
phase.ax.patterns_done = 0;
phase.patterns_until_next = ((rand() % 6) + 1);
boss_phase_frame = 0;
initial_hp_rendered = 0;
boss_palette_show(); // Unnecessary.
ent_shield.pos_cur_set(SHIELD_LEFT, SHIELD_TOP);
wand_lowered_snap();
wand_render_raise_both(true);
birds_reset();
break;
}
if(boss_phase_frame % 2) {
entrance_rings_still_active:
if(frame_half % 2) { // That's why we've renamed the variable
frame_delay(1);
}
#undef frame_half
}
} else if(boss_phase == 1) {
hud_hp_increment_render(initial_hp_rendered, boss_hp, boss_phase_frame);