aboutsummaryrefslogtreecommitdiff
path: root/src/sdl/draw.c
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2019-01-13 08:29:12 -0500
committerPaul Duncan <pabs@pablotron.org>2019-01-13 08:29:12 -0500
commitcd0f70f86d1cedffcd1bacf57d9250fdff1f7af3 (patch)
treea7be11a817a89e47700691f5042ba005e756bc4a /src/sdl/draw.c
parenta3f788b6a64bbf89342fec2111eb1e1b478db13f (diff)
downloadsok-cd0f70f86d1cedffcd1bacf57d9250fdff1f7af3.tar.bz2
sok-cd0f70f86d1cedffcd1bacf57d9250fdff1f7af3.zip
refactor sok-sdl, add zoom and warp_buf support
Diffstat (limited to 'src/sdl/draw.c')
-rw-r--r--src/sdl/draw.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/src/sdl/draw.c b/src/sdl/draw.c
new file mode 100644
index 0000000..f6e350b
--- /dev/null
+++ b/src/sdl/draw.c
@@ -0,0 +1,169 @@
+#include <stdbool.h> // bool
+#include "util.h" // warn()/die()
+#include "color.h" // set_color()
+#include "draw.h"
+
+static size_t
+get_cell_size(
+ const draw_ctx_t * const draw_ctx
+) {
+ return 32 + 8 * *draw_ctx->zoom;
+}
+
+static SDL_Rect
+get_cell_rect(
+ const draw_ctx_t * const draw_ctx,
+ const sok_pos_t pos
+) {
+ const size_t cell_size = get_cell_size(draw_ctx);
+
+ return (SDL_Rect) {
+ draw_ctx->render_ofs.x + pos.x * cell_size,
+ draw_ctx->render_ofs.y + pos.y * cell_size,
+ cell_size,
+ cell_size
+ };
+}
+
+static bool
+draw_on_size(
+ const sok_ctx_t * const ctx,
+ const sok_pos_t level_size,
+ void * const data
+) {
+ draw_ctx_t * const draw_ctx = data;
+ const size_t cell_size = get_cell_size(draw_ctx);
+
+ // get renderer size
+ int renderer_x, renderer_y;
+ if (SDL_GetRendererOutputSize(draw_ctx->renderer, &renderer_x, &renderer_y)) {
+ die("SDL_GetRendererOutputSize(): %s", SDL_GetError());
+ }
+
+ // calculate renderer offset
+ draw_ctx->render_ofs.x = (renderer_x - level_size.x * cell_size) / 2;
+ draw_ctx->render_ofs.y = (renderer_y - level_size.y * cell_size) / 2;
+
+ return true;
+}
+
+static bool
+draw_on_walls_start(
+ const sok_ctx_t * const ctx,
+ void * const data
+) {
+ draw_ctx_t * const draw_ctx = data;
+ set_color(draw_ctx->renderer, COLOR_WALL);
+
+ return true;
+}
+
+static bool
+draw_on_wall(
+ const sok_ctx_t * const ctx,
+ const sok_pos_t pos,
+ void * const data
+) {
+ draw_ctx_t * const draw_ctx = data;
+ const SDL_Rect rect = get_cell_rect(draw_ctx, pos);
+
+ if (SDL_RenderFillRect(draw_ctx->renderer, &rect)) {
+ die("SDL_RenderFillRect(): %s", SDL_GetError());
+ }
+
+ return true;
+}
+
+static bool
+draw_on_goals_start(
+ const sok_ctx_t * const ctx,
+ void * const data
+) {
+ draw_ctx_t * const draw_ctx = data;
+ set_color(draw_ctx->renderer, COLOR_GOAL);
+
+ return true;
+}
+
+static bool
+draw_on_goal(
+ const sok_ctx_t * const ctx,
+ const sok_pos_t pos,
+ const bool has_player,
+ const bool has_box,
+ void * const data
+) {
+ draw_ctx_t * const draw_ctx = data;
+ const SDL_Rect rect = get_cell_rect(draw_ctx, pos);
+
+ if (SDL_RenderFillRect(draw_ctx->renderer, &rect)) {
+ die("SDL_RenderFillRect(): %s", SDL_GetError());
+ }
+
+ return true;
+}
+
+static bool
+draw_on_home(
+ const sok_ctx_t * const ctx,
+ const sok_pos_t pos,
+ const bool has_goal,
+ void * const data
+) {
+ draw_ctx_t * const draw_ctx = data;
+ const SDL_Rect rect = get_cell_rect(draw_ctx, pos);
+
+ set_color(draw_ctx->renderer, has_goal ? COLOR_HOME_GOAL : COLOR_HOME);
+
+ if (SDL_RenderFillRect(draw_ctx->renderer, &rect)) {
+ die("SDL_RenderFillRect(): %s", SDL_GetError());
+ }
+
+ return true;
+}
+
+static bool
+draw_on_box(
+ const sok_ctx_t * const ctx,
+ const sok_pos_t pos,
+ const bool has_goal,
+ void * const data
+) {
+ draw_ctx_t * const draw_ctx = data;
+ const SDL_Rect rect = get_cell_rect(draw_ctx, pos);
+
+ set_color(draw_ctx->renderer, has_goal ? COLOR_BOX_GOAL : COLOR_BOX);
+
+ if (SDL_RenderFillRect(draw_ctx->renderer, &rect)) {
+ die("SDL_RenderFillRect(): %s", SDL_GetError());
+ }
+
+ return true;
+}
+
+static const sok_ctx_walk_cbs_t
+DRAW_CBS = {
+ .on_size = draw_on_size,
+ .on_walls_start = draw_on_walls_start,
+ .on_wall = draw_on_wall,
+ .on_goals_start = draw_on_goals_start,
+ .on_goal = draw_on_goal,
+ .on_home = draw_on_home,
+ .on_box = draw_on_box,
+};
+
+void
+draw(
+ draw_ctx_t * const draw_ctx
+) {
+ // clear background
+ set_color(draw_ctx->renderer, sok_ctx_is_done(draw_ctx->ctx) ? COLOR_BG_WON : COLOR_BG);
+ SDL_RenderClear(draw_ctx->renderer);
+
+ // render
+ sok_ctx_walk(draw_ctx->ctx, &DRAW_CBS, draw_ctx);
+
+ // flip
+ SDL_RenderPresent(draw_ctx->renderer);
+}
+