diff options
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | examples/keyboard.c | 91 | ||||
| -rw-r--r-- | fbgl.h | 91 |
3 files changed, 182 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index e47cc2c..69efb9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,3 +31,4 @@ add_example(raw_mode) add_example(framebuf_info) add_example(text) add_example(texture_show_fps) +add_example(keyboard) diff --git a/examples/keyboard.c b/examples/keyboard.c new file mode 100644 index 0000000..51a488e --- /dev/null +++ b/examples/keyboard.c @@ -0,0 +1,91 @@ +#include <stdio.h> +#include <stdbool.h> +#define FBGL_IMPLEMENTATION +#include "fbgl.h" + +#define RECT_WIDTH 50 +#define RECT_HEIGHT 30 +#define MOVE_STEP 10 +#define BG_COLOR 0x000000 // Black +#define RECT_COLOR 0xFFFFFF // White + +int main(void) +{ + // Initialize framebuffer + fbgl_t framebuffer; + if (fbgl_init(NULL, &framebuffer) != 0) { + fprintf(stderr, "Failed to initialize framebuffer\n"); + return EXIT_FAILURE; + } + + // Initialize keyboard + if (fbgl_keyboard_init() != 0) { + fprintf(stderr, "Failed to initialize keyboard\n"); + fbgl_destroy(&framebuffer); + return EXIT_FAILURE; + } + + atexit(fbgl_keyboard_clean); // Cleanup on exit + atexit((void (*)(void))fbgl_destroy, &framebuffer); + + // Initial rectangle position + fbgl_point_t top_left = {framebuffer.width / 2 - RECT_WIDTH / 2, framebuffer.height / 2 - RECT_HEIGHT / 2}; + fbgl_point_t bottom_right = {top_left.x + RECT_WIDTH, top_left.y + RECT_HEIGHT}; + + // Main loop + while (!fbgl_check_esc_key()) { + // Update keyboard state + fbgl_keyboard_update(); + + // Clear screen + fbgl_set_bg(&framebuffer, BG_COLOR); + + // Move rectangle based on key input + if (fbgl_key_down('w')) { + top_left.y -= MOVE_STEP; + bottom_right.y -= MOVE_STEP; + } + if (fbgl_key_down('s')) { + top_left.y += MOVE_STEP; + bottom_right.y += MOVE_STEP; + } + if (fbgl_key_down('a')) { + top_left.x -= MOVE_STEP; + bottom_right.x -= MOVE_STEP; + } + if (fbgl_key_down('d')) { + top_left.x += MOVE_STEP; + bottom_right.x += MOVE_STEP; + } + + // Ensure rectangle stays within screen bounds + if (top_left.x < 0) { + top_left.x = 0; + bottom_right.x = RECT_WIDTH; + } + if (top_left.y < 0) { + top_left.y = 0; + bottom_right.y = RECT_HEIGHT; + } + if (bottom_right.x > framebuffer.width) { + bottom_right.x = framebuffer.width; + top_left.x = framebuffer.width - RECT_WIDTH; + } + if (bottom_right.y > framebuffer.height) { + bottom_right.y = framebuffer.height; + top_left.y = framebuffer.height - RECT_HEIGHT; + } + + // Draw the rectangle + fbgl_draw_rectangle_filled(top_left, bottom_right, RECT_COLOR, &framebuffer); + + // Refresh frame (add a delay if needed) + usleep(16000); // ~60 FPS + } + + // Cleanup + fbgl_keyboard_clean(); + fbgl_destroy(&framebuffer); + + return EXIT_SUCCESS; +} @@ -190,9 +190,9 @@ void fbgl_render_psf1_text(fbgl_t *fb, fbgl_psf1_font_t *font, const char *text, int fbgl_keyboard_init(void); void fbgl_keyboard_clean(void); void fbgl_keyboard_update(void); +bool fbgl_key_down(unsigned char key); bool fbgl_key_pressed(unsigned char key); bool fbgl_key_released(unsigned char key); -bool fbgl_key_down(unsigned char key); #ifdef FBGL_IMPLEMENTATION @@ -732,6 +732,95 @@ void fbgl_render_psf1_text(fbgl_t *fb, fbgl_psf1_font_t *font, const char *text, } } +int fbgl_keyboard_init(void) +{ + if (keyboard.is_initialized) { + return 0; // Already initialized + } + + struct termios raw; + + if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) { + perror("tcgetattr"); + return -1; + } + + raw = orig_termios; + raw.c_lflag &= ~(ECHO | ICANON); // Disable echo and canonical mode + raw.c_cc[VMIN] = 0; // Non-blocking read + raw.c_cc[VTIME] = 0; // No timeout + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) { + perror("tcsetattr"); + return -1; + } + + memset(&keyboard, 0, sizeof(fbgl_keyboard_t)); + keyboard.is_initialized = true; + return 0; +} + +void fbgl_keyboard_clean(void) +{ + if (!keyboard.is_initialized) { + return; + } + + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1) { + perror("tcsetattr"); + } + + keyboard.is_initialized = false; +} + +void fbgl_keyboard_update(void) +{ + if (!keyboard.is_initialized) { + return; + } + + // Copy current state to previous state + memcpy(keyboard.prev_keys, keyboard.keys, sizeof(keyboard.keys)); + + char c; + while (read(STDIN_FILENO, &c, 1) > 0) { + if (c >= 0 && c < FBGL_MAX_KEYS) { + keyboard.keys[(unsigned char)c] = true; + } + } + + // Reset keys that are not pressed + for (int i = 0; i < FBGL_MAX_KEYS; i++) { + if (!keyboard.keys[i]) { + keyboard.keys[i] = false; + } + } +} + + +bool fbgl_key_down(unsigned char key) +{ + if (key >= FBGL_MAX_KEYS) { + return false; + } + return keyboard.keys[key]; +} + +bool fbgl_key_pressed(unsigned char key) +{ + if (key >= FBGL_MAX_KEYS) { + return false; + } + return keyboard.keys[key] && !keyboard.prev_keys[key]; +} + +bool fbgl_key_released(unsigned char key) +{ + if (key >= FBGL_MAX_KEYS) { + return false; + } + return !keyboard.keys[key] && keyboard.prev_keys[key]; +} + #endif // FBGL_IMPLEMENTATION #ifdef __cplusplus |
