[Decompilation] [th03] Hit circles: Rendering

Completes P0280, funded by [Anonymous], Blue Bolt, and JonathKane.
This commit is contained in:
nmlgc 2024-04-22 23:37:08 +02:00
parent 0c6e9e88d0
commit 87eed57ade
5 changed files with 91 additions and 116 deletions

View File

@ -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); \
}

View File

@ -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);
}

6
th03/main/v_colors.hpp Normal file
View File

@ -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,
};

View File

@ -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);

View File

@ -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