From 091f19f69b57b0cd77afbae7c2bb53607736a893 Mon Sep 17 00:00:00 2001 From: nmlgc Date: Thu, 20 Jan 2022 13:38:21 +0100 Subject: [PATCH] [Decompilation] [th01] Sariel: Pattern 16/16 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The one where Sariel's second form shoots sparks towards the top of the playfield, which then turn into leaf-like sprites that sway towards the bottom, killing Reimu on contact. And wow, what a finish! A weird "decimal subpixel" type, hardcoded sprites, and effectively unused non-hardcoded sprites. Too bad that it also ruins the nice `dot_rect_t(w, h)` parameter abstraction for grcg_put_8x8_mono()… Completes P0180, funded by Yanga. --- Tupfile | 2 + Tupfile.bat | 1 + th01/hardware/grcg8x8m.cpp | 4 +- th01/hardware/grcg8x8m.hpp | 2 +- th01/main/boss/b20m.cpp | 216 ++++++++++++ th01/main/shape.cpp | 2 +- th01/math/overlap.hpp | 7 + th01/sprites/leaf.bmp | Bin 0 -> 94 bytes th01/sprites/leaf.hpp | 4 + th01_reiiden.asm | 688 ++----------------------------------- 10 files changed, 255 insertions(+), 671 deletions(-) create mode 100644 th01/sprites/leaf.bmp create mode 100644 th01/sprites/leaf.hpp diff --git a/Tupfile b/Tupfile index 4a0ae4e4..c0568e5f 100644 --- a/Tupfile +++ b/Tupfile @@ -23,6 +23,7 @@ BMP2ARR = bin\\Pipeline\\bmp2arr.exe !bmp2arr = | $(BMP2ARR) |> $(BMP2ARR) -q -i %f -o %o |> %o +: th01/sprites/leaf.bmp |> !bmp2arr -sym _sLEAF -of asm -sw 8 -sh 8 |> th01/sprites/leaf.asp : th01/sprites/ileave_m.bmp |> !bmp2arr -sym _sINTERLEAVE_MASKS -of asm -sw 8 -sh 8 |> th01/sprites/ileave_m.asp # ZUN bug: Supposed to be 8 preshifted sprites, with a height of 1 and a width @@ -57,6 +58,7 @@ BMP2ARR = bin\\Pipeline\\bmp2arr.exe : th01_op.asm |> !as |> bin\\th01\\op.obj : th01_reiiden.asm | \ + th01/sprites/leaf.asp \ th01/sprites/ileave_m.asp \ th01/sprites/laser_s.asp \ th01/sprites/pellet_c.asp \ diff --git a/Tupfile.bat b/Tupfile.bat index 7bb687b6..568cc821 100644 --- a/Tupfile.bat +++ b/Tupfile.bat @@ -3,6 +3,7 @@ : if the Tupfile changes. @echo on bcc32 -w-8004 -w-8012 -O2 -v- -x- -nbin/Pipeline/ Pipeline/bmp2arr.c Pipeline/bmp2arrl.c +bin\\Pipeline\\bmp2arr.exe -q -i th01/sprites/leaf.bmp -o th01/sprites/leaf.asp -sym _sLEAF -of asm -sw 8 -sh 8 bin\\Pipeline\\bmp2arr.exe -q -i th01/sprites/ileave_m.bmp -o th01/sprites/ileave_m.asp -sym _sINTERLEAVE_MASKS -of asm -sw 8 -sh 8 bin\\Pipeline\\bmp2arr.exe -q -i th01/sprites/laser_s.bmp -o th01/sprites/laser_s.asp -sym _sSHOOTOUT_LASER -of asm -sw 16 -sh 8 bin\\Pipeline\\bmp2arr.exe -q -i th01/sprites/pellet.bmp -o th01/sprites/pellet.csp -sym sPELLET -of c -sw 8 -sh 8 -pshf inner diff --git a/th01/hardware/grcg8x8m.cpp b/th01/hardware/grcg8x8m.cpp index b8631825..8c3abccb 100644 --- a/th01/hardware/grcg8x8m.cpp +++ b/th01/hardware/grcg8x8m.cpp @@ -3,12 +3,12 @@ void grcg_put_8x8_mono( vram_offset_t vram_offset_topleft, char first_bit, - const dot_rect_t(8, 8)& sprite, + const dots8_t sprite[8], int col ) { grcg_setcolor_rmw(col); - for(pixel_t y = 0; y < sprite.h(); y++) { + for(pixel_t y = 0; y < 8; y++) { dots16_t d = ( (sprite[y] >> first_bit) + (sprite[y] << (16 - first_bit)) ); diff --git a/th01/hardware/grcg8x8m.hpp b/th01/hardware/grcg8x8m.hpp index 8c9fadf2..828085c8 100644 --- a/th01/hardware/grcg8x8m.hpp +++ b/th01/hardware/grcg8x8m.hpp @@ -3,6 +3,6 @@ void grcg_put_8x8_mono( vram_offset_t vram_offset_topleft, char first_bit, - const dot_rect_t(8, 8)& sprite, + const dots8_t sprite[8], int col ); diff --git a/th01/main/boss/b20m.cpp b/th01/main/boss/b20m.cpp index 72743a38..877ab7f0 100644 --- a/th01/main/boss/b20m.cpp +++ b/th01/main/boss/b20m.cpp @@ -20,6 +20,7 @@ extern "C" { #include "th01/math/vector.hpp" #include "th01/hardware/frmdelay.h" #include "th01/hardware/graph.h" +#include "th01/hardware/grcg8x8m.hpp" #include "th01/hardware/egc.h" #include "th01/hardware/palette.h" #include "th01/hardware/ptrans.hpp" @@ -32,6 +33,7 @@ extern "C" { #include "th01/formats/grp.h" #include "th01/formats/ptn.hpp" #include "th01/formats/stagedat.hpp" +#include "th01/sprites/leaf.hpp" #include "th01/sprites/pellet.h" #include "th01/sprites/shape8x8.hpp" #include "th01/main/spawnray.hpp" @@ -232,6 +234,16 @@ static const pixel_t SPAWNCROSS_W = 32; static const pixel_t SPAWNCROSS_H = 32; static const int SPAWNCROSS_CELS = 2; // -------------------------- + +// Leaf splash animation (BOSS6GR4.GRC) +// ------------------------------------ +// Never seen in the original game, due to a ZUN bug in the only pattern that +// uses it. + +static const pixel_t LEAFSPLASH_W = 32; +static const pixel_t LEAFSPLASH_H = 32; +static const int LEAFSPLASH_CELS = 3; +// ------------------------------------ /// ------------- // .PTN @@ -2513,3 +2525,207 @@ void pascal near pattern_curved_spray_leftright_twice(int &frame) #undef spray } + +// Subpixels with one decimal digit of fractional resolution?! Sure, if you +// absolutely want those precise multiples of 0.1 in your movement code... +typedef int decimal_subpixel_t; + +struct DecimalSubpixel { + decimal_subpixel_t v; + + pixel_t to_pixel() const { + return static_cast(v / 10); + } +}; + +inline decimal_subpixel_t to_dsp(float pixel_v) { + return static_cast(pixel_v * 10); +} + +void pascal near pattern_swaying_leaves(int &frame, int spawn_interval_or_reset) +{ + enum { + LEAF_COUNT = 30, + }; + + enum leaf_flag_t { + LF_FREE = 0, + LF_SPARK = 1, + LF_SPLASH = 2, + + // Separate state because it assigns the velocity for the next one. + LF_SPLASH_DONE = (LF_SPLASH + LEAFSPLASH_CELS), + + LF_LEAF, + + _leaf_flag_t_FORCE_INT16 = 0x7FFF, + }; + + #define flag pattern15_flag + #define left pattern15_left + #define top pattern15_top + #define velocity_x pattern15_velocity_x + #define velocity_y pattern15_velocity_y + + extern leaf_flag_t flag[LEAF_COUNT]; + extern DecimalSubpixel left[LEAF_COUNT]; + extern DecimalSubpixel top[LEAF_COUNT]; + extern DecimalSubpixel velocity_x[LEAF_COUNT]; + extern DecimalSubpixel velocity_y[LEAF_COUNT]; + + #define leaf_on_screen(i) \ + overlap_xy_rltb_lt_ge( \ + left[i].v, \ + top[i].v, \ + to_dsp(0.0f), \ + to_dsp(0.0f), \ + to_dsp(RES_X - LEAF_W), \ + to_dsp(RES_Y - LEAF_H) \ + ) + + #define leaf_put(tmp_vo, tmp_first_bit, i, sprite) { \ + if(leaf_on_screen(i)) { \ + vo = vram_offset_divmul(left[i].to_pixel(), top[i].to_pixel()); \ + tmp_first_bit = (left[i].to_pixel() % BYTE_DOTS); \ + grcg_put_8x8_mono(vo, tmp_first_bit, sprite, V_WHITE); \ + } \ + } + + const dot_rect_t(8, 8) sSPARK = sLEAF[0]; + const dot_rect_t(8, 8) sLEAF_LEFT = sLEAF[1]; + const dot_rect_t(8, 8) sLEAF_RIGHT = sLEAF[2]; + int i; + vram_offset_t vo; + int first_bit; + + if(spawn_interval_or_reset == 999) { + for(i = 0; i < LEAF_COUNT; i++) { + flag[i] = LF_FREE; + } + return; + } + if((frame % spawn_interval_or_reset) == 0) { + for(i = 0; i < LEAF_COUNT; i++) { + if(flag[i] != LF_FREE) { + continue; + } + left[i].v = ( + to_dsp(PLAYFIELD_LEFT) + (rand() % to_dsp(PLAYFIELD_W)) + ); + top[i].v = ( + to_dsp(FACE_CENTER_Y) + + (rand() % to_dsp((PLAYFIELD_H * 25) / 84)) + ); + vector2_between( + left[i].to_pixel(), + top[i].to_pixel(), + (PLAYFIELD_LEFT + playfield_rand_x()), + PLAYFIELD_TOP, + velocity_x[i].v, + velocity_y[i].v, + to_dsp(4.0f) + ); + flag[i] = LF_SPARK; + break; + } + } + + if((frame % 2) != 0) { + return; + } + + // Unblit and update + for(i = 0; i < LEAF_COUNT; i++) { + if(flag[i] == LF_FREE) { + continue; + } + if(flag[i] == LF_SPARK) { + if(leaf_on_screen(i)) { + egc_copy_rect_1_to_0_16_word_w( + left[i].to_pixel(), top[i].to_pixel(), LEAF_W, LEAF_H + ); + } + left[i].v += velocity_x[i].v; + top[i].v += velocity_y[i].v; + if(top[i].v < to_dsp(PLAYFIELD_TOP)) { + flag[i] = LF_SPLASH; + } + } else if(flag[i] <= LF_SPLASH_DONE) { + if(leaf_on_screen(i)) { + sloppy_unput_32x32(left[i].to_pixel(), top[i].to_pixel()); + } + if(flag[i] == LF_SPLASH_DONE) { + flag[i] = LF_LEAF; + velocity_y[i].v = (to_dsp(0.3f) + (rand() % to_dsp(0.2f))); + velocity_x[i].v = to_dsp(0.2f); + } + } else if(flag[i] == LF_LEAF) { + if(leaf_on_screen(i)) { + egc_copy_rect_1_to_0_16_word_w( + left[i].to_pixel(), top[i].to_pixel(), LEAF_W, LEAF_H + ); + } + left[i].v += velocity_x[i].v; + top[i].v += velocity_y[i].v; + velocity_y[i].v--; + if(velocity_y[i].v < to_dsp(-0.1f)) { + velocity_y[i].v = (to_dsp(3.0f) + (rand() % to_dsp(2.0f))); + velocity_x[i].v = (velocity_x[i].v < to_dsp(0.0f)) + ? to_dsp(+2.0f) + : to_dsp(-2.0f); + } + if(top[i].to_pixel() > PLAYFIELD_BOTTOM) { + flag[i] = LF_FREE; + } + } + } + + // Render and detect player collisions + for(i = 0; i < LEAF_COUNT; i++) { + if(flag[i] == LF_FREE) { + continue; + } + if(flag[i] == LF_SPARK) { + leaf_put(vo, first_bit, i, sSPARK.row); + } else if(flag[i] <= LF_SPLASH_DONE) { + if(leaf_on_screen(i)) { + // ZUN bug: Another missing conversion to screen pixels, + // resulting in the entire leaf splash animation never being + // actually rendered, and becoming effectively unused. + grc_put_8( + left[i].v, // should be pixels + top[i].v, // should be pixels + GRC_SLOT_LEAFSPLASH, + (flag[i] - LF_SPLASH), + V_WHITE + ); + } + if((frame % 4) == 0) { + static_cast(flag[i])++; + } + } else if(flag[i] == LF_LEAF) { + leaf_put(vo, first_bit, i, ((velocity_x[i].v < to_dsp(0.0f)) + ? sLEAF_LEFT.row + : sLEAF_RIGHT.row + )); + if( + (top[i].v > to_dsp(player_top)) && + (top[i].v < to_dsp(player_bottom() - LEAF_H)) && + (left[i].to_pixel() > player_left) && + (left[i].to_pixel() < (player_left + PLAYER_W - LEAF_W)) && + !player_invincible + ) { + done = true; + } + } + } + + #undef leaf_put + #undef leaf_on_screen + + #undef velocity_y + #undef velocity_x + #undef top + #undef left + #undef flag +} diff --git a/th01/main/shape.cpp b/th01/main/shape.cpp index 831f1465..f73c5579 100644 --- a/th01/main/shape.cpp +++ b/th01/main/shape.cpp @@ -9,7 +9,7 @@ if((left < 0) || (left >= RES_X) || (top < 0) || (top >= RES_Y)) { \ return; \ } \ - grcg_put_8x8_mono(vram_offset_topleft, first_bit, sprite, col); + grcg_put_8x8_mono(vram_offset_topleft, first_bit, sprite.row, col); void shape8x8_diamond_put(screen_x_t left, vram_y_t top, int col) { diff --git a/th01/math/overlap.hpp b/th01/math/overlap.hpp index 0ecae4aa..2aa78c66 100644 --- a/th01/math/overlap.hpp +++ b/th01/math/overlap.hpp @@ -41,6 +41,13 @@ ((y1) >= (top2)) \ ) +#define overlap_xy_rltb_lt_ge(x1, y1, left2, top2, right2, bottom2) ( \ + ((x1) < (right2)) && \ + ((x1) >= (left2)) && \ + ((y1) >= (top2)) && \ + ((y1) < (bottom2)) \ +) + #define overlap_xy_xywh_le_ge(x1, y1, x2, y2, w2, h2) \ overlap_xy_lrtb_le_ge(x1, y1, x2, y2, (x2 + w2), (y2 + h2)) diff --git a/th01/sprites/leaf.bmp b/th01/sprites/leaf.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2a52e4d964ceda01957642ef115e210fa430cfd8 GIT binary patch literal 94 zcmZ?rjbnfSJ0PV2#1cTv0mO_z2m%UV5|jA<|33rA0cHk?AMy+mHFgaDfVjS{jzPk% OhCza_fI)z -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_2BB46 proc near - -@@first_bit = word ptr -1Ah -var_18 = byte ptr -18h -var_10 = byte ptr -10h -var_8 = byte ptr -8 -arg_0 = word ptr 4 -arg_2 = dword ptr 6 - - enter 1Ah, 0 - push si - push di - lea ax, [bp+var_8] - push ss - push ax - push ds - push offset unk_35E7D - mov cx, 8 - call SCOPY@ - lea ax, [bp+var_10] - push ss - push ax - push ds - push offset unk_35E85 - mov cx, 8 - call SCOPY@ - lea ax, [bp+var_18] - push ss - push ax - push ds - push offset unk_35E8D - mov cx, 8 - call SCOPY@ - cmp [bp+arg_0], 3E7h - jnz short loc_2BB9D - xor si, si - jmp short loc_2BB95 -; --------------------------------------------------------------------------- - -loc_2BB8A: - mov bx, si - add bx, bx - mov word ptr [bx+14A1h], 0 - inc si - -loc_2BB95: - cmp si, 1Eh - jl short loc_2BB8A - jmp loc_2C0C4 -; --------------------------------------------------------------------------- - -loc_2BB9D: - les bx, [bp+arg_2] - mov ax, es:[bx] - cwd - idiv [bp+arg_0] - or dx, dx - jnz loc_2BC43 - xor si, si - jmp loc_2BC3C -; --------------------------------------------------------------------------- - -loc_2BBB2: - mov bx, si - add bx, bx - cmp word ptr [bx+14A1h], 0 - jnz short loc_2BC3B - call IRand - mov bx, 1900h - cwd - idiv bx - mov bx, si - add bx, bx - mov [bx+69A1h], dx - call IRand - mov bx, 3E8h - cwd - idiv bx - add dx, 4B0h - mov bx, si - add bx, bx - mov word_3B37D[bx], dx - push 28h ; '(' - push ds - mov ax, si - add ax, ax - add ax, offset word_3B3F5 - push ax - push ds - mov ax, si - add ax, ax - add ax, offset word_3B3B9 - push ax - push 40h - call IRand - mov bx, 280h - cwd - idiv bx - push dx - mov bx, si - add bx, bx - mov ax, word_3B37D[bx] - mov bx, 0Ah - cwd - idiv bx - push ax - mov bx, si - add bx, bx - mov ax, word_3B341[bx] - mov bx, 0Ah - cwd - idiv bx - push ax - call _vector2_between - add sp, 12h - mov bx, si - add bx, bx - mov word ptr [bx+14A1h], 1 - jmp short loc_2BC43 -; --------------------------------------------------------------------------- - -loc_2BC3B: - inc si - -loc_2BC3C: - cmp si, 1Eh - jl loc_2BBB2 - -loc_2BC43: - les bx, [bp+arg_2] - mov ax, es:[bx] - mov bx, 2 - cwd - idiv bx - or dx, dx - jnz loc_2C0C4 - xor si, si - jmp loc_2BE93 -; --------------------------------------------------------------------------- - -loc_2BC5A: - mov bx, si - add bx, bx - cmp word ptr [bx+14A1h], 0 - jz loc_2BE92 - mov bx, si - add bx, bx - cmp word ptr [bx+14A1h], 1 - jnz loc_2BD09 - mov bx, si - add bx, bx - cmp word ptr [bx+69A1h], 18B0h - jge short loc_2BCCE - mov bx, si - add bx, bx - cmp word ptr [bx+69A1h], 0 - jl short loc_2BCCE - mov bx, si - add bx, bx - cmp word ptr [bx+69DDh], 0 - jl short loc_2BCCE - mov bx, si - add bx, bx - cmp word ptr [bx+69DDh], 0F50h - jge short loc_2BCCE - push (8 shl 16) or 16 - mov bx, si - add bx, bx - mov ax, [bx+69DDh] - mov bx, 0Ah - cwd - idiv bx - push ax - mov bx, si - add bx, bx - mov ax, [bx+69A1h] - mov bx, 0Ah - cwd - idiv bx - push ax - call _egc_copy_rect_1_to_0_16 - add sp, 8 - -loc_2BCCE: - mov bx, si - add bx, bx - mov ax, [bx+6A19h] - mov bx, si - add bx, bx - add [bx+69A1h], ax - mov bx, si - add bx, bx - mov ax, [bx+6A55h] - mov bx, si - add bx, bx - add [bx+69DDh], ax - mov bx, si - add bx, bx - cmp word ptr [bx+69DDh], 280h - jge loc_2BE92 - mov bx, si - add bx, bx - mov word ptr [bx+14A1h], 2 - jmp loc_2BE92 -; --------------------------------------------------------------------------- - -loc_2BD09: - mov bx, si - add bx, bx - cmp word ptr [bx+14A1h], 5 - jg loc_2BDAA - mov bx, si - add bx, bx - cmp word ptr [bx+69A1h], 18B0h - jge short loc_2BD70 - mov bx, si - add bx, bx - cmp word ptr [bx+69A1h], 0 - jl short loc_2BD70 - mov bx, si - add bx, bx - cmp word ptr [bx+69DDh], 0 - jl short loc_2BD70 - mov bx, si - add bx, bx - cmp word ptr [bx+69DDh], 0F50h - jge short loc_2BD70 - push (32 shl 16) or 48 - mov bx, si - add bx, bx - mov ax, [bx+69DDh] - mov bx, 0Ah - cwd - idiv bx - push ax - mov bx, si - add bx, bx - mov ax, [bx+69A1h] - mov bx, 0Ah - cwd - idiv bx - push ax - call _egc_copy_rect_1_to_0_16 - add sp, 8 - -loc_2BD70: - mov bx, si - add bx, bx - cmp word ptr [bx+14A1h], 5 - jnz loc_2BE92 - mov bx, si - add bx, bx - mov word ptr [bx+14A1h], 6 - call IRand - mov bx, 2 - cwd - idiv bx - add dx, 3 - mov bx, si - add bx, bx - mov [bx+6A55h], dx - mov bx, si - add bx, bx - mov word ptr [bx+6A19h], 2 - jmp loc_2BE92 -; --------------------------------------------------------------------------- - -loc_2BDAA: - mov bx, si - add bx, bx - cmp word ptr [bx+14A1h], 6 - jnz loc_2BE92 - mov bx, si - add bx, bx - cmp word ptr [bx+69A1h], 18B0h - jge short loc_2BE11 - mov bx, si - add bx, bx - cmp word ptr [bx+69A1h], 0 - jl short loc_2BE11 - mov bx, si - add bx, bx - cmp word ptr [bx+69DDh], 0 - jl short loc_2BE11 - mov bx, si - add bx, bx - cmp word ptr [bx+69DDh], 0F50h - jge short loc_2BE11 - push (8 shl 16) or 16 - mov bx, si - add bx, bx - mov ax, [bx+69DDh] - mov bx, 0Ah - cwd - idiv bx - push ax - mov bx, si - add bx, bx - mov ax, [bx+69A1h] - mov bx, 0Ah - cwd - idiv bx - push ax - call _egc_copy_rect_1_to_0_16 - add sp, 8 - -loc_2BE11: - mov bx, si - add bx, bx - mov ax, [bx+6A19h] - mov bx, si - add bx, bx - add [bx+69A1h], ax - mov bx, si - add bx, bx - mov ax, [bx+6A55h] - mov bx, si - add bx, bx - add [bx+69DDh], ax - mov bx, si - add bx, bx - dec word ptr [bx+6A55h] - mov bx, si - add bx, bx - cmp word ptr [bx+6A55h], 0FFFFh - jge short loc_2BE75 - call IRand - mov bx, 14h - cwd - idiv bx - add dx, 1Eh - mov bx, si - add bx, bx - mov [bx+6A55h], dx - mov bx, si - add bx, bx - cmp word ptr [bx+6A19h], 0 - jge short loc_2BE6A - mov ax, 14h - jmp short loc_2BE6D -; --------------------------------------------------------------------------- - -loc_2BE6A: - mov ax, 0FFECh - -loc_2BE6D: - mov bx, si - add bx, bx - mov [bx+6A19h], ax - -loc_2BE75: - mov bx, si - add bx, bx - mov ax, [bx+69DDh] - mov bx, 0Ah - cwd - idiv bx - cmp ax, 190h - jle short loc_2BE92 - mov bx, si - add bx, bx - mov word ptr [bx+14A1h], 0 - -loc_2BE92: - inc si - -loc_2BE93: - cmp si, 1Eh - jl loc_2BC5A - xor si, si - jmp loc_2C0BD -; --------------------------------------------------------------------------- - -loc_2BE9F: - mov bx, si - add bx, bx - cmp word ptr [bx+14A1h], 0 - jz loc_2C0BC - mov bx, si - add bx, bx - cmp word ptr [bx+14A1h], 1 - jnz loc_2BF45 - mov bx, si - add bx, bx - cmp word ptr [bx+69A1h], 18B0h - jge loc_2C0BC - mov bx, si - add bx, bx - cmp word ptr [bx+69A1h], 0 - jl loc_2C0BC - mov bx, si - add bx, bx - cmp word ptr [bx+69DDh], 0 - jl loc_2C0BC - mov bx, si - add bx, bx - cmp word ptr [bx+69DDh], 0F50h - jge loc_2C0BC - mov bx, si - add bx, bx - mov ax, [bx+69A1h] - mov bx, 0Ah - cwd - idiv bx - mov bx, 8 - cwd - idiv bx - mov bx, si - add bx, bx - push ax - mov ax, [bx+69DDh] - mov bx, 0Ah - cwd - idiv bx - imul ax, ROW_SIZE - pop dx - add dx, ax - mov di, dx - mov bx, si - add bx, bx - mov ax, [bx+69A1h] - mov bx, 0Ah - cwd - idiv bx - mov bx, 8 - cwd - idiv bx - mov [bp+@@first_bit], dx - push 7 ; col - push ss ; sprite (segment) - lea ax, [bp+var_8] - push ax ; sprite (offset) - push dx ; first_bit - push di ; vram_offset_topleft - call _grcg_put_8x8_mono - add sp, 0Ah - jmp loc_2C0BC -; --------------------------------------------------------------------------- - -loc_2BF45: - mov bx, si - add bx, bx - cmp word ptr [bx+14A1h], 5 - jg short loc_2BFC3 - mov bx, si - add bx, bx - cmp word ptr [bx+69A1h], 18B0h - jge short loc_2BFA6 - mov bx, si - add bx, bx - cmp word ptr [bx+69A1h], 0 - jl short loc_2BFA6 - mov bx, si - add bx, bx - cmp word ptr [bx+69DDh], 0 - jl short loc_2BFA6 - mov bx, si - add bx, bx - cmp word ptr [bx+69DDh], 0F50h - jge short loc_2BFA6 - push 7 - mov bx, si - add bx, bx - mov ax, [bx+14A1h] - add ax, 0FFFEh - push ax - push GRC_SLOT_BOSS_4 - mov bx, si - add bx, bx - push word ptr [bx+69DDh] ; top - mov bx, si - add bx, bx - push word ptr [bx+69A1h] ; left - call _grc_put_8 - add sp, 0Ah - -loc_2BFA6: - les bx, [bp+arg_2] - mov ax, es:[bx] - mov bx, 4 - cwd - idiv bx - or dx, dx - jnz loc_2C0BC - mov bx, si - add bx, bx - inc word ptr [bx+14A1h] - jmp loc_2C0BC -; --------------------------------------------------------------------------- - -loc_2BFC3: - mov bx, si - add bx, bx - cmp word ptr [bx+14A1h], 6 - jnz loc_2C0BC - mov bx, si - add bx, bx - cmp word ptr [bx+69A1h], 18B0h - jge loc_2C06B - mov bx, si - add bx, bx - cmp word ptr [bx+69A1h], 0 - jl loc_2C06B - mov bx, si - add bx, bx - cmp word ptr [bx+69DDh], 0 - jl short loc_2C06B - mov bx, si - add bx, bx - cmp word ptr [bx+69DDh], 0F50h - jge short loc_2C06B - mov bx, si - add bx, bx - mov ax, [bx+69A1h] - mov bx, 0Ah - cwd - idiv bx - mov bx, 8 - cwd - idiv bx - mov bx, si - add bx, bx - push ax - mov ax, [bx+69DDh] - mov bx, 0Ah - cwd - idiv bx - imul ax, 50h - pop dx - add dx, ax - mov di, dx - mov bx, si - add bx, bx - mov ax, [bx+69A1h] - mov bx, 0Ah - cwd - idiv bx - mov bx, 8 - cwd - idiv bx - mov [bp+@@first_bit], dx - push 7 ; col - mov bx, si - add bx, bx - cmp word ptr [bx+6A19h], 0 - jge short loc_2C058 - mov dx, ss - lea ax, [bp+var_10] - jmp short loc_2C05D -; --------------------------------------------------------------------------- - -loc_2C058: - mov dx, ss - lea ax, [bp+var_18] - -loc_2C05D: - push dx ; sprite (segment) - push ax ; sprite (offset) - push [bp+@@first_bit] ; first_bit - push di ; vram_offset_topleft - call _grcg_put_8x8_mono - add sp, 0Ah - -loc_2C06B: - mov bx, si - add bx, bx - cmp word ptr [bx+69DDh], 0E60h - jle short loc_2C0BC - mov bx, si - add bx, bx - cmp word ptr [bx+69DDh], 0F50h - jge short loc_2C0BC - mov bx, si - add bx, bx - mov ax, [bx+69A1h] - mov bx, 0Ah - cwd - idiv bx - cmp ax, _player_left - jle short loc_2C0BC - mov bx, si - add bx, bx - mov ax, [bx+69A1h] - mov bx, 0Ah - cwd - idiv bx - mov dx, _player_left - add dx, 24 - cmp ax, dx - jge short loc_2C0BC - cmp _player_invincible, 0 - jnz short loc_2C0BC - mov _done, 1 - -loc_2C0BC: - inc si - -loc_2C0BD: - cmp si, 1Eh - jl loc_2BE9F - -loc_2C0C4: - pop di - pop si - leave - retn 6 -sub_2BB46 endp - - ; =============== S U B R O U T I N E ======================================= ; Attributes: bp-based frame @@ -23936,10 +23324,7 @@ loc_2C9DA: mov _hud_hp_first_white, 10 mov _hud_hp_first_redwhite, 3 mov _sariel_initial_hp_rendered, 0 - push ds - push offset _boss_phase_frame - push 3E7h - call sub_2BB46 + call @pattern_swaying_leaves$qmii pascal, ds, offset _boss_phase_frame, 999 jmp loc_2CDCE ; --------------------------------------------------------------------------- @@ -23980,10 +23365,7 @@ loc_2CB05: jz loc_2CB9D cmp word_35E95, 4 jnz short loc_2CB38 - push ds - push offset _boss_phase_frame - push _sariel_pattern_state - call sub_2BB46 + call @pattern_swaying_leaves$qmii pascal, ds, offset _boss_phase_frame, _sariel_pattern_state cmp _boss_phase_frame, 300 jle short loc_2CBA4 jmp short loc_2CB51 @@ -23992,10 +23374,7 @@ loc_2CB05: loc_2CB38: cmp word_35E95, 5 jnz short loc_2CB59 - push ds - push offset _boss_phase_frame - push 1F4h - call sub_2BB46 + call @pattern_swaying_leaves$qmii pascal, ds, offset _boss_phase_frame, 500 cmp _boss_phase_frame, 200 jle short loc_2CBA4 @@ -24007,10 +23386,7 @@ loc_2CB51: loc_2CB59: cmp word_35E95, 6 jnz short loc_2CB73 - push ds - push offset _boss_phase_frame - push 1F4h - call sub_2BB46 + call @pattern_swaying_leaves$qmii pascal, ds, offset _boss_phase_frame, 500 loc_2CB6A: call @pattern_curved_spray_leftright_o$qmi pascal, ds, offset _boss_phase_frame @@ -24020,10 +23396,7 @@ loc_2CB6A: loc_2CB73: cmp word_35E95, 7 jnz short loc_2CB8D - push ds - push offset _boss_phase_frame - push 1F4h - call sub_2BB46 + call @pattern_swaying_leaves$qmii pascal, ds, offset _boss_phase_frame, 500 loc_2CB84: call @pattern_rain_from_seal_center$qmi pascal, ds, offset _boss_phase_frame @@ -24033,10 +23406,7 @@ loc_2CB84: loc_2CB8D: cmp word_35E95, 8 jnz short loc_2CBA4 - push ds - push offset _boss_phase_frame - push 20h ; ' ' - call sub_2BB46 + call @pattern_swaying_leaves$qmii pascal, ds, offset _boss_phase_frame, 32 loc_2CB9D: call @pattern_curved_spray_leftright_t$qmi pascal, ds, offset _boss_phase_frame @@ -24904,6 +24274,7 @@ _spawnray_target_prev_y dw 999 BIRD_COUNT = 30 VORTEX_COUNT = 2 PARTICLE2X2_COUNT = 30 +LEAF_COUNT = 30 public _birds_alive _birds_alive db BIRD_COUNT dup(0) @@ -24932,31 +24303,11 @@ _particles2x2_wavy_col db PARTICLE2X2_COUNT dup(0) public _particles2x2_horizontal_col _particles2x2_horizontal_col db PARTICLE2X2_COUNT dup(0) - db 60 dup(0) -unk_35E7D db 10h - db 18h - db 18h - db 7Fh - db 0FEh - db 18h - db 18h - db 8 -unk_35E85 db 1 - db 0Eh - db 3Eh ; > - db 7Eh ; ~ - db 7Ch ; | - db 7Ch ; | - db 0F8h - db 0C0h ; À -unk_35E8D db 80h - db 70h ; p - db 7Ch ; | - db 7Eh ; ~ - db 3Eh ; > - db 3Eh ; > - db 1Fh - db 3 +public _pattern15_flag +_pattern15_flag dw LEAF_COUNT dup(0) + +include th01/sprites/leaf.asp + word_35E95 dw 0 word_35E97 dw 0 word_35E99 dw 0 @@ -25444,10 +24795,13 @@ _pattern13_debris_cel_prev dw ? public _pattern14_spray _pattern14_spray CurvedSpray -word_3B341 dw 30 dup(?) -word_3B37D dw 30 dup(?) -word_3B3B9 dw 30 dup(?) -word_3B3F5 dw 30 dup(?) +public _pattern15_left, _pattern15_top +public _pattern15_velocity_x, _pattern15_velocity_y +_pattern15_left dw LEAF_COUNT dup(?) +_pattern15_top dw LEAF_COUNT dup(?) +_pattern15_velocity_x dw LEAF_COUNT dup(?) +_pattern15_velocity_y dw LEAF_COUNT dup(?) + public _sariel_invincible, _sariel_invincibility_frame _sariel_invincible dw ? _sariel_invincibility_frame dw ?