diff options
| author | Franklin Wei <frankhwei536@gmail.com> | 2016-11-20 15:16:41 -0500 |
|---|---|---|
| committer | Franklin Wei <frankhwei536@gmail.com> | 2016-11-24 16:23:09 -0500 |
| commit | 56c9984511f016eab7e1278ba9e40d88bb59a162 (patch) | |
| tree | 1bfa6d3aeb3bf2a6ffec71387ac073cd0b8b2a51 /apps/plugins/puzzles/grid.h | |
| parent | 29648f817677b84c03c2bcfe89eb8cf53653e7db (diff) | |
| download | rockbox-puzzles.zip rockbox-puzzles.tar.gz rockbox-puzzles.tar.bz2 rockbox-puzzles.tar.xz | |
[WIP] Port of Simon Tatham's Puzzle Collectionpuzzles
Original revision: 5123b1bf68777ffa86e651f178046b26a87cf2d9
MIT Licensed. Some games still crash and others are unplayable due to
issues with controls. Still need a "real" polygon filling algorithm.
The following games are at least partially broken for various reasons:
Cube: crash with certain settings
Galaxies: crash
Inertia: crash
Keen: input issues
Loopy: weird stuff happens
Map: crash on input
Mines: weird stuff happens on target
Palisade: input issues
Signpost: crash on input
Solo: input issues
Towers: input and drawing issues
Train Tracks: drawing issues
Twiddle: weird animation on target
Undead: input and drawing issues
Unequal: input and drawing issues
Untangle: input issues
All in all, about 40% of the games are at least partially broken.
Change-Id: I7c69b6860ab115f973c8d76799502e9bb3d52368
Diffstat (limited to 'apps/plugins/puzzles/grid.h')
| -rw-r--r-- | apps/plugins/puzzles/grid.h | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/apps/plugins/puzzles/grid.h b/apps/plugins/puzzles/grid.h new file mode 100644 index 0000000..17d0aa1 --- /dev/null +++ b/apps/plugins/puzzles/grid.h @@ -0,0 +1,132 @@ +/* + * (c) Lambros Lambrou 2008 + * + * Code for working with general grids, which can be any planar graph + * with faces, edges and vertices (dots). Includes generators for a few + * types of grid, including square, hexagonal, triangular and others. + */ + +#ifndef PUZZLES_GRID_H +#define PUZZLES_GRID_H + +#include "puzzles.h" /* for random_state */ + +/* Useful macros */ +#define SQ(x) ( (x) * (x) ) + +/* ---------------------------------------------------------------------- + * Grid structures: + * A grid is made up of faces, edges and dots. These structures hold + * the incidence relationships between these types. For example, an + * edge always joins two dots, and is adjacent to two faces. + * The "grid_xxx **" members are lists of pointers which are dynamically + * allocated during grid generation. + * A pointer to a face/edge/dot will always point somewhere inside one of the + * three lists of the main "grid" structure: faces, edges, dots. + * Could have used integer offsets into these lists, but using actual + * pointers instead gives us type-safety. + */ + +/* Need forward declarations */ +typedef struct grid_face grid_face; +typedef struct grid_edge grid_edge; +typedef struct grid_dot grid_dot; + +struct grid_face { + int order; /* Number of edges, also the number of dots */ + grid_edge **edges; /* edges around this face */ + grid_dot **dots; /* corners of this face */ + /* + * For each face, we optionally compute and store its 'incentre'. + * The incentre of a triangle is the centre of a circle tangent to + * all three edges; I generalise the concept to arbitrary polygons + * by defining it to be the centre of the largest circle you can fit + * anywhere in the polygon. It's a useful thing to know because if + * you want to draw any symbol or text in the face (e.g. clue + * numbers in Loopy), that's the place it will most easily fit. + * + * When a grid is first generated, no face has this information + * computed, because it's fiddly to do. You can call + * grid_find_incentre() on a face, and it will fill in ix,iy below + * and set has_incentre to indicate that it's done so. + */ + int has_incentre; + int ix, iy; /* incentre (centre of largest inscribed circle) */ +}; +struct grid_edge { + grid_dot *dot1, *dot2; + grid_face *face1, *face2; /* Use NULL for the infinite outside face */ +}; +struct grid_dot { + int order; + grid_edge **edges; + grid_face **faces; /* A NULL grid_face* means infinite outside face */ + + /* Position in some fairly arbitrary (Cartesian) coordinate system. + * Use large enough values such that we can get away with + * integer arithmetic, but small enough such that arithmetic + * won't overflow. */ + int x, y; +}; +typedef struct grid { + /* These are (dynamically allocated) arrays of all the + * faces, edges, dots that are in the grid. */ + int num_faces; grid_face *faces; + int num_edges; grid_edge *edges; + int num_dots; grid_dot *dots; + + /* Cache the bounding-box of the grid, so the drawing-code can quickly + * figure out the proper scaling to draw onto a given area. */ + int lowest_x, lowest_y, highest_x, highest_y; + + /* A measure of tile size for this grid (in grid coordinates), to help + * the renderer decide how large to draw the grid. + * Roughly the size of a single tile - for example the side-length + * of a square cell. */ + int tilesize; + + /* We really don't want to copy this monstrosity! + * A grid is immutable once generated. + */ + int refcount; +} grid; + +/* Grids are specified by type: GRID_SQUARE, GRID_KITE, etc. */ + +#define GRIDGEN_LIST(A) \ + A(SQUARE,square) \ + A(HONEYCOMB,honeycomb) \ + A(TRIANGULAR,triangular) \ + A(SNUBSQUARE,snubsquare) \ + A(CAIRO,cairo) \ + A(GREATHEXAGONAL,greathexagonal) \ + A(OCTAGONAL,octagonal) \ + A(KITE,kites) \ + A(FLORET,floret) \ + A(DODECAGONAL,dodecagonal) \ + A(GREATDODECAGONAL,greatdodecagonal) \ + A(PENROSE_P2,penrose_p2_kite) \ + A(PENROSE_P3,penrose_p3_thick) + +#define ENUM(upper,lower) GRID_ ## upper, +typedef enum grid_type { GRIDGEN_LIST(ENUM) GRID_TYPE_MAX } grid_type; +#undef ENUM + +/* Free directly after use if non-NULL. Will never contain an underscore + * (so clients can safely use that as a separator). */ +char *grid_new_desc(grid_type type, int width, int height, random_state *rs); +char *grid_validate_desc(grid_type type, int width, int height, + const char *desc); + +grid *grid_new(grid_type type, int width, int height, const char *desc); + +void grid_free(grid *g); + +grid_edge *grid_nearest_edge(grid *g, int x, int y); + +void grid_compute_size(grid_type type, int width, int height, + int *tilesize, int *xextent, int *yextent); + +void grid_find_incentre(grid_face *f); + +#endif /* PUZZLES_GRID_H */ |