Skip to content

Commit

Permalink
[Reverse-engineering] [th05] Music Room piano functions
Browse files Browse the repository at this point in the history
No need to declare most of these in C land if 1) it isn't even clear
yet whether we can even decompile these functions with their 2)
complex __usercall conventions, which 3) aren't even called from
outside this slice. --Nmlgc
  • Loading branch information
Wintiger0222 authored and nmlgc committed Dec 17, 2019
1 parent 53f3167 commit 2a722db
Show file tree
Hide file tree
Showing 5 changed files with 321 additions and 318 deletions.
311 changes: 311 additions & 0 deletions th05/music/piano.asm
@@ -0,0 +1,311 @@
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_Y + (0 * PIANO_H_PADDED)) * ROW_SIZE
call piano_draw_part_keys
mov di, (PIANO_Y + (1 * PIANO_H_PADDED)) * ROW_SIZE
call piano_draw_part_keys
mov di, (PIANO_Y + (2 * PIANO_H_PADDED)) * ROW_SIZE
call piano_draw_part_keys
mov di, (PIANO_Y + (3 * PIANO_H_PADDED)) * ROW_SIZE
call piano_draw_part_keys
mov di, (PIANO_Y + (4 * PIANO_H_PADDED)) * ROW_SIZE
call piano_draw_part_keys
mov di, (PIANO_Y + (5 * PIANO_H_PADDED)) * ROW_SIZE
call piano_draw_part_keys
mov ah, GC_RI
call grcg_setcolor_direct_noint_1
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_Y + (5 * PIANO_H_PADDED)) * ROW_SIZE
call piano_draw_part_keys
lds bx, _pmd_workadr ; FMPart[0]
mov di, (PIANO_Y + (0 * PIANO_H_PADDED)) * ROW_SIZE
mov si, offset piano_notes_t.fm[0]
call piano_part_render
add bx, 2 ; FMPart[1]
mov di, (PIANO_Y + (1 * PIANO_H_PADDED)) * ROW_SIZE
mov si, offset piano_notes_t.fm[1]
call piano_part_render
add bx, 2 ; FMPart[2]
mov di, (PIANO_Y + (2 * PIANO_H_PADDED)) * ROW_SIZE
mov si, offset piano_notes_t.fm[2]
call piano_part_render
add bx, 2 ; FMPart[3]
mov di, (PIANO_Y + (3 * PIANO_H_PADDED)) * ROW_SIZE
mov si, offset piano_notes_t.fm[3]
call piano_part_render
add bx, 2 ; FMPart[4]
mov di, (PIANO_Y + (4 * PIANO_H_PADDED)) * ROW_SIZE
mov si, offset piano_notes_t.fm[4]
call piano_part_render
mov ah, GC_RI
call grcg_setcolor_direct_noint_1
mov di, (PIANO_Y + (5 * PIANO_H_PADDED)) * ROW_SIZE
add bx, 4 ; SSGPart[0]
call piano_get_note
call piano_draw_pressed_key
add bx, 2 ; SSGPart[1]
call piano_get_note
call piano_draw_pressed_key
GRCG_OFF_VIA_XOR al
pop ds
pop di
pop si
retf
_piano_render endp


; void __usercall near piano_part_render(
; void far *vram_at_x0_and_top_of_part<es:di>,
; int fm_part_num<si>,
; QQ **pmd_part<ds:bx>,
; void __seg own_ds<fs>
; );
piano_part_render proc near
call piano_get_note
push ds
push fs
pop ds
cmp al, _piano_notes_cur.fm[si]
jnz short @@note_changed
cmp al, _piano_notes_prev.fm[si]
jz short @@ret

@@note_changed:
mov ah, _piano_notes_cur.fm[si]
mov _piano_notes_prev.fm[si], ah
mov _piano_notes_cur.fm[si], al
call piano_draw_part_keys
mov ah, GC_RI
call grcg_setcolor_direct_noint_1
mov al, _piano_notes_cur.fm[si]
call piano_draw_pressed_key

@@ret:
pop ds
retn
piano_part_render endp


; char __usercall near piano_get_note(QQ **pmd_part<ds:bx>);
piano_get_note proc near
push bx
mov bx, [bx]
mov ax, word ptr [bx+qq.leng]
cmp ah, 4
jbe short @@above_gatetime?
mov ah, 4

@@above_gatetime?:
cmp al, ah
jbe short @@resting
cmp al, 1
jbe short @@resting
mov al, [bx+qq.onkai]
jmp short @@ret
; ---------------------------------------------------------------------------

@@resting:
mov al, ONKAI_REST

@@ret:
pop bx
retn
piano_get_note endp


; void __usercall near piano_draw_part_keys(
; void far *vram_at_x0_and_top_of_part<es:di>
; )
piano_draw_part_keys proc near
push di
push si
mov ah, GC_GI
call grcg_setcolor_direct_noint_1
add di, PIANO_VRAM_X
mov ax, PIANO_KEYS_WHITE
mov dl, PIANO_H

@@white_key_loop:
mov cx, PIANO_VRAM_W / 2
rep stosw
add di, ROW_SIZE - PIANO_VRAM_W
dec dl
jnz short @@white_key_loop
mov ah, GC_RGI
call grcg_setcolor_direct_noint_1
mov si, offset _PIANO_KEYS_BLACK
sub di, ROW_SIZE * PIANO_H
mov dl, PIANO_BLACK_H

@@black_key_loop:
mov cx, PIANO_VRAM_W / 2
rep movsw
sub si, PIANO_VRAM_W
add di, ROW_SIZE - PIANO_VRAM_W
dec dl
jnz short @@black_key_loop
pop si
pop di
retn
piano_draw_part_keys endp


; void __usercall near piano_draw_pressed_key(
; void far *vram_at_x0_and_top_of_part<es:di>, char onkai<al>
; )
piano_draw_pressed_key proc near
cmp al, ONKAI_REST
jnz short @@note_is_active
retn
; ---------------------------------------------------------------------------

@@note_is_active:
push bx
push di
mov ah, al
and ah, ONKAI_NOTE_MASK
xor bh, bh
mov bl, ah
shr al, 4
mov dl, PIANO_OCTAVE_W
mul dl
mov dl, cs:PIANO_KEY_PRESSED_TOP[bx]
add bx, bx
add ax, cs:PIANO_NOTE_X[bx]
mov cx, ax
shr ax, 3
add di, ax
and cl, 7
jmp cs:BLACK_OR_WHITE[bx]

white_key:
shr dl, cl
mov al, cl
mov cx, PIANO_BLACK_H

@@white_key_top_loop:
mov es:[di], dl
add di, ROW_SIZE
loop @@white_key_top_loop
mov cl, al
mov al, (111b shl 5) ; bottom part of any pressed key
shr al, cl
mov cx, PIANO_H - PIANO_BLACK_H

@@white_key_bottom_loop:
mov es:[di], al
add di, ROW_SIZE
loop @@white_key_bottom_loop
jmp short @@ret
; ---------------------------------------------------------------------------

black_key:
xor dh, dh
ror dx, cl
mov cx, PIANO_BLACK_PRESSED_H

@@black_key_loop:
mov es:[di], dx
add di, ROW_SIZE
loop @@black_key_loop

@@ret:
pop di
pop bx
retn
piano_draw_pressed_key endp

; ---------------------------------------------------------------------------
BLACK_OR_WHITE label word
dw offset white_key ; C
dw offset black_key ; C#
dw offset white_key ; D
dw offset black_key ; D#
dw offset white_key ; E
dw offset white_key ; F
dw offset black_key ; F#
dw offset white_key ; G
dw offset black_key ; G#
dw offset white_key ; A
dw offset black_key ; A#
dw offset white_key ; B

PIANO_NOTE_X label word
dw PIANO_X + 0 ; C
dw PIANO_X + 2 ; C#
dw PIANO_X + 4 ; D
dw PIANO_X + 6 ; D#
dw PIANO_X + 8 ; E
dw PIANO_X + 12 ; F
dw PIANO_X + 14 ; F#
dw PIANO_X + 16 ; G
dw PIANO_X + 18 ; G#
dw PIANO_X + 20 ; A
dw PIANO_X + 22 ; A#
dw PIANO_X + 24 ; B

; 1bpp sprite data for the top part of a pressed key, in the black key row.
PIANO_KEY_PRESSED_TOP label byte
db (110b shl 5) ; C
db (110b shl 5) ; C#
db (010b shl 5) ; D
db (110b shl 5) ; D#
db (011b shl 5) ; E
db (110b shl 5) ; F
db (110b shl 5) ; F#
db (010b shl 5) ; G
db (110b shl 5) ; G#
db (010b shl 5) ; A
db (110b shl 5) ; A#
db (011b shl 5) ; B


public PIANO_LABEL_PUT_RAW
piano_label_put_raw proc near
xor ah, ah
shl al, 3
add ax, offset _PIANO_LABEL_FONT
mov si, ax
mov cx, PIANO_LABEL_FONT_W

@@row_loop:
movsb
add di, ROW_SIZE - 1
loop @@row_loop
retn
piano_label_put_raw endp
5 changes: 5 additions & 0 deletions th05/music/piano.h
Expand Up @@ -11,6 +11,8 @@

#define PIANO_OCTAVES 8
#define PIANO_OCTAVE_W (7 * PIANO_KEY_W)

#define PIANO_VRAM_X (PIANO_X / 8)
#define PIANO_VRAM_W ((PIANO_OCTAVES * PIANO_OCTAVE_W) / 8)

// Sprite data
Expand Down Expand Up @@ -69,3 +71,6 @@ typedef struct {
extern piano_notes_t piano_notes_cur;
extern piano_notes_t piano_notes_prev;
// ---------

void piano_setup(void);
void piano_render(void);
2 changes: 2 additions & 0 deletions th05/music/piano.inc
Expand Up @@ -9,6 +9,8 @@ PIANO_H_PADDED = (PIANO_H + PIANO_PADDING_BOTTOM)

PIANO_OCTAVES = 8
PIANO_OCTAVE_W = (7 * PIANO_KEY_W)

PIANO_VRAM_X = (PIANO_X / 8)
PIANO_VRAM_W = ((PIANO_OCTAVES * PIANO_OCTAVE_W) / 8)

piano_notes_t struc
Expand Down
14 changes: 0 additions & 14 deletions th05/music/piano_label.asm

This file was deleted.

0 comments on commit 2a722db

Please sign in to comment.