[Reverse-engineering] [th04/th05] ZUN Soft logo explosions

Which seemed a nicer and more debuggable intro to how ZUN implements
sprites than starting with a random structure from MAIN.EXE.

Funded by -Tom-.
This commit is contained in:
nmlgc 2018-03-21 23:20:04 +01:00
parent 6b0d0c6940
commit 843905ecea
4 changed files with 270 additions and 2360 deletions

237
th04/zunsoft.asm Normal file
View File

@ -0,0 +1,237 @@
; Spawns [n] new explosions at [origin].
; [origin] uses screen pixels, *not* the 1/16th-pixel units of the structure.
; void pascal zunsoft_pyro_new(Point origin, int n, char patnum_base)
_zunsoft_pyro_new proc pascal near
local @@pyros_created:word, @@i:word
arg @@origin:Point, @@n:word, @@patnum_base:byte
push si
push di
mov di, @@origin.y
mov @@pyros_created, 0
mov ax, 16
imul @@origin.x
mov @@origin.x, ax
mov ax, 16
imul di
mov di, ax
mov si, offset _zunsoft_pyros
mov @@i, 0
jmp short loc_B68D
loc_B63E:
cmp [si+zunsoft_pyro_t.alive], 0
jnz short loc_B687
mov [si+zunsoft_pyro_t.alive], 1
mov [si+zunsoft_pyro_t.frame], 0
mov [si+zunsoft_pyro_t.origin.x], di
mov ax, @@origin.x
mov [si+zunsoft_pyro_t.origin.y], ax
mov [si+zunsoft_pyro_t.distance], 0
mov [si+zunsoft_pyro_t.distance_prev], 0
call IRand
mov bx, 224
cwd
idiv bx
add dx, 64
mov [si+zunsoft_pyro_t.speed], dx
call IRand
mov [si+zunsoft_pyro_t.angle], al
mov al, @@patnum_base
mov [si+zunsoft_pyro_t.patnum_base], al
inc @@pyros_created
mov ax, @@pyros_created
cmp ax, @@n
jge short loc_B694
loc_B687:
inc @@i
add si, size zunsoft_pyro_t
loc_B68D:
cmp @@i, ZUNSOFT_PYRO_COUNT
jl short loc_B63E
loc_B694:
pop di
pop si
ret
_zunsoft_pyro_new endp
; void pascal zunsoft_update_and_render(void)
_zunsoft_update_and_render proc pascal near
local @@patnum:word, @@draw_y:word, @@draw_x:word, @@anim_sprite:word
push si
push di
mov si, offset _zunsoft_pyros
xor di, di
jmp loc_B7B9
loc_B6A8:
cmp [si+zunsoft_pyro_t.alive], 1
jnz loc_B7B5
inc [si+zunsoft_pyro_t.frame]
mov al, [si+zunsoft_pyro_t.frame]
mov ah, 0
mov bx, 4
cwd
idiv bx
mov @@anim_sprite, ax
mov al, [si+zunsoft_pyro_t.patnum_base]
mov ah, 0
add ax, @@anim_sprite
mov @@patnum, ax
cmp [si+zunsoft_pyro_t.frame], 40
jb short loc_B6DB
mov [si+zunsoft_pyro_t.alive], 0
mov [si+zunsoft_pyro_t.frame], 0
jmp loc_B7B5
loc_B6DB:
cmp [si+zunsoft_pyro_t.frame], 16
jnb short loc_B6FA
mov ax, [si+zunsoft_pyro_t.origin.x]
mov bx, 16
cwd
idiv bx
add ax, -8
push ax
mov ax, [si+zunsoft_pyro_t.origin.y]
cwd
idiv bx
add ax, -8
jmp loc_B7AC
loc_B6FA:
cmp [si+zunsoft_pyro_t.frame], 32
jnb short loc_B754
cmp [si+zunsoft_pyro_t.frame], 16
jnz short loc_B70D
call snd_se_play pascal, 15
loc_B70D:
mov ax, [si+zunsoft_pyro_t.distance]
mov [si+zunsoft_pyro_t.distance_prev], ax
mov ax, [si+zunsoft_pyro_t.speed]
add [si+zunsoft_pyro_t.distance], ax
push [si+zunsoft_pyro_t.origin.x]
push [si+zunsoft_pyro_t.distance]
mov al, [si+zunsoft_pyro_t.angle]
mov ah, 0
add ax, ax
mov bx, ax
push _CosTable8[bx]
call vector1_at
add ax, -128
mov @@draw_x, ax
push [si+zunsoft_pyro_t.origin.y]
push [si+zunsoft_pyro_t.distance]
mov al, [si+zunsoft_pyro_t.angle]
mov ah, 0
add ax, ax
mov bx, ax
push _SinTable8[bx]
call vector1_at
add ax, -128
jmp short loc_B799
loc_B754:
mov ax, [si+zunsoft_pyro_t.distance]
mov [si+zunsoft_pyro_t.distance_prev], ax
mov ax, [si+zunsoft_pyro_t.speed]
add [si+zunsoft_pyro_t.distance], ax
push [si+zunsoft_pyro_t.origin.x]
push [si+zunsoft_pyro_t.distance]
mov al, [si+zunsoft_pyro_t.angle]
mov ah, 0
add ax, ax
mov bx, ax
push _CosTable8[bx]
call vector1_at
add ax, -256
mov @@draw_x, ax
push [si+zunsoft_pyro_t.origin.y]
push [si+zunsoft_pyro_t.distance]
mov al, [si+zunsoft_pyro_t.angle]
mov ah, 0
add ax, ax
mov bx, ax
push _SinTable8[bx]
call vector1_at
add ax, -256
loc_B799:
mov @@draw_y, ax
mov ax, @@draw_x
mov bx, 16
cwd
idiv bx
push ax
mov ax, @@draw_y
cwd
idiv bx
loc_B7AC:
push ax
push @@patnum
call super_put_rect
loc_B7B5:
inc di
add si, size zunsoft_pyro_t
loc_B7B9:
cmp di, ZUNSOFT_PYRO_COUNT
jl loc_B6A8
pop di
pop si
ret
_zunsoft_update_and_render endp
; void pascal zunsoft_palette_update_and_show(int tone)
_zunsoft_palette_update_and_show proc near
arg @@tone:word
push bp
mov bp, sp
push si
push di
xor si, si
jmp short loc_B7F6
loc_B7CE:
xor di, di
jmp short loc_B7F0
loc_B7D2:
mov bx, si
imul bx, 3
mov al, _zunsoft_palette[bx+di]
mov ah, 0
imul @@tone
mov bx, 100
cwd
idiv bx
mov bx, si
imul bx, 3
mov Palettes[bx+di], al
inc di
loc_B7F0:
cmp di, 3
jl short loc_B7D2
inc si
loc_B7F6:
cmp si, 15
jl short loc_B7CE
call palette_show
pop di
pop si
pop bp
retn 2
_zunsoft_palette_update_and_show endp

23
th04/zunsoft[bss].asm Normal file
View File

@ -0,0 +1,23 @@
; Copy of the palette used during the logo, to allow non-blocking fades in
; contrast to master.lib's blocking palette_black_in() and palette_black_out()
; functions. (Then again, master.lib has the PaletteTone global for that...)
_zunsoft_palette db 48 dup(?)
; ZUN Soft logo explosion structure.
; These are only animated by increasing the distance; origin, angle, and speed
; stay constant.
; For increased precision, all coordinates (origin, distance, and speed) are
; stored in units of 1/16th of a pixel.
zunsoft_pyro_t struc
alive db ?
frame db ? ; since creation
origin Point ?
distance_prev dw ? ; unused
distance dw ?
speed dw ?
angle db ?
patnum_base db ? ; displayed sprite is incremented every 4 frames
zunsoft_pyro_t ends
ZUNSOFT_PYRO_COUNT = 256
_zunsoft_pyros zunsoft_pyro_t ZUNSOFT_PYRO_COUNT dup(<?>)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff