/*
* Copyright (c) 2019-2021, 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;
}
}