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.c117
1 files changed, 72 insertions, 45 deletions
diff --git a/src/sdl/main.c b/src/sdl/main.c
index c3a9abe..8e96fa5 100644
--- a/src/sdl/main.c
+++ b/src/sdl/main.c
@@ -12,25 +12,7 @@
#include "draw.h"
#include "log-renderer-info.h"
#include "assets.h"
-
-static void
-log_moves(
- const sok_ctx_t * const ctx,
- const size_t 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);
- }
-
- buf[ofs++] = SOK_DIR_TO_CHAR(ctx->moves[i].dir);
- }
-
- SDL_Log("Solution (%d moves): %s", (int) (ctx->num_moves - skip_moves), buf);
-}
+#include "solve.h"
static TTF_Font *
load_font(
@@ -59,20 +41,6 @@ load_font(
}
static void
-solve_on_error(
- const char * const err,
- void *user_data
-) {
- UNUSED(user_data);
- die("Error solving level: %s", err);
-}
-
-static const sok_solve_cbs_t
-SOLVE_CBS = {
- .on_error = solve_on_error,
-};
-
-static void
set_level(
draw_ctx_t * const draw_ctx,
sok_ctx_t * const ctx,
@@ -95,6 +63,41 @@ set_level(
);
}
+static void
+log_moves(
+ const sok_ctx_t * const ctx
+) {
+ char buf[1024] = { 0 };
+ size_t ofs = 0;
+
+ for (size_t i = 0; i < ctx->num_moves; i++) {
+ if (ctx->moves[i].dir >= SOK_DIR_LAST) {
+ die("invalid move: %u", ctx->moves[i].dir);
+ }
+
+ buf[ofs++] = SOK_DIR_TO_CHAR(ctx->moves[i].dir);
+ }
+
+ SDL_Log("Solution (%d moves): %s", (int) ctx->num_moves, buf);
+}
+
+static void
+solve_on_done(
+ const bool result,
+ const sok_ctx_t * const solved_ctx,
+ const size_t num_steps,
+ void *user_data
+) {
+ if (result) {
+ // copy context
+ sok_ctx_t *ctx = user_data;
+ *ctx = *solved_ctx;
+
+ // log moves
+ log_moves(ctx);
+ }
+}
+
int main(int argc, char *argv[]) {
size_t level_num = (argc > 1) ? atoi(argv[1]) : 0,
zoom = 0;
@@ -154,6 +157,7 @@ int main(int argc, char *argv[]) {
// init draw context
draw_ctx_t draw_ctx = {
+ .state = GAME_STATE_PLAY,
.level_num = &level_num,
.ctx = &ctx,
.renderer = renderer,
@@ -168,6 +172,12 @@ int main(int argc, char *argv[]) {
sprites_init(renderer, draw_ctx.sprites);
draw_ctx.font = load_font(ASSET_ROBOTO_TTF);
+ // register solve event
+ const Uint32 solve_event_type = SDL_RegisterEvents(1);
+ if (solve_event_type == ((Uint32)-1)) {
+ die("SDL_RegisterEvents(): %s", SDL_GetError());
+ }
+
bool is_fullscreen = false;
bool done = false;
while (!done) {
@@ -176,7 +186,7 @@ int main(int argc, char *argv[]) {
// read events
while (SDL_PollEvent(&ev)) {
// get action
- const action_t action = get_action(&ev);
+ const action_t action = get_action(draw_ctx.state, &ev, solve_event_type);
// handle action
switch (action.type) {
@@ -236,17 +246,9 @@ int main(int argc, char *argv[]) {
break;
case ACTION_SOLVE:
- {
- // get current number of moves
- const size_t old_num_moves = ctx.num_moves;
-
- if (sok_solve(&ctx, &SOLVE_CBS, NULL)) {
- // found solution, print it
- log_moves(&ctx, old_num_moves);
- } else {
- warn("Couldn't solve level");
- }
- }
+ draw_ctx.state = GAME_STATE_SOLVE;
+ draw_ctx.solve_num_steps = 0;
+ draw_ctx.solve = solve(&ctx, solve_event_type);
break;
case ACTION_ZOOM_IN:
@@ -270,6 +272,31 @@ int main(int argc, char *argv[]) {
is_fullscreen = !is_fullscreen;
break;
+ case ACTION_SOLVE_CANCEL:
+ SDL_Log("solve cancelled by user");
+ draw_ctx.state = GAME_STATE_PLAY;
+ solve_cancel(draw_ctx.solve);
+
+ break;
+ case ACTION_SOLVE_EVENT_STEP:
+ draw_ctx.solve_num_steps = action.data;
+
+ break;
+ case ACTION_SOLVE_EVENT_DONE:
+ SDL_Log("solve done");
+ draw_ctx.state = GAME_STATE_PLAY;
+ // TODO: handle success
+ solve_fini(draw_ctx.solve, solve_on_done, &ctx);
+ draw_ctx.solve = NULL;
+
+ break;
+ case ACTION_SOLVE_EVENT_FAIL:
+ SDL_Log("solve fail");
+ draw_ctx.state = GAME_STATE_PLAY;
+ solve_fini(draw_ctx.solve, NULL, NULL);
+ draw_ctx.solve = NULL;
+
+ break;
default:
// ignore
break;