aboutsummaryrefslogtreecommitdiff
path: root/src/sdl/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sdl/main.c')
-rw-r--r--src/sdl/main.c335
1 files changed, 114 insertions, 221 deletions
diff --git a/src/sdl/main.c b/src/sdl/main.c
index 831d3f7..882eefb 100644
--- a/src/sdl/main.c
+++ b/src/sdl/main.c
@@ -6,171 +6,47 @@
#include <SDL_image.h>
#include "../text/levels.h"
#include "../libsok/sok.h"
+#include "util.h"
#include "action.h"
-
-#define warn(...) do { \
- SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, __VA_ARGS__); \
-} while (0)
-
-#define die(...) do { \
- SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, __VA_ARGS__); \
- exit(EXIT_FAILURE); \
-} while (0)
-
-static void
-solve_on_error(
- const char * const err
-) {
- die("Error solving level: %s", err);
-}
+#include "warp-buf.h"
+#include "draw.h"
static void
draw_moves(
const sok_ctx_t * const ctx,
const size_t skip_moves
) {
- printf("Solution (%zu moves): ", ctx->num_moves - skip_moves);
+ char buf[1024] = { 0 };
+ size_t ofs = 0;
+
for (size_t i = skip_moves; i < ctx->num_moves; i++) {
if (ctx->moves[i].dir >= SOK_DIR_LAST) {
die("invalid move: %u", ctx->moves[i].dir);
}
- fputs(SOK_DIR_TO_STR(ctx->moves[i].dir), stdout);
- }
- printf("\n");
-}
-
-static const SDL_Color
-RED = { .r = 0x00, .g = 0xFF, .b = 0x00, .a = 0xFF },
-BLACK = { .r = 0x00, .g = 0x00, .b = 0x00, .a = 0xFF };
-
-static SDL_Color
-get_bg(
- const sok_ctx_t * const ctx
-) {
- return (sok_ctx_is_done(ctx)) ? RED : BLACK;
-}
-
-bool draw_on_wall(
- const sok_ctx_t * const ctx,
- const sok_pos_t pos,
- void * const data
-) {
- SDL_Renderer *renderer = data;
- SDL_Rect rect = { 32 * pos.x, 32 * pos.y, 32, 32 };
-
- SDL_SetRenderDrawColor(renderer, 0x66, 0x66, 0x66, 0xFF);
-
- if (SDL_RenderFillRect(renderer, &rect)) {
- die("SDL_RenderFillRect(): %s", SDL_GetError());
- }
-
- return true;
-}
-
-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
-) {
- SDL_Renderer *renderer = data;
- SDL_Rect rect = { 32 * pos.x, 32 * pos.y, 32, 32 };
-
- SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF);
-
- if (SDL_RenderFillRect(renderer, &rect)) {
- die("SDL_RenderFillRect(): %s", SDL_GetError());
- }
-
- return true;
-}
-
-bool draw_on_home(
- const sok_ctx_t * const ctx,
- const sok_pos_t pos,
- const bool has_goal,
- void * const data
-) {
- SDL_Renderer *renderer = data;
- SDL_Rect rect = { 32 * pos.x, 32 * pos.y, 32, 32 };
-
- SDL_SetRenderDrawColor(renderer, 0xFF, has_goal ? 0xFF : 0x00, 0x00, 0xFF);
-
- if (SDL_RenderFillRect(renderer, &rect)) {
- die("SDL_RenderFillRect(): %s", SDL_GetError());
- }
-
- return true;
-}
-
-bool draw_on_box(
- const sok_ctx_t * const ctx,
- const sok_pos_t pos,
- const bool has_goal,
- void * const data
-) {
- SDL_Renderer *renderer = data;
- SDL_Rect rect = { 32 * pos.x, 32 * pos.y, 32, 32 };
-
- SDL_SetRenderDrawColor(renderer, 0x00, has_goal ? 0xFF : 0x00, 0xFF, 0xFF);
-
- if (SDL_RenderFillRect(renderer, &rect)) {
- die("SDL_RenderFillRect(): %s", SDL_GetError());
+ buf[ofs++] = SOK_DIR_TO_CHAR(ctx->moves[i].dir);
}
- return true;
+ SDL_Log("Solution (%zu moves): %s", ctx->num_moves - skip_moves, buf);
}
-static sok_ctx_walk_cbs_t
-DRAW_CBS = {
- .on_wall = draw_on_wall,
- .on_goal = draw_on_goal,
- .on_home = draw_on_home,
- .on_box = draw_on_box,
-};
-/*
- * typedef struct {
- * sok_ctx_walk_pos_cb_t on_size,
- * on_wall;
- * sok_ctx_walk_tile_cb_t on_home,
- * on_box;
- * sok_ctx_walk_goal_cb_t on_goal;
- * sok_ctx_walk_move_cb_t on_move;
- * } sok_ctx_walk_cbs_t;
- *
- * _Bool sok_ctx_walk(
- * const sok_ctx_t * const,
- * const sok_ctx_walk_cbs_t * const,
- * void * const
- * );
- */
-
static void
-draw(
- SDL_Renderer * const renderer,
- const sok_ctx_t * const ctx,
- const size_t level_num,
- const level_t * const level
+solve_on_error(
+ const char * const err
) {
- // clear
- const SDL_Color c = get_bg(ctx);
- SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, c.a);
- SDL_RenderClear(renderer);
-
- sok_ctx_walk(ctx, &DRAW_CBS, renderer);
-
- // flip
- SDL_RenderPresent(renderer);
+ die("Error solving level: %s", err);
}
int main(int argc, char *argv[]) {
- size_t warp_buf = 0;
- size_t level_num = (argc > 1) ? atoi(argv[1]) : 0;
+ size_t level_num = (argc > 1) ? atoi(argv[1]) : 0,
+ zoom = 0;
const level_t *level = levels_get_level(level_num);
- // init context
+ // init warp buffer
+ warp_buf_t warp_buf;
+ warp_buf_clear(&warp_buf);
+
+ // init sok context
sok_ctx_t ctx;
sok_ctx_init(&ctx, NULL);
@@ -195,102 +71,119 @@ int main(int argc, char *argv[]) {
die("SDL_CreateWindowAndRenderer(): %s", SDL_GetError());
}
+ // init draw context
+ draw_ctx_t draw_ctx = {
+ .level_num = &level_num,
+ .level = level,
+ .ctx = &ctx,
+ .renderer = renderer,
+ .zoom = &zoom,
+ };
+
bool done = false;
SDL_Event ev;
while (!done) {
while (SDL_PollEvent(&ev)) {
- switch (ev.type) {
- case SDL_QUIT:
+ const action_t action = get_action(&ev);
+
+ switch (action.type) {
+ case ACTION_NONE:
+ // do nothing
+ break;
+ case ACTION_QUIT:
done = true;
break;
- case SDL_KEYUP:
+ case ACTION_MOVE:
+ if (!sok_ctx_move(&ctx, (sok_dir_t) action.data)) {
+ warn("move %s failed", SOK_DIR_TO_STR((sok_dir_t) action.data));
+ }
+
+ break;
+ case ACTION_UNDO:
+ if (!sok_ctx_undo(&ctx)) {
+ warn("undo failed");
+ }
+
+ break;
+ case ACTION_NEXT:
+ if (sok_ctx_is_done(&ctx)) {
+ // advance level
+ level_num++;
+ level = levels_get_level(level_num);
+ draw_ctx.level = level;
+
+ // load next level
+ if (!sok_ctx_set_level(&ctx, level->data)) {
+ die("Couldn't load level %zu", level_num);
+ }
+ } else {
+ warn("cannot advance to next level");
+ }
+
+ break;
+ case ACTION_RESET:
+ // reset level
+ if (!sok_ctx_set_level(&ctx, level->data)) {
+ die("Couldn't load level %zu", level_num);
+ }
+
+ break;
+ case ACTION_WARP:
+ if (warp_buf_get(&warp_buf, &level_num)) {
+ level = levels_get_level(level_num);
+ draw_ctx.level = level;
+
+ // load level
+ if (!sok_ctx_set_level(&ctx, level->data)) {
+ die("Couldn't load level %zu", level_num);
+ }
+
+ // clear warp buf
+ warp_buf_clear(&warp_buf);
+ }
+
+ break;
+ case ACTION_WARP_BUF_PUSH:
+ warp_buf_push_num(&warp_buf, action.data);
+
+ break;
+ case ACTION_WARP_BUF_POP:
+ warp_buf_pop_num(&warp_buf);
+
+ break;
+ case ACTION_SOLVE:
{
- const action_t action = get_action(ev.key.keysym.sym);
-
- switch (action.type) {
- case ACTION_QUIT:
- done = true;
- break;
- case ACTION_MOVE:
- if (!sok_ctx_move(&ctx, (sok_dir_t) action.data)) {
- warn("move %s failed", SOK_DIR_TO_STR((sok_dir_t) action.data));
- }
-
- break;
- case ACTION_UNDO:
- if (!sok_ctx_undo(&ctx)) {
- warn("undo failed");
- }
-
- break;
- case ACTION_NEXT:
- if (sok_ctx_is_done(&ctx)) {
- // advance level
- level_num++;
- level = levels_get_level(level_num);
-
- // load next level
- if (!sok_ctx_set_level(&ctx, level->data)) {
- die("Couldn't load level %zu", level_num);
- }
- } else {
- warn("cannot advance to next level");
- }
-
- break;
- case ACTION_RESET:
- // reset level
- if (!sok_ctx_set_level(&ctx, level->data)) {
- die("Couldn't load level %zu", level_num);
- }
-
- break;
- case ACTION_WARP:
- level_num = warp_buf;
- level = levels_get_level(level_num);
-
- // load level
- if (!sok_ctx_set_level(&ctx, level->data)) {
- die("Couldn't load level %zu", level_num);
- }
-
- warp_buf = 0;
-
- break;
- case ACTION_WARP_BUF_PUSH:
- warp_buf = 10 * warp_buf + action.data;
-
- break;
- case ACTION_WARP_BUF_POP:
- warp_buf /= 10;
-
- break;
- case ACTION_SOLVE:
- {
- // get current number of moves
- const size_t old_num_moves = ctx.num_moves;
-
- if (sok_solve(&ctx, solve_on_error)) {
- // found solution, print it
- draw_moves(&ctx, old_num_moves);
- } else {
- warn("Couldn't solve level");
- }
- }
- default:
- // ignore
- break;
+ // get current number of moves
+ const size_t old_num_moves = ctx.num_moves;
+
+ if (sok_solve(&ctx, solve_on_error)) {
+ // found solution, print it
+ draw_moves(&ctx, old_num_moves);
+ } else {
+ warn("Couldn't solve level");
}
}
break;
+ case ACTION_ZOOM_IN:
+ if (zoom < 10) {
+ zoom++;
+ }
+
+ break;
+ case ACTION_ZOOM_OUT:
+ if (zoom > 0) {
+ zoom--;
+ }
+
+ break;
default:
// ignore
break;
}
}
- draw(renderer, &ctx, level_num, level);
+ draw(&draw_ctx);
}
// fini renderer, window