Skip to content

Commit

Permalink
[Decompilation] [th05] Stage 5 midboss: Rendering
Browse files Browse the repository at this point in the history
15 lines of code, and still not quirk-free.

Completes P0225, funded by Enderwolf, Blue Bolt, 32th System, and Yanga.
  • Loading branch information
nmlgc committed Nov 30, 2022
1 parent 4e648a6 commit 4f85326
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 60 deletions.
2 changes: 1 addition & 1 deletion Makefile.mak
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ bin\th05\op.exe: th05\op010.cpp bin\th05\op.obj th05\op011.cpp th05\m_char.cpp b
$**
|

bin\th05\main.exe: bin\th05\main.obj bin\th04\slowdown.obj th05\demo.cpp th05\ems.cpp bin\th05\cfg_lres.obj th05\main010.cpp th05\f_dialog.cpp th05\dialog.cpp th05\playfld.cpp bin\th04\mb_inv.obj bin\th04\boss_bd.obj th05\boss_bg.cpp th05\p_common.cpp th05\p_reimu.cpp th05\p_marisa.cpp th05\p_mima.cpp th05\p_yuuka.cpp bin\th05\player.obj bin\th05\hud_bar.obj bin\th05\scoreupd.obj th05\hud_ovrl.cpp bin\th04\player_p.obj bin\th04\vector2n.obj bin\th05\spark_a.obj th05\bullet_p.cpp bin\th04\grcg_3.obj th05\player_a.cpp bin\th05\bullet_1.obj th05\bullet_c.cpp bin\th03\vector2.obj bin\th03\hfliplut.obj bin\th04\snd_pmdr.obj bin\th04\snd_mmdr.obj bin\th04\snd_mode.obj bin\th05\bullet.obj th05\bullet_t.cpp bin\th04\cdg_p_na.obj bin\th04\snd_se_r.obj bin\th04\snd_se.obj bin\th05\cdg_put.obj bin\th04\exit.obj bin\th05\vector.obj bin\th05\snd_load.obj bin\th05\snd_kaja.obj bin\th05\initmain.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th04\scrolly3.obj bin\th04\motion_3.obj th05\gather.cpp th05\main032.cpp th05\midboss.cpp bin\th04\hud_hp.obj th05\mb_dft.cpp th05\laser_sc.cpp th05\cheeto_u.cpp bin\th04\it_spl_u.obj th05\bullet_u.cpp th05\midboss1.cpp th05\boss_4.cpp th05\boss_6.cpp th05\boss_x.cpp th05\boss.cpp th05\main014.cpp
bin\th05\main.exe: bin\th05\main.obj bin\th04\slowdown.obj th05\demo.cpp th05\ems.cpp bin\th05\cfg_lres.obj th05\main010.cpp th05\f_dialog.cpp th05\dialog.cpp th05\playfld.cpp bin\th04\mb_inv.obj bin\th04\boss_bd.obj th05\boss_bg.cpp th05\p_common.cpp th05\p_reimu.cpp th05\p_marisa.cpp th05\p_mima.cpp th05\p_yuuka.cpp bin\th05\player.obj bin\th05\hud_bar.obj bin\th05\scoreupd.obj th05\midboss5.cpp th05\hud_ovrl.cpp bin\th04\player_p.obj bin\th04\vector2n.obj bin\th05\spark_a.obj th05\bullet_p.cpp bin\th04\grcg_3.obj th05\player_a.cpp bin\th05\bullet_1.obj th05\bullet_c.cpp bin\th03\vector2.obj bin\th03\hfliplut.obj bin\th04\snd_pmdr.obj bin\th04\snd_mmdr.obj bin\th04\snd_mode.obj bin\th05\bullet.obj th05\bullet_t.cpp bin\th04\cdg_p_na.obj bin\th04\snd_se_r.obj bin\th04\snd_se.obj bin\th05\cdg_put.obj bin\th04\exit.obj bin\th05\vector.obj bin\th05\snd_load.obj bin\th05\snd_kaja.obj bin\th05\initmain.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th04\scrolly3.obj bin\th04\motion_3.obj th05\gather.cpp th05\main032.cpp th05\midboss.cpp bin\th04\hud_hp.obj th05\mb_dft.cpp th05\laser_sc.cpp th05\cheeto_u.cpp bin\th04\it_spl_u.obj th05\bullet_u.cpp th05\midboss1.cpp th05\boss_4.cpp th05\boss_6.cpp th05\boss_x.cpp th05\boss.cpp th05\main014.cpp
$(CC) $(CFLAGS) $(LARGE_LFLAGS) -3 -Z -DGAME=5 -DBINARY='M' -nbin\th05\ -eMAIN.EXE @&&|
$**
|
Expand Down
11 changes: 11 additions & 0 deletions master.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,5 +708,16 @@ void MASTER_RET vsync_end(void);
));
}
};

#ifdef PC98_H
// Generates a super_roll_put_1plane [plane_put] constant for blitting
// the sprite in the single given color.
inline uint16_t super_plane(uint8_t col, bool erase = false) {
return (
(erase ? PLANE_ERASE : (0xFF00 | GC_RMW)) +
((COLOR_COUNT - 1) - col)
);
}
#endif
#endif
/// ------------------
8 changes: 8 additions & 0 deletions th02/main/playfld.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@
}

#ifdef SCROLL_HPP
vram_y_t to_vram_top_scrolled_seg1(
pixel_t sprite_h_if_centered
) const {
return scroll_subpixel_y_to_vram_seg1(
y + (PLAYFIELD_TOP - (sprite_h_if_centered / 2))
);
}

vram_y_t to_vram_top_scrolled_seg3(
pixel_t sprite_h_if_centered
) const {
Expand Down
14 changes: 14 additions & 0 deletions th04/main/midboss/midboss.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,20 @@ inline int midboss_hittest_shots_invincible(
return midboss_hittest_shots_damage(radius_x, radius_y, 10);
}

// ZUN quirk: This is the place where [damage_this_frame] is reset, but this
// function is typically not called during PHASE_EXPLODE_BIG. As a result, the
// nonzero [damage_this_frame] value that caused the midboss to be defeated in
// the first place is carried over to the next midboss, causing it to flash
// white during the first frame that calls this function.
#define midboss_put_generic(left, top, patnum) { \
if(midboss.damage_this_frame == 0) { \
super_roll_put(left, top, patnum); \
} else { \
super_roll_put_1plane(left, top, patnum, 0, super_plane(V_WHITE)); \
midboss.damage_this_frame = 0; \
} \
}

// Updates the defeat animation during PHASE_EXPLODE_BIG, and resets the boss
// during any other phase. TH04's version also takes ownership of
// [midboss.phase_frame], incrementing it on every call.
Expand Down
2 changes: 1 addition & 1 deletion th04/main/scroll.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ extern bool scroll_active;

// Transforms [y] to its corresponding VRAM line, adding the current
// [scroll_line] or 0 if scrolling is disabled.
vram_y_t pascal near scroll_subpixel_y_to_vram_seg1(subpixel_t y);
extern "C" vram_y_t pascal near scroll_subpixel_y_to_vram_seg1(subpixel_t y);
vram_y_t pascal near scroll_subpixel_y_to_vram_seg3(subpixel_t y);
// Like the one above, but always adds [scroll_line], even if scrolling is
// disabled.
Expand Down
45 changes: 45 additions & 0 deletions th05/main/midboss/m5.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/// Stage 5 midboss
/// ---------------

#pragma option -zCmain_0_TEXT

#include "platform.h"
#include "pc98.h"
#include "master.hpp"
#include "th02/v_colors.hpp"
#include "th04/math/motion.hpp"
#include "th01/math/subpixel.hpp"
#include "th04/main/phase.hpp"
#include "th04/main/scroll.hpp"
#include "th04/main/playfld.hpp"
#include "th04/main/midboss/midboss.hpp"

// Constants
// ---------

static const pixel_t MIDBOSS5_W = 64;
static const pixel_t MIDBOSS5_H = 64;
// ---------

// Rendering
// ---------

void pascal near midboss5_render(void)
{
if(midboss.phase < PHASE_EXPLODE_BIG) {
// ZUN quirk: Should refer to the correct height of the midboss rather
// than hardcoding a wrong 32 pixels. As a result, this midboss plops
// into view rather suddenly during its initial entrance from the top
// of the playfield. Fixed in uth05win.
if(midboss.pos.cur.y < to_sp(PLAYFIELD_TOP - (32 / 2))) {
return;
}

screen_x_t left = midboss.pos.cur.to_screen_left(MIDBOSS5_W);
vram_y_t top = midboss.pos.cur.to_vram_top_scrolled_seg1(MIDBOSS5_H);
midboss_put_generic(left, top, midboss.sprite);
} else if(midboss.phase == PHASE_BOSS_EXPLODE_BIG) {
midboss_defeat_render();
}
}
// ---------
2 changes: 1 addition & 1 deletion th05/main/player/bombanim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ extern union {
star->topleft.screen_y.to_pixel_slow(), \
PAT_PLAYCHAR_BOMB, \
0, \
(PLANE_ERASE | ((COLOR_COUNT - 1) - col)) \
super_plane(col, true) \
);

void pascal near reimu_stars_update_and_render(void)
Expand Down
1 change: 1 addition & 0 deletions th05/midboss5.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "th05/main/midboss/m5.cpp"
57 changes: 0 additions & 57 deletions th05_main.asm
Original file line number Diff line number Diff line change
Expand Up @@ -6878,63 +6878,6 @@ loc_11862:
leave
retn
@exalice_fg_render$qv endp


; =============== S U B R O U T I N E =======================================

; Attributes: bp-based frame

public @MIDBOSS5_RENDER$QV
@midboss5_render$qv proc near
push bp
mov bp, sp
push si
push di
cmp _midboss_phase, PHASE_EXPLODE_BIG
jnb short loc_118C3
cmp _midboss_pos.cur.y, 0
jl short loc_118CD
mov ax, _midboss_pos.cur.x
sar ax, 4
mov si, ax
mov ax, _midboss_pos.cur.y
add ax, (-16 shl 4)
call scroll_subpixel_y_to_vram_seg1 pascal, ax
mov di, ax
cmp _midboss_damage_this_frame, 0
jnz short loc_118A9
push si
push ax
mov al, _midboss_sprite
mov ah, 0
push ax
call super_roll_put
jmp short loc_118CD
; ---------------------------------------------------------------------------

loc_118A9:
push si
push di
mov al, _midboss_sprite
mov ah, 0
push ax
pushd PLANE_PUT or GC_BRGI
call super_roll_put_1plane
mov _midboss_damage_this_frame, 0
jmp short loc_118CD
; ---------------------------------------------------------------------------

loc_118C3:
cmp _midboss_phase, PHASE_EXPLODE_BIG
jnz short loc_118CD
call @midboss_defeat_render$qv

loc_118CD:
pop di
pop si
pop bp
retn
@midboss5_render$qv endp
main_0_TEXT ends

HUD_OVRL_TEXT segment byte public 'CODE' use16
Expand Down

0 comments on commit 4f85326

Please sign in to comment.