summaryrefslogtreecommitdiff
path: root/fbgl.h
diff options
context:
space:
mode:
Diffstat (limited to 'fbgl.h')
-rw-r--r--fbgl.h163
1 files changed, 156 insertions, 7 deletions
diff --git a/fbgl.h b/fbgl.h
index 8b42682..5bd95c7 100644
--- a/fbgl.h
+++ b/fbgl.h
@@ -27,7 +27,6 @@
#define VERSION "0.1.0"
#define NAME "FBGL"
#define DEFAULT_FB "/dev/fb0"
-#define FBGL_MAX_KEYS 256 // Maximum number of keys to track
#include <fcntl.h>
#include <linux/fb.h>
@@ -45,11 +44,6 @@
#include <time.h>
#include <unistd.h>
-#ifdef FBGL_USE_FREETYPE
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#endif // FBGL_USE_FREETYPE
-
/**
* Structs
*/
@@ -91,11 +85,31 @@ typedef struct fbgl_psf1_font {
uint16_t char_width; // Character width in pixels (always 8 for PSF1)
} fbgl_psf1_font_t;
+typedef enum fbgl_key {
+ FBGL_KEY_NONE = 0,
+ FBGL_KEY_UP,
+ FBGL_KEY_DOWN,
+ FBGL_KEY_LEFT,
+ FBGL_KEY_RIGHT,
+ FBGL_KEY_ESCAPE,
+ FBGL_KEY_ENTER,
+ FBGL_KEY_SPACE,
+
+} fbgl_key_t;
+
+typedef struct fbgl_keyboard_state {
+ bool is_key_down;
+ fbgl_key_t current_key;
+ bool special_key_pressed;
+} fbgl_keyboard_state_t;
+
/**
* Key state function and variables
*
*/
static struct timespec previous_frame_time = { 0 };
+static struct termios orig_termios;
+static fbgl_keyboard_state_t g_keyboard_state = { 0 };
#ifdef __cplusplus
extern "C" {
@@ -158,7 +172,10 @@ void fbgl_render_psf1_text(fbgl_t *fb, fbgl_psf1_font_t *font, const char *text,
/**
* Keyboard
*/
-// Will refactor
+int fbgl_keyboard_init(void);
+void fbgl_destroy_keyboard(void);
+fbgl_key_t fbgl_get_key(void);
+bool fbgl_is_key_pressed(fbgl_key_t key);
/**
* Color Utilities
@@ -172,6 +189,42 @@ void fbgl_render_psf1_text(fbgl_t *fb, fbgl_psf1_font_t *font, const char *text,
(uint8_t)(b * 255)))
#define FBGL_F32RGBA_TO_U32(r, g, b, a) ((uint32_t)(((uint8_t)(a * 255) << 24) | ((uint8_t)(r * 255) << 16) | ((uint8_t)(g * 255) << 8) | (uint8_t)(b * 255))
+// Inside functions
+static void i_fbgl_die(const char *s);
+static void i_fbgl_disable_raw_mode();
+static void i_fbgl_enable_raw_mode();
+
+static void i_fbgl_die(const char *s)
+{
+ perror(s);
+ exit(1);
+}
+
+static void i_fbgl_enable_raw_mode()
+{
+ if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) {
+ i_fbgl_die("tcgetattr");
+ }
+ atexit(i_fbgl_disable_raw_mode);
+ struct termios raw = orig_termios;
+ raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+ raw.c_oflag &= ~(OPOST);
+ raw.c_cflag |= (CS8);
+ raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+ raw.c_cc[VMIN] = 0;
+ raw.c_cc[VTIME] = 1;
+ if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) {
+ i_fbgl_die("tcsetattr");
+ }
+}
+
+static void i_fbgl_disable_raw_mode()
+{
+ if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1) {
+ i_fbgl_die("tcesetattr");
+ }
+}
+
#ifdef FBGL_IMPLEMENTATION
char const *fbgl_name_info(void)
@@ -693,6 +746,102 @@ void fbgl_render_psf1_text(fbgl_t *fb, fbgl_psf1_font_t *font, const char *text,
}
}
+int fbgl_keyboard_init(void)
+{
+ i_fbgl_enable_raw_mode();
+
+ // Initialize keyboard state
+ g_keyboard_state.is_key_down = false;
+ g_keyboard_state.current_key = FBGL_KEY_NONE;
+ g_keyboard_state.special_key_pressed = false;
+
+ return 0;
+}
+
+void fbgl_destroy_keyboard(void)
+{
+ i_fbgl_disable_raw_mode();
+}
+fbgl_key_t fbgl_get_key(void)
+{
+ char c;
+ ssize_t bytes_read = read(STDIN_FILENO, &c, 1);
+
+ if (bytes_read <= 0) {
+ return FBGL_KEY_NONE;
+ }
+
+ // Handle escape sequences for special keys
+ if (c == 27) {
+ char seq[3];
+ if (read(STDIN_FILENO, &seq[0], 1) != 1)
+ return FBGL_KEY_ESCAPE;
+ if (read(STDIN_FILENO, &seq[1], 1) != 1)
+ return FBGL_KEY_ESCAPE;
+
+ if (seq[0] == '[') {
+ switch (seq[1]) {
+ case 'A':
+ return FBGL_KEY_UP;
+ case 'B':
+ return FBGL_KEY_DOWN;
+ case 'C':
+ return FBGL_KEY_RIGHT;
+ case 'D':
+ return FBGL_KEY_LEFT;
+ }
+ }
+
+ return FBGL_KEY_NONE;
+ }
+
+ // Handle direct key presses
+ switch (c) {
+ case 10: // Enter key
+ return FBGL_KEY_ENTER;
+ case 32: // Space key
+ return FBGL_KEY_SPACE;
+ case 'w':
+ case 'W':
+ return FBGL_KEY_UP;
+ case 's':
+ case 'S':
+ return FBGL_KEY_DOWN;
+ case 'a':
+ case 'A':
+ return FBGL_KEY_LEFT;
+ case 'd':
+ case 'D':
+ return FBGL_KEY_RIGHT;
+ case 27: // Escape key
+ return FBGL_KEY_ESCAPE;
+ }
+
+ return FBGL_KEY_NONE;
+}
+
+bool fbgl_is_key_pressed(fbgl_key_t key)
+{
+ // Use select() for non-blocking input check
+ fd_set read_fds;
+ struct timeval timeout;
+
+ FD_ZERO(&read_fds);
+ FD_SET(STDIN_FILENO, &read_fds);
+
+ // Set a very short timeout
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+
+ // Check if there's input available
+ if (select(STDIN_FILENO + 1, &read_fds, NULL, NULL, &timeout) > 0) {
+ fbgl_key_t pressed_key = fbgl_get_key();
+ return pressed_key == key;
+ }
+
+ return false;
+}
+
#endif // FBGL_IMPLEMENTATION
#ifdef __cplusplus