mirror of https://github.com/nmlgc/ReC98.git
[Decompilation] [th01] Player: Miss animation
And even the final function in this 3-push series comes with a potential visual glitch… Completes P0164, funded by Yanga.
This commit is contained in:
parent
f1fdc3e3fd
commit
7a0e5d8d85
|
@ -1,5 +1,7 @@
|
|||
extern "C" {
|
||||
#include "th01/hardware/frmdelay.h"
|
||||
#include "th01/hardware/input.hpp"
|
||||
#include "th01/hardware/scrollup.hpp"
|
||||
#include "th01/snd/mdrv2.h"
|
||||
#include "th01/sprites/main_ptn.h"
|
||||
#include "th01/main/vars.hpp"
|
||||
|
@ -7,11 +9,14 @@ extern "C" {
|
|||
}
|
||||
#include "th01/formats/pf.hpp"
|
||||
#include "th01/resident.hpp"
|
||||
#include "th01/math/subpixel.hpp"
|
||||
#include "th01/main/hud/hud.hpp"
|
||||
#include "th01/main/player/anim.hpp"
|
||||
#include "th01/main/player/orb.hpp"
|
||||
#include "th01/main/player/shots.hpp"
|
||||
#include "th01/main/bullet/pellet.hpp"
|
||||
#include "th01/main/bullet/pellet_s.hpp"
|
||||
#include "th01/main/stage/timer.hpp"
|
||||
|
||||
/// Durations
|
||||
/// ---------
|
||||
|
@ -957,3 +962,106 @@ void orb_player_hittest(int repel_friction)
|
|||
orb_force_new(ORB_FORCE_REPEL_CONSTANT, OF_IMMEDIATE);
|
||||
}
|
||||
}
|
||||
|
||||
#define miss_effect_put(left, frame) \
|
||||
ptn_put_8(left, player_top, (PTN_MISS_EFFECT + (frame % MISS_EFFECT_CELS)))
|
||||
|
||||
void player_miss_animate_and_update(void)
|
||||
{
|
||||
int frame;
|
||||
screen_x_t effect_left;
|
||||
screen_x_t moveout_target_right;
|
||||
screen_x_t moveout_target_left;
|
||||
int prev_bombs;
|
||||
|
||||
// Miss sprite and shake
|
||||
// ---------------------
|
||||
// ZUN bug: This should have been the 48×48 unblitting call that's done
|
||||
// after the shake. It's easily possible to get hit during an 48×48
|
||||
// animation, which will end up leaving the extra pixels on screen during
|
||||
// the next 16 frames.
|
||||
ptn_sloppy_unput_16(player_left, player_top);
|
||||
|
||||
ptn_put_8(orb_cur_left, orb_cur_top, PTN_ORB);
|
||||
player_put(PTN_MIKO_MISS + (
|
||||
(rand() % 8) == 0 ? (PTN_MIKO_MISS_ALTERNATE - PTN_MIKO_MISS) : 0
|
||||
));
|
||||
|
||||
for(frame = 0; frame < 16; frame++) {
|
||||
z_vsync_wait_and_scrollup(RES_Y - ((frame % 2) * 8));
|
||||
frame_delay(2);
|
||||
}
|
||||
z_vsync_wait_and_scrollup(0);
|
||||
// ---------------------
|
||||
|
||||
egc_copy_rect_1_to_0_16(
|
||||
player_48_left_for(player_left), player_48x48_top(), 48, 48
|
||||
);
|
||||
|
||||
Shots.unput_and_reset_all();
|
||||
Pellets.decay_all();
|
||||
player_unput_update_render(false);
|
||||
|
||||
// Effect
|
||||
// ------
|
||||
enum {
|
||||
MOVEOUT_FRAMES = 10,
|
||||
MOVEIN_FRAMES = 20,
|
||||
FRAMES = (MOVEOUT_FRAMES + MOVEIN_FRAMES),
|
||||
|
||||
MOVEOUT_DISTANCE_X = (PLAYFIELD_W / 4),
|
||||
MOVEOUT_DISTANCE_PER_FRAME_X = (MOVEOUT_DISTANCE_X / MOVEOUT_FRAMES),
|
||||
};
|
||||
|
||||
moveout_target_right = (player_left + MOVEOUT_DISTANCE_X);
|
||||
if(moveout_target_right >= PLAYER_LEFT_MAX) {
|
||||
moveout_target_right = PLAYER_LEFT_MAX;
|
||||
}
|
||||
moveout_target_left = (player_left - MOVEOUT_DISTANCE_X);
|
||||
if(moveout_target_left < PLAYER_LEFT_MIN) {
|
||||
moveout_target_left = PLAYER_LEFT_MIN;
|
||||
}
|
||||
|
||||
effect_left = player_left;
|
||||
for(frame = 0; frame < FRAMES; frame++) {
|
||||
ptn_sloppy_unput_16(player_left, player_top);
|
||||
ptn_sloppy_unput_16(effect_left, player_top);
|
||||
|
||||
player_left += (frame < MOVEOUT_FRAMES)
|
||||
? +MOVEOUT_DISTANCE_PER_FRAME_X
|
||||
: ((PLAYER_LEFT_START - moveout_target_right) / MOVEIN_FRAMES);
|
||||
effect_left += (frame < MOVEOUT_FRAMES)
|
||||
? -MOVEOUT_DISTANCE_PER_FRAME_X
|
||||
: ((PLAYER_LEFT_START - moveout_target_left) / MOVEIN_FRAMES);
|
||||
|
||||
if(player_left >= PLAYER_LEFT_MAX) {
|
||||
player_left = PLAYER_LEFT_MAX;
|
||||
}
|
||||
if(effect_left < PLAYER_LEFT_MIN) {
|
||||
effect_left = PLAYER_LEFT_MIN;
|
||||
}
|
||||
|
||||
// We might have accidentally unblitted it earlier, after all.
|
||||
ptn_put_8(orb_cur_left, orb_cur_top, PTN_ORB);
|
||||
|
||||
miss_effect_put(player_left, frame);
|
||||
miss_effect_put(effect_left, frame);
|
||||
frame_delay((frame < 6) ? 1 : (((FRAMES - frame) / 10) + 1));
|
||||
}
|
||||
|
||||
ptn_sloppy_unput_16(player_left, player_top);
|
||||
ptn_sloppy_unput_16(effect_left, player_top);
|
||||
// ------
|
||||
|
||||
hud_lives_put(lives + 1);
|
||||
|
||||
prev_bombs = bombs;
|
||||
bombs = (credit_bombs + bombs);
|
||||
if(bombs > BOMBS_MAX) {
|
||||
bombs = BOMBS_MAX;
|
||||
} else {
|
||||
hud_bombs_put(prev_bombs);
|
||||
}
|
||||
timer_extend_and_put();
|
||||
pellet_speed_lower(0.0f, -0.05f);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,12 @@ void invincibility_sprites_update_and_render(bool16 invincible);
|
|||
// instead.
|
||||
void player_unput_update_render(bool16 do_not_reset_player_state);
|
||||
|
||||
// Shows the player hit/respawn animation in a blocking way, and updates the
|
||||
// HUD to reflect the lost life, together with all related game state. Except
|
||||
// for, ironically, [lives], which is assumed to have been decremented prior
|
||||
// to calling this function.
|
||||
void player_miss_animate_and_update(void);
|
||||
|
||||
extern bool player_deflecting;
|
||||
extern bool player_sliding;
|
||||
extern bool16 player_invincible;
|
||||
|
|
|
@ -8,6 +8,7 @@ static const int CARDCOMBO_DIGITS = 2;
|
|||
static const int PORTAL_ANIM_CELS = 2;
|
||||
static const int TIMER_DIGITS = 4;
|
||||
|
||||
static const int MISS_EFFECT_CELS = 2;
|
||||
static const int DASH_CELS = 2;
|
||||
|
||||
typedef enum {
|
||||
|
@ -65,6 +66,12 @@ typedef enum {
|
|||
PTN_MIKO_R_CAST,
|
||||
PTN_MIKO_R_DASH_SHOOT,
|
||||
PTN_MIKO_R_DASH_SHOOT_last = (PTN_MIKO_R_DASH_SHOOT + DASH_CELS - 1),
|
||||
|
||||
PTN_MISS_EFFECT = PTN_ID(PTN_SLOT_MIKO, 20),
|
||||
PTN_MISS_EFFECT_last = (PTN_MISS_EFFECT + MISS_EFFECT_CELS - 1),
|
||||
|
||||
PTN_MIKO_MISS,
|
||||
PTN_MIKO_MISS_ALTERNATE,
|
||||
// --------
|
||||
|
||||
// HUD (snapped backgrounds)
|
||||
|
|
217
th01_reiiden.asm
217
th01_reiiden.asm
|
@ -63,7 +63,6 @@ main_01 group main_010_TEXT, main_011_TEXT, main_012_TEXT, main_013_TEXT
|
|||
main_15 group main_15_TEXT, main_15__TEXT
|
||||
main_19 group main_19_TEXT, main_19__TEXT
|
||||
main_21 group main_21_TEXT, main_21__TEXT
|
||||
main_27 group main_27_TEXT, main_27__TEXT
|
||||
main_29 group main_29_TEXT, main_29__TEXT
|
||||
main_31 group main_31_TEXT, main_31__TEXT
|
||||
main_32 group main_32_TEXT, main_32__TEXT
|
||||
|
@ -3163,7 +3162,7 @@ loc_DE72:
|
|||
les bx, _resident
|
||||
dec es:[bx+reiidenconfig_t.rem_lives]
|
||||
dec _lives
|
||||
call sub_1AE0D
|
||||
call _player_miss_animate_and_update
|
||||
mov _done, 0
|
||||
inc si
|
||||
mov _player_invincibility_time, MISS_INVINCIBILITY_FRAMES
|
||||
|
@ -5987,7 +5986,6 @@ main_25_TEXT segment byte public 'CODE' use16
|
|||
extern @hud_score_and_cardcombo_render$qv:proc
|
||||
extern @hud_bg_load$qnxc:proc
|
||||
extern @hud_lives_put$qi:proc
|
||||
extern @hud_bombs_put$qi:proc
|
||||
extern @hud_bg_snap_and_put$qv:proc
|
||||
main_25_TEXT ends
|
||||
|
||||
|
@ -5996,228 +5994,21 @@ main_25_TEXT ends
|
|||
; Segment type: Pure code
|
||||
main_26_TEXT segment byte public 'CODE' use16
|
||||
extern @timer_tick_and_put$qv:proc
|
||||
extern @timer_extend_and_put$qv:proc
|
||||
main_26_TEXT ends
|
||||
|
||||
; ===========================================================================
|
||||
|
||||
; Segment type: Pure code
|
||||
main_27_TEXT segment byte public 'CODE' use16
|
||||
main_27_TEXT ends
|
||||
|
||||
main_27__TEXT segment byte public 'CODE' use16
|
||||
assume cs:main_27
|
||||
;org 0Eh
|
||||
assume es:nothing, ss:nothing, ds:_DATA, fs:nothing, gs:nothing
|
||||
|
||||
OR_NONE = 0
|
||||
|
||||
extern _ptn_unput_8:proc
|
||||
extern _ptn_put_8:proc
|
||||
extern _ptn_put_quarter_8:proc
|
||||
extern _ptn_put_quarter:proc
|
||||
extern _player_unput_update_render:proc
|
||||
OR_NONE = 0
|
||||
extern @orb_player_hittest$qi:proc
|
||||
|
||||
; =============== S U B R O U T I N E =======================================
|
||||
|
||||
; Attributes: bp-based frame
|
||||
|
||||
sub_1AE0D proc far
|
||||
|
||||
@@prev_bombs = word ptr -6
|
||||
var_4 = word ptr -4
|
||||
var_2 = word ptr -2
|
||||
|
||||
enter 6, 0
|
||||
push si
|
||||
push di
|
||||
call _egc_copy_rect_1_to_0_16 c, _player_left, _player_top, large (32 shl 16) or 32
|
||||
call _ptn_put_8 c, _orb_cur_left, _orb_cur_top, PTN_ORB
|
||||
call IRand
|
||||
mov bx, 8
|
||||
cwd
|
||||
idiv bx
|
||||
or dx, dx
|
||||
jnz short loc_1AE4D
|
||||
mov ax, 1
|
||||
jmp short loc_1AE4F
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1AE4D:
|
||||
xor ax, ax
|
||||
|
||||
loc_1AE4F:
|
||||
add ax, 56h
|
||||
call _ptn_put_8 c, _player_left, _player_top, ax
|
||||
xor si, si
|
||||
jmp short loc_1AE85
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1AE65:
|
||||
mov ax, si
|
||||
mov bx, 2
|
||||
cwd
|
||||
idiv bx
|
||||
shl dx, 3
|
||||
mov ax, RES_Y
|
||||
sub ax, dx
|
||||
call _z_vsync_wait_and_scrollup stdcall, ax
|
||||
pop cx
|
||||
push 2
|
||||
call _frame_delay
|
||||
pop cx
|
||||
inc si
|
||||
|
||||
loc_1AE85:
|
||||
cmp si, 16
|
||||
jl short loc_1AE65
|
||||
call _z_vsync_wait_and_scrollup stdcall, 0
|
||||
pop cx
|
||||
push (48 shl 16) or 48
|
||||
push 352
|
||||
mov ax, _player_left
|
||||
add ax, -8
|
||||
push ax
|
||||
call _egc_copy_rect_1_to_0_16
|
||||
add sp, 8
|
||||
call @CShots@unput_and_reset_all$qv c, offset _Shots, ds
|
||||
call @CPellets@decay_all$qv c, offset _Pellets, ds
|
||||
call _player_unput_update_render stdcall, 0
|
||||
pop cx
|
||||
mov ax, _player_left
|
||||
add ax, 160
|
||||
mov [bp+var_2], ax
|
||||
cmp [bp+var_2], PLAYER_LEFT_MAX
|
||||
jl short loc_1AEDE
|
||||
mov [bp+var_2], PLAYER_LEFT_MAX
|
||||
|
||||
loc_1AEDE:
|
||||
mov ax, _player_left
|
||||
add ax, -160
|
||||
mov [bp+var_4], ax
|
||||
cmp [bp+var_4], PLAYER_LEFT_MIN
|
||||
jge short loc_1AEF2
|
||||
mov [bp+var_4], PLAYER_LEFT_MIN
|
||||
|
||||
loc_1AEF2:
|
||||
mov di, _player_left
|
||||
xor si, si
|
||||
jmp loc_1AFC8
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1AEFB:
|
||||
call _egc_copy_rect_1_to_0_16 c, _player_left, _player_top, large (32 shl 16) or 32
|
||||
call _egc_copy_rect_1_to_0_16 c, di, _player_top, large (32 shl 16) or 32
|
||||
cmp si, 0Ah
|
||||
jge short loc_1AF2C
|
||||
mov ax, 16
|
||||
jmp short loc_1AF38
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1AF2C:
|
||||
mov ax, 304
|
||||
sub ax, [bp+var_2]
|
||||
mov bx, 20
|
||||
cwd
|
||||
idiv bx
|
||||
|
||||
loc_1AF38:
|
||||
add _player_left, ax
|
||||
cmp si, 0Ah
|
||||
jge short loc_1AF46
|
||||
mov ax, 0FFF0h
|
||||
jmp short loc_1AF52
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1AF46:
|
||||
mov ax, 304
|
||||
sub ax, [bp+var_4]
|
||||
mov bx, 20
|
||||
cwd
|
||||
idiv bx
|
||||
|
||||
loc_1AF52:
|
||||
add di, ax
|
||||
cmp _player_left, PLAYER_LEFT_MAX
|
||||
jl short loc_1AF62
|
||||
mov _player_left, PLAYER_LEFT_MAX
|
||||
|
||||
loc_1AF62:
|
||||
or di, di
|
||||
jge short loc_1AF68
|
||||
xor di, di
|
||||
|
||||
loc_1AF68:
|
||||
call _ptn_put_8 c, _orb_cur_left, _orb_cur_top, PTN_ORB
|
||||
mov ax, si
|
||||
mov bx, 2
|
||||
cwd
|
||||
idiv bx
|
||||
add dx, 54h
|
||||
call _ptn_put_8 c, _player_left, _player_top, dx
|
||||
mov ax, si
|
||||
mov bx, 2
|
||||
cwd
|
||||
idiv bx
|
||||
add dx, 54h
|
||||
call _ptn_put_8 c, di, _player_top, dx
|
||||
cmp si, 6
|
||||
jge short loc_1AFB4
|
||||
mov ax, 1
|
||||
jmp short loc_1AFC0
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1AFB4:
|
||||
mov ax, 30
|
||||
sub ax, si
|
||||
mov bx, 10
|
||||
cwd
|
||||
idiv bx
|
||||
inc ax
|
||||
|
||||
loc_1AFC0:
|
||||
push ax
|
||||
call _frame_delay
|
||||
pop cx
|
||||
inc si
|
||||
|
||||
loc_1AFC8:
|
||||
cmp si, 1Eh
|
||||
jl loc_1AEFB
|
||||
call _egc_copy_rect_1_to_0_16 c, _player_left, _player_top, large (32 shl 16) or 32
|
||||
call _egc_copy_rect_1_to_0_16 c, di, _player_top, large (32 shl 16) or 32
|
||||
mov ax, _lives
|
||||
inc ax
|
||||
call @hud_lives_put$qi stdcall, ax
|
||||
pop cx
|
||||
mov al, _bombs
|
||||
cbw
|
||||
mov [bp+@@prev_bombs], ax
|
||||
mov al, _credit_bombs
|
||||
add al, _bombs
|
||||
mov _bombs, al
|
||||
cbw
|
||||
cmp ax, BOMBS_MAX
|
||||
jle short loc_1B01F
|
||||
mov _bombs, BOMBS_MAX
|
||||
jmp short loc_1B028
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1B01F:
|
||||
call @hud_bombs_put$qi stdcall, [bp+@@prev_bombs]
|
||||
pop cx
|
||||
|
||||
loc_1B028:
|
||||
call @timer_extend_and_put$qv
|
||||
call @pellet_speed_lower$qii c, large 0 or (-2 shl 16)
|
||||
pop di
|
||||
pop si
|
||||
leave
|
||||
retf
|
||||
sub_1AE0D endp
|
||||
|
||||
main_27__TEXT ends
|
||||
extern _player_miss_animate_and_update:proc
|
||||
main_27_TEXT ends
|
||||
|
||||
; ===========================================================================
|
||||
|
||||
|
|
Loading…
Reference in New Issue