From e6294c2c1a91deb75fcd65a908e262751d1d01c3 Mon Sep 17 00:00:00 2001 From: nmlgc Date: Wed, 18 Sep 2019 18:33:38 +0200 Subject: [PATCH] [Reverse-engineering] [th02/th04/th05] Score update and display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The TH02 version is a piece of cake… … but TH04 starts turning it into this un-decompilable piece of unnecessarily micro-optimized ZUN code. Couldn't have chosen anything better for the first separate ASM translation unit. Aside from now having to convert names of exported *variables* to uppercase for visibility in ASM translation units, the most notable lesson in this was the one about avoiding fixup overflows. From the Borland C++ Version 4.0 User's Guide: "In an assembly language program, a fixup overflow frequently occurs if you have declared an external variable within a segment definition, but this variable actually exists in a different segment." Can't be restated often enough. Completes P0032, funded by zorg. --- Makefile.mak | 19 +- libs/master.lib/master.inc | 9 + .../boldfont.inc} | 0 th02/hud/number_put[data].asm | 9 - th02/hud/score_put.asm | 71 +++++ th02/hud/score_put[data].asm | 9 + th02/th02.inc | 2 +- th02_main.asm | 106 +------ {th05 => th04}/hud/gaiji_row[data].asm | 2 +- th04/hud/popup[bss].asm | 4 +- th04/score[bss].asm | 8 +- th04/score[data].asm | 4 +- th04/scoreupd.asm | 300 ++++++++++++++++++ th04/scoreupd[data].asm | 8 + th04/shared.hpp | 1 + th04/shared.inc | 2 +- th04_main.asm | 198 +----------- th05/hud/number_put.asm | 4 +- th05/{main_01.cpp => main012.cpp} | 4 +- th05_main.asm | 175 +--------- 20 files changed, 462 insertions(+), 473 deletions(-) create mode 100644 libs/master.lib/master.inc rename th02/{gaiji_boldfont.inc => gaiji/boldfont.inc} (100%) delete mode 100644 th02/hud/number_put[data].asm create mode 100644 th02/hud/score_put.asm create mode 100644 th02/hud/score_put[data].asm rename {th05 => th04}/hud/gaiji_row[data].asm (91%) create mode 100644 th04/scoreupd.asm create mode 100644 th04/scoreupd[data].asm rename th05/{main_01.cpp => main012.cpp} (90%) diff --git a/Makefile.mak b/Makefile.mak index ec65568f..611d5e12 100644 --- a/Makefile.mak +++ b/Makefile.mak @@ -19,6 +19,16 @@ th03:: $(TH03:\=bin\th03\) th04:: $(TH04:\=bin\th04\) th05:: $(TH05:\=bin\th05\) +# Shared TH04/TH05 assembly units +# ------------------------------- +# Need to go into separate .obj directories since they will have different +# AFLAGS per game. +{th04}.asm{bin\th04}.obj: + $(AS) /dGAME=4 $**, $@ +{th04}.asm{bin\th05}.obj: + $(AS) /dGAME=5 $**, $@ +# ------------------------------- + .obj.exe: $(CC) $(CFLAGS) -ml $** @@ -73,7 +83,14 @@ bin\th04\op.exe: bin\th04\op.obj th04\op_02.c $** | -bin\th05\main.exe: bin\th05\main.obj th05\main_01.cpp +bin\th04\scoreupd.obj: th04\scoreupd.asm +bin\th04\main.exe: bin\th04\main.obj bin\th04\scoreupd.obj + $(CC) $(CFLAGS) -ml -DGAME=4 -nbin\th04\ -eMAIN.EXE @&&| +$** +| + +bin\th05\scoreupd.obj: th04\scoreupd.asm +bin\th05\main.exe: bin\th05\main.obj bin\th05\scoreupd.obj th05\main012.cpp $(CC) $(CFLAGS) -ml -3 -Z -DGAME=5 -nbin\th05\ -eMAIN.EXE @&&| $** | diff --git a/libs/master.lib/master.inc b/libs/master.lib/master.inc new file mode 100644 index 00000000..50cd7a65 --- /dev/null +++ b/libs/master.lib/master.inc @@ -0,0 +1,9 @@ +; ReC98 +; Relevant function definitions from master.h, together with the necessary +; types. Meant as a master.h equivalent for standalone, non-slice ASM +; translation units. + +include libs/master.lib/macros.inc + +GAIJI_PUTSA procdesc pascal far \ + x:word, y:word, strp_seg:word, strp_off:word, atrb:word diff --git a/th02/gaiji_boldfont.inc b/th02/gaiji/boldfont.inc similarity index 100% rename from th02/gaiji_boldfont.inc rename to th02/gaiji/boldfont.inc diff --git a/th02/hud/number_put[data].asm b/th02/hud/number_put[data].asm deleted file mode 100644 index 381c4a7f..00000000 --- a/th02/hud/number_put[data].asm +++ /dev/null @@ -1,9 +0,0 @@ -public _POWERS_OF_10_LONG -_POWERS_OF_10_LONG label dword - dd 1000000 - dd 100000 - dd 10000 - dd 1000 - dd 100 - dd 10 - dd 1 diff --git a/th02/hud/score_put.asm b/th02/hud/score_put.asm new file mode 100644 index 00000000..41ad7900 --- /dev/null +++ b/th02/hud/score_put.asm @@ -0,0 +1,71 @@ +HUD_CONTINUES_X = HUD_X + ((SCORE_DIGITS - 1) * 2) + +; Only prints the seven score digits, in contrast to the TH04/TH05 version! + +; void pascal near hud_score_put(unsigned int y, long value); +public HUD_SCORE_PUT +hud_score_put proc near +@@result = word ptr [bp-4] +@@digit = word ptr [bp-2] +@@value = dword ptr [bp+4] +@@y = word ptr [bp+8] + + push bp + mov bp, sp + sub sp, 4 + push si + push di + mov si, offset _SEVEN_DIGIT_POWERS_OF_10 + mov di, HUD_X + jmp short @@more_digits? + +@@put: + mov eax, @@value + cdq + idiv dword ptr [si] + mov @@result, ax + movsx eax, @@result + imul eax, [si] + sub @@value, eax + add si, 4 + mov ax, @@result + add ax, GB_DIGITS + mov @@digit, ax + call gaiji_putca pascal, di, @@y, ax, TX_WHITE + add di, 2 + +@@more_digits?: + cmp di, HUD_CONTINUES_X + jl short @@put + pop di + pop si + leave + retn 6 +hud_score_put endp + + +; void pascal near hud_continues_put(unsigned int y, int continues_used); +public HUD_CONTINUES_PUT +hud_continues_put proc near + +@@continues_displayed = word ptr [bp-2] +@@continues_used = word ptr [bp+4] +@@y = word ptr [bp+6] + + push bp + mov bp, sp + sub sp, 2 + push si + mov si, @@continues_used + cmp si, 10 + jl short @@put + mov si, 9 + +@@put: + lea ax, [si+GB_DIGITS] + mov @@continues_displayed, ax + call gaiji_putca pascal, HUD_CONTINUES_X, @@y, ax, TX_WHITE + pop si + leave + retn 4 +hud_continues_put endp diff --git a/th02/hud/score_put[data].asm b/th02/hud/score_put[data].asm new file mode 100644 index 00000000..f8702660 --- /dev/null +++ b/th02/hud/score_put[data].asm @@ -0,0 +1,9 @@ +public _SEVEN_DIGIT_POWERS_OF_10 +_SEVEN_DIGIT_POWERS_OF_10 label dword + dd 1000000 + dd 100000 + dd 10000 + dd 1000 + dd 100 + dd 10 + dd 1 diff --git a/th02/th02.inc b/th02/th02.inc index 7236f06f..e5b35895 100644 --- a/th02/th02.inc +++ b/th02/th02.inc @@ -3,7 +3,7 @@ include defconv_c.inc include th02/hardware/input.inc include th02/math/randring_next.inc -include th02/gaiji_boldfont.inc +include th02/gaiji/boldfont.inc include th02/hud/hud.inc include th02/score.inc diff --git a/th02_main.asm b/th02_main.asm index 376ef85b..4a9f8248 100644 --- a/th02_main.asm +++ b/th02_main.asm @@ -6694,81 +6694,7 @@ sub_DC4B proc near retn sub_DC4B endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_DC55 proc near - -var_4 = word ptr -4 -var_2 = word ptr -2 -arg_0 = dword ptr 4 -arg_4 = word ptr 8 - - push bp - mov bp, sp - sub sp, 4 - push si - push di - mov si, offset _POWERS_OF_10_LONG - mov di, HUD_X - jmp short loc_DC9A -; --------------------------------------------------------------------------- - -loc_DC65: - mov eax, [bp+arg_0] - cdq - idiv dword ptr [si] - mov [bp+var_4], ax - movsx eax, [bp+var_4] - imul eax, [si] - sub [bp+arg_0], eax - add si, 4 - mov ax, [bp+var_4] - add ax, GB_DIGITS - mov [bp+var_2], ax - call gaiji_putca pascal, di, [bp+arg_4], ax, TX_WHITE - add di, 2 - -loc_DC9A: - cmp di, HUD_X + ((SCORE_DIGITS - 1) * 2) - jl short loc_DC65 - pop di - pop si - leave - retn 6 -sub_DC55 endp - - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_DCA5 proc near - -var_2 = word ptr -2 -arg_0 = word ptr 4 -arg_2 = word ptr 6 - - push bp - mov bp, sp - sub sp, 2 - push si - mov si, [bp+arg_0] - cmp si, 0Ah - jl short loc_DCB7 - mov si, 9 - -loc_DCB7: - lea ax, [si+GB_DIGITS] - mov [bp+var_2], ax - call gaiji_putca pascal, HUD_X + ((SCORE_DIGITS - 1) * 2), [bp+arg_2], ax, TX_WHITE - pop si - leave - retn 4 -sub_DCA5 endp - +include th02/hud/score_put.asm ; =============== S U B R O U T I N E ======================================= @@ -6885,16 +6811,12 @@ loc_DDCE: mov dword_218AC, eax movzx eax, word_218B0 add dword_1E598, eax - push 6 - pushd [dword_1E598] - call sub_DC55 + call hud_score_put pascal, 6, large [dword_1E598] mov eax, dword_1E598 cmp eax, dword_252F8 jle short loc_DE01 mov dword_252F8, eax - push 4 - push eax - call sub_DC55 + call hud_score_put pascal, 4, eax loc_DE01: mov bx, word_1E5B6 @@ -6944,16 +6866,12 @@ sub_DE4E proc far mov bp, sp mov eax, dword_218AC add dword_1E598, eax - push 6 - pushd [dword_1E598] - call sub_DC55 + call hud_score_put pascal, 6, large [dword_1E598] mov eax, dword_1E598 cmp eax, dword_252F8 jle short loc_DE7A mov dword_252F8, eax - push 4 - push eax - call sub_DC55 + call hud_score_put pascal, 4, eax loc_DE7A: mov bx, word_1E5B6 @@ -7185,23 +7103,19 @@ sub_E012 proc near push bp mov bp, sp call gaiji_putsa pascal, (61 shl 16) + 5, ds, offset gsSCORE, TX_YELLOW - push 6 - pushd [dword_1E598] - call sub_DC55 + call hud_score_put pascal, 6, large [dword_1E598] push 6 les bx, mikoconfig assume es:nothing push es:[bx+mikoconfig_t.continues_used] - call sub_DCA5 + call hud_continues_put call gaiji_putsa pascal, (60 shl 16) + 3, ds, offset gsHISCORE, TX_YELLOW - push 4 - pushd [dword_252F8] - call sub_DC55 + call hud_score_put pascal, 4, large [dword_252F8] push 4 mov al, byte_252FC mov ah, 0 push ax - call sub_DCA5 + call hud_continues_put call gaiji_putsa pascal, (57 shl 16) + 17, ds, offset gsREIMU, TX_YELLOW call sub_DF76 call gaiji_putsa pascal, (57 shl 16) + 15, ds, offset gsREIGEKI, TX_YELLOW @@ -34557,7 +34471,7 @@ bombs db 3 db 5 word_1E5B6 dw 0 dword_1E5B8 dd 9C40h -include th02/hud/number_put[data].asm +include th02/hud/score_put[data].asm word_1E5D8 dw 4140h word_1E5DA dw 4342h word_1E5DC dw 44h diff --git a/th05/hud/gaiji_row[data].asm b/th04/hud/gaiji_row[data].asm similarity index 91% rename from th05/hud/gaiji_row[data].asm rename to th04/hud/gaiji_row[data].asm index 06bc1b29..a46832e7 100644 --- a/th05/hud/gaiji_row[data].asm +++ b/th04/hud/gaiji_row[data].asm @@ -1,6 +1,6 @@ ; Shared buffer for one full row of gaiji characters. Used for temporarily ; storing the two scores, and the enemy health, dream, and power bars. HUD_TRAM_W = 8 -public _hud_gaiji_row +public _HUD_GAIJI_ROW _hud_gaiji_row db (HUD_TRAM_W + 1) dup (0) db 0 ; (word alignment) diff --git a/th04/hud/popup[bss].asm b/th04/hud/popup[bss].asm index 2d9c8534..07f21b94 100644 --- a/th04/hud/popup[bss].asm +++ b/th04/hud/popup[bss].asm @@ -1,6 +1,6 @@ public _popup_gaiji_len, _popup_id_cur, _popup_dest_reached, _popup_shiftbuf -public _popup_cur_tram_x, _popup_dest_tram_x, _bgm_title_id, _popup_id_new -public _overlay_text_fp, _popup_fp, _popup_byte_unknown, _popup_bonus +public _popup_cur_tram_x, _popup_dest_tram_x, _bgm_title_id, _POPUP_ID_NEW +public _overlay_text_fp, _POPUP_FP, _popup_byte_unknown, _popup_bonus _popup_gaiji_len dw ? _popup_id_cur db ? _popup_dest_reached db ? diff --git a/th04/score[bss].asm b/th04/score[bss].asm index 439d5655..05e10984 100644 --- a/th04/score[bss].asm +++ b/th04/score[bss].asm @@ -3,17 +3,15 @@ ; which is then taken "times 10" ([score_delta] += 1 → 10 more on-screen ; points). -; Also ignoring the last digit. (= 61,110 points) -SCORE_DELTA_FRAME_LIMIT = 6111 - -public _continues_used, _score_lebcd, _hiscore_lebcd -public _score_delta, _score_delta_frame +public _CONTINUES_USED, _SCORE_LEBCD, _HISCORE_LEBCD +public _SCORE_DELTA, _SCORE_DELTA_FRAME label _continues_used byte _score_lebcd db SCORE_DIGITS dup(?) _hiscore_lebcd db SCORE_DIGITS dup(?) if GAME eq 4 +public _SCORE_UNUSED _score_unused db ? endif _score_delta dd ? diff --git a/th04/score[data].asm b/th04/score[data].asm index c91c800a..420ae852 100644 --- a/th04/score[data].asm +++ b/th04/score[data].asm @@ -1,2 +1,2 @@ -public _is_hiscore -_is_hiscore db 0 +public _HISCORE_POPUP_SHOWN +_hiscore_popup_shown db 0 diff --git a/th04/scoreupd.asm b/th04/scoreupd.asm new file mode 100644 index 00000000..9aa1c6c8 --- /dev/null +++ b/th04/scoreupd.asm @@ -0,0 +1,300 @@ + .386 + locals + +include libs/master.lib/master.inc +include th02/hud/hud.inc +include th04/hud/popup.inc +include th02/score.inc +include th02/gaiji/boldfont.inc + +SCORE_DIGIT_HIGHEST = SCORE_DIGITS - 1 +; Also ignoring the last digit. (= 61,110 points) +SCORE_DELTA_FRAME_LIMIT = 6111 +if SCORE_DELTA_FRAME_LIMIT ge 100000 + .err "SCORE_DELTA_FRAME_LIMIT can't have more than 5 decimal digits" +endif + +; Declaring everything here rather than inside a segment avoids fixup +; overflows… yup. + + extrn _score_lebcd:byte:SCORE_DIGITS + extrn _hiscore_lebcd:byte:SCORE_DIGITS + extrn _hiscore_popup_shown:byte + extrn _score_delta:dword + extrn _score_delta_frame:dword + + extrn _FIVE_DIGIT_POWERS_OF_10:word + + extrn _hud_gaiji_row:byte:SCORE_DIGITS + + extrn _popup_id_new:byte + extrn _popup_fp:word + POPUP_UPDATE_AND_RENDER procdesc near + +if GAME eq 4 + extrn _score_unused:byte + extrn _temp_lebcd:byte + SCORE_EXTEND_UPDATE procdesc near +else + _temp_lebcd equ _hud_gaiji_row +endif + +; ---------------------------------------------------------------------------- + +main_01_TEXT segment word public 'CODE' use16 + assume cs:main_01_TEXT + +; ============================================================================ + +; Renders both the current and high score. In contrast to TH02, it also +; displays the continues digit. + +; void pascal near hud_score_put(void); +public HUD_SCORE_PUT +hud_score_put proc pascal near +@@gaiji_p equ bx +@@score_p equ si +@@y equ di + + push si + push di + + mov @@score_p, offset _hiscore_lebcd[SCORE_DIGIT_HIGHEST] + mov @@y, 4 + +@@lebcd_to_gaiji: + mov cx, SCORE_DIGITS + mov @@gaiji_p, offset _hud_gaiji_row + +@@digit_loop: + mov al, [@@score_p] + add al, GB_DIGITS + mov [@@gaiji_p], al + inc @@gaiji_p + dec @@score_p + loop @@digit_loop + call gaiji_putsa pascal, HUD_X, @@y, ds, offset _hud_gaiji_row, TX_WHITE + add @@y, 2 + + ; Put exactly two lines, high score at (56, 4), and current score at + ; (56, 6). + ; You might notice that @@score_p is only assigned once. Yes, the code + ; assumes that @@score_p now points at the end of _score_lebcd, which in + ; turn assumes it's placed exactly before _hiscore_lebcd in memory, with + ; no padding. + cmp @@y, 6 + jz @@lebcd_to_gaiji + + ; And if that wasn't enough already, ZUN pops the registers in the wrong + ; order. Good thing it doesn't matter for any caller of this function! + ; + ; This could have easily been fixed by either defining two (or better, + ; three) LOCAL variables, or the USES directive if you *really* insist on + ; using registers. Both of which would have automatically inserted the + ; correct cleanup instructions before RET. Even in the 90's, "using an + ; assembler" did very much *not* mean "having to manually spell out every + ; instruction executed on the CPU"… + pop si + pop di + ret +hud_score_put endp + +; ============================================================================ + +; void pascal near score_update_and_render(void); +public SCORE_UPDATE_AND_RENDER +score_update_and_render proc near + +; The TH04 version is functionally identical, just less optimized. +if GAME eq 5 + @@delta_remaining_word equ dx + @@delta_remaining_char equ dl +else + @@delta_remaining_word equ cx + @@delta_remaining_char equ cl +endif + + mov eax, _score_delta + or eax, eax + jz short @@ret + cmp _score_delta_frame, eax + jbe short @@calculate_frame_delta + mov word ptr _score_delta_frame, ax + +@@calculate_frame_delta: + shr eax, 5 + or eax, eax + jnz short @@clamp_delta_to_frame_limit + inc ax + jmp short @@prefer_larger_delta + +@@clamp_delta_to_frame_limit: + cmp eax, SCORE_DELTA_FRAME_LIMIT + jbe short @@prefer_larger_delta + mov ax, SCORE_DELTA_FRAME_LIMIT + +@@prefer_larger_delta: + cmp word ptr _score_delta_frame, ax + jnb short @@commit_frame_delta + mov word ptr _score_delta_frame, ax + +@@commit_frame_delta: + mov @@delta_remaining_word, word ptr _score_delta_frame + jmp short @@update +; --------------------------------------------------------------------------- + +@@render: + cmp _hiscore_popup_shown, 0 + jnz short @@subtract_frame_delta_and_render + or al, al + jz short @@subtract_frame_delta_and_render + mov _hiscore_popup_shown, 1 + mov _popup_id_new, POPUP_ID_HISCORE_ENTRY + mov _popup_fp, offset popup_update_and_render + +@@subtract_frame_delta_and_render: + mov eax, _score_delta_frame + sub _score_delta, eax + call hud_score_put +if GAME eq 4 + mov _score_unused, 0 + call score_extend_update +endif + +@@ret: + retn +; --------------------------------------------------------------------------- + even + +@@update: + push si + push di +if GAME eq 5 + push ds + pop es + + @@bcd_p equ di + @@po10_p equ bx + + ; Since the delta can have at most 5 digits, we only have to work on the + ; range from _temp_lebcd[4] (highest) to _temp_lebcd[0] (lowest). + ; Zeroing the remaining 3 digits is simply more convenient to do in a + ; single 32-bit instruction if _temp_lebcd[4] is also (unnecessarily) + ; zeroed. + mov dword ptr _temp_lebcd[4], 0 +else + @@bcd_p equ bx + @@po10_p equ si +endif + mov @@bcd_p, offset _temp_lebcd[4] + mov @@po10_p, offset _FIVE_DIGIT_POWERS_OF_10 +if GAME eq 5 + ; 4 divisions, the units place doesn't need a separate one. + mov cx, 4 +endif + +@@delta_to_bcd: + mov ax, @@delta_remaining_word + ; 16-bit DIV interprets DX:AX as a 32-bit divisor… + xor dx, dx + ; … and returns the remainder in DX, so we actually aren't losing + ; anything here. + div word ptr [@@po10_p] +if GAME eq 5 + add @@po10_p, 2 +else + mov @@delta_remaining_word, dx +endif + + mov [@@bcd_p], al + dec @@bcd_p + +if GAME eq 5 + loop @@delta_to_bcd +else + add @@po10_p, 2 + cmp word ptr [@@po10_p], 1 + ja @@delta_to_bcd +endif + +@@last_digit: + mov [@@bcd_p], @@delta_remaining_char + + ; Obviously skipping the continues digit… + mov si, offset _score_lebcd[1] + ; … and the last one seen from there doesn't need special BCD treatment + ; either. + mov cx, SCORE_DIGITS - 2 + ; Yes, completely unnecessary in TH05, considering the next instruction. + xor ah, ah + + ; @@bcd_p == _temp_lebcd[0] +@@add_next_digit_to_score: +if GAME eq 5 + movzx ax, byte ptr [@@bcd_p] +else + mov al, [@@bcd_p] +endif + add al, [si] + aaa ; AL < 9, AH = carry + mov [si], al + inc @@bcd_p + inc si + ; Add the carry to next score digit. May now be 0Ah, but who cares, it's + ; fixed via AAA on the next digit anyway… *except* if it's already the + ; highest one, which is exactly where the infamous >100 million score + ; glitch comes from. + add [si], ah +if GAME eq 4 + mov ah, 0 +endif + loop @@add_next_digit_to_score + mov al, [@@bcd_p] + add [si], al + + ; Is this the high score? +@@is_hiscore equ dl ; Never read, though + +if GAME eq 4 + push ds + pop es +; assume es:_DATA +endif + mov si, offset _score_lebcd[SCORE_DIGIT_HIGHEST] + mov di, offset _hiscore_lebcd[SCORE_DIGIT_HIGHEST] + xor @@is_hiscore, @@is_hiscore + mov cx, SCORE_DIGITS + cmp _hiscore_popup_shown, 0 + jnz short @@hiscore_confirmed + +@@check_next_digit_for_hiscore: + mov al, [si] + cmp [di], al + ja short @@hiscore_denied + jb short @@hiscore_confirmed + dec di + dec si + loop @@check_next_digit_for_hiscore + +@@hiscore_confirmed: + ; Copy the remaining number of digits in CX, backwards (STD!) +if GAME eq 5 + cli +endif + std + rep movsb + cld +if GAME eq 5 + sti +endif + inc @@is_hiscore + +@@hiscore_denied: + mov al, @@is_hiscore + pop di + pop si + jmp @@render +score_update_and_render endp +main_01_TEXT ends + + end diff --git a/th04/scoreupd[data].asm b/th04/scoreupd[data].asm new file mode 100644 index 00000000..e9cea90d --- /dev/null +++ b/th04/scoreupd[data].asm @@ -0,0 +1,8 @@ +public _FIVE_DIGIT_POWERS_OF_10 +_FIVE_DIGIT_POWERS_OF_10 dw 10000, 1000, 100, 10, 1 + +if GAME eq 4 +; Temporary BCD conversion buffer. TH05 just uses _hud_gaiji_row instead. +public _TEMP_LEBCD +_temp_lebcd db SCORE_DIGITS dup(0) +endif diff --git a/th04/shared.hpp b/th04/shared.hpp index 5fce831f..b668993c 100644 --- a/th04/shared.hpp +++ b/th04/shared.hpp @@ -125,6 +125,7 @@ void pascal far explosions_small_reset(void); /// Score /// ----- +#define score_delta SCORE_DELTA extern unsigned long score_delta; void pascal near score_update_and_render(void); diff --git a/th04/shared.inc b/th04/shared.inc index 1f07e2fc..44373d9f 100644 --- a/th04/shared.inc +++ b/th04/shared.inc @@ -14,7 +14,7 @@ include th04/hardware/grcg.inc include th04/hardware/input.inc include th04/math/randring_next.inc include th04/math/motion.inc -include th02/gaiji_boldfont.inc +include th02/gaiji/boldfont.inc include th04/gaiji.inc include th04/hud/popup.inc include th02/score.inc diff --git a/th04_main.asm b/th04_main.asm index eb4fcfab..0622edda 100644 --- a/th04_main.asm +++ b/th04_main.asm @@ -966,7 +966,7 @@ sub_B1D0 proc near call sub_1DA1B call main_01:sub_FFA4 call sparks_init - call main_01:sub_11692 + call hud_score_put call sub_15D74 call main_01:sub_BCB2 nopcall main_01:sub_F204 @@ -6951,7 +6951,7 @@ loc_E796: nopcall main_01:sub_EFA1 inc _continues_used call sub_EEB0 - call sub_11692 + call hud_score_put mov al, 0 jmp short loc_E7DA ; --------------------------------------------------------------------------- @@ -7760,8 +7760,8 @@ playfield_fillm_0_120_384_128 endp ; =============== S U B R O U T I N E ======================================= ; Attributes: bp-based frame - -sub_EE06 proc near +public SCORE_EXTEND_UPDATE +score_extend_update proc near var_1 = byte ptr -1 @@ -7836,7 +7836,7 @@ loc_EE8C: locret_EEA3: leave retn -sub_EE06 endp +score_extend_update endp ; --------------------------------------------------------------------------- db 0 @@ -7869,7 +7869,7 @@ loc_EEBF: mov _score_delta_frame, 0 mov _score_unused, 0 mov byte_22DA6, 0 - mov _is_hiscore, 0 + mov _hiscore_popup_shown, 0 pop si pop bp retn @@ -8311,7 +8311,7 @@ sub_F204 proc far mov bp, sp call gaiji_putsa pascal, (60 shl 16) + 3, ds offset gsHISCORE, TX_YELLOW call gaiji_putsa pascal, (61 shl 16) + 5, ds offset gsSCORE, TX_YELLOW - call sub_11692 + call hud_score_put les bx, _humaconfig cmp byte ptr es:[bx+12h], 30h ; '0' jnz short loc_F245 @@ -12550,159 +12550,11 @@ loc_1168E: pop bp retn sub_11647 endp - - -; =============== S U B R O U T I N E ======================================= - - -sub_11692 proc near - push si - push di - mov si, offset _hiscore_lebcd[SCORE_DIGITS - 1] - mov di, 4 - -loc_1169A: - mov cx, SCORE_DIGITS - mov bx, 1EC6h - -loc_116A0: - mov al, [si] - add al, 0A0h - mov [bx], al - inc bx - dec si - loop loc_116A0 - call gaiji_putsa pascal, 56, di, ds, offset unk_23206, TX_WHITE - add di, 2 - cmp di, 6 - jz short loc_1169A - pop si - pop di - retn -sub_11692 endp - - -; =============== S U B R O U T I N E ======================================= - - -score_update_and_render proc near - mov eax, _score_delta - or eax, eax - jz short locret_1172C - cmp _score_delta_frame, eax - jbe short loc_116D7 - mov word ptr _score_delta_frame, ax - -loc_116D7: - shr eax, 5 - or eax, eax - jnz short loc_116E3 - inc ax - jmp short loc_116EE -; --------------------------------------------------------------------------- - -loc_116E3: - cmp eax, SCORE_DELTA_FRAME_LIMIT - jbe short loc_116EE - mov ax, SCORE_DELTA_FRAME_LIMIT - -loc_116EE: - cmp word ptr _score_delta_frame, ax - jnb short loc_116F7 - mov word ptr _score_delta_frame, ax - -loc_116F7: - mov cx, word ptr _score_delta_frame - jmp short loc_1172E -; --------------------------------------------------------------------------- - -loc_116FD: - cmp _is_hiscore, 0 - jnz short loc_11718 - or al, al - jz short loc_11718 - mov _is_hiscore, 1 - mov _popup_id_new, POPUP_ID_HISCORE_ENTRY - mov _popup_fp, offset popup_update_and_render - -loc_11718: - mov eax, _score_delta_frame - sub _score_delta, eax - call sub_11692 - mov _score_unused, 0 - call sub_EE06 - -locret_1172C: - retn -; --------------------------------------------------------------------------- - nop - -loc_1172E: - push si - push di - mov bx, 1EC2h - mov si, 1EB4h - -loc_11736: - mov ax, cx - xor dx, dx - div word ptr [si] - mov cx, dx - mov [bx], al - dec bx - add si, 2 - cmp word ptr [si], 1 - ja short loc_11736 - mov [bx], cl - mov si, offset _score_lebcd[1] - mov cx, SCORE_DIGITS - 2 - xor ah, ah - -loc_11753: - mov al, [bx] - add al, [si] - aaa - mov [si], al - inc bx - inc si - add [si], ah - mov ah, 0 - loop loc_11753 - mov al, [bx] - add [si], al - push ds - pop es - assume es:_DATA - mov si, offset _score_lebcd[SCORE_DIGITS - 1] - mov di, offset _hiscore_lebcd[SCORE_DIGITS - 1] - xor dl, dl - mov cx, SCORE_DIGITS - cmp _is_hiscore, 0 - jnz short loc_11786 - -loc_1177A: - mov al, [si] - cmp [di], al - ja short loc_1178C - jb short loc_11786 - dec di - dec si - loop loc_1177A - -loc_11786: - std - rep movsb - cld - inc dl - -loc_1178C: - mov al, dl - pop di - pop si - jmp loc_116FD -score_update_and_render endp main_01_TEXT ends + HUD_SCORE_PUT procdesc near + SCORE_UPDATE_AND_RENDER procdesc near + main_011_TEXT segment byte public 'CODE' use16 assume cs:main_01 @@ -40873,34 +40725,8 @@ aVivavvvvilcvb@ db ' aPnpcuyszlB@bCa db 'Yzȁ@` Capriccio ',0 include th04/formats/bb_txt_load[data].asm word_231F2 dw 10h - db 10h - db 27h ; ' - db 0E8h - db 3 - db 64h ; d - db 0 - db 0Ah - db 0 - db 1 - db 0 - db 0 - db 0 - db 0 - db 0 - db 0 - db 0 - db 0 - db 0 -unk_23206 db 0 - db 0 - db 0 - db 0 - db 0 - db 0 - db 0 - db 0 - db 0 - db 0 +include th04/scoreupd[data].asm +include th04/hud/gaiji_row[data].asm word_23210 dw 0 byte_23212 db 0 db 0 diff --git a/th05/hud/number_put.asm b/th05/hud/number_put.asm index 91391b63..a9267dce 100644 --- a/th05/hud/number_put.asm +++ b/th05/hud/number_put.asm @@ -15,7 +15,7 @@ pushstate nosmart lea di, _hud_gaiji_row + (SCORE_DIGITS - 5) movzx edx, [bp+@@val] - lea bx, _POWERS_OF_10_LONG + (2 * 4) + lea bx, _SEVEN_DIGIT_POWERS_OF_10 + (2 * 4) popstate mov ax, [bp+@@atrb] mov cx, 4 @@ -43,7 +43,7 @@ hud_points_put proc far mov di, offset _hud_gaiji_row mov ax, TX_WHITE mov _hud_gaiji_row[SCORE_DIGITS - 1], gb_0_ ; ("continues used" digit) - mov bx, offset _POWERS_OF_10_LONG + mov bx, offset _SEVEN_DIGIT_POWERS_OF_10 mov cx, SCORE_DIGITS - 2 hud_digits_put: diff --git a/th05/main_01.cpp b/th05/main012.cpp similarity index 90% rename from th05/main_01.cpp rename to th05/main012.cpp index 2660f782..a3052062 100644 --- a/th05/main_01.cpp +++ b/th05/main012.cpp @@ -1,8 +1,10 @@ /* ReC98 * ----- - * Code segment #1 of TH05's MAIN.EXE + * 2nd part of code segment #1 of TH05's MAIN.EXE */ +#pragma codeseg main_01_TEXT + extern "C" { #include "th05/th05.hpp" diff --git a/th05_main.asm b/th05_main.asm index da8fa0df..3a91ee63 100644 --- a/th05_main.asm +++ b/th05_main.asm @@ -1112,7 +1112,7 @@ sub_B55A proc near call sub_16D67 call sub_C473 call sparks_init - call sub_143CA + call hud_score_put call sub_C29E nopcall sub_106F3 mov fp_23F5A, offset tiles_render_all @@ -8896,7 +8896,7 @@ loc_FBB5: nopcall sub_104BB inc _continues_used call sub_10398 - call sub_143CA + call hud_score_put mov al, 0 jmp short loc_FBF7 ; --------------------------------------------------------------------------- @@ -9481,7 +9481,7 @@ loc_103E9: jg short loc_103A4 mov _score_delta, 0 mov _score_delta_frame, 0 - mov _is_hiscore, 0 + mov _hiscore_popup_shown, 0 pop si pop bp retn @@ -9865,7 +9865,7 @@ sub_106F3 proc far mov bp, sp call gaiji_putsa pascal, (60 shl 16) + 3, ds offset gsHISCORE, TX_YELLOW call gaiji_putsa pascal, (61 shl 16) + 5, ds offset gsSCORE, TX_YELLOW - call sub_143CA + call hud_score_put mov al, playchar mov ah, 0 mov bx, ax @@ -17712,156 +17712,8 @@ loc_143C1: retn 6 sub_1437E endp - -; =============== S U B R O U T I N E ======================================= - - -sub_143CA proc near - push si - push di - mov si, offset _hiscore_lebcd[SCORE_DIGITS - 1] - mov di, 4 - -loc_143D2: - mov cx, HUD_TRAM_W - mov bx, offset _hud_gaiji_row - -loc_143D8: - mov al, [si] - add al, 0A0h - mov [bx], al - inc bx - dec si - loop loc_143D8 - call gaiji_putsa pascal, 56, di, ds, offset _hud_gaiji_row, TX_WHITE - add di, 2 - cmp di, 6 - jz short loc_143D2 - pop si - pop di - retn -sub_143CA endp - - -; =============== S U B R O U T I N E ======================================= -;uth05win:CStage::StepScore() -;;_score_delta==curDelta=m_curScore-m_drawScore -public SCORE_UPDATE_AND_RENDER -score_update_and_render proc near - mov eax, _score_delta - or eax, eax ;if (eax==0) - jz short locret_1445C ; goto locret_1445C - cmp _score_delta_frame, eax ;if (m_drawScoreDelta<=m_curScore-m_drawScore) - jbe short loc_1440F ; goto loc_1440F - mov word ptr _score_delta_frame, ax;m_drawScoreDelta=curDelta; - -loc_1440F: - shr eax, 5 ;curDelta/=32 - or eax, eax ;if (curDelta!=0) - jnz short loc_1441B ; goto loc_1441B - inc ax ;curDelta=1 - jmp short loc_14426 ;goto loc_14426 -; --------------------------------------------------------------------------- - -loc_1441B: - cmp eax, SCORE_DELTA_FRAME_LIMIT - jbe short loc_14426 ; goto loc_14426 - mov ax, SCORE_DELTA_FRAME_LIMIT - -loc_14426: - cmp word ptr _score_delta_frame, ax - jnb short loc_1442F - mov word ptr _score_delta_frame, ax - -loc_1442F: - mov dx, word ptr _score_delta_frame - jmp short loc_1445E -; --------------------------------------------------------------------------- - -loc_14435: - cmp _is_hiscore, 0 - jnz short loc_14450 - or al, al - jz short loc_14450 - mov _is_hiscore, 1 - mov _popup_id_new, POPUP_ID_HISCORE_ENTRY - mov _popup_fp, offset popup_update_and_render - -loc_14450: - mov eax, _score_delta_frame - sub _score_delta, eax - call sub_143CA - -locret_1445C: - retn -; --------------------------------------------------------------------------- - nop - -loc_1445E: - push si - push di - push ds - pop es - mov dword ptr _hud_gaiji_row[4], 0 - mov di, offset _hud_gaiji_row[4] - mov bx, 1FBCh - mov cx, 4 - -loc_14474: - mov ax, dx - xor dx, dx - div word ptr [bx] - add bx, 2 - mov [di], al - dec di - loop loc_14474 - mov [di], dl - mov si, offset _score_lebcd[1] - mov cx, SCORE_DIGITS - 2 - xor ah, ah - -loc_1448C: - movzx ax, byte ptr [di] - add al, [si] - aaa - mov [si], al - inc di - inc si - add [si], ah - loop loc_1448C - mov al, [di] - add [si], al - mov si, offset _score_lebcd[SCORE_DIGITS - 1] - mov di, offset _hiscore_lebcd[SCORE_DIGITS - 1] - xor dl, dl - mov cx, SCORE_DIGITS - cmp _is_hiscore, 0 - jnz short loc_144BC - -loc_144B0: - mov al, [si] - cmp [di], al - ja short loc_144C4 - jb short loc_144BC - dec di - dec si - loop loc_144B0 - -loc_144BC: - cli - std - rep movsb - cld - sti - inc dl - -loc_144C4: - mov al, dl - pop di - pop si - jmp loc_14435 -score_update_and_render endp - + HUD_SCORE_PUT procdesc near + SCORE_UPDATE_AND_RENDER procdesc near BOSS_RESET procdesc near BB_STAGE_LOAD procdesc near BB_STAGE_FREE procdesc near @@ -38280,18 +38132,9 @@ SHOT_FUNCS label word dw shot_yuuka_l9 byte_2297E db 0 db 0 -include th02/hud/number_put[data].asm - db 10h - db 27h ; ' - db 0E8h - db 3 - db 64h ; d - db 0 - db 0Ah - db 0 - db 1 - db 0 -include th05/hud/gaiji_row[data].asm +include th02/hud/score_put[data].asm +include th04/scoreupd[data].asm +include th04/hud/gaiji_row[data].asm db 0 db 0 db 3