/*
* Curses UI for slide puzzle game
- * Copyright © 2022 Nick Bowler
+ * Copyright © 2022-2023 Nick Bowler
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include <curses.h>
#include "help.h"
+#include "xtra.h"
#include "version.h"
#include "cursesui.h"
};
static const char *progname = "rrace";
-static const struct option lopts[] = { LOPTS_INITIALIZER, {0} };
static struct app_state state;
fprintf(f, "Try %s --help for more information.\n", progname);
}
-static void print_help(void)
+static void print_help(const struct option *lopts)
{
struct lopt_help help = {0};
const struct option *opt;
static int
redraw_tile(WINDOW **win, unsigned x, unsigned y, unsigned start_column,
- uint_fast32_t bit0, uint_fast32_t bit1, uint_fast32_t bit2,
- unsigned selected)
+ uint_least32_t *gp, unsigned selected)
{
- uint_fast32_t pos = board_position(x, y);
- unsigned char tile = 0;
+ unsigned tile = board_tile(gp, 5*y+x);
- if (bit0 & pos) tile |= 1;
- if (bit1 & pos) tile |= 2;
- if (bit2 & pos) tile |= 4;
assert(tile < TILE_MAX);
-
draw_tile(win, tile, selected, x, y, start_column);
return tile;
}
if (mask == -1)
redraw_area_border(state->gamewin, 2, 5);
- if (state->view_goal_on_game) {
- for (i = 0; i < 3; i++) {
- buf[i] = state->board.goal[i];
- buf[i] = (gp[i] & ~GOAL_MASK) | (buf[i] << GOAL_SHIFT);
- }
- gp = buf;
- }
+ if (state->view_goal_on_game)
+ gp = game_overlay_goal(&state->board, buf);
for (i = 0; i < 25; i++) {
if (mask & 1) {
redraw_tile(state->gamewin, i%5, i/5,
- 4, gp[0], gp[1], gp[2],
- i == state->cursor);
+ 4, gp, i == state->cursor);
}
mask >>= 1;
}
static void curs_redraw_goal(struct app_state *state, uint_fast32_t mask)
{
- uint_least16_t *gp = state->board.goal;
+ uint_least32_t gp[3] = {
+ state->board.goal[0],
+ state->board.goal[1],
+ state->board.goal[2]
+ };
int i, x, y;
if (!state->goalwin[PLAYWIN_AREA])
for (i = 0; i < 9; i++) {
if (mask & 1) {
- redraw_tile(state->goalwin, i%3, i/3,
- x+2, gp[0], gp[1], gp[2], 0);
+ redraw_tile(state->goalwin, i%3, i/3, x+2, gp, 0);
}
mask >>= 1;
}
}
+/* Thin wrapper around wresize which returns ERR if support is unavailable. */
+static int do_wresize(WINDOW *window, int h, int w)
+{
+#if HAVE_CURSES_WRESIZE
+ return wresize(window, h, w);
+#endif
+ return ERR;
+}
+
static WINDOW *realloc_area(WINDOW **orig, int h, int w, int y, int x)
{
WINDOW *win = *orig;
if (win) {
-#if HAVE_CURSES_WRESIZE
- if (wresize(win, h, w) != ERR) {
+ if (do_wresize(win, h, w) != ERR) {
mvwin(win, y, x);
return win;
}
-#endif
+
delwin(win);
}
if (fill && border) {
int old_w, old_h;
-#if HAVE_CURSES_WRESIZE
- if (wresize(fill, h-2, w-2) != ERR
- && wresize(border, h, w) != ERR)
- {
+ if (do_wresize(fill, h-2, w-2) != ERR
+ && do_wresize(border, h, w) != ERR)
return;
- }
-#endif
getmaxyx(border, old_h, old_w);
if (old_h == h)
int enable_mouse = 1;
int opt;
+ XTRA_PACKED_LOPTS(lopts);
+
if (argc > 0)
progname = argv[0];
print_version();
exit(EXIT_SUCCESS);
case LOPT_HELP:
- print_help();
+ print_help(lopts);
exit(EXIT_SUCCESS);
default:
print_usage(stderr);
game_reset(&state->board);
do_reset_cursor(state);
+ state->view_goal_on_game = 0;
curs_redraw_game(state, -1);
curs_redraw_goal(state, -1);
update_timer(state, 0);