snake_compiler git · main
Snake compiled to a bare-metal RISC-V microcontroller
C 95.2% Markdown 3.3%git clone https://git.christianimmanuel.de/embedded/snake_compiler.gitwget https://git.christianimmanuel.de/embedded/snake_compiler/archive/snake_compiler.tar.gzsnake_SDL/src/main.c raw
#include "defaults.h"
#include "snake.h"
#include "matrix.h"
int main(void) {
wdt_disable();
gpio_output(WS2812_PIN);
static LEDMatrix m;
static Button b1, b2, b3, b4;
matrix = &m;
// Initialize buttons
Button* buttons[] = { &b1, &b2, &b3, &b4 };
uint8_t pins[] = { PIN_BUTTON_LEFT,
PIN_BUTTON_DOWN,
PIN_BUTTON_UP,
PIN_BUTTON_RIGHT };
uint64_t now;
uint64_t last_update;
uint64_t interval;
for (int i = 0; i < 4; i++) {
delay_ms(10);
buttons[i]->pin = pins[i];
gpio_input(buttons[i]->pin);
delay_ms(10);
buttons[i]->state_init = gpio_read(buttons[i]->pin);
delay_ms(10);
buttons[i]->state_prev = buttons[i]->state_init;
}
main_menu:
printf("# GAME MENU!\n", MATRIX_WIDTH);
printf("Game Mode: %d\n", game_mode);
printf("Start Game: Button 1 && Button 4\n", MATRIX_WIDTH);
printf("End Game: Button 2 && Button 3\n", MATRIX_WIDTH);
printf("Prev Mode: Button 2\n", MATRIX_WIDTH);
printf("Next Mode: Button 3\n", MATRIX_WIDTH);
last_update = 0;
interval = 1000000;
for (;;) {
uint64_t time_diff = uptime_us() - last_update;
delay_ms(10);
if ( gpio_read(buttons[0]->pin) != buttons[0]->state_init &&
gpio_read(buttons[3]->pin) != buttons[3]->state_init) {
goto start_game;
} else
if ( gpio_read(buttons[1]->pin) != buttons[1]->state_init &&
gpio_read(buttons[2]->pin) != buttons[2]->state_init) {
goto end;
} else
if ( gpio_read(buttons[2]->pin) != buttons[2]->state_init ) {
game_mode = (game_mode + 1) % GAME_MODE_LAST;
} else
if ( gpio_read(buttons[1]->pin) != buttons[1]->state_init ) {
game_mode--;
game_mode = game_mode < 0 ? 0 : game_mode;
}
delay_ms(10);
if (time_diff >= interval) {
last_update = uptime_us();
}
}
start_game:
printf("# GAME START!\n", MATRIX_WIDTH);
matrix_Blink(3, 300);
matrix_ClearAll(BLACK);
Snake snake;
snake_Init(&snake, MATRIX_WIDTH/2, MATRIX_HEIGHT/2);
now = uptime_us();
last_update = now;
interval = 500000;
spawn_apple();
while (1) {
now = uptime_us();
uint64_t time_diff = now - last_update;
bool is_next_step = time_diff >= interval;
// INPUT
if ( gpio_read(buttons[0]->pin) != buttons[0]->state_init &&
gpio_read(buttons[3]->pin) != buttons[3]->state_init) {
delay_ms(10);
goto start_game;
}
for (int i = 0; i < 4; i++) {
bool curr = gpio_read(buttons[i]->pin);
if (curr != buttons[i]->state_prev) {
buttons[i]->state_prev = curr;
switch (i) {
case 0: snake_SetDirection(&snake, DIR_LEFT); break;
case 1: snake_SetDirection(&snake, DIR_DOWN); break;
case 2: snake_SetDirection(&snake, DIR_UP); break;
case 3: snake_SetDirection(&snake, DIR_RIGHT); break;
}
}
}
if (!snake_Move(&snake, is_next_step, interval, time_diff)) {
break;
}
if (is_next_step)
last_update = now;
// UPDATE
matrix_Update();
// RENDER
matrix_WriteLed();
if (is_next_step)
matrix_Print();
delay_ms(10);
}
goto main_menu;
end:
matrix_ClearAll(RED);
printf("# GAME END!\n", MATRIX_WIDTH);
}