From 87eed57ade4e2abd0f12272e568fe65a3643aeb3 Mon Sep 17 00:00:00 2001 From: nmlgc Date: Mon, 22 Apr 2024 23:37:08 +0200 Subject: [PATCH] [Decompilation] [th03] Hit circles: Rendering Completes P0280, funded by [Anonymous], Blue Bolt, and JonathKane. --- libs/sprite16/sprite16.h | 19 +++++++ th03/main/hitcirc.cpp | 63 +++++++++++++++++++- th03/main/v_colors.hpp | 6 ++ th03/sprites/main_s16.hpp | 2 + th03_main.asm | 117 +------------------------------------- 5 files changed, 91 insertions(+), 116 deletions(-) create mode 100644 th03/main/v_colors.hpp diff --git a/libs/sprite16/sprite16.h b/libs/sprite16/sprite16.h index 44f29eb7..09305610 100644 --- a/libs/sprite16/sprite16.h +++ b/libs/sprite16/sprite16.h @@ -39,3 +39,22 @@ static const vram_byte_amount_t SPRITE16_PLANE_SIZE = ( SPRITE16_RES_Y * ROW_SIZE ); static const vram_offset_t SPRITE16_OFFSET = SPRITE16_PLANE_SIZE; + +inline void sprite16_mono(bool enable) { + _AH = SPRITE16_SET_MONO; + _DX = enable; + geninterrupt(SPRITE16); +} + +// ZUN bloat: Remove. +inline void sprite16_mono_(bool enable) { + _DX = enable; + _AH = SPRITE16_SET_MONO; + geninterrupt(SPRITE16); +} + +#define sprite16_mono_color(col) { \ + _AH = SPRITE16_SET_COLOR; \ + _DX = col; \ + geninterrupt(SPRITE16); \ +} diff --git a/th03/main/hitcirc.cpp b/th03/main/hitcirc.cpp index 5e586a6b..4a2da8f7 100644 --- a/th03/main/hitcirc.cpp +++ b/th03/main/hitcirc.cpp @@ -1,15 +1,26 @@ #include "platform.h" +#include "x86real.h" #include "pc98.h" +#include "planar.h" +#include "libs/sprite16/sprite16.h" #include "th03/common.h" #include "th03/math/randring.hpp" +#include "th03/main/frames.h" #include "th03/main/playfld.hpp" #include "th03/main/hitbox.hpp" #include "th03/main/hitcirc.hpp" +#include "th03/main/v_colors.hpp" +extern "C" { +#include "th03/sprites/main_s16.hpp" +} static const pixel_t HITCIRCLE_W = 48; static const pixel_t HITCIRCLE_H = 48; +static const uvram_byte_amount_t HITCIRCLE_VRAM_W = (HITCIRCLE_W / BYTE_DOTS); -static const int HITCIRCLE_FRAMES = 16; +static const int HITCIRCLE_CELS = 4; +static const unsigned int HITCIRCLE_FRAMES_PER_CEL = 4; +static const int HITCIRCLE_FRAMES = (HITCIRCLE_FRAMES_PER_CEL * HITCIRCLE_CELS); static const int HITCIRCLE_ENEMY_COUNT = 12; @@ -33,6 +44,18 @@ struct HitCircle { age = 1; pid = pid_; } + + sprite16_offset_t cel(void) const { + // ZUN bloat: (SO_HITCIRCLE + ( + // ((age - 1) / HITCIRCLE_FRAMES_PER_CEL) * HITCIRCLE_VRAM_W) + // ). 1 SHR, 1 IMUL. This compiles to both those *and* a bunch of MOVs + // and ADDs in between... + static_assert(HITCIRCLE_VRAM_W == 6); + _BX = (age - 1); + _BX /= HITCIRCLE_FRAMES_PER_CEL; + _BX *= 2; + return (SO_HITCIRCLE + _BX + _BX + _BX); + } }; // ZUN bloat: Merge into HitCircle::spawn(). @@ -100,3 +123,41 @@ void near hitcircles_update(void) p++; } } + +void near hitcircles_render(void) +{ + const HitCircle near* p = hitcircles; + + sprite16_mono_(true); + + // ZUN bloat + _DX = round_or_result_frame; + asm { and dx, 1 }; + _DX += V_YELLOW_DARK; + sprite16_mono_color(_DX); + + sprite16_put_size.set(HITCIRCLE_W, HITCIRCLE_H); + + int i = 0; + while(i < HITCIRCLE_ENEMY_COUNT) { + if(p->age) { + sprite16_clip_set_for_pid(p->pid); + sprite16_offset_t so = p->cel(); + sprite16_put(p->topleft.x, p->topleft.y, so); + } + i++; + p++; + } + + // Player circle + static_assert(HITCIRCLE_PLAYER_COUNT == 1); + _DX = V_WHITE; + sprite16_mono_color(_DX); + if(p->age) { + sprite16_clip_set_for_pid(p->pid); + sprite16_offset_t so = p->cel(); + sprite16_put(p->topleft.x, p->topleft.y, so); + } + + sprite16_mono_(false); +} diff --git a/th03/main/v_colors.hpp b/th03/main/v_colors.hpp new file mode 100644 index 00000000..b178fd79 --- /dev/null +++ b/th03/main/v_colors.hpp @@ -0,0 +1,6 @@ +// Commonly used VRAM hardware palette indices in MAIN.EXE. +enum th03_main_vram_colors_t { + V_YELLOW_DARK = 11, + V_YELLOW_BRIGHT = 12, + V_WHITE = 15, +}; diff --git a/th03/sprites/main_s16.hpp b/th03/sprites/main_s16.hpp index 68021cd9..97f292a4 100644 --- a/th03/sprites/main_s16.hpp +++ b/th03/sprites/main_s16.hpp @@ -7,3 +7,5 @@ // Base position for all attack sprites static const sprite16_offset_t SO_ATTACK_P1 = XY(0, 0); static const sprite16_offset_t SO_ATTACK_P2 = XY(320, 0); + +static const sprite16_offset_t SO_HITCIRCLE = XY(128, 80); diff --git a/th03_main.asm b/th03_main.asm index f6603bd3..5d920aa0 100644 --- a/th03_main.asm +++ b/th03_main.asm @@ -300,7 +300,7 @@ loc_986C: call shots_render call sub_164DA call sub_1837C - call sub_B80B + call @hitcircles_render$qv mov _pid_current, 0 mov _pid_PID_so_attack, SO_ATTACK_P1 call p1_1FE74 @@ -2581,124 +2581,11 @@ sub_B60A endp extern @HITCIRCLES_ENEMY_ADD$QIII:proc extern @HITCIRCLES_PLAYER_ADD$QIII:proc @hitcircles_update$qv procdesc near + @hitcircles_render$qv procdesc near HITCIRC_TEXT ends PLAYER_M_TEXT segment byte public 'CODE' use16 -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_B80B proc near - -@@sprite_offset = word ptr -2 - - enter 2, 0 - push si - push di - mov si, offset _hitcircles - mov dx, 1 - mov ah, SPRITE16_SET_MONO - int SPRITE16 - mov dx, _round_or_result_frame - ; Hack (and dx, 1) - db 081h - db 0e2h - db 001h - db 000h - add dx, 11 - mov ah, SPRITE16_SET_COLOR - int SPRITE16 - mov _sprite16_put_w, (48 / 16) - mov _sprite16_put_h, 24 - xor di, di - jmp short loc_B88F -; --------------------------------------------------------------------------- - -loc_B839: - cmp [si+hitcircle_t.HITCIRCLE_age], 0 - jz short loc_B88B - cmp [si+hitcircle_t.HITCIRCLE_pid], 0 - jnz short loc_B852 - mov _sprite16_clip_left, PLAYFIELD1_CLIP_LEFT - mov _sprite16_clip_right, PLAYFIELD1_CLIP_RIGHT - jmp short loc_B85E -; --------------------------------------------------------------------------- - -loc_B852: - mov _sprite16_clip_left, PLAYFIELD2_CLIP_LEFT - mov _sprite16_clip_right, PLAYFIELD2_CLIP_RIGHT - -loc_B85E: - mov al, [si+hitcircle_t.HITCIRCLE_age] - mov ah, 0 - dec ax - mov bx, ax - mov ax, bx - shr ax, 2 - mov bx, ax - mov ax, 2 - imul bx - mov bx, ax - mov ax, bx - add ax, bx - add ax, bx - add ax, 1910h - mov [bp+@@sprite_offset], ax - call sprite16_put pascal, [si+HITCIRCLE_topleft.x], [si+HITCIRCLE_topleft.y], ax - -loc_B88B: - inc di - add si, size hitcircle_t - -loc_B88F: - cmp di, HITCIRCLE_ENEMY_COUNT - jl short loc_B839 - mov dx, V_WHITE - mov ah, SPRITE16_SET_COLOR - int SPRITE16 - cmp [si+hitcircle_t.HITCIRCLE_age], 0 - jz short loc_B8ED - cmp [si+hitcircle_t.HITCIRCLE_pid], 0 - jnz short loc_B8B4 - mov _sprite16_clip_left, PLAYFIELD1_CLIP_LEFT - mov _sprite16_clip_right, PLAYFIELD1_CLIP_RIGHT - jmp short loc_B8C0 -; --------------------------------------------------------------------------- - -loc_B8B4: - mov _sprite16_clip_left, PLAYFIELD2_CLIP_LEFT - mov _sprite16_clip_right, PLAYFIELD2_CLIP_RIGHT - -loc_B8C0: - mov al, [si+hitcircle_t.HITCIRCLE_age] - mov ah, 0 - dec ax - mov bx, ax - mov ax, bx - shr ax, 2 - mov bx, ax - mov ax, 2 - imul bx - mov bx, ax - mov ax, bx - add ax, bx - add ax, bx - add ax, 1910h - mov [bp+@@sprite_offset], ax - call sprite16_put pascal, [si+HITCIRCLE_topleft.x], [si+HITCIRCLE_topleft.y], ax - -loc_B8ED: - xor dx, dx - mov ah, SPRITE16_SET_MONO - int SPRITE16 - pop di - pop si - leave - retn -sub_B80B endp - - ; =============== S U B R O U T I N E ======================================= ; Attributes: bp-based frame