[Decompilation] [th01] Boss entities: 16×8 section unblitting + blitting

Yet another unused function. No idea what it could have been intended
for – no boss sprite has animated sections that small.

But come on, out of all places that could have required the macro form
of a VRAM offset function, it had to be a unused one…

Anyway, that completes the low-level blitting functions for boss
entities!

Part of P0108, funded by Yanga.
This commit is contained in:
nmlgc 2020-08-08 23:11:38 +02:00
parent a2c4aadda9
commit 9ce0034934
4 changed files with 61 additions and 209 deletions

View File

@ -64,11 +64,14 @@ extern dots8_t *VRAM_PLANE_G;
extern dots8_t *VRAM_PLANE_R;
extern dots8_t *VRAM_PLANE_E;
#define VRAM_OFFSET_SHIFT(x, y) \
(x >> 3) + (y << 6) + (y << 4)
#ifdef __cplusplus
// MODDERS: Replace with a single function
static inline unsigned int vram_offset_shift(int x, int y)
{
return (x >> 3) + (y << 6) + (y << 4);
return VRAM_OFFSET_SHIFT(x, y);
}
static inline unsigned int vram_offset_muldiv(int x, int y)

View File

@ -236,6 +236,12 @@ void pascal near vram_put_unaligned_bg_fg(
vram_put_bg_fg(fg.G, VRAM_PLANE_G, vram_offset, bg.G); \
vram_put_bg_fg(fg.E, VRAM_PLANE_E, vram_offset, bg.E);
#define vram_put_bg_word_planar(vram_offset, bg, planes, p) \
vram_put_bg_fg(planes.B[p], VRAM_PLANE_B, vram_offset, bg.B); \
vram_put_bg_fg(planes.R[p], VRAM_PLANE_R, vram_offset, bg.R); \
vram_put_bg_fg(planes.G[p], VRAM_PLANE_G, vram_offset, bg.G); \
vram_put_bg_fg(planes.E[p], VRAM_PLANE_E, vram_offset, bg.E);
#define vram_put_unaligned_bg_fg_planar(vram_offset, bg, fg, first_bit) \
vram_put_unaligned_bg_fg(fg.B, VRAM_PLANE_B, vram_offset, bg.B, first_bit); \
vram_put_unaligned_bg_fg(fg.R, VRAM_PLANE_R, vram_offset, bg.R, first_bit); \
@ -453,4 +459,47 @@ void CBossEntity::egc_sloppy_wave_unput_double_broken(
}
}
}
void CBossEntity::unput_and_put_16x8_8(int bos_left, int bos_top) const
{
int16_t vram_offset_row = vram_offset_shift(cur_left, cur_top);
int bos_row;
size_t bos_p = 0;
int intended_y;
int image = bos_image;
Planar<dots16_t> bg_masked;
bos_image_t &bos = bos_images[bos_slot].image[image];
// Yes, the macro form. Out of all places that could have required it, it
// had to be an originally unused function…
vram_offset_row += VRAM_OFFSET_SHIFT(bos_left, bos_top);
bos_p = (((vram_w / 2) * bos_top) + (bos_left / 16));
if(bos_image_count <= image) {
return;
}
for(bos_row = 0; bos_row < 8; bos_row++) {
int16_t vram_offset = vram_offset_row;
// Note the difference between this and vram_offset_at_intended_y_16()!
intended_y = (bos_left < 0)
? ((vram_offset_row / ROW_SIZE) - 1)
: ((vram_offset_row / ROW_SIZE) - 0);
if(
(((vram_offset + 1) / ROW_SIZE) == intended_y) &&
(vram_offset >= 0) // Clip at the top edge
) {
graph_accesspage_func(1);
vram_snap_masked_planar(bg_masked, vram_offset, bos.alpha[bos_p]);
graph_accesspage_func(0);
vram_put_bg_word_planar(vram_offset, bg_masked, bos.planes, bos_p);
vram_offset += 2;
}
bos_p += (vram_w / 2);
vram_offset_row += ROW_SIZE;
if(vram_offset_row >= PLANE_SIZE) { // Clip at the bottom edge
break;
}
}
}
/// --------

View File

@ -96,5 +96,13 @@ public:
int left_2,
int len_2, int amp_2, int phase_2
) const;
// Blits the 16×8 pixels of [bos_image] in [bos_slot] starting at
// (bos_left, bos_top), relative to the top-left corner of the sprite, to
// ((⌊cur_left/8⌋ + bos_left/8⌋) * 8, (cur_top + bos_top))
// after precisely restoring pixels according to the alpha mask of the
// pixels to be blitted from VRAM page 1.
// Additionally clips at the top and bottom edges of VRAM.
void unput_and_put_16x8_8(int bos_left, int bos_top) const;
/// --------
};

View File

@ -8876,9 +8876,6 @@ main_21_TEXT segment byte public 'CODE' use16
extern @CBossEntity@bos_load$qxnxci:proc
extern @CBossEntity@bos_metadata_get$xqmimuct1t1:proc
extern @CBossEntity@put_8$xqiii:proc
VRAM_SNAP_MASKED procdesc pascal near
VRAM_PUT_BG_FG procdesc pascal near \
fg:word, plane:dword, vram_offset:word, bg_masked:word
extern @CBossEntity@unput_and_put_1line$xqiiii:proc
extern @CBossEntity@unput_and_put_8$xqiii:proc
extern @CBossEntity@wave_put$xqiiiiii:proc
@ -8889,211 +8886,6 @@ main_21__TEXT segment byte public 'CODE' use16
;org 4
assume es:nothing, ss:nothing, ds:_DATA, fs:nothing, gs:nothing
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_164E6 proc far
@@bos = dword ptr -14h
var_10 = word ptr -10h
var_E = word ptr -0Eh
var_C = word ptr -0Ch
var_A = word ptr -0Ah
@@image = word ptr -8
var_6 = word ptr -6
var_4 = word ptr -4
var_2 = word ptr -2
arg_0 = dword ptr 6
arg_4 = word ptr 0Ah
arg_6 = word ptr 0Ch
enter 14h, 0
push si
push di
les bx, [bp+arg_0]
mov ax, es:[bx]
sar ax, 3
mov dx, es:[bx+2]
shl dx, 6
add ax, dx
mov dx, es:[bx+2]
shl dx, 4
add ax, dx
mov [bp+var_2], ax
xor di, di
mov ax, es:[bx+24h]
mov [bp+@@image], ax
mov al, es:[bx+31h]
mov ah, 0
imul ax, size bos_t
mov dx, [bp+@@image]
imul dx, size bos_image_t
add ax, dx
add ax, offset _bos_images
mov word ptr [bp+@@bos+2], ds
mov word ptr [bp+@@bos], ax
mov ax, [bp+arg_4]
sar ax, 3
mov dx, [bp+arg_6]
shl dx, 6
add ax, dx
mov dx, [bp+arg_6]
shl dx, 4
add ax, dx
add [bp+var_2], ax
mov ax, es:[bx+8]
cwd
sub ax, dx
sar ax, 1
imul [bp+arg_6]
push ax
mov ax, [bp+arg_4]
mov bx, 10h
cwd
idiv bx
pop dx
add dx, ax
mov di, dx
mov bx, word ptr [bp+arg_0]
mov ax, es:[bx+20h]
cmp ax, [bp+@@image]
jle loc_166CE
mov [bp+var_4], 0
jmp loc_166C6
; ---------------------------------------------------------------------------
loc_16578:
mov si, [bp+var_2]
cmp [bp+arg_4], 0
jge short loc_1658D
mov ax, [bp+var_2]
mov bx, 50h ; 'P'
cwd
idiv bx
dec ax
jmp short loc_16596
; ---------------------------------------------------------------------------
loc_1658D:
mov ax, [bp+var_2]
mov bx, 50h ; 'P'
cwd
idiv bx
loc_16596:
mov [bp+var_6], ax
lea ax, [si+1]
mov bx, 50h ; 'P'
cwd
idiv bx
cmp ax, [bp+var_6]
jnz loc_166AA
or si, si
jl loc_166AA
push 1
call _graph_accesspage_func
push ss
lea ax, [bp+var_10]
push ax
pushd [_VRAM_PLANE_B]
push si
les bx, [bp+@@bos]
les bx, es:[bx+bos_image_t.BOS_alpha]
mov ax, di
add ax, ax
add bx, ax
push word ptr es:[bx]
call vram_snap_masked
push ss
lea ax, [bp+var_E]
push ax
pushd [_VRAM_PLANE_R]
push si
les bx, [bp+@@bos]
les bx, es:[bx+bos_image_t.BOS_alpha]
mov ax, di
add ax, ax
add bx, ax
push word ptr es:[bx]
call vram_snap_masked
push ss
lea ax, [bp+var_C]
push ax
pushd [_VRAM_PLANE_G]
push si
les bx, [bp+@@bos]
les bx, es:[bx+bos_image_t.BOS_alpha]
mov ax, di
add ax, ax
add bx, ax
push word ptr es:[bx]
call vram_snap_masked
push ss
lea ax, [bp+var_A]
push ax
pushd [_VRAM_PLANE_E]
push si
les bx, [bp+@@bos]
les bx, es:[bx+bos_image_t.BOS_alpha]
mov ax, di
add ax, ax
add bx, ax
push word ptr es:[bx]
call vram_snap_masked
push 0
call _graph_accesspage_func
add sp, 4
les bx, [bp+@@bos]
les bx, es:[bx+bos_image_t.BOS_B]
mov ax, di
add ax, ax
add bx, ax
call vram_put_bg_fg pascal, word ptr es:[bx], large [_VRAM_PLANE_B], si, [bp+var_10]
les bx, [bp+@@bos]
les bx, es:[bx+bos_image_t.BOS_R]
mov ax, di
add ax, ax
add bx, ax
call vram_put_bg_fg pascal, word ptr es:[bx], large [_VRAM_PLANE_R], si, [bp+var_E]
les bx, [bp+@@bos]
les bx, es:[bx+bos_image_t.BOS_G]
mov ax, di
add ax, ax
add bx, ax
call vram_put_bg_fg pascal, word ptr es:[bx], large [_VRAM_PLANE_G], si, [bp+var_C]
les bx, [bp+@@bos]
les bx, es:[bx+bos_image_t.BOS_E]
mov ax, di
add ax, ax
add bx, ax
call vram_put_bg_fg pascal, word ptr es:[bx], large [_VRAM_PLANE_E], si, [bp+var_A]
add si, 2
loc_166AA:
les bx, [bp+arg_0]
mov ax, es:[bx+8]
cwd
sub ax, dx
sar ax, 1
add di, ax
add [bp+var_2], 50h ; 'P'
cmp [bp+var_2], 7D00h
jge short loc_166CE
inc [bp+var_4]
loc_166C6:
cmp [bp+var_4], 8
jl loc_16578
loc_166CE:
pop di
pop si
leave
retf
sub_164E6 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame