1
0
Fork 0
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:
Franklin Wei 2017-01-01 14:57:30 -05:00
parent 985f6e6935
commit 6e5f287606
9 changed files with 115 additions and 31 deletions

View 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)

View file

@ -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) {

View file

@ -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);

View file

@ -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 &&

View file

@ -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

View file

@ -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;

View file

@ -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]) {

View file

@ -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);
}
}

View file

@ -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);