forked from len0rd/rockbox
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
This commit is contained in:
parent
985f6e6935
commit
6e5f287606
9 changed files with 115 additions and 31 deletions
21
apps/plugins/puzzles/README.rockbox
Normal file
21
apps/plugins/puzzles/README.rockbox
Normal file
|
@ -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)
|
|
@ -361,7 +361,6 @@ static void enum_grid_squares(const game_params *params, egc_callback callback,
|
||||||
} else {
|
} else {
|
||||||
int row, rowlen, other, i, firstix = -1;
|
int row, rowlen, other, i, firstix = -1;
|
||||||
float theight = (float)(sqrt(3) / 2.0);
|
float theight = (float)(sqrt(3) / 2.0);
|
||||||
//float theight = 0.8660254037844386467;
|
|
||||||
|
|
||||||
for (row = 0; row < params->d1 + params->d2; row++) {
|
for (row = 0; row < params->d1 + params->d2; row++) {
|
||||||
if (row < params->d2) {
|
if (row < params->d2) {
|
||||||
|
|
|
@ -1935,6 +1935,24 @@ static gint configure_window(GtkWidget *widget,
|
||||||
return FALSE;
|
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)
|
static void resize_fe(frontend *fe)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
|
@ -1942,7 +1960,7 @@ static void resize_fe(frontend *fe)
|
||||||
get_size(fe, &x, &y);
|
get_size(fe, &x, &y);
|
||||||
|
|
||||||
#if GTK_CHECK_VERSION(3,0,0)
|
#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
|
#else
|
||||||
fe->drawing_area_shrink_pending = FALSE;
|
fe->drawing_area_shrink_pending = FALSE;
|
||||||
gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y);
|
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);
|
midend_new_game(fe->me);
|
||||||
changed_preset(fe);
|
changed_preset(fe);
|
||||||
resize_fe(fe);
|
resize_fe(fe);
|
||||||
|
midend_redraw(fe->me);
|
||||||
}
|
}
|
||||||
|
|
||||||
GdkAtom compound_text_atom, utf8_string_atom;
|
GdkAtom compound_text_atom, utf8_string_atom;
|
||||||
|
@ -2213,6 +2232,7 @@ static void menu_load_event(GtkMenuItem *menuitem, gpointer data)
|
||||||
|
|
||||||
changed_preset(fe);
|
changed_preset(fe);
|
||||||
resize_fe(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);
|
midend_new_game(fe->me);
|
||||||
resize_fe(fe);
|
resize_fe(fe);
|
||||||
|
midend_redraw(fe->me);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void menu_about_event(GtkMenuItem *menuitem, gpointer data)
|
static void menu_about_event(GtkMenuItem *menuitem, gpointer data)
|
||||||
|
@ -2648,15 +2669,23 @@ static frontend *new_window(char *arg, int argtype, char **error)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
GdkGeometry geom;
|
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,
|
gtk_window_set_geometry_hints(GTK_WINDOW(fe->window), fe->area,
|
||||||
&geom, GDK_HINT_BASE_SIZE);
|
&geom, GDK_HINT_BASE_SIZE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
fe->w = -1;
|
fe->w = -1;
|
||||||
fe->h = -1;
|
fe->h = -1;
|
||||||
get_size(fe, &x, &y);
|
get_size(fe, &x, &y);
|
||||||
#if GTK_CHECK_VERSION(3,0,0)
|
#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
|
#else
|
||||||
fe->drawing_area_shrink_pending = FALSE;
|
fe->drawing_area_shrink_pending = FALSE;
|
||||||
gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y);
|
gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y);
|
||||||
|
|
|
@ -1610,8 +1610,6 @@ static void check_completion(game_state *state, int mark)
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < w*h; i++) {
|
for (i = 0; i < w*h; i++) {
|
||||||
int comp = dsf_canonify(dsf, 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 &&
|
if ((component_state[comp] == COMP_PATH &&
|
||||||
-1 != largest_comp) ||
|
-1 != largest_comp) ||
|
||||||
(component_state[comp] == COMP_LOOP &&
|
(component_state[comp] == COMP_LOOP &&
|
||||||
|
|
|
@ -42,6 +42,7 @@ PUZZLES_ROCKS := $(addprefix $(PUZZLES_OBJDIR)/sgt-, $(notdir $(PUZZLES_GAMES_SR
|
||||||
ROCKS += $(PUZZLES_ROCKS)
|
ROCKS += $(PUZZLES_ROCKS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Hack to suppress all warnings:
|
||||||
PUZZLESFLAGS = $(filter-out -O%,$(PLUGINFLAGS)) -Os \
|
PUZZLESFLAGS = $(filter-out -O%,$(PLUGINFLAGS)) -Os \
|
||||||
-Wno-unused-parameter -Wno-sign-compare -Wno-strict-aliasing -w \
|
-Wno-unused-parameter -Wno-sign-compare -Wno-strict-aliasing -w \
|
||||||
-DFOR_REAL
|
-DFOR_REAL
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* \/ \/ \/ \/ \/
|
* \/ \/ \/ \/ \/
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Franklin Wei
|
* Copyright (C) 2017 Franklin Wei
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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 fix_size(void);
|
||||||
|
|
||||||
static void rb_start_draw(void *handle)
|
|
||||||
{
|
|
||||||
(void) handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct viewport clip_rect;
|
static struct viewport clip_rect;
|
||||||
static bool clipped = false;
|
static bool clipped = false;
|
||||||
|
|
||||||
static struct settings_t {
|
static struct settings_t {
|
||||||
int slowmo_factor;
|
int slowmo_factor;
|
||||||
bool bulk, timerflash;
|
bool bulk, timerflash, clipoff;
|
||||||
} settings;
|
} settings;
|
||||||
|
|
||||||
/* clipping is implemented through viewports and offsetting
|
/* clipping is implemented through viewports and offsetting
|
||||||
* coordinates */
|
* coordinates */
|
||||||
static void rb_clip(void *handle, int x, int y, int w, int h)
|
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);
|
if(!settings.clipoff)
|
||||||
clip_rect.x = x;
|
{
|
||||||
clip_rect.y = y;
|
LOGF("rb_clip(%d %d %d %d)", x, y, w, h);
|
||||||
clip_rect.width = w;
|
clip_rect.x = x;
|
||||||
clip_rect.height = h;
|
clip_rect.y = y;
|
||||||
clip_rect.font = FONT_UI;
|
clip_rect.width = w;
|
||||||
clip_rect.drawmode = DRMODE_SOLID;
|
clip_rect.height = h;
|
||||||
|
clip_rect.font = FONT_UI;
|
||||||
|
clip_rect.drawmode = DRMODE_SOLID;
|
||||||
#if LCD_DEPTH > 1
|
#if LCD_DEPTH > 1
|
||||||
clip_rect.fg_pattern = LCD_DEFAULT_FG;
|
clip_rect.fg_pattern = LCD_DEFAULT_FG;
|
||||||
clip_rect.bg_pattern = LCD_DEFAULT_BG;
|
clip_rect.bg_pattern = LCD_DEFAULT_BG;
|
||||||
#endif
|
#endif
|
||||||
rb->lcd_set_viewport(&clip_rect);
|
rb->lcd_set_viewport(&clip_rect);
|
||||||
clipped = true;
|
clipped = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rb_unclip(void *handle)
|
static void rb_unclip(void *handle)
|
||||||
|
@ -407,6 +405,7 @@ static void rb_blitter_free(void *handle, blitter *bl)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* originally from emcc.c */
|
||||||
static void trim_rect(int *x, int *y, int *w, int *h)
|
static void trim_rect(int *x, int *y, int *w, int *h)
|
||||||
{
|
{
|
||||||
int x0, x1, y0, y1;
|
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);
|
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)
|
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);
|
LOGF("rb_draw_update(%d, %d, %d, %d)", x, y, w, h);
|
||||||
if(!settings.bulk)
|
|
||||||
rb->lcd_update_rect(x, y, w, h);
|
/* It seems that the puzzles use a different definition of
|
||||||
else
|
* "updating" the display than Rockbox does; by calling this
|
||||||
rb->lcd_update();
|
* 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)
|
static void rb_end_draw(void *handle)
|
||||||
{
|
{
|
||||||
|
(void) handle;
|
||||||
|
|
||||||
LOGF("rb_end_draw");
|
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;
|
static char *titlebar = NULL;
|
||||||
|
@ -893,6 +925,7 @@ static void debug_menu(void)
|
||||||
"Randomize colors",
|
"Randomize colors",
|
||||||
"Toggle bulk update",
|
"Toggle bulk update",
|
||||||
"Toggle flash pixel on timer",
|
"Toggle flash pixel on timer",
|
||||||
|
"Toggle clip",
|
||||||
"Back");
|
"Back");
|
||||||
bool quit = false;
|
bool quit = false;
|
||||||
int sel = 0;
|
int sel = 0;
|
||||||
|
@ -920,6 +953,9 @@ static void debug_menu(void)
|
||||||
settings.timerflash = !settings.timerflash;
|
settings.timerflash = !settings.timerflash;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
|
settings.clipoff = !settings.clipoff;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
default:
|
default:
|
||||||
quit = true;
|
quit = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -284,7 +284,7 @@ static int check_nums(game_state *orig, game_state *copy, int only_immutable)
|
||||||
int i, ret = 1;
|
int i, ret = 1;
|
||||||
assert(copy->n == orig->n);
|
assert(copy->n == orig->n);
|
||||||
for (i = 0; i < copy->n; i++) {
|
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] >= 0);
|
||||||
assert(copy->nums[i] <= copy->n);
|
assert(copy->nums[i] <= copy->n);
|
||||||
if (copy->nums[i] != orig->nums[i]) {
|
if (copy->nums[i] != orig->nums[i]) {
|
||||||
|
|
|
@ -1072,7 +1072,7 @@ static int solve_check_single_sub(game_state *state, int si, int id, int n,
|
||||||
x = i%w;
|
x = i%w;
|
||||||
y = i/w;
|
y = i/w;
|
||||||
if (abs(ox-x) > 1 || abs(oy-y) > 1) {
|
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);
|
did += solve_set_sflag(state, x, y, S_NOTRACK, what);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
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;
|
why = "Expecting number in game description"; goto fail;
|
||||||
}
|
}
|
||||||
n = atoi(p);
|
n = atoi(p);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue