ReC98/th05/music/piano.asm

312 lines
6.5 KiB
NASM

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