From c04ca8da91c8072b272fc3275988698435592664 Mon Sep 17 00:00:00 2001 From: nmlgc Date: Sun, 6 Feb 2022 17:24:09 +0100 Subject: [PATCH] [Reverse-engineering] [th03] Collision bitmap: Drawing slopes (undecompilable) Reason: Self-modifying. -.- Only used in Chiyuri's EX Attack (the one with the diagonal lasers). Part of P0182, funded by Lmocinemod and [Anonymous]. --- Makefile.mak | 2 +- Tupfile | 1 + Tupfile.bat | 1 + th03/collmap.asm | 1 + th03/main/collmap.asm | 120 ++++++++++++++++++++++++++++++++++++++++++ th03/main/collmap.hpp | 11 ++++ th03/main/collmap.inc | 2 + th03_main.asm | 84 ++++------------------------- 8 files changed, 146 insertions(+), 76 deletions(-) create mode 100644 th03/collmap.asm create mode 100644 th03/main/collmap.asm diff --git a/Makefile.mak b/Makefile.mak index 50f17245..e8c8aa70 100644 --- a/Makefile.mak +++ b/Makefile.mak @@ -98,7 +98,7 @@ bin\th03\op.exe: th03\op_01.cpp th03\op_02.cpp bin\th03\scoredat.obj th03\op_03. $** | -bin\th03\main.exe: bin\th03\main.obj th03\main_01.cpp bin\th03\cfg_lres.obj bin\th01\vplanset.obj bin\th02\snd_mode.obj bin\th02\snd_pmdr.obj bin\th03\vector2.obj bin\th03\exit.obj bin\th03\vector1.obj bin\th02\frmdely1.obj bin\th03\input_s.obj bin\th02\snd_se_r.obj bin\th03\snd_se.obj bin\th03\snd_kaja.obj bin\th03\initmain.obj bin\th03\pi_load.obj bin\th03\inp_m_w.obj bin\th03\hfliplut.obj th03\mrs.cpp th03\sprite16.cpp +bin\th03\main.exe: bin\th03\main.obj th03\main_01.cpp bin\th03\cfg_lres.obj bin\th01\vplanset.obj bin\th02\snd_mode.obj bin\th02\snd_pmdr.obj bin\th03\vector2.obj bin\th03\exit.obj bin\th03\vector1.obj bin\th02\frmdely1.obj bin\th03\input_s.obj bin\th02\snd_se_r.obj bin\th03\snd_se.obj bin\th03\snd_kaja.obj bin\th03\initmain.obj bin\th03\pi_load.obj bin\th03\inp_m_w.obj bin\th03\collmap.obj bin\th03\hfliplut.obj th03\mrs.cpp th03\sprite16.cpp $(CC) $(CFLAGS) $(LARGE_LFLAGS) -Z -DGAME=3 -nbin\th03\ -eMAIN.EXE @&&| $** | diff --git a/Tupfile b/Tupfile index 1673eec7..f3daad77 100644 --- a/Tupfile +++ b/Tupfile @@ -80,6 +80,7 @@ BMP2ARR = bin\\Pipeline\\bmp2arr.exe : th03\\cdg_put.asm |> !as3 |> : th03\\cdg_p_na.asm |> !as3 |> : th03\\hfliplut.asm |> !as3 |> +: th03\\collmap.asm |> !as3 |> : th03_op.asm |> !as |> bin\\th03\\op.obj : th03_main.asm | \ th03/sprites/score.asp \ diff --git a/Tupfile.bat b/Tupfile.bat index 8abf852a..86e286a2 100644 --- a/Tupfile.bat +++ b/Tupfile.bat @@ -32,6 +32,7 @@ tasm32 /m /mx /kh32768 /t th02_maine.asm bin\th02\maine.obj tasm32 /m /mx /kh32768 /t /DTHIEF libs\sprite16\sprite16.asm bin\th03\zunsp.obj tasm32 /m /mx /kh32768 /t /dGAME=3 th03\cdg_put.asm bin\th03\cdg_put.obj tasm32 /m /mx /kh32768 /t /dGAME=3 th03\cdg_p_na.asm bin\th03\cdg_p_na.obj +tasm32 /m /mx /kh32768 /t /dGAME=3 th03\\collmap.asm bin\th03\collmap.obj tasm32 /m /mx /kh32768 /t /dGAME=3 th03\\hfliplut.asm bin\th03\hfliplut.obj tasm32 /m /mx /kh32768 /t th03_op.asm bin\th03\op.obj tasm32 /m /mx /kh32768 /t th03_main.asm bin\th03\main.obj diff --git a/th03/collmap.asm b/th03/collmap.asm new file mode 100644 index 00000000..f59ad38d --- /dev/null +++ b/th03/collmap.asm @@ -0,0 +1 @@ +include th03/main/collmap.asm diff --git a/th03/main/collmap.asm b/th03/main/collmap.asm new file mode 100644 index 00000000..a4414d38 --- /dev/null +++ b/th03/main/collmap.asm @@ -0,0 +1,120 @@ + .186 + .model use16 large + locals + +include libs/master.lib/macros.inc +include th01/math/subpixel.inc +include th03/common.inc +include th03/main/playfld.inc +include th03/main/collmap.inc + +extrn _collmap_topleft:Point +extrn _collmap_stripe_tile_w:word +extrn _collmap_bottomright:Point +extrn _collmap_pid:byte +extrn _collmap:byte:(PLAYER_COUNT * COLLMAP_SIZE) + +; Sets @@dst to the offset of column @@x inside [collmap]. +offset_x macro @@dst:req, @@x:req + if ((@@dst eq ax) and (@@x eq al)) + ; MODDERS: This performs a 8→16-bit multiplication of AX = (AH * AL). + ; Effectively limits both COLLMAP_H and COLLMAP_MEMORY_W to 8 bits! + mov ah, COLLMAP_H + mul ah + else + .err "Come on, just rewrite this in C++." + endif +endm + +MAIN_04 group COLLMAP_TEXT + + .code + assume cs:MAIN_04 + +public _collmap_set_slope_striped +_collmap_set_slope_striped proc c far + uses si, di + @@collmap_p equ + @@first_bit equ + @@first_bit_wide equ ; Just remove this + @@left equ + @@y_double equ + +SLOPE_STRIPES = (COLLMAP_H / COLLMAP_SLOPE_VSTRIPE_DISTANCE) + + mov bx, (COLLMAP_H - 1) + cmp _collmap_pid, 0 + jz short @@set_collmap_base + add bx, COLLMAP_SIZE + +@@set_collmap_base: + add bx, offset _collmap + mov @@collmap_p_base_player_and_row, bx + + ; @@pattern = ~(0xFF >> collmap_sprite_tile_w); + ; AH needs to be 0x00 for the carry pixel rotate trick below. + mov al, 11111111b + mov cx, _collmap_stripe_tile_w + shr al, cl + not al + xor ah, ah + mov @@pattern, ax + + mov ax, _collmap_bottomright.x + sub ax, _collmap_topleft.x + mov @@slope_subpixel_w, ax + jmp short $+2 + mov @@left, _collmap_bottomright.x + mov @@y_double, (SLOPE_STRIPES - 1) + even + +@@row_loop: + mov ax, @@left + shr ax, (SUBPIXEL_BITS + COLLMAP_TILE_W_BITS) + mov @@first_bit_wide, ax + and @@first_bit_wide, 7 + shr ax, 3 ; AX = ((AX / BYTE_DOTS) * COLLMAP_H) + offset_x ax, al ; + + @@collmap_p_base_player_and_row = word ptr $+1 + mov @@collmap_p, 1234h + add @@collmap_p, ax + + ; Right-rotate the pattern by [first_bit]. If the pattern then extends into + ; a second bitmap byte, that byte's pattern will end up in AH. + @@pattern = word ptr $+1 + mov ax, 1234h + ror ax, @@first_bit + or [@@collmap_p], al + or ah, ah + jz short @@skip_blank + add @@collmap_p, COLLMAP_H + or [@@collmap_p], ah + +@@skip_blank: + dec @@y_double + jz short @@ret + + ; Interpolate new left X coordinate + ; + ; left = (collmap_topleft.x + ( + ; static_cast(slope_subpixel_w * y_double) / SLOPE_STRIPES + ; )); + @@slope_subpixel_w = word ptr $+1 + mov ax, 1234h + imul @@y_double + mov cx, SLOPE_STRIPES + idiv cx ; 32-bit division of DX:AX by CX! + mov @@left, _collmap_topleft.x + add @@left, ax + + sub @@collmap_p_base_player_and_row, COLLMAP_SLOPE_VSTRIPE_DISTANCE + jmp short @@row_loop +; --------------------------------------------------------------------------- + +@@ret: + ret +_collmap_set_slope_striped endp + even + + end diff --git a/th03/main/collmap.hpp b/th03/main/collmap.hpp index 099686ce..9e2c1586 100644 --- a/th03/main/collmap.hpp +++ b/th03/main/collmap.hpp @@ -19,6 +19,8 @@ static const char COLLMAP_TILE_H_BITS = 1; static const size_t COLLMAP_MEMORY_W = ((PLAYFIELD_W / COLLMAP_TILE_W) / 8); static const size_t COLLMAP_H = (PLAYFIELD_H / COLLMAP_TILE_H); static const size_t COLLMAP_SIZE = (COLLMAP_MEMORY_W * COLLMAP_H); + +static const collmap_tile_amount_t COLLMAP_SLOPE_VSTRIPE_DISTANCE = 2; // --------- // Function parameters @@ -38,4 +40,13 @@ extern unsigned char collmap_pid; // Stored as columns from left to right, not rows from top to bottom. extern uint8_t collmap[PLAYER_COUNT][COLLMAP_MEMORY_W][COLLMAP_H]; // ------------------- + +// Sets all bits on every [COLLMAP_SLOPE_VSTRIPE_DISTANCE]th row of a +// potentially sloped vertical line across one whole playfield. +// Takes the following parameters: +// • [collmap_topleft.x] (always uses 0 for [y]) +// • [collmap_bottomright.x] (always uses to_sp(PLAYFIELD_H) for [y]) +// • [collmap_stripe_tile_w] (between 0 and 7) +// • [collmap_pid] +void collmap_set_slope_striped(); /// ---------------- diff --git a/th03/main/collmap.inc b/th03/main/collmap.inc index ba0a1264..ece0b4b6 100644 --- a/th03/main/collmap.inc +++ b/th03/main/collmap.inc @@ -6,3 +6,5 @@ COLLMAP_TILE_H_BITS = 1 COLLMAP_MEMORY_W = ((PLAYFIELD_W / COLLMAP_TILE_W) / 8) COLLMAP_H = (PLAYFIELD_H / COLLMAP_TILE_H) COLLMAP_SIZE = COLLMAP_MEMORY_W * COLLMAP_H + +COLLMAP_SLOPE_VSTRIPE_DISTANCE = 2 diff --git a/th03_main.asm b/th03_main.asm index ced035d4..afe01765 100644 --- a/th03_main.asm +++ b/th03_main.asm @@ -28,6 +28,7 @@ include libs/sprite16/sprite16.inc extern _execl:proc main_01 group main_0_TEXT, CFG_LRES_TEXT, main_01_TEXT +main_04 group main_04_TEXT, COLLMAP_TEXT, main_04__TEXT ; =========================================================================== @@ -16963,7 +16964,7 @@ main_03_TEXT ends ; Segment type: Pure code main_04_TEXT segment byte public 'CODE' use16 - assume cs:main_04_TEXT + assume cs:main_04 ;org 0Ah assume es:nothing, ss:nothing, ds:_DATA, fs:nothing, gs:nothing @@ -17131,80 +17132,13 @@ sub_13B42 endp ; --------------------------------------------------------------------------- nop +main_04_TEXT ends -; =============== S U B R O U T I N E ======================================= +COLLMAP_TEXT segment byte public 'CODE' use16 + extern _collmap_set_slope_striped:proc +COLLMAP_TEXT ends - -sub_13B9A proc far - push si - push di - mov bx, (COLLMAP_H - 1) - cmp _collmap_pid, 0 - jz short loc_13BAA - add bx, COLLMAP_SIZE - -loc_13BAA: - add bx, offset _collmap - mov word ptr cs:loc_13BE9+1, bx - mov al, 11111111b - mov cx, _collmap_stripe_tile_w - shr al, cl - not al - xor ah, ah - mov word ptr cs:loc_13BEE+1, ax - mov ax, _collmap_bottomright.x - sub ax, _collmap_topleft.x - mov word ptr cs:loc_13C02+1, ax - jmp short $+2 - mov si, _collmap_bottomright.x - mov di, 5Bh ; '[' - nop - -loc_13BD8: - mov ax, si - shr ax, 5 - mov cx, ax - and cx, 7 - shr ax, 3 - mov ah, COLLMAP_H - mul ah - -loc_13BE9: - mov bx, 1234h - add bx, ax - -loc_13BEE: - mov ax, 1234h - ror ax, cl - or [bx], al - or ah, ah - jz short loc_13BFF - add bx, COLLMAP_H - or [bx], ah - -loc_13BFF: - dec di - jz short loc_13C1A - -loc_13C02: - mov ax, 1234h - imul di - mov cx, 5Ch - idiv cx - mov si, _collmap_topleft.x - add si, ax - sub word ptr cs:loc_13BE9+1, 2 - jmp short loc_13BD8 -; --------------------------------------------------------------------------- - -loc_13C1A: - pop di - pop si - retf -sub_13B9A endp - -; --------------------------------------------------------------------------- - nop +main_04__TEXT segment byte public 'CODE' use16 ; =============== S U B R O U T I N E ======================================= @@ -25980,7 +25914,7 @@ loc_183B9: retf sub_1837C endp -main_04_TEXT ends +main_04__TEXT ends ; =========================================================================== @@ -27625,7 +27559,7 @@ loc_192DB: add si, 20h ; ' ' mov ax, [si+2] mov _collmap_bottomright.x, ax - call sub_13B9A + call _collmap_set_slope_striped jmp short loc_1930C ; ---------------------------------------------------------------------------