b0VIM 9.1ÉàliK@£Ç#n76310nimgnu~n76310/Documents/Studium/HsNr/25_WS/Compilerbau/Abgabe/snake_SDL/editor/main.cutf-8 3210#"! UtpuxvîkmJØad.uÀª•‚nZF10/ûÞÄì•€T(ô Ÿ ž … l X B î ˜ — † x o n ] 7 '  ø ï î Ý Î ¹ ¨ ž � Œ Z ý Ò – F / & %  á Ñ ¿ ¤ – • u ^  ΆP%#"÷ö±™kjP? ÐÆ¹�O óíìÛ«{zV'Ö²°¯sLæäã˜sONÌ�A currently_overlap = true; if (head.x >= light->pos.x && head.x < light->pos.x + light->width) { // Check if head is within light's horizontal bounds if (head.y >= light->pos.y && head.y < light->pos.y + light->height) { // Check if head is within light's vertical bounds bool currently_overlap = false; Point head = snake->segments[0];void check_light_brightness(Light lights[3], Light *light, Snake *snake) {} snake->segments[0].y == button->pos.y; return snake->segments[0].x == button->pos.x && if (!button->active) return false;bool check_button_collision(Snake *snake, Button *button) {} *collided_with_wall = true; snake->segments[0].y >= GRID_SIZE_Y) snake->segments[0].y < 0 || snake->segments[0].x >= GRID_SIZE_X || if (snake->segments[0].x < 0 || snake->segments[0].y += snake->direction.y; snake->segments[0].x += snake->direction.x; // Move head } snake->length++; } snake->segments[i] = snake->segments[i - 1]; for (int i = snake->length; i > 0; i--) { // Growing: shift all segments and add new head } else { } snake->segments[i] = snake->segments[i - 1]; for (int i = snake->length - 1; i > 0; i--) { if (!grow) { // Move body segments snake->direction = snake->next_direction; // Update directionvoid move_snake(Snake *snake, bool grow, bool* collided_with_wall) {int max_brightness = MAX_BRIGHTNESS_STEPS;} snake->next_direction = (Point){1, 0}; snake->direction = (Point){1, 0}; // moving right snake->segments[2] = (Point){GRID_SIZE_X / 2 - 2, GRID_SIZE_Y / 2}; snake->segments[1] = (Point){GRID_SIZE_X / 2 - 1, GRID_SIZE_Y / 2}; snake->segments[0] = (Point){GRID_SIZE_X / 2 , GRID_SIZE_Y / 2}; snake->length = 3;void init_snake(Snake *snake) {} MatrixData; pthread_mutex_t mutex; bool running; FILE *pipe; SDL_Color matrix[MATRIX_HEIGHT][MATRIX_WIDTH];typedef struct {} Light; bool last_overlap; int brightness; // current brightness level (0 to MAX_BRIGHTNESS_STEPS) SDL_Color base_color; // base color at full brightness int height; // height in tiles int width; // width in tiles (should be 8: 1 for off + 7 for brightness levels) Point pos; // top-left tile positiontypedef struct {} Button; bool active; SDL_Color color; Point pos;typedef struct {} Snake; Point next_direction; Point direction; int length; Point segments[MAX_SNAKE_LENGTH];typedef struct {} Point; int x, y;typedef struct {#define MATRIX_WINDOW_HEIGHT (MATRIX_HEIGHT * (LED_SIZE + LED_SPACING) + LED_SPACING)#define MATRIX_WINDOW_WIDTH (MATRIX_WIDTH * (LED_SIZE + LED_SPACING) + LED_SPACING)#define LED_SPACING 2#define LED_SIZE 30#define MATRIX_HEIGHT 16#define MATRIX_WIDTH 16#define MAX_BRIGHTNESS_STEPS 7 // Fixed number of brightness levels (0=off, 1-7=on)#define MAX_SNAKE_LENGTH (GRID_SIZE_X* GRID_SIZE_Y)#define WINDOW_SIZE_Y TILE_SIZE*GRID_SIZE_Y#define WINDOW_SIZE_X TILE_SIZE*GRID_SIZE_X#define TILE_SIZE 30#define GRID_SIZE_Y 30#define GRID_SIZE_X 40int pclose(FILE *stream);char *strdup(const char *s);FILE *popen(const char *command, const char *type);#include #include #include #include #include #include #include // gcc snake.c -o snake_game $(pkg-config --cflags --libs sdl3)adü<JöЛ‘f>=&  Ô±‰ˆubONÎ Ž � y Z 2 s N ý ì ë µ š k C B  ö Ò Ñ ° ^ ] -  û â º Š e S E D  Ø¢vuZPO*ÿÝ×Ö§�]ML><9}}} return 0; SDL_Quit(); SDL_DestroyWindow(control_win); SDL_DestroyRenderer(control_ren); pthread_mutex_destroy(&matrix_data.mutex); } pclose(matrix_data.pipe); pthread_join(reader_thread, NULL); matrix_data.running = false; } SDL_Delay(16); SDL_RenderPresent(control_ren); render_matrix(control_ren, &matrix_data); SDL_RenderClear(control_ren); SDL_SetRenderDrawColor(control_ren, 10, 10, 10, 255); } } running = false; if (e.type == SDL_EVENT_QUIT) { while (SDL_PollEvent(&e)) { SDL_Event e; while (running) { running = true; // Continue rendering until user closes pthread_create(&reader_thread, NULL, matrix_reader_thread, &matrix_data); pthread_t reader_thread; matrix_data.running = true; if (matrix_data.pipe) { matrix_data.pipe = popen(monitor_cmd, "r"); "make -C ../src/ monitor"); snprintf(monitor_cmd, sizeof(monitor_cmd), char monitor_cmd[512]; // Now start the monitor and matrix reader thread system(cmd); collided_with_wall, snake.length, max_brightness, red, green, blue); "make -C ../src/ flash", "EXTRA_CFLAGS='-DWALL_COLLISION=%d -DSNAKE_START_LENGTH=%d -DMAX_BRIGHTNESS=%d -DSNAKE_COLOR_R=%d -DSNAKE_COLOR_G=%d -DSNAKE_COLOR_B=%d' && " "make -C ../src/ build " "make -C ../src/ clean && " snprintf(cmd, sizeof(cmd), char cmd[1024]; if (lights[2].brightness > 0) blue = lights[2].brightness; if (lights[1].brightness > 0) green = lights[1].brightness; if (lights[0].brightness > 0) red = lights[0].brightness; int blue = 0; int green = 0; int red = 0; system("export PORT=/dev/ttyUSB0"); system("export ARCH=esp32c3"); system("export MDK=/usr/src/u_esp/baremetal/mdk"); // Flash to ESP } SDL_Delay(16); SDL_RenderPresent(control_ren); render_snake(control_ren, &snake); } render_button(control_ren, &buttons[i]); for (int i = 0; i < 5; i++) { }ad xµ�€&öõÑ•[ML!î ä Þ Ý ° ¯ ˆ o M % ÷ í ç Ô “ t n l k A  × › ‚ x r ` ^ ] ( ú ß ± ƒ h N C B &  × Æ � ƒ [ U S R  ùøáº“|f_^áßÞ©m:ñË´Žƒ‚YXûÕ¾§�1Û­QGFìS:!ïå䫃}{zT"!   // Vertical lines SDL_SetRenderDrawColor(ren, 30, 30, 30, 255);void render_grid(SDL_Renderer *ren) {} } SDL_RenderFillRect(ren, &rect); SDL_SetRenderDrawColor(ren, c.r, c.g, c.b, 255); } rect.h -= 4; rect.w -= 4; rect.y += 2; rect.x += 2; SDL_RenderFillRect(ren, &rect); SDL_SetRenderDrawColor(ren, light->base_color.r, light->base_color.g, light->base_color.b, 140); if (col == light->brightness) { // Highlight the current brightness level } c.b = (uint8_t)(c.b * intensity); c.g = (uint8_t)(c.g * intensity); c.r = (uint8_t)(c.r * intensity); float intensity = (float)light->brightness / (float)MAX_BRIGHTNESS_STEPS; // Brightness columns - show the brightness level for that column } else { c.b /= 10; c.g /= 10; c.r /= 10; // Off column - very dark if (col == 0) { // Column 0 is "off", columns 1-7 show increasing brightness SDL_Color c = light->base_color; }; light->height * TILE_SIZE TILE_SIZE, light->pos.y * TILE_SIZE, (light->pos.x + col) * TILE_SIZE, SDL_FRect rect = { for (int col = 0; col < light->width; col++) { // Draw each column of the light with visual indicationvoid render_light(SDL_Renderer *ren, Light *light) {} SDL_RenderFillRect(ren, &rect); SDL_SetRenderDrawColor(ren, button->color.r, button->color.g, button->color.b, 255); }; TILE_SIZE - 4 TILE_SIZE - 4, button->pos.y * TILE_SIZE + 2, button->pos.x * TILE_SIZE + 2, SDL_FRect rect = { if (!button->active) return;void render_button(SDL_Renderer *ren, Button *button) {} } SDL_RenderFillRect(ren, &rect); } SDL_SetRenderDrawColor(ren, 0, 200, 0, 255); } else { SDL_SetRenderDrawColor(ren, 0, 255, 0, 255); if (i == 0) { // Head is brighter }; TILE_SIZE - 2 TILE_SIZE - 2, snake->segments[i].y * TILE_SIZE, snake->segments[i].x * TILE_SIZE, SDL_FRect rect = { for (int i = 0; i < snake->length; i++) {void render_snake(SDL_Renderer *ren, Snake *snake) {} return false; } } return true; snake->segments[0].y == snake->segments[i].y) { if (snake->segments[0].x == snake->segments[i].x && for (int i = 1; i < snake->length; i++) {bool check_self_collision(Snake *snake) {} } light->brightness = 1; // If all off, force this light on at minimum brightness if (!any_on) { } } break; any_on = true; if (lights[i].brightness > 0) { for (int i = 0; i < 3; i++) { bool any_on = false; // Ensure at least one light is on light->last_overlap = currently_overlap; } } light->brightness = target_brightness; // Set the brightness directly } target_brightness = MAX_BRIGHTNESS_STEPS; if (target_brightness > MAX_BRIGHTNESS_STEPS) { // Clamp to valid range int target_brightness = relative_x; // Map column to brightness: column 0 = off (0), columns 1-7 = brightness 1-7 int relative_x = head.x - light->pos.x; // Calculate relative position from left (0 = leftmost column)ad%9Ó|vu]0ÙÓÑЪ¨�mlaM;! Ã Â Ž q Y X 5 ø á ¾ ° š � � m 9   ì Õ Ô ¨ y \ [  æ ¾ £ ‘ � ^ , ú ù É ´ ¦ x w P ;  é×É¿¹¸§¥¤jDC䶈ZY:þ¨�€HþÖ¶–vWDä´vA3)#"úø÷æÁ‰wqpS¾¦fR@:98 } return 1; SDL_Quit(); SDL_Log("SDL_CreateWindow failed: %s", SDL_GetError()); if (!control_win) { WINDOW_SIZE_X, WINDOW_SIZE_Y, 0); SDL_Window *control_win = SDL_CreateWindow("Snake Game - WASD to move", // Create control window } return 1; SDL_Log("SDL_Init failed: %s", SDL_GetError()); if (!SDL_Init(SDL_INIT_VIDEO)) {int main(void) {} pthread_mutex_unlock(&data->mutex); } } } SDL_RenderFillRect(ren, &highlight); SDL_SetRenderDrawColor(ren, hr, hg, hb, 200); uint8_t hb = b + (255 - b) / 2; uint8_t hg = g + (255 - g) / 2; uint8_t hr = r + (255 - r) / 2; }; rect.h / 3 rect.w / 3, rect.y + 2, rect.x + 2, SDL_FRect highlight = { if (r+g+b > 0) { SDL_RenderFillRect(ren, &rect); SDL_SetRenderDrawColor(ren, r, g, b, 255); }; LED_SIZE LED_SIZE, LED_SPACING + y * (LED_SIZE + LED_SPACING), LED_SPACING + x * (LED_SIZE + LED_SPACING), SDL_FRect rect = { uint8_t b = data->matrix[y][x].b; uint8_t g = data->matrix[y][x].g; uint8_t r = data->matrix[y][x].r; for (int x = 0; x < MATRIX_WIDTH; x++) { for (int y = 0; y < MATRIX_HEIGHT; y++) { pthread_mutex_lock(&data->mutex);void render_matrix(SDL_Renderer *ren, MatrixData *data) {} return NULL; } } } } state = WAIT_START; if (y >= MATRIX_HEIGHT) { y++; if (state != WAIT_START) { pthread_mutex_unlock(&md->mutex); } x++; tile = strtok(NULL, " \t\n\r"); md->matrix[y][x].b = b * 255 / 7; md->matrix[y][x].g = g * 255 / 7; md->matrix[y][x].r = r * 255 / 7; } break; state = WAIT_START; /* corrupted tile → resync */ if (sscanf(tile, "%d|%d|%d", &r, &g, &b) != 3) { int r, g, b; while (tile && x < MATRIX_WIDTH) { pthread_mutex_lock(&md->mutex); int x = 0; char *tile = strtok(line, " \t\n\r"); continue; if (line[0] == '\n' || line[0] == '\r') if (state == READ_ROWS) { } continue; } state = READ_ROWS; y = 0; if (strncmp(line, "## START MATRIX", 15) == 0) { if (state == WAIT_START) { fflush(stdout); fputs(line, stdout); /* Always forward ESP output to terminal */ while (md->running && md->pipe && fgets(line, sizeof(line), md->pipe)) { int y = 0; } state = WAIT_START; READ_ROWS WAIT_START, enum { char line[512]; MatrixData *md = (MatrixData*)arg;{void* matrix_reader_thread(void* arg)} } SDL_RenderLine(ren, 0, i * TILE_SIZE, GRID_SIZE_X * TILE_SIZE, i * TILE_SIZE); for (int i = 0; i <= GRID_SIZE_Y; i++) { // Horizontal lines } SDL_RenderLine(ren, i * TILE_SIZE, 0, i * TILE_SIZE, GRID_SIZE_Y * TILE_SIZE); for (int i = 0; i <= GRID_SIZE_X; i++) {ad Ïkµ�[3 ÜÛʲ±›�QÛ • N G F 1  Ð — – ~ : ä ‹ „ ƒ j A  ÷ ö Ø ¶ • c b L 7  ç Æ ¸ · ‡ ] 4 ½žuAÿà·ƒ@!øÄ‚cF'ýüѪ}^]3ðÁ …sed)(þº¬«e$õô×ÍÌ«pJ(ÏÎ render_light(control_ren, &lights[i]); for (int i = 0; i < 3; i++) { render_grid(control_ren); SDL_RenderClear(control_ren); SDL_SetRenderDrawColor(control_ren, 0, 0, 0, 255); // Render control window } last_move = now; } running = false; printf("Game Over! Length: %d\n", snake.length); if (check_self_collision(&snake) || collided_with_wall) { } check_light_brightness(lights, &lights[i], &snake); for (int i = 0; i < 3; i++) { move_snake(&snake, grow, &collided_with_wall); } } break; grow = true; buttons[i].active = false; if (check_button_collision(&snake, &buttons[i])) { for (int i = 0; i < 5; i++) { bool grow = false; if (now - last_move >= move_delay) { uint64_t now = SDL_GetTicks(); // Move snake at regular intervals } } } break; default: break; snake.next_direction = (Point){1, 0}; if (snake.direction.x == 0) case SDL_SCANCODE_D: break; snake.next_direction = (Point){-1, 0}; if (snake.direction.x == 0) case SDL_SCANCODE_A: break; snake.next_direction = (Point){0, 1}; if (snake.direction.y == 0) case SDL_SCANCODE_S: break; snake.next_direction = (Point){0, -1}; if (snake.direction.y == 0) case SDL_SCANCODE_W: switch (e.key.scancode) { if (e.type == SDL_EVENT_KEY_DOWN) { } running = false; if (e.type == SDL_EVENT_QUIT) { while (SDL_PollEvent(&e)) { SDL_Event e; while (running) { pthread_mutex_init(&matrix_data.mutex, NULL); matrix_data.running = false; MatrixData matrix_data = {0}; // Matrix data and thread bool collided_with_wall = false; const uint64_t move_delay = 250; uint64_t last_move = SDL_GetTicks(); bool running = true; }; {{start_x + 2*(light_width + 1), 5}, light_width, 2, {0, 0, 255, 255}, 0, false} {{start_x + light_width + 1, 5}, light_width, 2, {0, 255, 0, 255}, 4, false}, {{start_x, 5}, light_width, 2, {255, 0, 0, 255}, 0, false}, Light lights[3] = { int start_x = (GRID_SIZE_X - total_light_width) / 2; int total_light_width = 3 * light_width + 2; int light_width = MAX_BRIGHTNESS_STEPS + 1; // Create lights }; {{GRID_SIZE_X/2, GRID_SIZE_Y/2+5}, {0 , 255, 255, 255}, true} {{GRID_SIZE_X-6, GRID_SIZE_Y-6}, {255, 0 , 255, 255}, true}, {{5 , GRID_SIZE_Y-6}, {255, 255, 0 , 255}, true}, {{GRID_SIZE_X-6, 5}, {0 , 0 , 255, 255}, true}, {{5 , 5}, {255, 0 , 0 , 255}, true}, Button buttons[5] = { // Create buttons init_snake(&snake); Snake snake; // Create matrix visualization window } return 1; SDL_Quit(); SDL_DestroyWindow(control_win); SDL_Log("SDL_CreateRenderer failed: %s", SDL_GetError()); if (!control_ren) { SDL_Renderer *control_ren = SDL_CreateRenderer(control_win, "opengl");