Skip to content

Instantly share code, notes, and snippets.

@iglosiggio
Created October 15, 2022 18:10
Show Gist options
  • Save iglosiggio/2ce3a0a70c53a344eb9916387d0f7e67 to your computer and use it in GitHub Desktop.
Save iglosiggio/2ce3a0a70c53a344eb9916387d0f7e67 to your computer and use it in GitHub Desktop.
#include "keyboard_input.h"
#include "screen.h"
static void unrecognized_scancode(uint8_t scancode);
#define TOGGLE_SHIFT_IDX 1
static void toggle_shift(uint8_t);
#define MOVE_DOWN_IDX 2
static void move_down(uint8_t);
#define MOVE_UP_IDX 3
static void move_up(uint8_t);
#define MOVE_LEFT_IDX 4
static void move_left(uint8_t);
#define MOVE_RIGHT_IDX 5
static void move_right(uint8_t);
#define NEW_LINE_IDX 6
static void new_line(uint8_t);
// Este es un array de punteros a funciones
typedef void (*scancode_handler) (uint8_t scancode);
static const scancode_handler special_scancodes[] = {
unrecognized_scancode,
toggle_shift,
move_down,
move_up,
move_left,
move_right,
new_line
};
struct scancode_info {
// Si es distinto de '\0' su valor es la letra a imprimir de no estar
// shift activado.
uint8_t main_value;
// Si `main_value` es distinto de '\0' su valor es la letra a imprimir
// de estar shift activado.
//
// Sino su valor es un índice en la tabla `special_scancodes` que
// determina el código a ejecutar para esta tecla.
uint8_t special_value;
};
// Lista sacada de https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
static const struct scancode_info scancode_defs[256] = {
[0x01] = { '\0', '\0' }, // Esc
[0x02] = { '1', '!' },
[0x03] = { '2', '@' },
[0x04] = { '3', '#' },
[0x05] = { '4', '$' },
[0x06] = { '5', '%' },
[0x07] = { '6', '^' },
[0x08] = { '7', '&' },
[0x09] = { '8', '*' },
[0x0a] = { '9', '(' },
[0x0b] = { '0', ')' },
[0x0c] = { '-', '_' },
[0x0d] = { '=', '+' },
[0x0e] = { '\0', MOVE_LEFT_IDX }, // Backspace
[0x0f] = { '\0', '\0' }, // Tab
[0x10] = { 'q', 'Q' },
[0x11] = { 'w', 'W' },
[0x12] = { 'e', 'E' },
[0x13] = { 'r', 'R' },
[0x14] = { 't', 'T' },
[0x15] = { 'y', 'Y' },
[0x16] = { 'u', 'U' },
[0x17] = { 'i', 'I' },
[0x18] = { 'o', 'O' },
[0x19] = { 'p', 'P' },
[0x1a] = { '[', '{' },
[0x1b] = { ']', '}' },
[0x1c] = { '\0', NEW_LINE_IDX }, // Enter
[0x1d] = { '\0', '\0' }, // LCtrl
[0x1e] = { 'a', 'A' },
[0x1f] = { 's', 'S' },
[0x20] = { 'd', 'D' },
[0x21] = { 'f', 'F' },
[0x22] = { 'g', 'G' },
[0x23] = { 'h', 'H' },
[0x24] = { 'j', 'J' },
[0x25] = { 'k', 'K' },
[0x26] = { 'l', 'L' },
[0x27] = { ';', ':' },
[0x28] = { '\'', '"' },
[0x29] = { '`', '~' },
[0x2a] = { '\0', TOGGLE_SHIFT_IDX }, // LShift
[0x80 | 0x2a] = { '\0', TOGGLE_SHIFT_IDX }, // LShift (UP)
[0x2b] = { '\\', '|' }, // on a 102-key keyboard
[0x2c] = { 'z', 'Z' },
[0x2d] = { 'x', 'X' },
[0x2e] = { 'c', 'C' },
[0x2f] = { 'v', 'V' },
[0x30] = { 'b', 'B' },
[0x31] = { 'n', 'N' },
[0x32] = { 'm', 'M' },
[0x33] = { ',', '<' },
[0x34] = { '.', '>' },
[0x35] = { '/', '?' },
[0x36] = { '\0', '\0' }, // RShift
[0x37] = { '\0', '\0' }, // Keypad-* or */PrtScn on a 83/84-key keyboard
[0x38] = { '\0', '\0' }, // LAlt
[0x39] = { ' ', ' ' }, // Space bar
[0x3a] = { '\0', TOGGLE_SHIFT_IDX }, // CapsLock
// IDEA: ¿Como usarian los Fx para poder cambiar de color?
[0x3b] = { '\0', '\0' }, // F1
[0x3c] = { '\0', '\0' }, // F2
[0x3d] = { '\0', '\0' }, // F3
[0x3e] = { '\0', '\0' }, // F4
[0x3f] = { '\0', '\0' }, // F5
[0x40] = { '\0', '\0' }, // F6
[0x41] = { '\0', '\0' }, // F7
[0x42] = { '\0', '\0' }, // F8
[0x43] = { '\0', '\0' }, // F9
[0x44] = { '\0', '\0' }, // F10
[0x45] = { '\0', '\0' }, // NumLock
[0x46] = { '\0', '\0' }, // ScrollLock
[0x47] = { '\0', '\0' }, // Keypad-7/Home
[0x48] = { '\0', MOVE_UP_IDX }, // Keypad-8/Up
[0x49] = { '\0', '\0' }, // Keypad-9/PgUp
[0x4a] = { '\0', '\0' }, // Keypad--
[0x4b] = { '\0', MOVE_LEFT_IDX }, // Keypad-4/Left
[0x4c] = { '\0', '\0' }, // Keypad-5
[0x4d] = { '\0', MOVE_RIGHT_IDX }, // Keypad-6/Right
[0x4e] = { '\0', '\0' }, // Keypad-+
[0x4f] = { '\0', '\0' }, // Keypad-1/End
[0x50] = { '\0', MOVE_DOWN_IDX }, // Keypad-2/Down
[0x51] = { '\0', '\0' }, // Keypad-3/PgDn
[0x52] = { '\0', '\0' }, // Keypad-0/Ins
[0x53] = { '\0', '\0' }, // Keypad-./Del
[0x54] = { '\0', '\0' }, // Alt-SysRq on a 84+ key keyboard
[0x57] = { '\0', '\0' }, // F11 on a 101+ key keyboard
[0x58] = { '\0', '\0' } // F12 on a 101+ key keyboard
};
static int curr_row = 0;
static int curr_column = 0;
static int is_shift_pressed = 0;
static uint8_t curr_attr = C_FG_BLACK | C_BG_RED;
static ca under_marker = { .c = ' ', C_FG_BLACK | C_BG_BLUE };
static void fix_rowcol() {
int old_column = curr_column;
curr_column = ((curr_column % VIDEO_COLS) + VIDEO_COLS) % VIDEO_COLS;
curr_row += (old_column - curr_column) / VIDEO_COLS;
curr_row = ((curr_row % VIDEO_FILS) + VIDEO_FILS) % VIDEO_FILS;
}
static void put(char to_print) {
ca(*screen)[VIDEO_COLS] = (ca(*)[VIDEO_COLS])VIDEO;
screen[curr_row][curr_column].c = to_print;
screen[curr_row][curr_column].a = curr_attr;
}
static void put_marker() {
ca(*screen)[VIDEO_COLS] = (ca(*)[VIDEO_COLS])VIDEO;
under_marker = screen[curr_row][curr_column];
screen[curr_row][curr_column].c = 0xDB;
screen[curr_row][curr_column].a = curr_attr | C_BLINK;
}
static void restore_marker() {
ca(*screen)[VIDEO_COLS] = (ca(*)[VIDEO_COLS])VIDEO;
screen[curr_row][curr_column] = under_marker;
}
static void unrecognized_scancode(uint8_t scancode) {
if(!(scancode & 0x80))
print_hex(scancode,2,80/2-1,50/2,C_FG_CYAN | C_FG_BLUE);
}
// GCC se queja de que no usamos el scancode si no le aseguramos que esa es
// nuestra intención.
#define unused __attribute__((unused))
static void toggle_shift(unused uint8_t scancode) {
is_shift_pressed = !is_shift_pressed;
}
static void move_down(unused uint8_t scancode) {
restore_marker();
curr_row++;
fix_rowcol();
put_marker();
}
static void move_up(unused uint8_t scancode) {
restore_marker();
curr_row--;
fix_rowcol();
put_marker();
}
static void move_left(unused uint8_t scancode) {
restore_marker();
curr_column--;
fix_rowcol();
put_marker();
}
static void move_right(unused uint8_t scancode) {
restore_marker();
curr_column++;
fix_rowcol();
put_marker();
}
static void new_line(unused uint8_t scancode) {
restore_marker();
curr_column = 0;
curr_row++;
fix_rowcol();
put_marker();
}
void process_scancode(uint8_t scancode) {
struct scancode_info info = scancode_defs[scancode];
if (info.main_value == '\0') {
special_scancodes[info.special_value](scancode);
return;
}
put(is_shift_pressed ? info.special_value : info.main_value);
curr_column++;
fix_rowcol();
put_marker();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment