Skip to content

Commit

Permalink
[Reverse-engineering] [th04/th05] Item spawn "splash" circles
Browse files Browse the repository at this point in the history
"Splashes"? That's what uth05win calls them. Oh well, "circle" is
already taken, and merely keeping the slices in the item/ directory
won't avoid the name collision when looking at game code.

These are hardly visible on top of regular enemy explosion animations;
you can most clearly see them at the end of the TH04 Extra Stage
midboss. Easy enough to *almost* completely cover right now, even
during a position independence push. Struct strITEM_SPLASH in uth05win.

Part of P0057, funded by [Anonymous] and -Tom-.
  • Loading branch information
nmlgc committed Nov 13, 2019
1 parent d1acb70 commit 2918e6d
Show file tree
Hide file tree
Showing 7 changed files with 268 additions and 490 deletions.
15 changes: 15 additions & 0 deletions th04/item/splash_dot_render.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
public @item_splash_dot_render
@item_splash_dot_render proc near
mov cx, ax
sar ax, 3
shl dx, 6
add ax, dx
shr dx, 2
add ax, dx
mov bx, ax
mov al, 10000000b
and cl, 7
shr al, cl
mov es:[bx], al
retn
@item_splash_dot_render endp
28 changes: 28 additions & 0 deletions th04/item/splashes.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// An expanding dotted circle, shown when spawning items. Note the slight
// semantic differences to the circle_t structure.
struct item_splash_t {
char flag;
char time; // unused
SPPoint center;
Subpixel radius_cur;
Subpixel radius_prev;
};

#define ITEM_SPLASH_COUNT 8
#if GAME == 5
# define ITEM_SPLASH_DOTS 32
#else
# define ITEM_SPLASH_DOTS 64
#endif
#define ITEM_SPLASH_RADIUS_START 2
#define ITEM_SPLASH_RADIUS_DELTA 2
#define ITEM_SPLASH_RADIUS_END 32

extern item_splash_t item_splashes[ITEM_SPLASH_COUNT];
extern unsigned char item_splash_last_id;

void __fastcall near item_splash_dot_render(int x, int vram_y);
void pascal near item_splashes_init(void);
void pascal near item_splashes_add(Subpixel x, Subpixel y);
void pascal near item_splashes_update(void);
void pascal near item_splashes_render(void);
23 changes: 23 additions & 0 deletions th04/item/splashes[bss].asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
item_splash_t struc
flag db ?
ITEM_SPLASH_time db ?
center Point ?
radius_cur dw ?
radius_prev dw ?
item_splash_t ends

ITEM_SPLASH_COUNT = 8
if GAME eq 5
ITEM_SPLASH_DOTS = 32
else
ITEM_SPLASH_DOTS = 64
endif
ITEM_SPLASH_RADIUS_START = (2 shl 4)
ITEM_SPLASH_RADIUS_DELTA = (2 shl 4)
ITEM_SPLASH_RADIUS_END = (32 shl 4)

public _item_splashes, _item_splash_last_id
_item_splashes item_splash_t ITEM_SPLASH_COUNT dup(<?>)
_item_splashes_unused item_splash_t <?>
_item_splash_last_id db ?
db ?
66 changes: 66 additions & 0 deletions th04/item/splashes_render.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
public ITEM_SPLASHES_RENDER
item_splashes_render proc near

@@radius = word ptr -4
@@i = word ptr -2

enter 4, 0
push si
push di
mov ah, 15
call grcg_setcolor_direct_noint_1
mov si, offset _item_splashes
mov [bp+@@i], 0
jmp short @@more?

@@alive?:
cmp [si+item_splash_t.flag], 1
jnz short @@next_circle
xor di, di
jmp short @@drawn_all_dots?

@@draw:
mov ax, [si+item_splash_t.radius_cur]
mov [bp+@@radius], ax
push offset _drawpoint
push [si+item_splash_t.center.x]
push [si+item_splash_t.center.y]
push ax
push di
call vector2_at
cmp _drawpoint.y, 0
jl short @@next_dot
cmp _drawpoint.y, (PLAYFIELD_H shl 4)
jge short @@next_dot
cmp _drawpoint.x, 0
jl short @@next_dot
cmp _drawpoint.x, (PLAYFIELD_W shl 4)
jge short @@next_dot
mov ax, _drawpoint.y
add ax, (PLAYFIELD_Y shl 4)
call scroll_subpixel_y_to_vram_seg1 pascal, ax
mov dx, ax
mov ax, _drawpoint.x
sar ax, 4
add ax, PLAYFIELD_X
call @item_splash_dot_render

@@next_dot:
add di, 256 / ITEM_SPLASH_DOTS

@@drawn_all_dots?:
cmp di, 256
jl short @@draw

@@next_circle:
inc [bp+@@i]
add si, size item_splash_t

@@more?:
cmp [bp+@@i], ITEM_SPLASH_COUNT
jl short @@alive?
pop di
pop si
leave
retn
item_splashes_render endp
92 changes: 92 additions & 0 deletions th04/item/splashes_update.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
public ITEM_SPLASHES_INIT
item_splashes_init proc near
push bp
mov bp, sp
push di
mov cx, size _item_splashes / 2
mov ax, ds
mov es, ax
assume es:_DATA
xor ax, ax
mov di, offset _item_splashes
rep stosw
mov _item_splash_last_id, 0
pop di
pop bp
retn
item_splashes_init endp


public ITEM_SPLASHES_ADD
item_splashes_add proc near
@@y = word ptr 4
@@x = word ptr 6

push bp
mov bp, sp
push si
mov al, _item_splash_last_id
mov ah, 0
imul ax, size item_splash_t
add ax, offset _item_splashes
mov si, ax
inc _item_splash_last_id
cmp _item_splash_last_id, ITEM_SPLASH_COUNT
jb short @@found
mov _item_splash_last_id, 0

@@found:
cmp [si+item_splash_t.flag], 0
jnz short @@ret
mov [si+item_splash_t.flag], 1
mov ax, [bp+@@x]
mov [si+item_splash_t.center.x], ax
mov ax, [bp+@@y]
mov [si+item_splash_t.center.y], ax
mov [si+item_splash_t.radius_cur], ITEM_SPLASH_RADIUS_START
mov [si+item_splash_t.ITEM_SPLASH_time], 16
mov [si+item_splash_t.radius_prev], ITEM_SPLASH_RADIUS_START

@@ret:
pop si
pop bp
retn 4
item_splashes_add endp


public ITEM_SPLASHES_UPDATE
item_splashes_update proc near
push bp
mov bp, sp
push si
mov si, offset _item_splashes
xor dx, dx
jmp short @@more?

@@loop:
cmp [si+item_splash_t.flag], 0
jz short @@next
cmp [si+item_splash_t.flag], 2
jnz short @@alive
mov [si+item_splash_t.flag], 0
jmp short @@next

@@alive:
mov ax, [si+item_splash_t.radius_cur]
mov [si+item_splash_t.radius_prev], ax
add [si+item_splash_t.radius_cur], ITEM_SPLASH_RADIUS_DELTA
cmp [si+item_splash_t.radius_cur], ITEM_SPLASH_RADIUS_END
jl short @@next
mov [si+item_splash_t.flag], 2

@@next:
inc dx
add si, size item_splash_t

@@more?:
cmp dx, ITEM_SPLASH_COUNT
jl short @@loop
pop si
pop bp
retn
item_splashes_update endp
Loading

0 comments on commit 2918e6d

Please sign in to comment.