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/matrix.c raw
#include "matrix.h"
static uint8_t pixels_buffer[NUM_PIXELS * 3];
GameMode game_mode;
Button* button_1;
Button* button_2;
Button* button_3;
Button* button_4;
LEDMatrix* matrix;
// Generate a pseudo-random number in [0, max)
int random_Int(int max) {
uint64_t t = uptime_us(); // get current microseconds
t ^= t >> 33; // mix bits
t *= 0xff51afd7ed558ccdULL; // arbitrary constant
t ^= t >> 33;
t *= 0xc4ceb9fe1a85ec53ULL; // arbitrary constant
t ^= t >> 33;
return (int)t % max; // limit to range
}
void
matrix_Init(Color color) {
for (int y = 0; y < MATRIX_HEIGHT; y++) {
for (int x = 0; x < MATRIX_WIDTH; x++) {
matrix->pixels[y][x].color = color;
matrix->pixels[y][x].type = NONE;
}
}
}
void
matrix_SetPixelColor(int x, int y, Color c) {
if (x < 0 || x >= MATRIX_WIDTH || y < 0 || y >= MATRIX_HEIGHT) return;
matrix->pixels[y][x].color = c;
}
void
matrix_ToMdkBuffer() {
for (int y = 0, yy = MATRIX_HEIGHT-1; y < MATRIX_HEIGHT; y++, yy--) {
int xx = 0;
bool is_un = (y+1)%2;
for (int x = is_un ? 0 : MATRIX_WIDTH-1;
is_un ? (x < MATRIX_WIDTH)
: (x >= 0) ;
xx++,
is_un ? x++
: x--) {
int idx = (y * MATRIX_WIDTH + xx) * 3;
pixels_buffer[idx + 0] = matrix->pixels[yy][x].color.g;
pixels_buffer[idx + 1] = matrix->pixels[yy][x].color.r;
pixels_buffer[idx + 2] = matrix->pixels[yy][x].color.b;
}
}
/*
for (int y = 0; y < MATRIX_HEIGHT; y++) {
for (int x = 0; x < MATRIX_WIDTH; x++) {
int idx = (y * MATRIX_WIDTH + x) * 3;
pixels_buffer[idx + 0] = matrix->pixels[y][x].color.g;
pixels_buffer[idx + 1] = matrix->pixels[y][x].color.r;
pixels_buffer[idx + 2] = matrix->pixels[y][x].color.b;
}
}
*/
}
void
matrix_WriteLed() {
matrix_ToMdkBuffer();
ws2812_show(WS2812_PIN, pixels_buffer, NUM_PIXELS * 3);
}
void
matrix_ClearAll(Color color) {
matrix_Init(color);
matrix_WriteLed();
}
void
matrix_Blink(int count, unsigned long delay_millis) {
Color green = {0, MAX_BRIGHTNESS, 0};
Color black = {0, 0, 0};
for (int i = 0; i < count; i++) {
// Set all pixels to green
for (int y = 0; y < MATRIX_HEIGHT; y++) {
for (int x = 0; x < MATRIX_WIDTH; x++) {
matrix_SetPixelColor(x, y, green);
}
}
matrix_WriteLed();
delay_ms(delay_millis);
// Set all pixels to black
for (int y = 0; y < MATRIX_HEIGHT; y++) {
for (int x = 0; x < MATRIX_WIDTH; x++) {
matrix_SetPixelColor(x, y, black);
}
}
matrix_WriteLed();
delay_ms(delay_millis);
}
}
static inline Color
hsv_to_rgb_u8(uint8_t h, uint8_t s, uint8_t v) {
uint8_t region = h / 43;
uint8_t rem = (h - region * 43) * 6;
uint8_t p = (uint8_t)(v * (255 - s)) >> 8;
uint8_t q = (uint8_t)(v * (255 - ((s * rem) >> 8))) >> 8;
uint8_t t = (uint8_t)(v * (255 - ((s * (255 - rem)) >> 8))) >> 8;
switch (region) {
case 0: return (Color){ v, t, p };
case 1: return (Color){ q, v, p };
case 2: return (Color){ p, v, t };
case 3: return (Color){ p, q, v };
case 4: return (Color){ t, p, v };
default:return (Color){ v, p, q };
}
}
void matrix_Print() {
printf("## START MATRIX\n", MATRIX_HEIGHT);
for (int y = 0; y < MATRIX_HEIGHT; y++) {
for (int x = 0; x < MATRIX_WIDTH; x++)
printf("%u|%u|%u ",
matrix->pixels[y][x].color.r,
matrix->pixels[y][x].color.g,
matrix->pixels[y][x].color.b);
//printf("%3d ", (matrix->pixels[y][x].color.r+matrix->pixels[y][x].color.g+matrix->pixels[y][x].color.b));
//printf("%d ", matrix->pixels[y][x].type);
printf("\n\n", MATRIX_HEIGHT);
}
printf("\n", MATRIX_HEIGHT);
}
void matrix_Update() {
static uint64_t last = 0;
static uint64_t now = 0;
static int counter = 0;
if (last == 0) {
last = uptime_us();
now = last;
}
now = uptime_us();
uint64_t interval = 50000;
if (now - last > interval) {
last = now;
counter++;
}
for (int y = 0; y < MATRIX_HEIGHT; y++) {
for (int x = 0; x < MATRIX_WIDTH; x++) {
Color c = matrix->pixels[y][x].color;
if (game_mode == FANCY) {
if (matrix->pixels[y][x].type == NONE) {
int cx = MATRIX_WIDTH / 2;
int cy = MATRIX_HEIGHT / 2;
int dx = (uint16_t)(x - cx);
int dy = (uint16_t)(y - cy);
uint16_t dist = (uint16_t)(dx*dx + dy*dy);
uint16_t maxd = (uint16_t)(cx*cx + cy*cy);
uint8_t hue = (uint8_t)((dist * 255) / maxd);
c = hsv_to_rgb_u8(hue, 255, 255);
/* downscale to MAX_BRIGHTNESS */
c.r = (uint8_t)(c.r + counter) % MAX_BRIGHTNESS;
c.g = (uint8_t)(c.g + counter) % MAX_BRIGHTNESS;
c.b = (uint8_t)(c.b + counter) % MAX_BRIGHTNESS;
}
}
matrix_SetPixelColor(x, y, c);
}
}
}