diff --git a/th01/main/boss/b20j.cpp b/th01/main/boss/b20j.cpp index 5fd0c906..132637d0 100644 --- a/th01/main/boss/b20j.cpp +++ b/th01/main/boss/b20j.cpp @@ -10,6 +10,7 @@ extern "C" { #include "th01/common.h" #include "th01/math/area.hpp" #include "th01/math/subpixel.hpp" +#include "th01/math/vector.hpp" #include "th01/hardware/frmdelay.h" #include "th01/hardware/palette.h" #include "th01/hardware/graph.h" @@ -23,10 +24,13 @@ extern "C" { #include "th01/formats/ptn.hpp" #include "th01/formats/stagedat.hpp" #include "th01/sprites/pellet.h" +#include "th01/sprites/shape8x8.hpp" #include "th01/main/boss/entity_a.hpp" #include "th01/main/stage/palette.hpp" } #include "th01/main/stage/stageobj.hpp" +#include "th01/main/shape.hpp" +#include "th01/main/player/player.hpp" #include "th01/main/boss/boss.hpp" #include "th01/main/boss/palette.hpp" #include "th01/main/bullet/pellet.hpp" @@ -387,6 +391,167 @@ void slash_put(int image) graph_accesspage_func(0); grx_put(image); } +void pattern_diamond_cross_to_edges_followed_by_rain(void) +{ + #define DIAMOND_COUNT 4 + #define DIAMOND_ORIGIN_X (PLAYFIELD_CENTER_X - (DIAMOND_W / 2)) + #define DIAMOND_ORIGIN_Y (PLAYFIELD_CENTER_Y + (DIAMOND_H / 2)) + + int i; + + #define diamonds pattern0_diamonds + extern struct { + pixel_t velocity_bottomleft_x, velocity_topleft_x; + pixel_t velocity_bottomleft_y, velocity_topleft_y; + screen_x_t left[DIAMOND_COUNT]; + screen_y_t top[DIAMOND_COUNT]; + } diamonds; + extern int frames_with_diamonds_at_edges; + + #define diamonds_unput(i) \ + for(i = 0; i < DIAMOND_COUNT; i++) { \ + egc_copy_rect_1_to_0_16( \ + diamonds.left[i], diamonds.top[i], 16, DIAMOND_H \ + ); \ + } + + #define diamonds_put(i) \ + for(i = 0; i < DIAMOND_COUNT; i++) { \ + shape8x8_diamond_put(diamonds.left[i], diamonds.top[i], 9); \ + } + + if(boss_phase_frame == 10) { + face_expression_set_and_put(FE_NEUTRAL); + } + if(boss_phase_frame < 100) { + return; + } else if(boss_phase_frame == 100) { + // MODDERS: Just use a local variable. + select_for_rank(pattern_state.group, + PG_2_SPREAD_NARROW_AIMED, + PG_3_SPREAD_NARROW_AIMED, + PG_5_SPREAD_WIDE_AIMED, + PG_5_SPREAD_NARROW_AIMED + ); + + vector2_between( + DIAMOND_ORIGIN_X, DIAMOND_ORIGIN_Y, + PLAYFIELD_LEFT, player_center_y, + diamonds.velocity_bottomleft_x, diamonds.velocity_bottomleft_y, + 7 + ); + vector2_between( + DIAMOND_ORIGIN_X, DIAMOND_ORIGIN_Y, + PLAYFIELD_LEFT, PLAYFIELD_TOP, + diamonds.velocity_topleft_x, diamonds.velocity_topleft_y, + 7 + ); + + for(i = 0; i < DIAMOND_COUNT; i++) { + diamonds.left[i] = DIAMOND_ORIGIN_X; + diamonds.top[i] = DIAMOND_ORIGIN_Y; + } + Pellets.add_group( + (PLAYFIELD_LEFT + (PLAYFIELD_W / 2) - PELLET_W), + (PLAYFIELD_TOP + playfield_fraction_y(8 / 21.0f) - (PELLET_H / 2)), + static_cast(pattern_state.group), + to_sp(3.0f) + ); + select_for_rank(pattern_state.interval, 18, 16, 14, 12); + mdrv2_se_play(12); + } else if(diamonds.left[0] > PLAYFIELD_LEFT) { + diamonds_unput(i); + diamonds.left[0] += diamonds.velocity_bottomleft_x; + diamonds.top[0] += diamonds.velocity_bottomleft_y; + diamonds.left[1] -= diamonds.velocity_bottomleft_x; + diamonds.top[1] += diamonds.velocity_bottomleft_y; + diamonds.left[2] += diamonds.velocity_topleft_x; + diamonds.top[2] += diamonds.velocity_topleft_y; + diamonds.left[3] -= diamonds.velocity_topleft_x; + diamonds.top[3] += diamonds.velocity_topleft_y; + if(diamonds.left[0] <= PLAYFIELD_LEFT) { + diamonds.left[0] = PLAYFIELD_LEFT; + diamonds.left[2] = PLAYFIELD_LEFT; + diamonds.left[1] = (PLAYFIELD_RIGHT - DIAMOND_W); + diamonds.left[3] = (PLAYFIELD_RIGHT - DIAMOND_W); + } else { + diamonds_put(i); + } + return; + } else if(diamonds.top[0] > PLAYFIELD_TOP) { + diamonds_unput(i); + diamonds.top[0] -= 3; + diamonds.top[1] -= 3; + diamonds.left[2] += 6; + diamonds.left[3] -= 6; + if(diamonds.top[0] <= PLAYFIELD_TOP) { + diamonds.top[0] = PLAYFIELD_TOP; + } else { + diamonds_put(i); + } + return; + } else if(frames_with_diamonds_at_edges < 200) { + frames_with_diamonds_at_edges++; + if((frames_with_diamonds_at_edges % pattern_state.interval) == 0) { + #define speed to_sp(2.5f) + screen_x_t from_left; + screen_y_t from_top; + screen_x_t to_left; + screen_y_t to_top; + unsigned char angle; + + from_left = PLAYFIELD_LEFT; + from_top = (PLAYFIELD_TOP + playfield_rand_y(25 / 42.0f)); + // Should actually be + // to_left = (PLAYFIELD_RIGHT - playfield_rand_x(5 / 8.0f)); + to_left = (PLAYFIELD_LEFT + + playfield_rand_x(5 / 8.0f) + playfield_fraction_x(3 / 8.0f) + ); + to_top = PLAYFIELD_BOTTOM; + angle = iatan2((to_top - from_top), (to_left - from_left)); + Pellets.add_single(from_left, from_top, angle, speed, PM_NORMAL); + + from_left = (PLAYFIELD_RIGHT - PELLET_W); + from_top = (PLAYFIELD_TOP + playfield_rand_y(25 / 42.0f)); + to_left = (PLAYFIELD_LEFT + playfield_rand_x( 5 / 8.0f)); + to_top = PLAYFIELD_BOTTOM; + angle = iatan2((to_top - from_top), (to_left - from_left)); + Pellets.add_single(from_left, from_top, angle, speed, PM_NORMAL); + + from_top = PLAYFIELD_TOP; + from_left = (PLAYFIELD_LEFT + playfield_rand_x()); + to_top = PLAYFIELD_BOTTOM; + to_left = (PLAYFIELD_LEFT + playfield_rand_x()); + angle = iatan2((to_top - from_top), (to_left - from_left)); + Pellets.add_single(from_left, from_top, angle, speed, PM_NORMAL); + + from_top = PLAYFIELD_TOP; + from_left = (PLAYFIELD_LEFT + playfield_rand_x()); + to_top = PLAYFIELD_BOTTOM; + to_left = (PLAYFIELD_LEFT + playfield_rand_x()); + angle = iatan2((to_top - from_top), (to_left - from_left)); + Pellets.add_single(from_left, from_top, angle, speed, PM_NORMAL); + + from_top = PLAYFIELD_TOP; + from_left = (PLAYFIELD_LEFT + playfield_rand_x()); + Pellets.add_group(from_left, from_top, PG_1_AIMED, speed); + + #undef speed + } + return; + } else { + boss_phase_frame = 0; + } + frames_with_diamonds_at_edges = 0; + + #undef diamonds_put + #undef diamonds_unput + #undef diamonds + #undef DIAMOND_ORIGIN_Y + #undef DIAMOND_ORIGIN_X + #undef DIAMOND_COUNT +} + char konngara_esc_cls[] = "\x1B*"; char konngara_esc_mode_graph[] = "\x1B)3"; char konngara_esc_color_bg_black_fg_black[] = "\x1B[16;40m"; diff --git a/th01/main/playfld.hpp b/th01/main/playfld.hpp index 1430389b..441ba84e 100644 --- a/th01/main/playfld.hpp +++ b/th01/main/playfld.hpp @@ -10,6 +10,10 @@ static const screen_x_t PLAYFIELD_CENTER_X = ( ((PLAYFIELD_RIGHT - PLAYFIELD_LEFT) / 2) + PLAYFIELD_LEFT ); +static const screen_y_t PLAYFIELD_CENTER_Y = ( + ((PLAYFIELD_BOTTOM - PLAYFIELD_TOP) / 2) + PLAYFIELD_TOP +); + inline pixel_t playfield_fraction_x(float fraction = 1.0f) { return ((int)(PLAYFIELD_W * fraction)); } diff --git a/th01/sprites/shape8x8.hpp b/th01/sprites/shape8x8.hpp index d27d25e6..57099b9f 100644 --- a/th01/sprites/shape8x8.hpp +++ b/th01/sprites/shape8x8.hpp @@ -5,4 +5,8 @@ typedef enum { SHAPE8X8_COUNT } shape8x8_t; +// For consistency in usage code... +static const pixel_t DIAMOND_W = 8; +static const pixel_t DIAMOND_H = 8; + extern const dot_rect_t(8, 8) sSHAPE8X8[SHAPE8X8_COUNT]; diff --git a/th01_reiiden.asm b/th01_reiiden.asm index f969dbaa..821cfdc2 100644 --- a/th01_reiiden.asm +++ b/th01_reiiden.asm @@ -37643,6 +37643,7 @@ main_37_TEXT segment byte public 'CODE' use16 extern @face_direction_set_and_put$q16face_direction_t:proc extern @face_expression_set_and_put$q17face_expression_t:proc extern @slash_put$qi:proc + extern @pattern_diamond_cross_to_edges_f$qv:proc main_37_TEXT ends main_37__TEXT segment byte public 'CODE' use16 @@ -37662,305 +37663,6 @@ FE_CLOSED = 1 FE_GLARE = 2 FE_AIM = 3 -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_2D439 proc far - -@@angle = byte ptr -7 -@@y = word ptr -6 -@@x = word ptr -4 -@@top = word ptr -2 - - enter 8, 0 - push si - push di - cmp _boss_phase_frame, 10 - jnz short loc_2D44D - call @face_expression_set_and_put$q17face_expression_t stdcall, FE_NEUTRAL - pop cx - -loc_2D44D: - cmp _boss_phase_frame, 100 - jl loc_2D7D3 - cmp _boss_phase_frame, 100 - jnz loc_2D500 - call @konngara_select_for_rank$qmiiiii stdcall, offset _konngara_pattern_state, ds, large PG_2_SPREAD_NARROW_AIMED or (PG_3_SPREAD_NARROW_AIMED shl 16), large PG_5_SPREAD_WIDE_AIMED or (PG_5_SPREAD_NARROW_AIMED shl 16) - call _vector2_between stdcall, large (236 shl 16) or 316, large (384 shl 16) or 0, offset x_3B43A, ds, offset y_3B43E, ds, 7 - call _vector2_between stdcall, large (236 shl 16) or 316, large ( 64 shl 16) or 0, offset x_3B43C, ds, offset y_3B440, ds, 7 - add sp, 30h - xor si, si - jmp short loc_2D4C5 -; --------------------------------------------------------------------------- - -loc_2D4B0: - mov bx, si - add bx, bx - mov word ptr [bx+6AA2h], 13Ch - mov bx, si - add bx, bx - mov word ptr [bx+6AAAh], 0ECh - inc si - -loc_2D4C5: - cmp si, 4 - jl short loc_2D4B0 - call @CPellets@add_group$qii14pellet_group_ti stdcall, offset _Pellets, ds, large 312 or (188 shl 16), _konngara_pattern_state, (3 shl 4) - call @konngara_select_for_rank$qmiiiii stdcall, offset _konngara_pattern_state, ds, large 18 or (16 shl 16), large 14 or (12 shl 16) - push 0Ch - call _mdrv2_se_play - add sp, 1Ah - jmp loc_2D7CD -; --------------------------------------------------------------------------- - -loc_2D500: - cmp word_3B442, 0 - jle loc_2D5B2 - xor si, si - jmp short loc_2D52C -; --------------------------------------------------------------------------- - -loc_2D50D: - push (8 shl 16) or 16 - mov bx, si - add bx, bx - push word ptr [bx+6AAAh] - mov bx, si - add bx, bx - push word ptr [bx+6AA2h] - call _egc_copy_rect_1_to_0_16 - add sp, 8 - inc si - -loc_2D52C: - cmp si, 4 - jl short loc_2D50D - mov ax, x_3B43A - add word_3B442, ax - mov ax, y_3B43E - add word_3B44A, ax - mov ax, x_3B43A - sub word_3B444, ax - mov ax, y_3B43E - add word_3B44C, ax - mov ax, x_3B43C - add word_3B446, ax - mov ax, y_3B440 - add word_3B44E, ax - mov ax, x_3B43C - sub word_3B448, ax - mov ax, y_3B440 - add word_3B450, ax - cmp word_3B442, 0 - jg short loc_2D58B - mov word_3B442, 0 - mov word_3B446, 0 - mov word_3B444, 278h - mov word_3B448, 278h - jmp loc_2D7D3 -; --------------------------------------------------------------------------- - -loc_2D58B: - xor si, si - jmp short loc_2D5AA -; --------------------------------------------------------------------------- - -loc_2D58F: - push 9 ; col - mov bx, si - add bx, bx - push word ptr [bx+6AAAh] ; top - mov bx, si - add bx, bx - push word ptr [bx+6AA2h] ; left - call @shape8x8_diamond_put$qiii - add sp, 6 - inc si - -loc_2D5AA: - cmp si, 4 - jl short loc_2D58F - jmp loc_2D7D3 -; --------------------------------------------------------------------------- - -loc_2D5B2: - cmp word_3B44A, 40h - jle short loc_2D62C - xor si, si - jmp short loc_2D5DC -; --------------------------------------------------------------------------- - -loc_2D5BD: - push (8 shl 16) or 16 - mov bx, si - add bx, bx - push word ptr [bx+6AAAh] - mov bx, si - add bx, bx - push word ptr [bx+6AA2h] - call _egc_copy_rect_1_to_0_16 - add sp, 8 - inc si - -loc_2D5DC: - cmp si, 4 - jl short loc_2D5BD - sub word_3B44A, 3 - sub word_3B44C, 3 - add word_3B446, 6 - sub word_3B448, 6 - cmp word_3B44A, 40h - jg short loc_2D605 - mov word_3B44A, 40h - jmp loc_2D7D3 -; --------------------------------------------------------------------------- - -loc_2D605: - xor si, si - jmp short loc_2D624 -; --------------------------------------------------------------------------- - -loc_2D609: - push 9 ; col - mov bx, si - add bx, bx - push word ptr [bx+6AAAh] ; top - mov bx, si - add bx, bx - push word ptr [bx+6AA2h] ; left - call @shape8x8_diamond_put$qiii - add sp, 6 - inc si - -loc_2D624: - cmp si, 4 - jl short loc_2D609 - jmp loc_2D7D3 -; --------------------------------------------------------------------------- - -loc_2D62C: - cmp word_3B452, 0C8h ; '?' - jge loc_2D7C7 - inc word_3B452 - mov ax, word_3B452 - cwd - idiv _konngara_pattern_state - or dx, dx - jnz loc_2D7D3 - xor di, di - call IRand - mov bx, 200 - cwd - idiv bx - add dx, PLAYFIELD_TOP - mov [bp+@@top], dx - call IRand - mov bx, 400 - cwd - idiv bx - add dx, 240 - mov [bp+@@x], dx - mov [bp+@@y], PLAYFIELD_BOTTOM - mov ax, [bp+@@y] - sub ax, [bp+@@top] - push ax - mov ax, [bp+@@x] - sub ax, di - push ax - call iatan2 - mov [bp+@@angle], al - call @CPellets@add_single$qiiuci15pellet_motion_tiii stdcall, offset _Pellets, ds, di, [bp+@@top], word ptr [bp+@@angle], (2 shl 4) + 8, large PM_NORMAL or (0 shl 16), large 0 or (0 shl 16) - mov di, (PLAYFIELD_RIGHT - 8) - call IRand - mov bx, 200 - cwd - idiv bx - add dx, PLAYFIELD_TOP - mov [bp+@@top], dx - call IRand - mov bx, PLAYFIELD_BOTTOM - cwd - idiv bx - mov [bp+@@x], dx - mov [bp+@@y], PLAYFIELD_BOTTOM - mov ax, [bp+@@y] - sub ax, [bp+@@top] - push ax - mov ax, [bp+@@x] - sub ax, di - push ax - call iatan2 - mov [bp+@@angle], al - call @CPellets@add_single$qiiuci15pellet_motion_tiii stdcall, offset _Pellets, ds, di, [bp+@@top], word ptr [bp+@@angle], (2 shl 4) + 8, large PM_NORMAL or (0 shl 16), large 0 or (0 shl 16) - add sp, 28h - mov [bp+@@top], PLAYFIELD_TOP - call IRand - mov bx, PLAYFIELD_RIGHT - cwd - idiv bx - mov di, dx - mov [bp+@@y], PLAYFIELD_BOTTOM - call IRand - mov bx, PLAYFIELD_RIGHT - cwd - idiv bx - mov [bp+@@x], dx - mov ax, [bp+@@y] - sub ax, [bp+@@top] - push ax - mov ax, [bp+@@x] - sub ax, di - push ax - call iatan2 - mov [bp+@@angle], al - call @CPellets@add_single$qiiuci15pellet_motion_tiii stdcall, offset _Pellets, ds, di, [bp+@@top], word ptr [bp+@@angle], (2 shl 4) + 8, large PM_NORMAL or (0 shl 16), large 0 or (0 shl 16) - mov [bp+@@top], PLAYFIELD_TOP - call IRand - mov bx, PLAYFIELD_RIGHT - cwd - idiv bx - mov di, dx - mov [bp+@@y], PLAYFIELD_BOTTOM - call IRand - mov bx, PLAYFIELD_RIGHT - cwd - idiv bx - mov [bp+@@x], dx - mov ax, [bp+@@y] - sub ax, [bp+@@top] - push ax - mov ax, [bp+@@x] - sub ax, di - push ax - call iatan2 - mov [bp+@@angle], al - call @CPellets@add_single$qiiuci15pellet_motion_tiii stdcall, offset _Pellets, ds, di, [bp+@@top], word ptr [bp+@@angle], (2 shl 4) + 8, large PM_NORMAL or (0 shl 16), large 0 or (0 shl 16) - add sp, 28h - mov [bp+@@top], PLAYFIELD_TOP - call IRand - mov bx, PLAYFIELD_RIGHT - cwd - idiv bx - mov di, dx - call @CPellets@add_group$qii14pellet_group_ti c, offset _Pellets, ds, dx, [bp+@@top], large PG_1_AIMED or (((2 shl 4) + 8) shl 16) - jmp short loc_2D7D3 -; --------------------------------------------------------------------------- - -loc_2D7C7: - mov _boss_phase_frame, 0 - -loc_2D7CD: - mov word_3B452, 0 - -loc_2D7D3: - pop di - pop si - leave - retf -sub_2D439 endp - - ; =============== S U B R O U T I N E ======================================= ; Attributes: bp-based frame @@ -40124,7 +39826,7 @@ loc_2EF22: pop cx cmp word_35FF8, 0 jnz short loc_2EF38 - call sub_2D439 + call @pattern_diamond_cross_to_edges_f$qv jmp short loc_2EF97 ; --------------------------------------------------------------------------- @@ -40847,7 +40549,7 @@ loc_2F62F: pop cx cmp word_35FF8, 0 jnz short loc_2F646 - call sub_2D439 + call @pattern_diamond_cross_to_edges_f$qv jmp loc_2F720 ; --------------------------------------------------------------------------- @@ -42544,21 +42246,16 @@ word_3B435 dw ? public _sariel_initial_hp_rendered _sariel_initial_hp_rendered db ? -public _konngara_pattern_state +public _konngara_pattern_state, _pattern0_diamonds, _frames_with_diamonds_at_edges _konngara_pattern_state dw ? -x_3B43A dw ? -x_3B43C dw ? -y_3B43E dw ? -y_3B440 dw ? -word_3B442 dw ? -word_3B444 dw ? -word_3B446 dw ? -word_3B448 dw ? -word_3B44A dw ? -word_3B44C dw ? -word_3B44E dw ? -word_3B450 dw ? -word_3B452 dw ? +_pattern0_diamonds label byte + P0D_velocity_bottomleft_x dw ? + P0D_velocity_topleft_x dw ? + P0D_velocity_bottomleft_y dw ? + P0D_velocity_topleft_y dw ? + P0D_left dw 4 dup(?) + P0D_top dw 4 dup(?) +_frames_with_diamonds_at_edges dw ? angle_3B454 db ? word_3B455 dw ? word_3B457 dw ?