aboutsummaryrefslogtreecommitdiffstats
path: root/src/renderer.c
diff options
context:
space:
mode:
authoryzrh <yzrh@noema.org>2020-10-10 17:16:14 +0000
committeryzrh <yzrh@noema.org>2020-10-10 17:37:53 +0000
commitb9b74e88028f81e7b169a5e168102138e8c2c46c (patch)
tree2b8f9f8896db3a6871c56215acf71cb502fe7be4 /src/renderer.c
downloadsnake-sdl-b9b74e88028f81e7b169a5e168102138e8c2c46c.tar.gz
snake-sdl-b9b74e88028f81e7b169a5e168102138e8c2c46c.tar.zst
Initial commit.
Diffstat (limited to 'src/renderer.c')
-rw-r--r--src/renderer.c244
1 files changed, 244 insertions, 0 deletions
diff --git a/src/renderer.c b/src/renderer.c
new file mode 100644
index 0000000..c742e18
--- /dev/null
+++ b/src/renderer.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2019-2020, yzrh <yzrh@noema.org>
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdbool.h>
+
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_ttf.h>
+
+#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;
+ }
+}