From 6e5f287606a3039ee26eb4fc8c8f7a05deebe9f0 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Sun, 1 Jan 2017 14:57:30 -0500 Subject: Fixes and re-sync for puzzles - Updates to latest upstream (7cae89fb4b22c305b3fd98b4e1be065ad527a9f7). - Also fixes a bug relating to updating parts of the display. - Adds some docs. Change-Id: Idfcce66e0cf3c59e467bab42eafc161df2e495bb --- apps/plugins/puzzles/README.rockbox | 21 ++++++++++ apps/plugins/puzzles/cube.c | 1 - apps/plugins/puzzles/gtk.c | 35 ++++++++++++++-- apps/plugins/puzzles/pearl.c | 2 - apps/plugins/puzzles/puzzles.make | 1 + apps/plugins/puzzles/rockbox.c | 80 +++++++++++++++++++++++++++---------- apps/plugins/puzzles/signpost.c | 2 +- apps/plugins/puzzles/tracks.c | 2 +- apps/plugins/puzzles/unequal.c | 2 +- 9 files changed, 115 insertions(+), 31 deletions(-) create mode 100644 apps/plugins/puzzles/README.rockbox diff --git a/apps/plugins/puzzles/README.rockbox b/apps/plugins/puzzles/README.rockbox new file mode 100644 index 0000000000..e11025dbec --- /dev/null +++ b/apps/plugins/puzzles/README.rockbox @@ -0,0 +1,21 @@ +This is the readme for the Rockbox port of Simon Tatham's Portable +Puzzle Collection. + +Upstream version used is 7cae89fb4b22c305b3fd98b4e1be065ad527a9f7 from +December 2016. It should be relatively trivial to update it to a newer +version, and should probably be done periodically as changes are made. + +Most of the upstream files are essentially untouched, apart from some +minor adjustments to make it compile happily on Rockbox. Some games +still don't work due to issues with their cursor-only control scheme +(untangle being the big culprit here) but the ones that don't are +commented out in SOURCES.games. I'll get around to fixing them +eventually. + +Building is done rather hackily, with a rule for every puzzle to be +built... almost 40 at the time of writing. Mr. Someone ought to figure +out how to do that with a wildcard or something. + +Kudos to Simon (duh), and Frank, for telling me about it. + +Franklin Wei (__builtin) diff --git a/apps/plugins/puzzles/cube.c b/apps/plugins/puzzles/cube.c index 5a09648226..d0d9525130 100644 --- a/apps/plugins/puzzles/cube.c +++ b/apps/plugins/puzzles/cube.c @@ -361,7 +361,6 @@ static void enum_grid_squares(const game_params *params, egc_callback callback, } else { int row, rowlen, other, i, firstix = -1; float theight = (float)(sqrt(3) / 2.0); - //float theight = 0.8660254037844386467; for (row = 0; row < params->d1 + params->d2; row++) { if (row < params->d2) { diff --git a/apps/plugins/puzzles/gtk.c b/apps/plugins/puzzles/gtk.c index aa3ba06eed..e132c3db58 100644 --- a/apps/plugins/puzzles/gtk.c +++ b/apps/plugins/puzzles/gtk.c @@ -1935,6 +1935,24 @@ static gint configure_window(GtkWidget *widget, return FALSE; } +#if GTK_CHECK_VERSION(3,0,0) +static int window_extra_height(frontend *fe) +{ + int ret = 0; + if (fe->menubar) { + GtkRequisition req; + gtk_widget_get_preferred_size(fe->menubar, &req, NULL); + ret += req.height; + } + if (fe->statusbar) { + GtkRequisition req; + gtk_widget_get_preferred_size(fe->statusbar, &req, NULL); + ret += req.height; + } + return ret; +} +#endif + static void resize_fe(frontend *fe) { int x, y; @@ -1942,7 +1960,7 @@ static void resize_fe(frontend *fe) get_size(fe, &x, &y); #if GTK_CHECK_VERSION(3,0,0) - gtk_window_resize_to_geometry(GTK_WINDOW(fe->window), x, y); + gtk_window_resize(GTK_WINDOW(fe->window), x, y + window_extra_height(fe)); #else fe->drawing_area_shrink_pending = FALSE; gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y); @@ -1970,6 +1988,7 @@ static void menu_preset_event(GtkMenuItem *menuitem, gpointer data) midend_new_game(fe->me); changed_preset(fe); resize_fe(fe); + midend_redraw(fe->me); } GdkAtom compound_text_atom, utf8_string_atom; @@ -2213,6 +2232,7 @@ static void menu_load_event(GtkMenuItem *menuitem, gpointer data) changed_preset(fe); resize_fe(fe); + midend_redraw(fe->me); } } @@ -2250,6 +2270,7 @@ static void menu_config_event(GtkMenuItem *menuitem, gpointer data) midend_new_game(fe->me); resize_fe(fe); + midend_redraw(fe->me); } static void menu_about_event(GtkMenuItem *menuitem, gpointer data) @@ -2648,15 +2669,23 @@ static frontend *new_window(char *arg, int argtype, char **error) #endif { GdkGeometry geom; - geom.base_width = geom.base_height = 0; + geom.base_width = 0; +#if GTK_CHECK_VERSION(3,0,0) + geom.base_height = window_extra_height(fe); + gtk_window_set_geometry_hints(GTK_WINDOW(fe->window), NULL, + &geom, GDK_HINT_BASE_SIZE); +#else + geom.base_height = 0; gtk_window_set_geometry_hints(GTK_WINDOW(fe->window), fe->area, &geom, GDK_HINT_BASE_SIZE); +#endif } fe->w = -1; fe->h = -1; get_size(fe, &x, &y); #if GTK_CHECK_VERSION(3,0,0) - gtk_window_set_default_geometry(GTK_WINDOW(fe->window), x, y); + gtk_window_set_default_size(GTK_WINDOW(fe->window), + x, y + window_extra_height(fe)); #else fe->drawing_area_shrink_pending = FALSE; gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y); diff --git a/apps/plugins/puzzles/pearl.c b/apps/plugins/puzzles/pearl.c index 59effeda40..1f41f65af2 100644 --- a/apps/plugins/puzzles/pearl.c +++ b/apps/plugins/puzzles/pearl.c @@ -1610,8 +1610,6 @@ static void check_completion(game_state *state, int mark) */ for (i = 0; i < w*h; i++) { int comp = dsf_canonify(dsf, i); - if (component_state[comp] == COMP_PATH) - comp = -1; /* part of the 'all paths' quasi-component */ if ((component_state[comp] == COMP_PATH && -1 != largest_comp) || (component_state[comp] == COMP_LOOP && diff --git a/apps/plugins/puzzles/puzzles.make b/apps/plugins/puzzles/puzzles.make index 054e53eeb1..4e1f3a1001 100644 --- a/apps/plugins/puzzles/puzzles.make +++ b/apps/plugins/puzzles/puzzles.make @@ -42,6 +42,7 @@ PUZZLES_ROCKS := $(addprefix $(PUZZLES_OBJDIR)/sgt-, $(notdir $(PUZZLES_GAMES_SR ROCKS += $(PUZZLES_ROCKS) endif +# Hack to suppress all warnings: PUZZLESFLAGS = $(filter-out -O%,$(PLUGINFLAGS)) -Os \ -Wno-unused-parameter -Wno-sign-compare -Wno-strict-aliasing -w \ -DFOR_REAL diff --git a/apps/plugins/puzzles/rockbox.c b/apps/plugins/puzzles/rockbox.c index 3a1c00e615..aac2781c5d 100644 --- a/apps/plugins/puzzles/rockbox.c +++ b/apps/plugins/puzzles/rockbox.c @@ -7,7 +7,7 @@ * \/ \/ \/ \/ \/ * $Id$ * - * Copyright (C) 2016 Franklin Wei + * Copyright (C) 2017 Franklin Wei * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -62,36 +62,34 @@ static long last_keystate = 0; static void fix_size(void); -static void rb_start_draw(void *handle) -{ - (void) handle; -} - static struct viewport clip_rect; static bool clipped = false; static struct settings_t { int slowmo_factor; - bool bulk, timerflash; + bool bulk, timerflash, clipoff; } settings; /* clipping is implemented through viewports and offsetting * coordinates */ static void rb_clip(void *handle, int x, int y, int w, int h) { - LOGF("rb_clip(%d %d %d %d)", x, y, w, h); - clip_rect.x = x; - clip_rect.y = y; - clip_rect.width = w; - clip_rect.height = h; - clip_rect.font = FONT_UI; - clip_rect.drawmode = DRMODE_SOLID; + if(!settings.clipoff) + { + LOGF("rb_clip(%d %d %d %d)", x, y, w, h); + clip_rect.x = x; + clip_rect.y = y; + clip_rect.width = w; + clip_rect.height = h; + clip_rect.font = FONT_UI; + clip_rect.drawmode = DRMODE_SOLID; #if LCD_DEPTH > 1 - clip_rect.fg_pattern = LCD_DEFAULT_FG; - clip_rect.bg_pattern = LCD_DEFAULT_BG; + clip_rect.fg_pattern = LCD_DEFAULT_FG; + clip_rect.bg_pattern = LCD_DEFAULT_BG; #endif - rb->lcd_set_viewport(&clip_rect); - clipped = true; + rb->lcd_set_viewport(&clip_rect); + clipped = true; + } } static void rb_unclip(void *handle) @@ -407,6 +405,7 @@ static void rb_blitter_free(void *handle, blitter *bl) return; } +/* originally from emcc.c */ static void trim_rect(int *x, int *y, int *w, int *h) { int x0, x1, y0, y1; @@ -476,18 +475,51 @@ static void rb_blitter_load(void *handle, blitter *bl, int x, int y) rb->lcd_bitmap((fb_data*)bl->bmp.data, x, y, w, h); } +static bool need_draw_update = false; + +static int ud_l = 0, ud_u = 0, ud_r = LCD_WIDTH, ud_d = LCD_HEIGHT; + static void rb_draw_update(void *handle, int x, int y, int w, int h) { LOGF("rb_draw_update(%d, %d, %d, %d)", x, y, w, h); - if(!settings.bulk) - rb->lcd_update_rect(x, y, w, h); - else - rb->lcd_update(); + + /* It seems that the puzzles use a different definition of + * "updating" the display than Rockbox does; by calling this + * function, it tells us that it has either already drawn to the + * updated area (as rockbox assumes), or that it WILL draw to the + * said area. Thus we simply remember a rectangle that contains + * all the updated regions and update it at the very end. */ + + /* adapted from gtk.c */ + if (!need_draw_update || ud_l > x ) ud_l = x; + if (!need_draw_update || ud_r < x+w) ud_r = x+w; + if (!need_draw_update || ud_u > y ) ud_u = y; + if (!need_draw_update || ud_d < y+h) ud_d = y+h; + + need_draw_update = true; +} + +static void rb_start_draw(void *handle) +{ + (void) handle; + + /* ... mumble mumble ... not ... reentrant ... mumble mumble ... */ + + need_draw_update = false; + ud_l = 0; + ud_r = LCD_WIDTH; + ud_u = 0; + ud_d = LCD_HEIGHT; } static void rb_end_draw(void *handle) { + (void) handle; + LOGF("rb_end_draw"); + + if(need_draw_update) + rb->lcd_update_rect(ud_l, ud_u, ud_r - ud_l, ud_d - ud_u); } static char *titlebar = NULL; @@ -893,6 +925,7 @@ static void debug_menu(void) "Randomize colors", "Toggle bulk update", "Toggle flash pixel on timer", + "Toggle clip", "Back"); bool quit = false; int sel = 0; @@ -920,6 +953,9 @@ static void debug_menu(void) settings.timerflash = !settings.timerflash; break; case 4: + settings.clipoff = !settings.clipoff; + break; + case 5: default: quit = true; break; diff --git a/apps/plugins/puzzles/signpost.c b/apps/plugins/puzzles/signpost.c index a2e431e746..ce27da1a9d 100644 --- a/apps/plugins/puzzles/signpost.c +++ b/apps/plugins/puzzles/signpost.c @@ -284,7 +284,7 @@ static int check_nums(game_state *orig, game_state *copy, int only_immutable) int i, ret = 1; assert(copy->n == orig->n); for (i = 0; i < copy->n; i++) { - if (only_immutable && !copy->flags[i] & FLAG_IMMUTABLE) continue; + if (only_immutable && !(copy->flags[i] & FLAG_IMMUTABLE)) continue; assert(copy->nums[i] >= 0); assert(copy->nums[i] <= copy->n); if (copy->nums[i] != orig->nums[i]) { diff --git a/apps/plugins/puzzles/tracks.c b/apps/plugins/puzzles/tracks.c index dd00e32b9a..3dfbf62d6a 100644 --- a/apps/plugins/puzzles/tracks.c +++ b/apps/plugins/puzzles/tracks.c @@ -1072,7 +1072,7 @@ static int solve_check_single_sub(game_state *state, int si, int id, int n, x = i%w; y = i/w; if (abs(ox-x) > 1 || abs(oy-y) > 1) { - if (!state->sflags[i] & S_TRACK) + if (!(state->sflags[i] & S_TRACK)) did += solve_set_sflag(state, x, y, S_NOTRACK, what); } } diff --git a/apps/plugins/puzzles/unequal.c b/apps/plugins/puzzles/unequal.c index 457965b4ff..1293de28e8 100644 --- a/apps/plugins/puzzles/unequal.c +++ b/apps/plugins/puzzles/unequal.c @@ -1214,7 +1214,7 @@ static game_state *load_game(const game_params *params, const char *desc, why = "Too much data to fill grid"; goto fail; } - if (*p < '0' && *p > '9') { + if (*p < '0' || *p > '9') { why = "Expecting number in game description"; goto fail; } n = atoi(p); -- cgit v1.2.3