diff options
author | Paul Duncan <pabs@pablotron.org> | 2019-01-13 08:29:12 -0500 |
---|---|---|
committer | Paul Duncan <pabs@pablotron.org> | 2019-01-13 08:29:12 -0500 |
commit | cd0f70f86d1cedffcd1bacf57d9250fdff1f7af3 (patch) | |
tree | a7be11a817a89e47700691f5042ba005e756bc4a /src/sdl/draw.c | |
parent | a3f788b6a64bbf89342fec2111eb1e1b478db13f (diff) | |
download | sok-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.c | 169 |
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); +} + |