From 5278747bc6615197749a4e882283c9d06901cd80 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Mon, 2 Jan 2023 17:15:27 -0500 Subject: [PATCH] motif: Combine status details into a single flags member. The timer_tick, view_goal_on_game and use_ewmh_icons values all are used to encode just a single bit of information. We can combine them into a single member to reduce the overall size of the state structure. Dropping the timer ID further enables a slight reorganization of the timer process which seems to reduce the overall code size somewhat. --- src/motif.c | 27 ++++++++++++++------------- src/motif.h | 19 +++++++++++-------- src/version.c | 20 +++++++++++++++++++- src/version.h | 18 ++++++++++++++++++ src/x11.c | 6 +++--- 5 files changed, 65 insertions(+), 25 deletions(-) diff --git a/src/motif.c b/src/motif.c index fbdc9a7..66e31df 100644 --- a/src/motif.c +++ b/src/motif.c @@ -1,6 +1,6 @@ /* * X11 GUI 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 @@ -143,14 +143,13 @@ static void timer_tick(void *data, XtIntervalId *id) if (state->board.x > 4) { /* Game is over */ - state->timer_tick = 0; + state->flags &= ~FLAG_TIMER_RUNNING; return; } - app = XtWidgetToApplicationContext(state->game); ui_timer_update(state, game_elapsed(&state->board)); - state->timer_tick = XtAppAddTimeOut(app, TIMER_UPDATE_MS, - timer_tick, state); + app = XtWidgetToApplicationContext(state->game); + XtAppAddTimeOut(app, TIMER_UPDATE_MS, timer_tick, state); } static void do_input_move(struct app_state *state, int x, int y) @@ -178,7 +177,9 @@ static void do_input_move(struct app_state *state, int x, int y) static void set_view_goal(struct app_state *state, int view_goal) { - state->view_goal_on_game = !!view_goal; + state->flags &= ~FLAG_VIEW_GOAL_ON_GAME; + state->flags |= view_goal ? FLAG_VIEW_GOAL_ON_GAME : 0; + x11_redraw_game(state, game_check_goal(&state->board)); } @@ -231,18 +232,18 @@ static void proc_exit(Widget w, XEvent *e, String *argv, Cardinal *argc) static void proc_new_game(Widget w, XEvent *e, String *argv, Cardinal *argc) { + XtAppContext app; + game_reset(&state.board); x11_redraw_goal(&state, -1, get_shell(w)); x11_redraw_game(&state, -1); - if (!state.timer_tick) { - XtAppContext app = XtWidgetToApplicationContext(w); - state.timer_tick = XtAppAddTimeOut(app, TIMER_UPDATE_MS, - timer_tick, &state); - } - game_begin(&state.board); + if (!(state.flags & FLAG_TIMER_RUNNING)) { + state.flags |= FLAG_TIMER_RUNNING; + timer_tick(&state, 0); + } } static void proc_about(Widget w, XEvent *e, String *argv, Cardinal *argc) @@ -312,7 +313,7 @@ static XtAppContext app_initialize(int argc, char **argv) state.board.game[i] = state.board.goal[i] << GOAL_SHIFT; game_finish(&state.board); - state.use_ewmh_icons = ewmh_probe_wm_icon(shell); + state.flags = ewmh_probe_wm_icon(shell); XtRealizeWidget(shell); x11_redraw_goal(&state, 0, shell); diff --git a/src/motif.h b/src/motif.h index b168c4e..922f5c1 100644 --- a/src/motif.h +++ b/src/motif.h @@ -1,6 +1,6 @@ /* * X11 GUI 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 @@ -23,25 +23,28 @@ #include "colour.h" #include "game.h" +/* If set, _NET_WM_ICON property will be added/updated to toplevel window. */ +#define FLAG_USE_EWMH_ICONS 1u + +/* If set, the goal will be displayed over the main play area. */ +#define FLAG_VIEW_GOAL_ON_GAME 2u + +/* If set, the Xt timer update process is currently installed. */ +#define FLAG_TIMER_RUNNING 4u + struct app_state { struct board board; Widget game, goal; struct xcounter *timer; - XtIntervalId timer_tick; Pixmap icon_pixmap; GC tile_gc; uint_least32_t render_game_mask; uint_least16_t render_goal_mask; uint_least16_t game_tile_sz, goal_tile_sz; - - /* If true, the goal will be displayed over the main play area. */ - uint_least8_t view_goal_on_game; - - /* Whether to set _NET_WM_ICON property on WMShell */ - uint_least8_t use_ewmh_icons; + uint_least16_t flags; uint_least32_t tile_colour[TILE_MAX-1][3]; }; diff --git a/src/version.c b/src/version.c index 6a5ce9a..de174b5 100644 --- a/src/version.c +++ b/src/version.c @@ -1,3 +1,21 @@ +/* + * Version string boilerplate for slide puzzle game. + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include #include #include @@ -19,7 +37,7 @@ const char *init_copysign(char **alloc) return "(C)"; } -#define VERSION_HEAD_FMT "%s (RRace) %s\nCopyright %s 2022 Nick Bowler" +#define VERSION_HEAD_FMT "%s (RRace) %s\nCopyright %s 2023 Nick Bowler" #define VERSION_HEAD_ARGS progname, PACKAGE_VERSION, copysign void version_print_head(const char *progname, FILE *f) diff --git a/src/version.h b/src/version.h index 5c3850f..b8d4f78 100644 --- a/src/version.h +++ b/src/version.h @@ -1,3 +1,21 @@ +/* + * Version string boilerplate for slide puzzle game. + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #ifndef RRACE_VERSION_H_ #define RRACE_VERSION_H_ diff --git a/src/x11.c b/src/x11.c index 459694a..44bb867 100644 --- a/src/x11.c +++ b/src/x11.c @@ -1,6 +1,6 @@ /* * X11 GUI 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 @@ -214,7 +214,7 @@ static void set_icon(struct app_state *state, Display *display, XtVaSetValues(shell, XtNiconPixmap, None, (char *)NULL); XtVaSetValues(shell, XtNiconPixmap, state->icon_pixmap, (char *)NULL); - if (state->use_ewmh_icons) { + if (state->flags & FLAG_USE_EWMH_ICONS) { Atom net_wm_icon = XInternAtom(display, "_NET_WM_ICON", FALSE); Colormap cmap = DefaultColormapOfScreen(XtScreen(shell)); XColor colours[(TILE_MAX-1)*COLOUR_MAX]; @@ -285,7 +285,7 @@ void x11_redraw_game(struct app_state *state, uint_fast32_t mask) unsigned sz = state->game_tile_sz; int i; - if (state->view_goal_on_game) { + if (state->flags & FLAG_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); -- 2.43.2