apps/piano: refactoring, part 2

- Fixed bugs in keys and buttons reading and audio play
- Refactored data tables and removed loops
- Used more constants for everything
- Changes Spanish encoding to CP850
- Shifted notes on keys by -0x10 to match buttons
- Configured events mask for help thread
- Shift now works for buttons also
- Help window have relative coordinates from main window
- Maybe something else that I already forgot

Co-authored-by: Doczom <mixa.frolov2003@gmail.com>
This commit is contained in:
2025-12-26 20:58:46 +02:00
committed by Max Logaev
parent 39cd149625
commit 498ec0d276

View File

@@ -6,6 +6,7 @@
; Contributor ??? - Initial code
; Contributor Antonio - Refactoring and new functionality
; Contributor Burer - Refactoring and Spanish translation
; Contributor Doczom - Refactoring and bugfixes
; Contributor qullarwee - New keyboard layout
; ====================================================================
@@ -15,7 +16,7 @@ org 0
; ====================================================================
db 'MENUET01'
db "MENUET01"
dd 1
dd START
dd I_END
@@ -26,28 +27,26 @@ dd 0
; ====================================================================
include '../../macros.inc'
include "../../macros.inc"
include "../../KOSfuncs.inc"
include "../../encoding.inc"
; ====================================================================
START:
mcall SF_KEYBOARD, SSF_SET_INPUT_MODE, 1
jmp redraw
; ====================================================================
still:
mcall SF_WAIT_EVENT
cmp al, 1
cmp al, EV_REDRAW
je redraw
cmp al, 2
cmp al, EV_KEY
je key
cmp al, 3
cmp al, EV_BUTTON
je button
jmp still
@@ -55,7 +54,6 @@ still:
; ====================================================================
key:
mcall SF_GET_KEY
; drop keys release
@@ -68,46 +66,50 @@ key:
; check if Shift is pressed
; increase note_id by 0x40
mov bl, ah
movzx ecx, ah
mcall SF_KEYBOARD, SSF_GET_CONTROL_KEYS
xor dl, dl
xor edx, edx
test al, KEY_SHIFT
jz .key_map_setup
jz .key_map_play
mov dl, INC_SHIFT
; loop to find note_id by key_scancode
.key_map_setup:
mov edi, key_note_map
.key_note_loop:
cmp edi, key_note_map_end
; play note if valid key pressed
.key_map_play:
cmp cl, key_note_map.count
jae still
cmp bl, [edi]
jne .key_note_next
mov ah, [edi + 1]
mov ah, [key_note_map + ecx]
cmp ah, BAD_NOTE
je still
add ah, dl
jmp play
.key_note_next:
add edi, KM_SIZE
jmp .key_note_loop
; help window thread creation
.help:
cmp [hp_tid], 0
cmp [hw_tid], 0
jne still
sub esp, 1024
mov ebx, esp
mcall SF_THREAD_INFO, ebx, -1
mov eax, [esp + process_information.box.left]
mov edx, [esp + process_information.box.top]
add esp, 1024
shl eax, 16
mov ax, dx
mov [mw_pos], eax
mcall SF_CREATE_THREAD, 1, help_thread, help_stack_top
cmp eax, -1
je still
mov [hp_tid], eax
mov [hw_tid], eax
jmp still
button:
mcall SF_GET_BUTTON
cmp ah, 1
@@ -115,24 +117,33 @@ button:
; note_id is always button_id - 0x10
sub ah, 0x10
jmp play
mov dl, ah
.exit:
mcall SF_TERMINATE_PROCESS
; check if Shift is pressed
; increase note_id by 0x40
mcall SF_KEYBOARD, SSF_GET_CONTROL_KEYS
test al, KEY_SHIFT
jz .no_shift
add dl, INC_SHIFT
.no_shift:
mov ah, dl
jmp play
.exit:
mcall SF_TERMINATE_PROCESS
; =======================================================================
play:
mov [melody + 1], ah
mcall SF_SPEAKER_PLAY, SF_SPEAKER_PLAY, , , , melody
mcall SF_SPEAKER_PLAY, SF_SPEAKER_PLAY, , , melody
jmp still
; =======================================================================
redraw:
mcall SF_REDRAW, SSF_BEGIN_DRAW
mcall SF_STYLE_SETTINGS, SSF_GET_COLORS, sc, sizeof.system_colors
mcall , SSF_GET_SKIN_HEIGHT,
@@ -140,34 +151,35 @@ redraw:
mov ecx, eax
add ecx, WN_MAIN.Y shl 16 + WN_MAIN.H
mov edx, [sc.work]
or edx, 0x34000000
or edx, 0x34000000 ; skin, no resize, caption, client area
mcall SF_CREATE_WINDOW, <WN_MAIN.X, WN_MAIN.W>, , , , cp_main
; white buttons rows
mov eax, SF_DEFINE_BUTTON ; constant syscall number
mov ebx, BT_WHITE.X shl 16 + BT_WHITE.W ; packed <x, width>, x starts at 0
mov ecx, BT_WHITE.Y shl 16 + BT_WHITE.H ; packed <y, height>, constant
mov edi, white_top_buttons
mov ebp, white_bottom_buttons
mov edi, white_button_colors
mov ebp, white_button_ids
.white_buttons_loop:
cmp edi, white_top_buttons_end
cmp edi, end_white_button_colors
jae .black_buttons_setup
mov edx, [edi]
mov esi, [edi + 4]
movzx edx, byte[ebp]
mov esi, [edi]
mcall
mov ecx, (BT_WHITE.Y + BT_WHITE.H) shl 16 + BT_WHITE.H
mov edx, [ebp]
mov esi, [ebp + 4]
movzx edx, byte[ebp + 1]
mov esi, [edi + 4]
mcall
mov ecx, BT_WHITE.Y shl 16 + BT_WHITE.H
add ebx, BT_WHITE.W shl 16
add edi, DT_SIZE
add ebp, DT_SIZE
add edi, WT_SIZE
add ebp, 2
jmp .white_buttons_loop
; black buttons rows
@@ -177,7 +189,6 @@ redraw:
mov edi, black_buttons
.black_buttons_loop:
cmp edi, black_buttons_end
jae .black_buttons_loop_end
@@ -206,76 +217,83 @@ redraw:
mcall SF_DRAW_TEXT, <RT_NOTES.X, RT_NOTES.Y>, 0x90FFFFFF, lb_notes
mcall SF_REDRAW, SSF_END_DRAW
jmp still
; =======================================================================
help_thread:
mcall SF_SET_EVENTS_MASK, EVM_REDRAW + EVM_BUTTON
jmp .redraw
jmp .help_redraw
.help_still:
.still:
mcall SF_WAIT_EVENT
cmp al, 1
je .help_redraw
cmp al, 3
je .help_button
cmp al, EV_REDRAW
je .redraw
cmp al, EV_BUTTON
je .button
jmp .help_still
.help_button:
jmp .still
.button:
mcall SF_GET_BUTTON
cmp ah, 1
jne .help_still
jne .still
mov dword [hp_tid], 0
mov dword [hw_tid], 0
mcall SF_TERMINATE_PROCESS
.help_redraw:
.redraw:
mcall SF_REDRAW, SSF_BEGIN_DRAW
mcall SF_STYLE_SETTINGS, SSF_GET_COLORS, sc, sizeof.system_colors
mcall , SSF_GET_SKIN_HEIGHT,
mov ecx, eax
add ecx, WN_HELP.Y shl 16 + WN_HELP.H
mov ebp, eax
mov ebx, [mw_pos]
mov ecx, ebx
shr ebx, 16
and ecx, 0xFFFF
add ebx, WN_HELP.X
shl ebx, 16
mov bx, WN_HELP.W
add ecx, WN_HELP.Y
add ecx, ebp
shl ecx, 16
mov cx, WN_HELP.H
mov edx, [sc.work]
or edx, 0x34000000
mcall SF_CREATE_WINDOW, <WN_HELP.X, WN_HELP.W>, , , , cp_help
or edx, 0x34000000 ; skin, no resize, caption, client area
mcall SF_CREATE_WINDOW, , , , , cp_help
mov eax, SF_DRAW_TEXT
mov ecx, [sc.work_text]
or ecx, 0x90000000
or ecx, 0x90000000 ; null terminator, 8x16 OLE
mov ebx, RT_HELP.X shl 16 + RT_HELP.Y
mov edi, help_texts
; draw all help text in rows
.help_text_loop:
cmp edi, help_texts_end
jae .help_text_loop_done
mov edx, [edi]
mcall
mcall ; draw text
add ebx, RT_HELP.H
add edi, 4
jmp .help_text_loop
.help_text_loop_done:
mcall SF_REDRAW, SSF_END_DRAW
jmp help_thread.help_still
jmp .still
; =======================================================================
sc system_colors
WN_MAIN RECT 32, 32, BT_WHITE.W * 15 + 10, BT_WHITE.H * 2 + 9
WN_MAIN RECT 32, 32, BT_WHITE.W * 15 + 10, BT_WHITE.H * 2 + (5 + 4)
BT_WHITE RECT 0, 4, 48, 100
BT_BLACK RECT 33, 0, 30, 50
@@ -298,20 +316,20 @@ if lang eq ru_RU
lb_help4 cp866 "Должен звучать встроенный динамик ПК (не колонки).", 0
lb_notes cp866 "ДО РЕ МИ ФА СОЛЬ ЛЯ СИ ДО", 0
WN_HELP RECT 64, 64, 521, 106
WN_HELP RECT 14, 13, 521, 106
RT_NOTES RECT 16, 183, 0, 0
else if lang eq es_ES
cp_main db "Piano de Juguete [Escape - Abrir Ayuda]", 0
cp_help db "Piano de Juguete - Ayuda", 0
lb_help1 db "Teclas de 1 a = y de Q a ] - fila superior.", 0
lb_help2 db "Teclas de A a Enter y de Z a /, \ y Backspace - fila inferior.", 0
lb_help3 db "Mantenga Shift para subir 4 octavas.", 0
lb_help4 db "Deberias oir el altavoz interno del PC (no los externos).", 0
lb_notes db "DO RE MI FA SOL LA SI DO", 0
cp_main cp850 "Piano de Juguete [Escape - Abrir Ayuda]", 0
cp_help cp850 "Piano de Juguete - Ayuda", 0
lb_help1 cp850 "Teclas de 1 a = y de Q a ] - fila superior.", 0
lb_help2 cp850 "Teclas de A a Enter y de Z a /, \ y Backspace - fila inferior.", 0
lb_help3 cp850 "Mantenga Shift para subir 4 octavas.", 0
lb_help4 cp850 "Deberias oir el altavoz interno del PC (no los externos).", 0
lb_notes cp850 "DO RE MI FA SOL LA SI DO", 0
WN_HELP RECT 64, 64, 521, 106
WN_HELP RECT 14, 13, 521, 106
RT_NOTES RECT 16, 183, 0, 0
else
@@ -324,55 +342,59 @@ else
lb_help4 db "You should hear the built-in PC speaker (not external speakers).", 0
lb_notes db "C D E F G A B C", 0
WN_HELP RECT 64, 64, 561, 106
WN_HELP RECT 14, 13, 561, 106
RT_NOTES RECT 20, 183, 0, 0
end if
; =======================================================================
DT_SIZE = 8 ; white buttons entry size
BL_SIZE = 2 ; black buttons entry size
WT_SIZE = 8 ; white buttons entry size
BL_SIZE = 2 ; black buttons entry size
; button id and color
white_top_buttons:
dd 0x31, 0xFF7A74
dd 0x33, 0x907040
dd 0x35, 0xA08050
dd 0x36, 0xB09060
dd 0x38, 0xC0A070
dd 0x3A, 0xD0B080
dd 0x3C, 0xE0C090
dd 0x41, 0xFFA97C
dd 0x43, 0xAF8D8D
dd 0x45, 0xBF9D9D
dd 0x46, 0xCFADAD
dd 0x48, 0xDFBDBD
dd 0x4A, 0xEFCDCD
dd 0x4C, 0xFFDDDD
dd 0x51, 0xFFE558
white_top_buttons_end:
; white button colors
white_button_colors: ; 1 top, 1 bottom, 2 top, 2 bottom, N top, N bottom
dd 0xFF7A74, 0x702050
dd 0x907040, 0x683638
dd 0xA08050, 0x784648
dd 0xB09060, 0x885658
dd 0xC0A070, 0x986668
dd 0xD0B080, 0xA87678
dd 0xE0C090, 0xB88688
; button id and color
white_bottom_buttons:
dd 0x11, 0x702050
dd 0x13, 0x683638
dd 0x15, 0x784648
dd 0x16, 0x885658
dd 0x18, 0x986668
dd 0x1A, 0xA87678
dd 0x1C, 0xB88688
dd 0x21, 0x880040
dd 0x23, 0x90622B
dd 0x25, 0xA0723B
dd 0x26, 0xB0824B
dd 0x28, 0xC0925B
dd 0x2A, 0xD0A26B
dd 0x2C, 0xE0B27B
dd 0x31, 0xFF7A74
white_bottom_buttons_end:
dd 0xFFA97C, 0x880040
dd 0xAF8D8D, 0x90622B
dd 0xBF9D9D, 0xA0723B
dd 0xCFADAD, 0xB0824B
dd 0xDFBDBD, 0xC0925B
dd 0xEFCDCD, 0xD0A26B
dd 0xFFDDDD, 0xE0B27B
; parent white button id and button id
dd 0xFFE558, 0xFF7A74
end_white_button_colors:
; white button ids
white_button_ids: ; 1 top, 1 bottom, 2 top, 2 bottom, N top, N bottom
db 0x31, 0x11
db 0x33, 0x13
db 0x35, 0x15
db 0x36, 0x16
db 0x38, 0x18
db 0x3A, 0x1A
db 0x3C, 0x1C
db 0x41, 0x21
db 0x43, 0x23
db 0x45, 0x25
db 0x46, 0x26
db 0x48, 0x28
db 0x4A, 0x2A
db 0x4C, 0x2C
db 0x51, 0x31 ; ?
end_white_button_ids:
; parent white button index in row and black button ids
black_buttons:
db 0x00, 0x12
db 0x01, 0x14
@@ -386,7 +408,7 @@ black_buttons:
db 0x0C, 0x2B
black_buttons_end:
; corrensponding help string label
; help string labels
help_texts:
dd lb_help1
dd lb_help2
@@ -396,67 +418,74 @@ help_texts_end:
; =======================================================================
KM_SIZE = 2 ; key map entry size
BAD_NOTE = 0xFF
; key scancode and note id
key_note_map:
db 0x02, 0x31 ; '1' -> note 0x31
db 0x03, 0x32 ; '2' -> note 0x32
db 0x04, 0x33 ; '3' -> note 0x33
db 0x05, 0x34 ; '4' -> note 0x34
db 0x06, 0x35 ; '5' -> note 0x35
db 0x07, 0x36 ; '6' -> note 0x36
db 0x08, 0x37 ; '7' -> note 0x37
db 0x09, 0x38 ; '8' -> note 0x38
db 0x0A, 0x39 ; '9' -> note 0x39
db 0x0B, 0x3A ; '0' -> note 0x3A
db 0x0C, 0x3B ; '-' -> note 0x3B
db 0x0D, 0x3C ; '=' -> note 0x3C
db BAD_NOTE ;db 0x00, 0xFF
db BAD_NOTE ;db 0x01, 0xFF
db 0x21 ;db 0x02, 0x31 ; '1' -> note 0x31
db 0x22 ;db 0x03, 0x32 ; '2' -> note 0x32
db 0x23 ;db 0x04, 0x33 ; '3' -> note 0x33
db 0x24 ;db 0x05, 0x34 ; '4' -> note 0x34
db 0x25 ;db 0x06, 0x35 ; '5' -> note 0x35
db 0x26 ;db 0x07, 0x36 ; '6' -> note 0x36
db 0x27 ;db 0x08, 0x37 ; '7' -> note 0x37
db 0x28 ;db 0x09, 0x38 ; '8' -> note 0x38
db 0x29 ;db 0x0A, 0x39 ; '9' -> note 0x39
db 0x2A ;db 0x0B, 0x3A ; '0' -> note 0x3A
db 0x2B ;db 0x0C, 0x3B ; '-' -> note 0x3B
db 0x2C ;db 0x0D, 0x3C ; '=' -> note 0x3C
db 0x1C ;db 0x0E, 0x2C ; Backspace -> note 0x2C
db BAD_NOTE ;db 0x0F, 0xFF
db 0x10, 0x41 ; 'q' -> note 0x41
db 0x11, 0x42 ; 'w' -> note 0x42
db 0x12, 0x43 ; 'e' -> note 0x43
db 0x13, 0x44 ; 'r' -> note 0x44
db 0x14, 0x45 ; 't' -> note 0x45
db 0x15, 0x46 ; 'y' -> note 0x46
db 0x16, 0x47 ; 'u' -> note 0x47
db 0x17, 0x48 ; 'i' -> note 0x48
db 0x18, 0x49 ; 'o' -> note 0x49
db 0x19, 0x4A ; 'p' -> note 0x4A
db 0x1A, 0x4B ; '[' -> note 0x4B
db 0x1B, 0x4C ; ']' -> note 0x4C
db 0x31 ;db 0x10, 0x41 ; 'q' -> note 0x41
db 0x32 ;db 0x11, 0x42 ; 'w' -> note 0x42
db 0x33 ;db 0x12, 0x43 ; 'e' -> note 0x43
db 0x34 ;db 0x13, 0x44 ; 'r' -> note 0x44
db 0x35 ;db 0x14, 0x45 ; 't' -> note 0x45
db 0x36 ;db 0x15, 0x46 ; 'y' -> note 0x46
db 0x37 ;db 0x16, 0x47 ; 'u' -> note 0x47
db 0x38 ;db 0x17, 0x48 ; 'i' -> note 0x48
db 0x39 ;db 0x18, 0x49 ; 'o' -> note 0x49
db 0x3A ;db 0x19, 0x4A ; 'p' -> note 0x4A
db 0x3B ;db 0x1A, 0x4B ; '[' -> note 0x4B
db 0x3C ;db 0x1B, 0x4C ; ']' -> note 0x4C
db 0x0C ;db 0x1C, 0x1C ; Enter -> note 0x1C
db BAD_NOTE ;db 0x1D, 0xFF
db 0x1E, 0x11 ; 'a' -> note 0x11
db 0x1F, 0x12 ; 's' -> note 0x12
db 0x20, 0x13 ; 'd' -> note 0x13
db 0x21, 0x14 ; 'f' -> note 0x14
db 0x22, 0x15 ; 'g' -> note 0x15
db 0x23, 0x16 ; 'h' -> note 0x16
db 0x24, 0x17 ; 'j' -> note 0x17
db 0x25, 0x18 ; 'k' -> note 0x18
db 0x26, 0x19 ; 'l' -> note 0x19
db 0x27, 0x1A ; ';' -> note 0x1A
db 0x28, 0x1B ; ''' -> note 0x1B
db 0x1C, 0x1C ; Enter -> note 0x1C
db 0x01 ;db 0x1E, 0x11 ; 'a' -> note 0x11
db 0x02 ;db 0x1F, 0x12 ; 's' -> note 0x12
db 0x03 ;db 0x20, 0x13 ; 'd' -> note 0x13
db 0x04 ;db 0x21, 0x14 ; 'f' -> note 0x14
db 0x05 ;db 0x22, 0x15 ; 'g' -> note 0x15
db 0x06 ;db 0x23, 0x16 ; 'h' -> note 0x16
db 0x07 ;db 0x24, 0x17 ; 'j' -> note 0x17
db 0x08 ;db 0x25, 0x18 ; 'k' -> note 0x18
db 0x09 ;db 0x26, 0x19 ; 'l' -> note 0x19
db 0x0A ;db 0x27, 0x1A ; ';' -> note 0x1A
db 0x0B ;db 0x28, 0x1B ; ''' -> note 0x1B
db BAD_NOTE ;db 0x29, 0xFF
db BAD_NOTE ;db 0x2A, 0xFF
db 0x2C, 0x21 ; 'z' -> note 0x21
db 0x2D, 0x22 ; 'x' -> note 0x22
db 0x2E, 0x23 ; 'c' -> note 0x23
db 0x2F, 0x24 ; 'v' -> note 0x24
db 0x30, 0x25 ; 'b' -> note 0x25
db 0x31, 0x26 ; 'n' -> note 0x26
db 0x32, 0x27 ; 'm' -> note 0x27
db 0x33, 0x28 ; ',' -> note 0x28
db 0x34, 0x29 ; '.' -> note 0x29
db 0x35, 0x2A ; '/' -> note 0x2A
db 0x2B, 0x2B ; '\' -> note 0x2B
db 0x0E, 0x2C ; Backspace -> note 0x2C
key_note_map_end:
db 0x1B ;db 0x2B, 0x2B ; '\' -> note 0x2B
db 0x11 ;db 0x2C, 0x21 ; 'z' -> note 0x21
db 0x12 ;db 0x2D, 0x22 ; 'x' -> note 0x22
db 0x13 ;db 0x2E, 0x23 ; 'c' -> note 0x23
db 0x14 ;db 0x2F, 0x24 ; 'v' -> note 0x24
db 0x15 ;db 0x30, 0x25 ; 'b' -> note 0x25
db 0x16 ;db 0x31, 0x26 ; 'n' -> note 0x26
db 0x17 ;db 0x32, 0x27 ; 'm' -> note 0x27
db 0x18 ;db 0x33, 0x28 ; ',' -> note 0x28
db 0x19 ;db 0x34, 0x29 ; '.' -> note 0x29
db 0x1A ;db 0x35, 0x2A ; '/' -> note 0x2A
.count = $ - key_note_map
; =======================================================================
melody db 0x90, 0x30, 0
hp_tid dd 0
mw_pos dd 0
hw_tid dd 0
; =======================================================================