/* * Copyright (c) 2019-2021, yzrh * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include "renderer.h" #include "screen.h" #include "game.h" void draw_clear(SDL_Renderer *renderer) { SDL_SetRenderDrawColor(renderer, COLOUR_BACKGROUND_R, COLOUR_BACKGROUND_G, COLOUR_BACKGROUND_B, 255); SDL_RenderClear(renderer); } void draw_colour(SDL_Renderer *renderer, Snake_Colour colour) { int r; int g; int b; switch (colour) { case SNAKE_FOREGROUND: r = COLOUR_FOREGROUND_R; g = COLOUR_FOREGROUND_G; b = COLOUR_FOREGROUND_B; break; case SNAKE_BACKGROUND: r = COLOUR_BACKGROUND_R; g = COLOUR_BACKGROUND_G; b = COLOUR_BACKGROUND_B; break; case SNAKE_BACKGROUND_SHADE: r = COLOUR_BACKGROUND_SHADE_R; g = COLOUR_BACKGROUND_SHADE_G; b = COLOUR_BACKGROUND_SHADE_B; break; case SNAKE_RED: r = COLOUR_RED_R; g = COLOUR_RED_G; b = COLOUR_RED_B; break; case SNAKE_GREEN: r = COLOUR_GREEN_R; g = COLOUR_GREEN_G; b = COLOUR_GREEN_B; break; case SNAKE_BLUE: r = COLOUR_RED_R; g = COLOUR_RED_G; b = COLOUR_RED_B; break; case SNAKE_YELLOW: r = COLOUR_RED_R; g = COLOUR_RED_G; b = COLOUR_RED_B; break; case SNAKE_MAGENTA: r = COLOUR_RED_R; g = COLOUR_RED_G; b = COLOUR_RED_B; break; case SNAKE_CYAN: r = COLOUR_RED_R; g = COLOUR_RED_G; b = COLOUR_RED_B; break; case SNAKE_WHITE: r = COLOUR_RED_R; g = COLOUR_RED_G; b = COLOUR_RED_B; break; case SNAKE_BLACK: r = COLOUR_RED_R; g = COLOUR_RED_G; b = COLOUR_RED_B; break; default: break; } SDL_SetRenderDrawColor(renderer, r, g, b, 255); } void draw_text(SDL_Renderer *renderer, TTF_Font *font, int text_x, int text_y, char *text, bool centre, bool select, SDL_Color fg, SDL_Color bg, Snake_Text *message) { if (!message->cache) { if (message->texture != NULL) SDL_DestroyTexture(message->texture); SDL_Surface *surface = TTF_RenderUTF8_Shaded(font, text, fg, bg); message->texture = SDL_CreateTextureFromSurface(renderer, surface); SDL_FreeSurface(surface); message->pos.x = text_x; message->pos.y = text_y; TTF_SizeText(font, text, &message->pos.w, &message->pos.h); if (centre) message->pos.x -= message->pos.w / 2; message->pos.y -= message->pos.h; message->cache = 1; } SDL_RenderCopy(renderer, message->texture, NULL, &message->pos); if (select) { SDL_SetRenderDrawColor(renderer, COLOUR_FOREGROUND_R, COLOUR_FOREGROUND_G, COLOUR_FOREGROUND_B, 255); SDL_RenderDrawLine(renderer, message->pos.x, message->pos.y, message->pos.x, message->pos.y + message->pos.h); SDL_RenderDrawLine(renderer, message->pos.x, message->pos.y, message->pos.x + message->pos.w, message->pos.y); SDL_RenderDrawLine(renderer, message->pos.x, message->pos.y + message->pos.h, message->pos.x + message->pos.w, message->pos.y + message->pos.h); SDL_RenderDrawLine(renderer, message->pos.x + message->pos.w, message->pos.y, message->pos.x + message->pos.w, message->pos.y + message->pos.h); } } void draw_wall(SDL_Renderer *renderer) { SDL_RenderDrawLine(renderer, 0, 0, 0, SCREEN_HEIGHT); SDL_RenderDrawLine(renderer, 0, 0, SCREEN_HEIGHT, 0); SDL_RenderDrawLine(renderer, 0, SCREEN_HEIGHT - 1, SCREEN_HEIGHT, SCREEN_HEIGHT - 1); SDL_RenderDrawLine(renderer, SCREEN_HEIGHT, 0, SCREEN_HEIGHT, SCREEN_HEIGHT); } void draw_snake(SDL_Renderer *renderer, Snake_Pos **snake) { Snake_Pos *ptr = *snake; SDL_Rect pos; while (ptr != NULL) { pos.x = ptr->x; pos.y = ptr->y; pos.w = SCREEN_UNIT; pos.h = SCREEN_UNIT; SDL_RenderFillRect(renderer, &pos); ptr = ptr->next; } } void draw_fruit(SDL_Renderer *renderer, int *fruit) { int rx = fruit[0] + SCREEN_UNIT / 2; int ry = fruit[1] + SCREEN_UNIT / 2; /* Midpoint circle algorithm */ int x = SCREEN_UNIT / 2; int y = 0; int dx = 1; int dy = 1; int err = dx - ((SCREEN_UNIT / 2) << 1); while (x >= y) { SDL_RenderDrawLine(renderer, rx - y, ry + x, rx + y, ry + x); SDL_RenderDrawLine(renderer, rx - x, ry + y, rx + x, ry + y); SDL_RenderDrawLine(renderer, rx - x, ry - y, rx + x, ry - y); SDL_RenderDrawLine(renderer, rx - y, ry - x, rx + y, ry - x); if (err <= 0) { y++; err += dy; dy += 2; } if (err > 0) { x--; dx += 2; err += dx - ((SCREEN_UNIT / 2) << 1); } } } void draw_pipe(SDL_Renderer *renderer, Snake_Pos **pipe) { Snake_Pos *ptr = *pipe; SDL_Rect pos; while (ptr != NULL) { pos.x = ptr->x; pos.y = 0; pos.w = SCREEN_UNIT; if (ptr->x + SCREEN_UNIT > SCREEN_HEIGHT) pos.w -= ptr->x + SCREEN_UNIT - SCREEN_HEIGHT; pos.h = ptr->y - PIPE_GAP / 2 * SCREEN_UNIT; SDL_RenderFillRect(renderer, &pos); pos.y = ptr->y + PIPE_GAP / 2 * SCREEN_UNIT; pos.h = SCREEN_HEIGHT - ptr->y - SCREEN_UNIT; SDL_RenderFillRect(renderer, &pos); ptr = ptr->next; } }