diff options
author | Paul Duncan <pabs@pablotron.org> | 2019-01-08 21:44:04 -0500 |
---|---|---|
committer | Paul Duncan <pabs@pablotron.org> | 2019-01-08 21:44:04 -0500 |
commit | 13717391b4469072c0cb8041666f0d50ae9996fd (patch) | |
tree | e38fb3ec96227bd91d0f0b425d2cc9a009851abe /src/text/draw.c | |
parent | 3f95b53036f456c2cff9ebc4fc6f26c36a1740eb (diff) | |
download | sok-13717391b4469072c0cb8041666f0d50ae9996fd.tar.bz2 sok-13717391b4469072c0cb8041666f0d50ae9996fd.zip |
add draw.[hc] and util.h
Diffstat (limited to 'src/text/draw.c')
-rw-r--r-- | src/text/draw.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/text/draw.c b/src/text/draw.c new file mode 100644 index 0000000..e6584bb --- /dev/null +++ b/src/text/draw.c @@ -0,0 +1,110 @@ +#include <stdbool.h> // bool +#include <string.h> // atoi() +#include <stdlib.h> // EXIT_{FAILURE,SUCCESS} +#include <stdio.h> +#include "../libsok/sok.h" +#include "util.h" +#include "draw.h" + +static char print_buf[(SOK_LEVEL_MAX_WIDTH + 1) * SOK_LEVEL_MAX_HEIGHT + 1]; + +static bool +draw_on_size( + const sok_ctx_t * const ctx, + const sok_pos_t size, + void * const data +) { + UNUSED(ctx); + UNUSED(data); + + // fprintf(stderr, "size: x = %u, y = %u\n", size.x, size.y); + + memset(print_buf, ' ', sizeof(print_buf)); + print_buf[(size.x + 1) * size.y + 1] = '\0'; + for (size_t i = 0; i < size.y; i++) { + print_buf[(i + 1) * (size.x + 1) - 1] = '\n'; + } + + 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 +) { + UNUSED(data); + print_buf[pos.y * (ctx->level.size.x + 1) + pos.x] = has_goal ? '+' : '@'; + return true; +} + +static bool +draw_on_wall( + const sok_ctx_t * const ctx, + const sok_pos_t pos, + void * const data +) { + // fprintf(stderr, "wall: x = %u, y = %u\n", pos.x, pos.y); + UNUSED(data); + print_buf[pos.y * (ctx->level.size.x + 1) + pos.x] = '#'; + 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 +) { + UNUSED(data); + const char c = has_player ? '+' : (has_box ? '*' : '.'); + print_buf[pos.y * (ctx->level.size.x + 1) + pos.x] = c; + 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 +) { + UNUSED(data); + print_buf[pos.y * (ctx->level.size.x + 1) + pos.x] = has_goal ? '*' : '$'; + return true; +} + +static sok_ctx_walk_cbs_t +DRAW_CBS = { + .on_size = draw_on_size, + .on_home = draw_on_home, + .on_wall = draw_on_wall, + .on_goal = draw_on_goal, + .on_box = draw_on_box, +}; + +void +draw( + const sok_ctx_t * const ctx, + const size_t level_num, + const level_t * const level +) { + // fill print buffer + if (!sok_ctx_walk(ctx, &DRAW_CBS, NULL)) { + die("Couldn't print level"); + } + + // print title, level, and console + printf( + "%s: %s (#%zu)\n" // set name, level name, and level number + "%s\n" // level + "%zu%s> ", // console + level->pack, level->name, level_num, + print_buf, + ctx->num_moves, sok_ctx_is_done(ctx) ? " (won!)" : "" + ); +} |