From 40561a65374e167644024070fe0cbd6d97b7e769 Mon Sep 17 00:00:00 2001 From: xamidev <121681048+xamidev@users.noreply.github.com> Date: Thu, 12 Sep 2024 17:54:30 +0200 Subject: [PATCH] Add: snake game! (basics) --- src/drivers/framebuffer.c | 6 +- src/drivers/kb.c | 16 ++++ src/drivers/kb.h | 2 + src/kernel/shell.c | 1 + src/libc/stdio.c | 19 +++++ src/libc/stdio.h | 4 +- src/programs/misc.c | 2 +- src/programs/programs.h | 1 + src/programs/snake.c | 161 ++++++++++++++++++++++++++++++++++++++ 9 files changed, 206 insertions(+), 6 deletions(-) create mode 100644 src/programs/snake.c diff --git a/src/drivers/framebuffer.c b/src/drivers/framebuffer.c index 9b4b231..0767638 100644 --- a/src/drivers/framebuffer.c +++ b/src/drivers/framebuffer.c @@ -12,10 +12,8 @@ extern char* framebuffer; void putpixel(uint32_t* fb, int pitch, int bpp, int x, int y, uint32_t color) { - if (bpp == 32) { - uint32_t* pixel_addr = (uint32_t*)((uint8_t*)fb + y * pitch + x *(bpp / 8)); - *pixel_addr = color; - } + uint32_t* pixel_addr = (uint32_t*)((uint8_t*)fb + y * pitch + x *(bpp / 8)); + *pixel_addr = color; } void draw_char(unsigned short int c, int cx, int cy, uint32_t fg, uint32_t bg) diff --git a/src/drivers/kb.c b/src/drivers/kb.c index f4c556c..b45e5f1 100644 --- a/src/drivers/kb.c +++ b/src/drivers/kb.c @@ -140,3 +140,19 @@ char keyboard_getchar() keyboard_buffer_start = (keyboard_buffer_start+1) % KEYBOARD_BUFFER_SIZE; return c; } + +int keyboard_has_input() +{ + return keyboard_buffer_start != keyboard_buffer_end; +} + +char keyboard_getchar_non_blocking() +{ + if (keyboard_has_input()) + { + char c = keyboard_buffer[keyboard_buffer_start]; + keyboard_buffer_start = (keyboard_buffer_start+1)%KEYBOARD_BUFFER_SIZE; + return c; + } + return 0; +} diff --git a/src/drivers/kb.h b/src/drivers/kb.h index d40730f..ceff888 100644 --- a/src/drivers/kb.h +++ b/src/drivers/kb.h @@ -14,5 +14,7 @@ #define RIGHT_SHIFT_RELEASED 0xB6 char keyboard_getchar(); +int keyboard_has_input(); +char keyboard_getchar_non_blocking(); #endif diff --git a/src/kernel/shell.c b/src/kernel/shell.c index 4635483..10ec05e 100644 --- a/src/kernel/shell.c +++ b/src/kernel/shell.c @@ -145,6 +145,7 @@ void shell_install() register_command("bmp", program_bmp); register_command("lspci", program_lspci); register_command("naval", program_navalbattle); + register_command("snake", program_snake); for (;;) { diff --git a/src/libc/stdio.c b/src/libc/stdio.c index 220b8ea..d332202 100644 --- a/src/libc/stdio.c +++ b/src/libc/stdio.c @@ -39,6 +39,25 @@ void draw_cursor(uint32_t color) } } +void draw_pixel(int x, int y, uint32_t color) //high level wrapper for putpixel +{ + putpixel(framebuffer, scanline, 32, x, y, color); +} + +void draw_square(int x, int y, uint32_t color, int size) +{ + int startx = x*size; + int starty = y*size; + + for (int i=0; i0; i--) + { + snake.segments[i] = snake.segments[i-1]; + } + + snake.segments[0].x += snake.dx; + snake.segments[0].y += snake.dy; + + if (snake.segments[0].x < 0) snake.segments[0].x = WIDTH-1; + if (snake.segments[0].x >= WIDTH) snake.segments[0].x = 0; + if (snake.segments[0].y < 0) snake.segments[0].y = HEIGHT-1; + if (snake.segments[0].y >= HEIGHT) snake.segments[0].y = 0; + + if (snake.segments[0].x == food.x && snake.segments[0].y == food.y) + { + snake.length++; + food.x = rand() % (WIDTH-1); + food.y = rand() % (HEIGHT-1); + } +} + +void handle_input(char key) +{ + if (key == 'w' && snake.dy == 0) { + snake.dx = 0; + snake.dy = -1; + } else if (key == 's' && snake.dy == 0) { + snake.dx = 0; + snake.dy = 1; + } else if (key == 'a' && snake.dx == 0) { + snake.dx = -1; + snake.dy = 0; + } else if (key == 'd' && snake.dx == 0) { + snake.dx = 1; + snake.dy = 0; + } else if (key =='q') { + clear(); + shell_install(); + } +} + +void program_snake(int argc, char* argv[]) +{ + int game_speed; + if (argc < 2) + { + game_speed = 4; + } else { + game_speed = atoi(argv[1]); + } + + clear(); + init_game(); + + for(;;) + { + char key = keyboard_getchar_non_blocking(); + + if (key) + { + handle_input(key); + } + + move_snake(); + draw_board(); + delay(game_speed); + } +}