mirror of https://github.com/nmlgc/ReC98.git
[Decompilation] [th05] Music Room piano (decompilable functions)
If anything, these decompilations of barely decompilable functions can
at least indicate that I tried. 🤷 Nice __fastcall abuse though, which
allows us to least formalize *some* of the implicit state passed
between those functions.
Completes P0135, funded by [Anonymous].
This commit is contained in:
parent
152ecaa496
commit
252c13d383
|
@ -152,7 +152,7 @@ bin\th05\res_kso.com: th05\res_kso.cpp
|
|||
$**
|
||||
| masters.lib
|
||||
|
||||
bin\th05\op.exe: th05\op010.cpp bin\th05\op.obj th05\op011.cpp th05\m_char.cpp bin\th05\musicp_a.obj bin\th05\bgimager.obj bin\th05\snd_load.obj bin\th05\snd_kaja.obj bin\th05\pi_cpp_1.obj bin\th05\pi_asm_1.obj bin\th05\pi_cpp_2.obj bin\th05\pi_asm_2.obj bin\th05\initop.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\snd_dlym.obj th05\cdg_p_nc.cpp bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th05\egcrect.obj bin\hfliplut.obj
|
||||
bin\th05\op.exe: th05\op010.cpp bin\th05\op.obj th05\op011.cpp th05\m_char.cpp bin\th05\musicp_c.obj bin\th05\musicp_a.obj bin\th05\bgimager.obj bin\th05\snd_load.obj bin\th05\snd_kaja.obj bin\th05\pi_cpp_1.obj bin\th05\pi_asm_1.obj bin\th05\pi_cpp_2.obj bin\th05\pi_asm_2.obj bin\th05\initop.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\snd_dlym.obj th05\cdg_p_nc.cpp bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th05\egcrect.obj bin\hfliplut.obj
|
||||
$(CC) $(CFLAGS) $(LARGE_LFLAGS) -DGAME=5 -DBINARY='O' -3 -Z -nbin\th05\ -eOP.EXE @&&|
|
||||
$**
|
||||
|
|
||||
|
|
|
@ -1,57 +1,6 @@
|
|||
/// Graphics
|
||||
/// --------
|
||||
#define PIANO_LEFT 384
|
||||
#define PIANO_TOP 64
|
||||
#define PIANO_H 15
|
||||
#define PIANO_KEY_W 4
|
||||
#define PIANO_BLACK_H 9
|
||||
#define PIANO_BLACK_PRESSED_H 8
|
||||
#define PIANO_PADDING_BOTTOM 3
|
||||
#define PIANO_H_PADDED (PIANO_H + PIANO_PADDING_BOTTOM)
|
||||
// Initializes note rendering and draws blank pianos for all monitored PMD
|
||||
// channels.
|
||||
void piano_setup_and_put_initial(void);
|
||||
|
||||
#define PIANO_OCTAVES 8
|
||||
#define PIANO_OCTAVE_W (7 * PIANO_KEY_W)
|
||||
|
||||
#define PIANO_VRAM_LEFT (PIANO_LEFT / BYTE_DOTS)
|
||||
#define PIANO_VRAM_W ((PIANO_OCTAVES * PIANO_OCTAVE_W) / BYTE_DOTS)
|
||||
|
||||
// Sprite data
|
||||
extern const dots8_t PIANO_KEYS_BLACK[PIANO_VRAM_W];
|
||||
/// --------
|
||||
|
||||
#define PIANO_LABEL_DIST_X 32
|
||||
#define PIANO_LABEL_DIST_Y 4
|
||||
|
||||
#define PIANO_LABEL_LEFT(col) \
|
||||
(PIANO_LEFT - PIANO_LABEL_DIST_X + (col * PIANO_LABEL_FONT_W))
|
||||
#define PIANO_LABEL_TOP(row) \
|
||||
(PIANO_TOP + PIANO_LABEL_DIST_Y + (row * PIANO_H_PADDED))
|
||||
|
||||
// Assumes that the GRCG is active.
|
||||
#define piano_label_puts(row, chr1, chr2, chr3) \
|
||||
piano_label_putc(0, row, chr1); \
|
||||
piano_label_putc(1, row, chr2); \
|
||||
piano_label_putc(2, row, chr3); \
|
||||
|
||||
#define piano_label_putc(col, row, chr) \
|
||||
_AL = chr; \
|
||||
_DI = vram_offset_muldiv(PIANO_LABEL_LEFT(col), PIANO_LABEL_TOP(row)); \
|
||||
piano_label_put_raw();
|
||||
|
||||
void pascal piano_label_put_raw();
|
||||
|
||||
// Note data
|
||||
// ---------
|
||||
extern OPEN_WORK *pmd_workadr;
|
||||
|
||||
typedef struct {
|
||||
char fm[5];
|
||||
char unused[3]; // SSG?
|
||||
} piano_notes_t;
|
||||
|
||||
extern piano_notes_t piano_notes_cur;
|
||||
extern piano_notes_t piano_notes_prev;
|
||||
// ---------
|
||||
|
||||
void piano_setup(void);
|
||||
// Renders the currently played PMD notes.
|
||||
void piano_render(void);
|
||||
|
|
|
@ -1,25 +1,4 @@
|
|||
PIANO_LEFT = 384
|
||||
PIANO_TOP = 64
|
||||
PIANO_H = 15
|
||||
PIANO_KEY_W = 4
|
||||
PIANO_BLACK_H = 9
|
||||
PIANO_BLACK_PRESSED_H = 8
|
||||
PIANO_PADDING_BOTTOM = 3
|
||||
PIANO_H_PADDED = (PIANO_H + PIANO_PADDING_BOTTOM)
|
||||
|
||||
PIANO_OCTAVES = 8
|
||||
PIANO_OCTAVE_W = (7 * PIANO_KEY_W)
|
||||
|
||||
PIANO_VRAM_LEFT = (PIANO_LEFT / 8)
|
||||
PIANO_VRAM_W = ((PIANO_OCTAVES * PIANO_OCTAVE_W) / 8)
|
||||
|
||||
piano_notes_t struc
|
||||
fm db 5 dup(?)
|
||||
db 3 dup(?)
|
||||
piano_notes_t ends
|
||||
|
||||
PIANO_LABEL_DIST_X = 32
|
||||
PIANO_LABEL_DIST_Y = 4
|
||||
|
||||
PIANO_LABEL_LEFT = PIANO_LEFT - PIANO_LABEL_DIST_X
|
||||
PIANO_LABEL_TOP = PIANO_TOP + PIANO_LABEL_DIST_Y
|
||||
|
|
|
@ -7,6 +7,18 @@ include libs/kaja/kaja.inc
|
|||
include th04/hardware/grcg.inc
|
||||
include th05/music/piano.inc
|
||||
|
||||
PIANO_LEFT = 384
|
||||
PIANO_H = 15
|
||||
PIANO_KEY_W = 4
|
||||
PIANO_BLACK_H = 9
|
||||
PIANO_BLACK_PRESSED_H = 8
|
||||
|
||||
PIANO_OCTAVES = 8
|
||||
PIANO_OCTAVE_W = (7 * PIANO_KEY_W)
|
||||
|
||||
PIANO_VRAM_LEFT = (PIANO_LEFT / 8)
|
||||
PIANO_VRAM_W = ((PIANO_OCTAVES * PIANO_OCTAVE_W) / 8)
|
||||
|
||||
extern _sPIANO_LABEL_FONT:byte
|
||||
extern _PIANO_KEYS_BLACK:byte:PIANO_VRAM_W
|
||||
extern _piano_notes_cur:piano_notes_t
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
@piano_fm_part_put_raw procdesc near
|
||||
@piano_current_note_from procdesc near
|
||||
_piano_part_keys_put_raw procdesc near
|
||||
@piano_pressed_key_put procdesc near
|
||||
@piano_label_put_raw procdesc near
|
||||
_grcg_setcolor_direct_seg1_raw procdesc near
|
||||
|
||||
PIANO_LABEL_FONT_W = 8
|
||||
PIANO_LABEL_FONT_H = 8
|
||||
|
||||
piano_label_puts macro row:req, chr1:req, chr2:req, chr3:req
|
||||
piano_label_putc 0, row, chr1
|
||||
piano_label_putc 1, row, chr2
|
||||
piano_label_putc 2, row, chr3
|
||||
endm
|
||||
|
||||
piano_label_putc macro col:req, row:req, chr:req
|
||||
mov al, chr
|
||||
mov di, ((PIANO_LABEL_TOP + (row * PIANO_H_PADDED)) * ROW_SIZE) + ((PIANO_LABEL_LEFT + (col * PIANO_LABEL_FONT_W)) / 8)
|
||||
call @piano_label_put_raw
|
||||
endm
|
||||
|
||||
|
||||
public _piano_setup
|
||||
_piano_setup proc far
|
||||
push si
|
||||
push di
|
||||
GRCG_SETMODE_VIA_MOV al, GC_RMW
|
||||
mov ax, GRAM_400
|
||||
mov es, ax
|
||||
assume es:nothing
|
||||
mov di, (PIANO_TOP + (0 * PIANO_H_PADDED)) * ROW_SIZE
|
||||
call _piano_part_keys_put_raw
|
||||
mov di, (PIANO_TOP + (1 * PIANO_H_PADDED)) * ROW_SIZE
|
||||
call _piano_part_keys_put_raw
|
||||
mov di, (PIANO_TOP + (2 * PIANO_H_PADDED)) * ROW_SIZE
|
||||
call _piano_part_keys_put_raw
|
||||
mov di, (PIANO_TOP + (3 * PIANO_H_PADDED)) * ROW_SIZE
|
||||
call _piano_part_keys_put_raw
|
||||
mov di, (PIANO_TOP + (4 * PIANO_H_PADDED)) * ROW_SIZE
|
||||
call _piano_part_keys_put_raw
|
||||
mov di, (PIANO_TOP + (5 * PIANO_H_PADDED)) * ROW_SIZE
|
||||
call _piano_part_keys_put_raw
|
||||
mov ah, GC_RI
|
||||
call _grcg_setcolor_direct_seg1_raw
|
||||
piano_label_puts 0, pl_F, pl_M, pl_1
|
||||
piano_label_puts 1, pl_F, pl_M, pl_2
|
||||
piano_label_puts 2, pl_F, pl_M, pl_3
|
||||
piano_label_puts 3, pl_F, pl_M, pl_4
|
||||
piano_label_puts 4, pl_F, pl_M, pl_5
|
||||
piano_label_puts 5, pl_S, pl_S, pl_G
|
||||
GRCG_OFF_VIA_XOR al
|
||||
push ds
|
||||
mov ah, PMD_GET_WORKAREA_ADDRESS
|
||||
int PMD
|
||||
mov ax, ds
|
||||
pop ds
|
||||
mov word ptr _pmd_workadr, dx
|
||||
mov word ptr _pmd_workadr+2, ax
|
||||
pop di
|
||||
pop si
|
||||
retf
|
||||
_piano_setup endp
|
||||
|
||||
|
||||
public _piano_render
|
||||
_piano_render proc far
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
push ds
|
||||
pop fs
|
||||
GRCG_SETMODE_VIA_MOV al, GC_RMW
|
||||
mov ax, GRAM_400
|
||||
mov es, ax
|
||||
mov di, (PIANO_TOP + (5 * PIANO_H_PADDED)) * ROW_SIZE
|
||||
call _piano_part_keys_put_raw
|
||||
lds bx, _pmd_workadr ; FMPart[0]
|
||||
mov di, (PIANO_TOP + (0 * PIANO_H_PADDED)) * ROW_SIZE
|
||||
mov si, offset piano_notes_t.fm[0]
|
||||
call @piano_fm_part_put_raw
|
||||
add bx, 2 ; FMPart[1]
|
||||
mov di, (PIANO_TOP + (1 * PIANO_H_PADDED)) * ROW_SIZE
|
||||
mov si, offset piano_notes_t.fm[1]
|
||||
call @piano_fm_part_put_raw
|
||||
add bx, 2 ; FMPart[2]
|
||||
mov di, (PIANO_TOP + (2 * PIANO_H_PADDED)) * ROW_SIZE
|
||||
mov si, offset piano_notes_t.fm[2]
|
||||
call @piano_fm_part_put_raw
|
||||
add bx, 2 ; FMPart[3]
|
||||
mov di, (PIANO_TOP + (3 * PIANO_H_PADDED)) * ROW_SIZE
|
||||
mov si, offset piano_notes_t.fm[3]
|
||||
call @piano_fm_part_put_raw
|
||||
add bx, 2 ; FMPart[4]
|
||||
mov di, (PIANO_TOP + (4 * PIANO_H_PADDED)) * ROW_SIZE
|
||||
mov si, offset piano_notes_t.fm[4]
|
||||
call @piano_fm_part_put_raw
|
||||
mov ah, GC_RI
|
||||
call _grcg_setcolor_direct_seg1_raw
|
||||
mov di, (PIANO_TOP + (5 * PIANO_H_PADDED)) * ROW_SIZE
|
||||
add bx, 4 ; SSGPart[0]
|
||||
call @piano_current_note_from
|
||||
call @piano_pressed_key_put
|
||||
add bx, 2 ; SSGPart[1]
|
||||
call @piano_current_note_from
|
||||
call @piano_pressed_key_put
|
||||
GRCG_OFF_VIA_XOR al
|
||||
pop ds
|
||||
pop di
|
||||
pop si
|
||||
retf
|
||||
_piano_render endp
|
|
@ -1,3 +1,94 @@
|
|||
#pragma codeseg SHARED_
|
||||
#pragma option -k-
|
||||
|
||||
extern "C" {
|
||||
#include "platform.h"
|
||||
#include "x86real.h"
|
||||
#include "pc98.h"
|
||||
#include "planar.h"
|
||||
#include "decomp.h"
|
||||
#include "master.hpp"
|
||||
#include "libs/kaja/kaja.h"
|
||||
#include "th05/music/piano.h"
|
||||
#include "th05/sprites/piano_l.h"
|
||||
|
||||
/// Coordinates
|
||||
/// -----------
|
||||
|
||||
static const screen_x_t PIANO_LEFT = 384;
|
||||
static const vram_y_t PIANO_TOP = 64;
|
||||
static const pixel_t PIANO_H = 15;
|
||||
static const pixel_t PIANO_KEY_W = 4;
|
||||
static const pixel_t PIANO_BLACK_H = 9;
|
||||
static const pixel_t PIANO_BLACK_PRESSED_H = 8;
|
||||
static const pixel_t PIANO_PADDING_BOTTOM = 3;
|
||||
static const pixel_t PIANO_H_PADDED = (PIANO_H + PIANO_PADDING_BOTTOM);
|
||||
|
||||
static const int PIANO_OCTAVES = 8;
|
||||
static const pixel_t PIANO_OCTAVE_W = (7 * PIANO_KEY_W);
|
||||
|
||||
static const vram_x_t PIANO_VRAM_LEFT = (PIANO_LEFT / BYTE_DOTS);
|
||||
static const vram_byte_amount_t PIANO_VRAM_W = (
|
||||
(PIANO_OCTAVES * PIANO_OCTAVE_W) / BYTE_DOTS
|
||||
);
|
||||
|
||||
static const pixel_t PIANO_LABEL_DIST_X = 32;
|
||||
static const pixel_t PIANO_LABEL_DIST_Y = 4;
|
||||
|
||||
static inline screen_x_t label_left(int col) {
|
||||
return (PIANO_LEFT - PIANO_LABEL_DIST_X + (col * PIANO_LABEL_FONT_W));
|
||||
}
|
||||
|
||||
static inline screen_x_t label_top(int row) {
|
||||
return (PIANO_TOP + PIANO_LABEL_DIST_Y + (row * PIANO_H_PADDED));
|
||||
}
|
||||
|
||||
static inline vram_y_t part_top(int part_id) {
|
||||
return (PIANO_TOP + (part_id * PIANO_H_PADDED));
|
||||
}
|
||||
/// -----------
|
||||
|
||||
// Sprite data
|
||||
extern const dots8_t PIANO_KEYS_BLACK[PIANO_VRAM_W];
|
||||
|
||||
/// Note data
|
||||
/// ---------
|
||||
|
||||
// Actually a single `OPEN_WORK far *`.
|
||||
extern uint16_t pmd_workadr[2];
|
||||
|
||||
typedef struct {
|
||||
char fm[5];
|
||||
char unused[3]; // SSG?
|
||||
} piano_notes_t;
|
||||
|
||||
extern piano_notes_t piano_notes_cur;
|
||||
extern piano_notes_t piano_notes_prev;
|
||||
/// ---------
|
||||
|
||||
/// Redundant garbage
|
||||
/// -----------------
|
||||
|
||||
#undef grcg_setmode
|
||||
#undef grcg_off
|
||||
|
||||
#define grcg_setmode(mode) __asm { \
|
||||
mov al, mode; \
|
||||
out 0x7C, al; \
|
||||
}
|
||||
|
||||
#define grcg_off() __asm { \
|
||||
db 0x32, 0xC0; /* XOR AL, AL (alternate encoding) */ \
|
||||
out 0x7C, al; \
|
||||
}
|
||||
|
||||
void near grcg_setcolor_direct_seg1_raw();
|
||||
#define grcg_setcolor(col) { \
|
||||
_AH = col; \
|
||||
grcg_setcolor_direct_seg1_raw(); \
|
||||
}
|
||||
/// -----------------
|
||||
|
||||
/// Helper functions
|
||||
/// ----------------
|
||||
|
||||
|
@ -11,18 +102,26 @@
|
|||
void __fastcall near piano_fm_part_put_raw(
|
||||
int16_t ax_unused, int16_t dx_unused, QQ near *near *qq
|
||||
);
|
||||
#define piano_fm_part_put(part_id, qq) \
|
||||
_DI = vram_offset_shift(0, part_top(part_id)); \
|
||||
__asm { mov si, part_id; } \
|
||||
piano_fm_part_put_raw(_AX, _DX, qq);
|
||||
|
||||
// Returns the currently played note from [qq] as a KAJA onkai value, or
|
||||
// ONKAI_REST if none is played.
|
||||
char __fastcall near piano_current_note_from(
|
||||
int16_t ax_unused, int16_t dx_unused, QQ near *near *qq
|
||||
);
|
||||
);
|
||||
|
||||
// Additionally takes:
|
||||
// • `void far *vram_at_x0_and_top_of_part<es:di>`
|
||||
// Draws a blank piano, for the part is indicated through the VRAM offset in
|
||||
// ES:DI.
|
||||
void near piano_part_keys_put_raw();
|
||||
inline void piano_part_keys_put(int part_id) {
|
||||
_DI = vram_offset_shift(0, part_top(part_id));
|
||||
piano_part_keys_put_raw();
|
||||
}
|
||||
|
||||
// Additionally takes:
|
||||
// • `void far *vram_at_x0_and_top_of_part<es:di>`
|
||||
|
@ -35,4 +134,85 @@ void __fastcall near piano_pressed_key_put(char onkai);
|
|||
// Blits a piano label character to the top-left VRAM position indicated in
|
||||
// ES:DI. Assumes that the GRCG is active.
|
||||
void __fastcall near piano_label_put_raw(piano_label_t label_char);
|
||||
inline void piano_label_putc(int col, int row, piano_label_t chr) {
|
||||
_AL = chr;
|
||||
_DI = vram_offset_muldiv(label_left(col), label_top(row));
|
||||
piano_label_put_raw(static_cast<piano_label_t>(_AL));
|
||||
}
|
||||
#define piano_label_puts(row, chr1, chr2, chr3) \
|
||||
piano_label_putc(0, row, pl_##chr1); \
|
||||
piano_label_putc(1, row, pl_##chr2); \
|
||||
piano_label_putc(2, row, pl_##chr3);
|
||||
/// ----------------
|
||||
|
||||
void piano_setup_and_put_initial(void)
|
||||
{
|
||||
grcg_setmode(GC_RMW);
|
||||
_ES = SEG_PLANE_B;
|
||||
// Thanks, Turbo C++, for indicating that SI actually didn't need to be
|
||||
// saved in this function!
|
||||
_SI = _SI;
|
||||
|
||||
piano_part_keys_put(0);
|
||||
piano_part_keys_put(1);
|
||||
piano_part_keys_put(2);
|
||||
piano_part_keys_put(3);
|
||||
piano_part_keys_put(4);
|
||||
piano_part_keys_put(5);
|
||||
|
||||
grcg_setcolor(GC_RI);
|
||||
piano_label_puts(0, F, M, 1);
|
||||
piano_label_puts(1, F, M, 2);
|
||||
piano_label_puts(2, F, M, 3);
|
||||
piano_label_puts(3, F, M, 4);
|
||||
piano_label_puts(4, F, M, 5);
|
||||
piano_label_puts(5, S, S, G);
|
||||
grcg_off();
|
||||
|
||||
__asm { push ds; }
|
||||
_AH = PMD_GET_WORKAREA_ADDRESS;
|
||||
geninterrupt(PMD);
|
||||
_AX = _DS;
|
||||
__asm { pop ds; }
|
||||
|
||||
// pmd_workadr = reinterpret_cast<OPEN_WORK far *>(MK_FP(_DX, _AX));
|
||||
pmd_workadr[0] = _DX;
|
||||
pmd_workadr[1] = _AX;
|
||||
}
|
||||
|
||||
void piano_render(void)
|
||||
{
|
||||
__asm { push ds; }
|
||||
__asm { push ds; }
|
||||
__emit__(0x0F, 0xA1); // POP FS
|
||||
|
||||
grcg_setmode(GC_RMW);
|
||||
_ES = SEG_PLANE_B;
|
||||
|
||||
piano_part_keys_put(5);
|
||||
|
||||
__asm { lds bx, dword ptr pmd_workadr; } // BX = FMPart[0]
|
||||
|
||||
#define _BX reinterpret_cast<QQ near *near *>(_BX)
|
||||
|
||||
piano_fm_part_put(0, _BX); _BX++; // BX = FMPart[1]
|
||||
piano_fm_part_put(1, _BX); _BX++; // BX = FMPart[2]
|
||||
piano_fm_part_put(2, _BX); _BX++; // BX = FMPart[3]
|
||||
piano_fm_part_put(3, _BX); _BX++; // BX = FMPart[4]
|
||||
piano_fm_part_put(4, _BX);
|
||||
|
||||
grcg_setcolor(GC_RI);
|
||||
_DI = vram_offset_shift(0, part_top(5));
|
||||
_BX += 2; // BX = SSGPart[0]
|
||||
piano_pressed_key_put(piano_current_note_from(_AX, _DX, _BX));
|
||||
_BX++; // BX = SSGPart[1]
|
||||
piano_pressed_key_put(piano_current_note_from(_AX, _DX, _BX));
|
||||
|
||||
#undef _BX
|
||||
|
||||
grcg_off();
|
||||
|
||||
__asm { pop ds; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#include "th05/music/piano_c.cpp"
|
|
@ -1924,7 +1924,7 @@ _musicroom proc near
|
|||
call pi_palette_apply pascal, 0
|
||||
call pi_put_8 pascal, large 0, 0
|
||||
call pi_free pascal, 0
|
||||
call _piano_setup
|
||||
call _piano_setup_and_put_initial
|
||||
call screen_back_B_snap
|
||||
call bgimage_snap
|
||||
call draw_tracks pascal, word ptr _music_sel
|
||||
|
@ -2537,7 +2537,8 @@ include th04/formats/cdg_put.asm
|
|||
include th02/exit.asm
|
||||
include th04/math/vector1_at.asm
|
||||
include th04/math/vector2_at.asm
|
||||
include th05/music/piano_c.asm
|
||||
extern _piano_render:proc
|
||||
extern _piano_setup_and_put_initial:proc
|
||||
extern BGIMAGE_PUT_RECT:proc
|
||||
extern SND_LOAD:proc
|
||||
extern SND_KAJA_INTERRUPT:proc
|
||||
|
|
Loading…
Reference in New Issue