summaryrefslogtreecommitdiff
path: root/apps/plugins/puzzles/src
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2017-11-21 19:28:16 -0500
committerFranklin Wei <git@fwei.tk>2017-11-21 19:29:45 -0500
commite8e85c5762da65ef7fa6e49ee8cc61f132be6d34 (patch)
tree1fb2c9724e61d121fe0b4460e3e626908f94fcea /apps/plugins/puzzles/src
parentf4c42213062170ddfcc706b3c5ed19f47517c253 (diff)
downloadrockbox-e8e85c5762da65ef7fa6e49ee8cc61f132be6d34.tar.gz
rockbox-e8e85c5762da65ef7fa6e49ee8cc61f132be6d34.zip
puzzles: resync with upstream; add Loopy and Palisade, mouse mode
This brings a various small changes to the drawing and input code, as well as a brand new "mouse mode", where input goes to a virtual mouse cursor. Only Loopy has this mouse mode enabled by default, while other games have it hidden away under the debug menu. Some changes by me to Palisade were required to make it playable; those are included here as well. Right now, sgt-net is pushing the c200v2's upper limit on size and may have to be dropped in a future commit. Change-Id: I495d2a2125462c2985aec1ffbc54bbe3fe5133bd
Diffstat (limited to 'apps/plugins/puzzles/src')
-rw-r--r--apps/plugins/puzzles/src/LICENCE5
-rw-r--r--apps/plugins/puzzles/src/filling.c2
-rw-r--r--apps/plugins/puzzles/src/grid.c96
-rw-r--r--apps/plugins/puzzles/src/grid.h1
-rw-r--r--apps/plugins/puzzles/src/loopy.c3
-rw-r--r--apps/plugins/puzzles/src/palisade.c21
6 files changed, 122 insertions, 6 deletions
diff --git a/apps/plugins/puzzles/src/LICENCE b/apps/plugins/puzzles/src/LICENCE
index 4235005ea7..ce0418e6cc 100644
--- a/apps/plugins/puzzles/src/LICENCE
+++ b/apps/plugins/puzzles/src/LICENCE
@@ -1,8 +1,9 @@
1This software is copyright (c) 2004-2014 Simon Tatham. 1This software is copyright (c) 2004-2014 Simon Tatham.
2 2
3Portions copyright Richard Boulton, James Harvey, Mike Pinna, Jonas 3Portions copyright Richard Boulton, James Harvey, Mike Pinna, Jonas
4Kölker, Dariusz Olszewski, Michael Schierl, Lambros Lambrou, Bernd 4Kölker, Dariusz Olszewski, Michael Schierl, Lambros Lambrou, Bernd
5Schmidt, Steffen Bauer, Lennard Sprong and Rogier Goossens. 5Schmidt, Steffen Bauer, Lennard Sprong, Rogier Goossens and Michael
6Quevillon.
6 7
7Permission is hereby granted, free of charge, to any person 8Permission is hereby granted, free of charge, to any person
8obtaining a copy of this software and associated documentation files 9obtaining a copy of this software and associated documentation files
diff --git a/apps/plugins/puzzles/src/filling.c b/apps/plugins/puzzles/src/filling.c
index 7e71eb25b4..231de4c079 100644
--- a/apps/plugins/puzzles/src/filling.c
+++ b/apps/plugins/puzzles/src/filling.c
@@ -1,6 +1,6 @@
1/* -*- tab-width: 8; indent-tabs-mode: t -*- 1/* -*- tab-width: 8; indent-tabs-mode: t -*-
2 * filling.c: An implementation of the Nikoli game fillomino. 2 * filling.c: An implementation of the Nikoli game fillomino.
3 * Copyright (C) 2007 Jonas Kölker. See LICENSE for the license. 3 * Copyright (C) 2007 Jonas Kölker. See LICENSE for the license.
4 */ 4 */
5 5
6/* TODO: 6/* TODO:
diff --git a/apps/plugins/puzzles/src/grid.c b/apps/plugins/puzzles/src/grid.c
index 52648e5a92..b5e6bb0937 100644
--- a/apps/plugins/puzzles/src/grid.c
+++ b/apps/plugins/puzzles/src/grid.c
@@ -2060,6 +2060,102 @@ static grid *grid_new_greathexagonal(int width, int height, const char *desc)
2060 return g; 2060 return g;
2061} 2061}
2062 2062
2063#define KAGOME_TILESIZE 18
2064/* Vector for side of triangle - ratio is close to sqrt(3) */
2065#define KAGOME_A 15
2066#define KAGOME_B 26
2067
2068static void grid_size_kagome(int width, int height,
2069 int *tilesize, int *xextent, int *yextent)
2070{
2071 int a = KAGOME_A;
2072 int b = KAGOME_B;
2073
2074 *tilesize = KAGOME_TILESIZE;
2075 *xextent = (4*a) * (width-1) + 6*a;
2076 *yextent = (2*b) * (height-1) + 2*b;
2077}
2078
2079static grid *grid_new_kagome(int width, int height, const char *desc)
2080{
2081 int x, y;
2082 int a = KAGOME_A;
2083 int b = KAGOME_B;
2084
2085 /* Upper bounds - don't have to be exact */
2086 int max_faces = 6 * (width + 1) * (height + 1);
2087 int max_dots = 6 * width * height;
2088
2089 tree234 *points;
2090
2091 grid *g = grid_empty();
2092 g->tilesize = KAGOME_TILESIZE;
2093 g->faces = snewn(max_faces, grid_face);
2094 g->dots = snewn(max_dots, grid_dot);
2095
2096 points = newtree234(grid_point_cmp_fn);
2097
2098 for (y = 0; y < height; y++) {
2099 for (x = 0; x < width; x++) {
2100 grid_dot *d;
2101 /* centre of hexagon */
2102 int px = (4*a) * x;
2103 int py = (2*b) * y;
2104 if (y % 2)
2105 px += 2*a;
2106
2107 /* hexagon */
2108 grid_face_add_new(g, 6);
2109 d = grid_get_dot(g, points, px + a, py - b); grid_face_set_dot(g, d, 0);
2110 d = grid_get_dot(g, points, px + 2*a, py ); grid_face_set_dot(g, d, 1);
2111 d = grid_get_dot(g, points, px + a, py + b); grid_face_set_dot(g, d, 2);
2112 d = grid_get_dot(g, points, px - a, py + b); grid_face_set_dot(g, d, 3);
2113 d = grid_get_dot(g, points, px - 2*a, py ); grid_face_set_dot(g, d, 4);
2114 d = grid_get_dot(g, points, px - a, py - b); grid_face_set_dot(g, d, 5);
2115
2116 /* Triangle above right */
2117 if ((x < width - 1) || (!(y % 2) && y)) {
2118 grid_face_add_new(g, 3);
2119 d = grid_get_dot(g, points, px + 3*a, py - b); grid_face_set_dot(g, d, 0);
2120 d = grid_get_dot(g, points, px + 2*a, py ); grid_face_set_dot(g, d, 1);
2121 d = grid_get_dot(g, points, px + a, py - b); grid_face_set_dot(g, d, 2);
2122 }
2123
2124 /* Triangle below right */
2125 if ((x < width - 1) || (!(y % 2) && (y < height - 1))) {
2126 grid_face_add_new(g, 3);
2127 d = grid_get_dot(g, points, px + 3*a, py + b); grid_face_set_dot(g, d, 0);
2128 d = grid_get_dot(g, points, px + a, py + b); grid_face_set_dot(g, d, 1);
2129 d = grid_get_dot(g, points, px + 2*a, py ); grid_face_set_dot(g, d, 2);
2130 }
2131
2132 /* Left triangles */
2133 if (!x && (y % 2)) {
2134 /* Triangle above left */
2135 grid_face_add_new(g, 3);
2136 d = grid_get_dot(g, points, px - a, py - b); grid_face_set_dot(g, d, 0);
2137 d = grid_get_dot(g, points, px - 2*a, py ); grid_face_set_dot(g, d, 1);
2138 d = grid_get_dot(g, points, px - 3*a, py - b); grid_face_set_dot(g, d, 2);
2139
2140 /* Triangle below left */
2141 if (y < height - 1) {
2142 grid_face_add_new(g, 3);
2143 d = grid_get_dot(g, points, px - a, py + b); grid_face_set_dot(g, d, 0);
2144 d = grid_get_dot(g, points, px - 3*a, py + b); grid_face_set_dot(g, d, 1);
2145 d = grid_get_dot(g, points, px - 2*a, py ); grid_face_set_dot(g, d, 2);
2146 }
2147 }
2148 }
2149 }
2150
2151 freetree234(points);
2152 assert(g->num_faces <= max_faces);
2153 assert(g->num_dots <= max_dots);
2154
2155 grid_make_consistent(g);
2156 return g;
2157}
2158
2063#define OCTAGONAL_TILESIZE 40 2159#define OCTAGONAL_TILESIZE 40
2064/* b/a approx sqrt(2) */ 2160/* b/a approx sqrt(2) */
2065#define OCTAGONAL_A 29 2161#define OCTAGONAL_A 29
diff --git a/apps/plugins/puzzles/src/grid.h b/apps/plugins/puzzles/src/grid.h
index 19079a44b8..26d0b16633 100644
--- a/apps/plugins/puzzles/src/grid.h
+++ b/apps/plugins/puzzles/src/grid.h
@@ -100,6 +100,7 @@ typedef struct grid {
100 A(SNUBSQUARE,snubsquare) \ 100 A(SNUBSQUARE,snubsquare) \
101 A(CAIRO,cairo) \ 101 A(CAIRO,cairo) \
102 A(GREATHEXAGONAL,greathexagonal) \ 102 A(GREATHEXAGONAL,greathexagonal) \
103 A(KAGOME,kagome) \
103 A(OCTAGONAL,octagonal) \ 104 A(OCTAGONAL,octagonal) \
104 A(KITE,kites) \ 105 A(KITE,kites) \
105 A(FLORET,floret) \ 106 A(FLORET,floret) \
diff --git a/apps/plugins/puzzles/src/loopy.c b/apps/plugins/puzzles/src/loopy.c
index 5f1940e945..c14412d6be 100644
--- a/apps/plugins/puzzles/src/loopy.c
+++ b/apps/plugins/puzzles/src/loopy.c
@@ -278,6 +278,7 @@ static void check_caches(const solver_state* sstate);
278 A("Penrose (kite/dart)",PENROSE_P2,3,3) \ 278 A("Penrose (kite/dart)",PENROSE_P2,3,3) \
279 A("Penrose (rhombs)",PENROSE_P3,3,3) \ 279 A("Penrose (rhombs)",PENROSE_P3,3,3) \
280 A("Great-Great-Dodecagonal",GREATGREATDODECAGONAL,2,2) \ 280 A("Great-Great-Dodecagonal",GREATGREATDODECAGONAL,2,2) \
281 A("Kagome",KAGOME,3,3) \
281 /* end of list */ 282 /* end of list */
282 283
283#define GRID_NAME(title,type,amin,omin) title, 284#define GRID_NAME(title,type,amin,omin) title,
@@ -544,6 +545,7 @@ static const game_params loopy_presets_more[] = {
544#ifdef SMALL_SCREEN 545#ifdef SMALL_SCREEN
545 { 7, 7, DIFF_HARD, LOOPY_GRID_HONEYCOMB }, 546 { 7, 7, DIFF_HARD, LOOPY_GRID_HONEYCOMB },
546 { 5, 4, DIFF_HARD, LOOPY_GRID_GREATHEXAGONAL }, 547 { 5, 4, DIFF_HARD, LOOPY_GRID_GREATHEXAGONAL },
548 { 5, 4, DIFF_HARD, LOOPY_GRID_KAGOME },
547 { 5, 5, DIFF_HARD, LOOPY_GRID_OCTAGONAL }, 549 { 5, 5, DIFF_HARD, LOOPY_GRID_OCTAGONAL },
548 { 3, 3, DIFF_HARD, LOOPY_GRID_FLORET }, 550 { 3, 3, DIFF_HARD, LOOPY_GRID_FLORET },
549 { 3, 3, DIFF_HARD, LOOPY_GRID_DODECAGONAL }, 551 { 3, 3, DIFF_HARD, LOOPY_GRID_DODECAGONAL },
@@ -552,6 +554,7 @@ static const game_params loopy_presets_more[] = {
552#else 554#else
553 { 10, 10, DIFF_HARD, LOOPY_GRID_HONEYCOMB }, 555 { 10, 10, DIFF_HARD, LOOPY_GRID_HONEYCOMB },
554 { 5, 4, DIFF_HARD, LOOPY_GRID_GREATHEXAGONAL }, 556 { 5, 4, DIFF_HARD, LOOPY_GRID_GREATHEXAGONAL },
557 { 5, 4, DIFF_HARD, LOOPY_GRID_KAGOME },
555 { 7, 7, DIFF_HARD, LOOPY_GRID_OCTAGONAL }, 558 { 7, 7, DIFF_HARD, LOOPY_GRID_OCTAGONAL },
556 { 5, 5, DIFF_HARD, LOOPY_GRID_FLORET }, 559 { 5, 5, DIFF_HARD, LOOPY_GRID_FLORET },
557 { 5, 4, DIFF_HARD, LOOPY_GRID_DODECAGONAL }, 560 { 5, 4, DIFF_HARD, LOOPY_GRID_DODECAGONAL },
diff --git a/apps/plugins/puzzles/src/palisade.c b/apps/plugins/puzzles/src/palisade.c
index 5227a1d56c..e495bbed2c 100644
--- a/apps/plugins/puzzles/src/palisade.c
+++ b/apps/plugins/puzzles/src/palisade.c
@@ -865,14 +865,16 @@ static char *game_text_format(const game_state *state)
865 865
866struct game_ui { 866struct game_ui {
867 int x, y; 867 int x, y;
868 unsigned int show: 1; 868 unsigned int show: 1;
869 unsigned int fake_ctrl: 1;
870 unsigned int fake_shift: 1;
869}; 871};
870 872
871static game_ui *new_ui(const game_state *state) 873static game_ui *new_ui(const game_state *state)
872{ 874{
873 game_ui *ui = snew(game_ui); 875 game_ui *ui = snew(game_ui);
874 ui->x = ui->y = 0; 876 ui->x = ui->y = 0;
875 ui->show = FALSE; 877 ui->show = ui->fake_ctrl = ui->fake_shift = FALSE;
876 return ui; 878 return ui;
877} 879}
878 880
@@ -916,7 +918,10 @@ static char *interpret_move(const game_state *state, game_ui *ui,
916 const game_drawstate *ds, int x, int y, int button) 918 const game_drawstate *ds, int x, int y, int button)
917{ 919{
918 int w = state->shared->params.w, h = state->shared->params.h; 920 int w = state->shared->params.w, h = state->shared->params.h;
919 int control = button & MOD_CTRL, shift = button & MOD_SHFT; 921 int control = (button & MOD_CTRL) | ui->fake_ctrl, shift = (button & MOD_SHFT) | ui->fake_shift;
922
923 /* reset */
924 ui->fake_ctrl = ui->fake_shift = FALSE;
920 925
921 button &= ~MOD_MASK; 926 button &= ~MOD_MASK;
922 927
@@ -999,6 +1004,16 @@ static char *interpret_move(const game_state *state, game_ui *ui,
999 return UI_UPDATE; 1004 return UI_UPDATE;
1000 } 1005 }
1001 } 1006 }
1007 else if(IS_CURSOR_SELECT(button)) {
1008 /* CURSOR_SELECT or CURSOR_SELECT2 tells us to toggle whether
1009 * the button press should be interpreted as having CTRL or
1010 * shift pressed along with it, respectively. */
1011 ui->show = TRUE;
1012 if(button == CURSOR_SELECT2)
1013 ui->fake_shift = !ui->fake_shift;
1014 else
1015 ui->fake_ctrl = !ui->fake_ctrl;
1016 }
1002 1017
1003 return NULL; 1018 return NULL;
1004} 1019}