diff --git a/th04/end/end.h b/th04/end/end.h index 6038f468..e21f5e18 100644 --- a/th04/end/end.h +++ b/th04/end/end.h @@ -1,6 +1,6 @@ typedef enum { - ES_1CC = 0xFF, - ES_CONTINUED = 0xFE, + ES_GOOD = 0xFF, + ES_BAD = 0xFE, ES_EXTRA = 0xFD, ES_INGAME = 0x37, ES_SCORE = 0, diff --git a/th04/end/end.inc b/th04/end/end.inc index 63652df4..d1e9b5f1 100644 --- a/th04/end/end.inc +++ b/th04/end/end.inc @@ -1,5 +1,5 @@ -ES_1CC = 0FFh -ES_CONTINUED = 0FEh +ES_GOOD = 0FFh +ES_BAD = 0FEh ES_EXTRA = 0FDh ES_INGAME = 037h ES_SCORE = 0 diff --git a/th04/end/entry.cpp b/th04/end/entry.cpp index 9f12b15e..ff9dd941 100644 --- a/th04/end/entry.cpp +++ b/th04/end/entry.cpp @@ -4,20 +4,38 @@ #include "pc98.h" #include "planar.h" #include "master.hpp" +#include "libs/kaja/kaja.h" +#include "th01/rank.h" +#include "th02/hardware/frmdelay.h" extern "C" { #include "th03/formats/cdg.h" +#if (GAME == 4) + #include "th03/formats/pi.hpp" + #include "th04/hardware/input.h" +#endif } #include "th03/formats/cfg_impl.hpp" #include "th03/core/initexit.h" #include "th03/cutscene/cutscene.hpp" #include "th04/score.h" +extern "C" { +#include "th04/snd/snd.h" +} #include "th04/end/end.h" +#include "th04/end/staff.hpp" +#include "th04/end/verdict.hpp" +#include "th04/hiscore/regist.hpp" #if (GAME == 5) #include "th04/shiftjis/fnshared.hpp" + #include "th05/mem.h" #include "th05/resident.hpp" #include "th05/shiftjis/fns.hpp" + #include "th05/end/allcast.hpp" #else + #include "th03/shiftjis/fnshared.hpp" + #include "th04/mem.h" #include "th04/resident.hpp" + #include "th04/shiftjis/fns.hpp" #endif resident_t far* resident; @@ -44,8 +62,8 @@ void pascal near game_exit_and_exec(char* fn) void near end_animate(void) { #if (GAME == 5) - static char* SCRIPT_FN = "_ED00.TXT\0" OP_AND_END_PF_FN "\0" SE_FN; - if(resident->end_sequence == ES_CONTINUED) { + static char* SCRIPT_FN = "_ED00.TXT"; + if(resident->end_sequence == ES_BAD) { SCRIPT_FN[3] = '0'; } else if(resident->end_sequence == ES_EXTRA) { SCRIPT_FN[3] = '2'; @@ -63,3 +81,101 @@ void near end_animate(void) cutscene_animate(); cutscene_script_free(); } + +#define congratulations_animate(pic_fn) { \ + /* \ + * ZUN bloat: The hardware palette is entirely black when we get here, and \ + * we don't flip any pages, so the picture could have been just blitted to \ + * VRAM page #0. \ + * (Would have also been nice to add a palette_black() call here, as an \ + * assert() of sorts.) \ + */ \ + graph_accesspage(1); \ + pi_load_put_8_free(0, pic_fn); \ + graph_copy_page(0); \ + \ + palette_black_in(1); \ + input_wait_for_change(0); \ + palette_black_out(4); \ +} + +inline void delay_then_regist_menu(void) { + #if (GAME == 4) + frame_delay(100); + #endif + regist_menu(); +} + +void main(void) +{ + #if (GAME == 4) + char* congratulations_pic_fn = "CONG00.pi"; + #endif + + if(!cfg_load_resident_ptr()) { + return; + } + + #if (GAME == 4) + congratulations_pic_fn[4] = resident->playchar_ascii; + #endif + + mem_assign_paras = MEM_ASSIGN_PARAS_MAINE; + game_init_main(OP_AND_END_PF_FN); + #if (GAME == 4) + gaiji_backup(); + gaiji_entry_bfnt(GAIJI_FN); + #endif + snd_determine_modes(resident->bgm_mode, resident->se_mode); + #if (GAME == 5) + snd_load(SE_FN, SND_LOAD_SE); + graph_show(); + random_seed = resident->rand; + frame_delay(100); + #else + graph_show(); + #endif + + static_assert(ES_GOOD > ES_BAD); + if(resident->end_sequence >= ES_BAD) { + end_animate(); + staffroll_animate(); + #if (GAME == 4) + verdict_animate(); + + // The rank condition causes the congratulation image to be shown + // for the enforced Bad Ending after clearing Stage 5 on Easy Mode, + // regardless of whether the player continued or not. You might + // consider it a quirk to show 「EASY ALL CLEAR!!」 for a ≥2CC, but + // 「Try to Normal Rank!!」 could very well be ZUN's roundabout way + // of implying "because this is how you avoid the Bad Ending". + if( + (resident->end_sequence == ES_GOOD) || + (resident->rank == RANK_EASY) + ) { + congratulations_pic_fn[5] += resident->rank; + congratulations_animate(congratulations_pic_fn); + } + snd_kaja_func(KAJA_SONG_FADE, 4); + #endif + delay_then_regist_menu(); + } else if(resident->end_sequence == ES_EXTRA) { + #if (GAME == 5) + end_animate(); + allcast_animate(); + verdict_animate(); + delay_then_regist_menu(); + #else + delay_then_regist_menu(); + congratulations_pic_fn[5] = ('0' + RANK_EXTRA); + palette_black(); + congratulations_animate(congratulations_pic_fn); + verdict_animate(); + #endif + } else { // resident->end_sequence == ES_SCORE + delay_then_regist_menu(); + verdict_animate(); + } + snd_kaja_func(KAJA_SONG_FADE, 4); + game_exit_and_exec(BINARY_OP); +} diff --git a/th04/mem.inc b/th04/mem.inc index 4c6384f5..6e07ad05 100644 --- a/th04/mem.inc +++ b/th04/mem.inc @@ -1,6 +1,5 @@ ; Various memory sizes of external TH04 files. MEM_ASSIGN_PARAS_OP equ (336000 shr 4) MEM_ASSIGN_PARAS_MAIN equ (320000 shr 4) -MEM_ASSIGN_PARAS_MAINE equ (336000 shr 4) DEMO_N = 4000 ; ZUN symbol [MAGNet2010] diff --git a/th04_main.asm b/th04_main.asm index 8b5969b7..b5554cc0 100644 --- a/th04_main.asm +++ b/th04_main.asm @@ -1038,7 +1038,7 @@ public @end_game_good$qv push bp mov bp, sp les bx, _resident - mov es:[bx+resident_t.end_sequence], ES_1CC + mov es:[bx+resident_t.end_sequence], ES_GOOD mov es:[bx+resident_t.end_type_ascii], '0' kajacall KAJA_SONG_FADE, 4 push 10h @@ -1059,7 +1059,7 @@ public @end_game_bad$qv push bp mov bp, sp les bx, _resident - mov es:[bx+resident_t.end_sequence], ES_CONTINUED + mov es:[bx+resident_t.end_sequence], ES_BAD mov es:[bx+resident_t.end_type_ascii], '1' kajacall KAJA_SONG_FADE, 4 push 10h diff --git a/th04_maine.asm b/th04_maine.asm index d933ec23..34aec687 100644 --- a/th04_maine.asm +++ b/th04_maine.asm @@ -147,130 +147,11 @@ _TEXT ends ; =========================================================================== MAINE_E_TEXT segment byte public 'CODE' use16 - @cfg_load_resident_ptr$qv procdesc near - @GAME_EXIT_AND_EXEC$QNC procdesc pascal near \ - fn_off:word, fn_seg:word - @end_animate$qv procdesc near MAINE_E_TEXT ends -; Segment type: Pure code CUTSCENE_TEXT segment byte public 'CODE' use16 assume cs:group_01 - ;org 9 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 - -; int __cdecl main(int argc, const char **argv, const char **envp) -public _main -_main proc far - -@@cong_fn = dword ptr -4 - - enter 4, 0 - mov word ptr [bp+@@cong_fn+2], ds - mov word ptr [bp+@@cong_fn], offset _CongFN - call @cfg_load_resident_ptr$qv - or ax, ax - jz locret_A290 - les bx, _resident - mov al, es:[bx+resident_t.playchar_ascii] - les bx, [bp+@@cong_fn] - mov es:[bx+4], al - mov _mem_assign_paras, MEM_ASSIGN_PARAS_MAINE - call @game_init_main$qnxuc pascal, ds, offset aMSzlEd_dat - call gaiji_backup - push ds - push offset aGameft_bft ; "GAMEFT.bft" - call gaiji_entry_bfnt - les bx, _resident - mov al, es:[bx+resident_t.bgm_mode] - mov ah, 0 - push ax - mov al, es:[bx+resident_t.se_mode] - mov ah, 0 - push ax - call snd_determine_modes - call graph_show - les bx, _resident - cmp es:[bx+resident_t.end_sequence], ES_CONTINUED - jb loc_A1FE - call @end_animate$qv - call @staffroll_animate$qv - call @verdict_animate$qv - les bx, _resident - cmp es:[bx+resident_t.end_sequence], ES_1CC - jz short loc_A187 - cmp es:[bx+resident_t.rank], RANK_EASY - jnz short loc_A1E9 - -loc_A187: - les bx, [bp+@@cong_fn] - mov al, es:[bx+5] - les bx, _resident - add al, es:[bx+resident_t.rank] - les bx, [bp+@@cong_fn] - mov es:[bx+5], al - graph_accesspage 1 - call pi_load pascal, 0, word ptr [bp+@@cong_fn+2], bx - call pi_palette_apply pascal, 0 - call pi_put_8 pascal, large 0, 0 - freePISlotLarge 0 - call graph_copy_page pascal, 0 - push 1 - call palette_black_in - call input_wait_for_change pascal, 0 - push 4 - call palette_black_out - -loc_A1E9: - kajacall KAJA_SONG_FADE, 4 - call @frame_delay$qi pascal, 100 - call @regist_menu$qv - jmp loc_A281 -; --------------------------------------------------------------------------- - -loc_A1FE: - les bx, _resident - cmp es:[bx+resident_t.end_sequence], ES_EXTRA - jnz short loc_A274 - call @frame_delay$qi pascal, 100 - call @regist_menu$qv - les bx, [bp+@@cong_fn] - mov byte ptr es:[bx+5], '4' - mov PaletteTone, 0 - call far ptr palette_show - graph_accesspage 1 - call pi_load pascal, 0, large [bp+@@cong_fn] - call pi_palette_apply pascal, 0 - call pi_put_8 pascal, large 0, 0 - freePISlotLarge 0 - call graph_copy_page pascal, 0 - push 1 - call palette_black_in - call input_wait_for_change pascal, 0 - push 4 - call palette_black_out - jmp short loc_A27E -; --------------------------------------------------------------------------- - -loc_A274: - call @frame_delay$qi pascal, 100 - call @regist_menu$qv - -loc_A27E: - call @verdict_animate$qv - -loc_A281: - kajacall KAJA_SONG_FADE, 4 - call @game_exit_and_exec$qnc pascal, ds, offset arg0 ; "op" - -locret_A290: - leave - retf -_main endp CUTSCENE_TEXT ends maine_01_TEXT segment byte public 'CODE' use16 @@ -1519,7 +1400,7 @@ loc_BC79: les bx, _resident cmp es:[bx+resident_t.stage], STAGE_EXTRA jz short loc_BD0A - cmp es:[bx+resident_t.end_sequence], ES_1CC + cmp es:[bx+resident_t.end_sequence], ES_GOOD jnz short loc_BCFF mov es:[bx+resident_t.std_frames], 44000 @@ -1748,7 +1629,7 @@ loc_BF96: loc_BFA1: les bx, _resident - cmp es:[bx+resident_t.end_sequence], ES_CONTINUED + cmp es:[bx+resident_t.end_sequence], ES_BAD jnz short loc_BFB4 sub [bp+var_4], 100000 @@ -2703,7 +2584,7 @@ loc_C8D9: loc_C909: les bx, _resident - cmp es:[bx+resident_t.end_sequence], ES_1CC + cmp es:[bx+resident_t.end_sequence], ES_GOOD jz short loc_C922 cmp es:[bx+resident_t.end_sequence], ES_EXTRA jz short loc_C922 @@ -3131,7 +3012,6 @@ include th02/snd/snd.inc extern INPUT_WAIT_FOR_CHANGE:proc extern @POLAR$QIII:proc extern SND_KAJA_INTERRUPT:proc - extern SND_DETERMINE_MODES:proc extern SND_DELAY_UNTIL_MEASURE:proc extern CDG_PUT_PLANE:proc extern SND_LOAD:proc @@ -3143,7 +3023,6 @@ SHARED_ segment word public 'CODE' use16 include th04/hardware/grppsafx.asm extern CDG_PUT_8:proc - extern @GAME_INIT_MAIN$QNXUC:proc extern _input_reset_sense:proc extern _input_sense:proc extern _bgimage_snap:proc @@ -3157,13 +3036,6 @@ SHARED_ ends .data -public _CongFN -_CongFN db 'CONG00.pi',0 -aMSzlEd_dat db 'zed.dat',0 -aGameft_bft db 'GAMEFT.bft',0 -; char arg0[] -arg0 db 'op',0 - db 0 include libs/master.lib/atrtcmod[data].asm include libs/master.lib/bfnt_id[data].asm include libs/master.lib/clip[data].asm diff --git a/th05/mem.inc b/th05/mem.inc index d63513e5..7ca69e43 100644 --- a/th05/mem.inc +++ b/th05/mem.inc @@ -1,6 +1,5 @@ ; Various memory sizes of external TH05 files. MEM_ASSIGN_PARAS_OP equ (336000 shr 4) MEM_ASSIGN_PARAS_MAIN equ (291200 shr 4) -MEM_ASSIGN_PARAS_MAINE equ (336000 shr 4) DEMO_N = 5000 ; ZUN symbol [MAGNet2010] diff --git a/th05_main.asm b/th05_main.asm index f17d39a9..7038b471 100644 --- a/th05_main.asm +++ b/th05_main.asm @@ -2782,13 +2782,13 @@ public @end_game$qv jz short loc_E45D les bx, _resident assume es:nothing - mov es:[bx+resident_t.end_sequence], ES_CONTINUED + mov es:[bx+resident_t.end_sequence], ES_BAD jmp short loc_E466 ; --------------------------------------------------------------------------- loc_E45D: les bx, _resident - mov es:[bx+resident_t.end_sequence], ES_1CC + mov es:[bx+resident_t.end_sequence], ES_GOOD loc_E466: kajacall KAJA_SONG_FADE, 4 diff --git a/th05_maine.asm b/th05_maine.asm index 023852a9..442bdf35 100644 --- a/th05_maine.asm +++ b/th05_maine.asm @@ -154,84 +154,11 @@ _TEXT ends ; =========================================================================== MAINE_E_TEXT segment byte public 'CODE' use16 - @cfg_load_resident_ptr$qv procdesc near - @GAME_EXIT_AND_EXEC$QNC procdesc pascal near \ - fn_off:word, fn_seg:word - @end_animate$qv procdesc near MAINE_E_TEXT ends -; Segment type: Pure code CUTSCENE_TEXT segment byte public 'CODE' use16 assume cs:group_01 - ;org 5 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 - -; int __cdecl main(int argc, const char **argv, const char **envp) -public _main -_main proc far - -_argc = word ptr 6 -_argv = dword ptr 8 -_envp = dword ptr 0Ch - - push bp - mov bp, sp - call @cfg_load_resident_ptr$qv - or ax, ax - jz loc_A693 - mov _mem_assign_paras, MEM_ASSIGN_PARAS_MAINE - call @game_init_main$qnxuc pascal, ds, offset aKaikidan1_dat - les bx, _resident - mov al, es:[bx+resident_t.bgm_mode] - mov ah, 0 - push ax - mov al, es:[bx+resident_t.se_mode] - mov ah, 0 - push ax - call snd_determine_modes - call snd_load pascal, ds, offset aMiko, SND_LOAD_SE - call graph_show - les bx, _resident - mov eax, es:[bx+resident_t.rand] - mov random_seed, eax - call @frame_delay$qi pascal, 100 - les bx, _resident - cmp es:[bx+resident_t.end_sequence], ES_CONTINUED - jb short loc_A665 - call @end_animate$qv - call @staffroll_animate$qv - jmp short loc_A679 -; --------------------------------------------------------------------------- - -loc_A665: - les bx, _resident - cmp es:[bx+resident_t.end_sequence], ES_EXTRA - jnz short loc_A67E - call @end_animate$qv - call @allcast_animate$qv - call @verdict_animate$qv - -loc_A679: - call @regist_menu$qv - jmp short loc_A684 -; --------------------------------------------------------------------------- - -loc_A67E: - call @regist_menu$qv - call @verdict_animate$qv - -loc_A684: - kajacall KAJA_SONG_FADE, 4 - call @game_exit_and_exec$qnc pascal, ds, offset arg0 ; "op" - -loc_A693: - pop bp - retf -_main endp CUTSCENE_TEXT ends maine_01_TEXT segment byte public 'CODE' use16 @@ -2995,7 +2922,7 @@ sub_CA02 proc near push bp mov bp, sp les bx, _resident - cmp es:[bx+resident_t.end_sequence], ES_1CC + cmp es:[bx+resident_t.end_sequence], ES_GOOD jz short loc_CA17 cmp es:[bx+resident_t.end_sequence], ES_EXTRA jnz short loc_CA57 @@ -3044,7 +2971,7 @@ loc_CA53: loc_CA57: les bx, _resident - cmp es:[bx+resident_t.end_sequence], ES_CONTINUED + cmp es:[bx+resident_t.end_sequence], ES_BAD jnz short loc_CA66 mov al, 2 pop bp @@ -3269,7 +3196,7 @@ loc_CBE3: les bx, _resident cmp es:[bx+resident_t.stage], STAGE_EXTRA jz short loc_CCC6 - cmp es:[bx+resident_t.end_sequence], ES_CONTINUED + cmp es:[bx+resident_t.end_sequence], ES_BAD jb short loc_CCB3 mov es:[bx+resident_t.std_frames], 46000 @@ -6237,7 +6164,6 @@ maine_01__TEXT ends ; Segment type: Pure code SHARED segment word public 'CODE' use16 - extern SND_DETERMINE_MODES:proc SHARED ends SHARED_ segment word public 'CODE' use16 @@ -6263,7 +6189,6 @@ include th04/hardware/grppsafx.asm extern PI_PUT_QUARTER_8:proc extern PI_PALETTE_APPLY:proc extern PI_FREE:proc - extern @GAME_INIT_MAIN$QNXUC:proc extern _input_reset_sense_held:proc extern INPUT_WAIT_FOR_CHANGE:proc extern _snd_bgm_measure:proc @@ -6274,11 +6199,6 @@ SHARED_ ends .data -aKaikidan1_dat = ($ - 17) -aMiko = ($ - 5) -; char arg0[] -arg0 db 'op',0 - db 0 include libs/master.lib/atan8[data].asm include libs/master.lib/atrtcmod[data].asm include libs/master.lib/bfnt_id[data].asm