Nimbin[12]?Embedded / snake_compiler / snake_SDL/src/main.c

snake_compiler git · main

Snake compiled to a bare-metal RISC-V microcontroller

riscv embedded bare-metal c snake · first commit 2026-01-18 · last commit 2026-01-18 (8 months ago) · synced 3 days ago · upstream: git.ide3.de/hsnr/compilerbau/snake_compiler

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.gz
snake_SDL/src/main.c 3.6 KB · 137 lines 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);
}