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, ; int fm_part_num, ; QQ **pmd_part, ; void __seg own_ds ; ); 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); 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 ; ) 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, char onkai ; ) 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