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;
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 }
void beeperSilent()
[Beeper] Выключить звук
Definition: beeper.c:42
void beeperPlay(uint32_t frequency)
Вопроизвести звук (квадратной формы волны)
Definition: beeper.c:21
Основные определения ядра
char * getCharKeyboard(int key, bool mode)
Выводит символ, в зависимости от кода полученного с клавиатуры
Definition: keyboard.c:67
size_t strlen(const char *str)
Возращает длину строки
Definition: string.c:88
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
Definition: string.c:203