SayoriOS 0.3.3

piano.c
1 #include <common.h>
2 #include <drv/beeper.h>
3 #include <io/screen.h>
4 #include <gui/basics.h>
5 #include <drv/psf.h>
6 #include <lib/string.h>
7 #include <drv/input/keyboard.h>
8 #include <io/tty.h>
9
10 #define PADDING 32
11 #define KEY_SIZE 32
12
13 char keys_black[] = "we tyu o";
14 char keys_white[] = "asdfghjk";
15
16 typedef struct {
17 char key;
18 uint16_t note;
19 } KeyboardNote_t;
20
21 char keystates[2][8] = {
22 {0, 0, 0, 0, 0, 0, 0, 0},
23 {0, 0, 0, 0, 0, 0, 0, 0}
24 };
25
26 KeyboardNote_t keyboard_notes[14] = {
27 {'w', Cd4},
28 {'e', Dd4},
29 {'t', Fd4},
30 {'y', Gd4},
31 {'u', Ad4},
32 {'o', Cd5},
33
34 {'a', C4},
35 {'s', D4},
36 {'d', E4},
37 {'f', F4},
38 {'g', G4},
39 {'h', A4},
40 {'j', B4},
41 {'k', C5}
42 };
43
44 void draw_key(size_t x, size_t y, char* letter, bool pressed) {
45 draw_filled_rectangle(x, y, KEY_SIZE, KEY_SIZE, pressed?0xaaaaaa:0x303030);
46 draw_vga_str(letter, 1, x+16, y+16, pressed?0x303030:0xaaaaaa);
47 }
48
49 void play_key(char key) {
50 for(char i = 0; i < 14; i++) {
51 if(keyboard_notes[i].key == key) {
52 beeperPlay(keyboard_notes[i].note);
53 break;
54 }
55 }
56 }
57
58 void draw_piano() {
59 size_t dispw = getScreenWidth();
60 size_t disph = getScreenHeight();
61
62 size_t starth = (disph - (KEY_SIZE*2)+PADDING)/2;
63 size_t startbw = (dispw - (KEY_SIZE+PADDING)*(strlen(keys_black)+1))/2;
64 // size_t startww = (dispw - (KEY_SIZE+PADDING)*(strlen(keys_white)+1))/2;
65
66 for(size_t bi = 0; bi < strlen(keys_black); bi++) {
67 if(keys_black[bi] == ' ') continue;
68 draw_key(PADDING + startbw + (bi*(KEY_SIZE+PADDING)),
69 starth,
70 (char[]){keys_black[bi], 0},
71 keystates[0][bi]
72 );
73 }
74
75 for(size_t wi = 0; wi < strlen(keys_white); wi++) {
76 draw_key(startbw + (wi*(KEY_SIZE+PADDING)),
77 starth+(KEY_SIZE + PADDING),
78 (char[]){keys_white[wi], 0},
79 keystates[1][wi]
80 );
81 }
82 }
83
84 void handle_key_piano(int key) {
85 if(key == 0) return;
86 char* printable_key = getCharKeyboard(key, false);
87 uint8_t pressed = !getPressReleaseKeyboard();
88
89 // qemu_log("Key pressed: %d (%d)", pressed, key);
90
91 if(!pressed) {
92 memset(&keystates, 0, 8*2);
93 // qemu_log("Key down: %d", key);
94 beeperSilent();
95 }
96
97 for(size_t i = 0; i < strlen(keys_black); i++) {
98 if(printable_key[0] == keys_black[i]) {
99 if(pressed) {
100 // qemu_log("Key up: %d", key);
101 keystates[0][i] = 1;
102 play_key(printable_key[0]);
103 }
104 break;
105 }
106 }
107
108 for(size_t i = 0; i < strlen(keys_white); i++) {
109 if(printable_key[0] == keys_white[i]) {
110 if(pressed) {
111 // qemu_log("Key up: %d", key);
112 keystates[1][i] = 1;
113 play_key(printable_key[0]);
114 }
115 break;
116 }
117 }
118 }
119
120 void piano() {
121 clean_screen();
122
123 set_cursor_enabled(false);
124 keyboardctl(KEYBOARD_ECHO, false);
125
126 while(1) {
127 int key = getCharRaw();
128 if(key == 129 || key == 1) break;
129
130 handle_key_piano(key);
131
132 draw_piano();
133 draw_vga_str("NDRAEY >_ [Press Esc to exit]", 36, 8, getScreenHeight() - 16, 0xaaaaaa);
134 punch();
135 }
136
137 clean_screen();
138 set_cursor_enabled(true);
139 keyboardctl(KEYBOARD_ECHO, true);
140 }
beeperSilent
void beeperSilent()
[Beeper] Выключить звук
Definition: beeper.c:42
beeperPlay
void beeperPlay(uint32_t frequency)
Вопроизвести звук (квадратной формы волны)
Definition: beeper.c:21
common.h
Основные определения ядра
getCharKeyboard
char * getCharKeyboard(int key, bool mode)
Выводит символ, в зависимости от кода полученного с клавиатуры
Definition: keyboard.c:67
strlen
size_t strlen(const char *str)
Возращает длину строки
Definition: string.c:88
memset
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
Definition: string.c:203
KeyboardNote_t
Definition: piano.c:16