diff options
author | Franklin Wei <frankhwei536@gmail.com> | 2016-11-20 15:16:41 -0500 |
---|---|---|
committer | Franklin Wei <me@fwei.tk> | 2016-12-18 18:13:22 +0100 |
commit | 1a6a8b52f7aa4e2da6f4c34a0c743c760b8cfd99 (patch) | |
tree | 8e7f2d6b0cbdb5d15c13457b2c3e1de69f598440 /apps/plugins/puzzles/puzzles.h | |
parent | 3ee79724f6fb033d50e26ef37b33d3f8cedf0c5b (diff) | |
download | rockbox-1a6a8b52f7aa4e2da6f4c34a0c743c760b8cfd99.tar.gz rockbox-1a6a8b52f7aa4e2da6f4c34a0c743c760b8cfd99.zip |
Port of Simon Tatham's Puzzle Collection
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.
Currently builds one plugin per puzzle (about 40 in total, around 100K
each on ARM), but can easily be made to build a single monolithic
overlay (800K or so on ARM).
The following games are at least partially broken for various reasons,
and have been disabled on this commit:
Cube: failed assertion with "Icosahedron" setting
Keen: input issues
Mines: weird stuff happens on target
Palisade: input issues
Solo: input issues, occasional crash on target
Towers: input issues
Undead: input issues
Unequal: input and drawing issues (concave polys)
Untangle: input issues
Features left to do:
- In-game help system
- Figure out the weird bugs
Change-Id: I7c69b6860ab115f973c8d76799502e9bb3d52368
Diffstat (limited to 'apps/plugins/puzzles/puzzles.h')
-rw-r--r-- | apps/plugins/puzzles/puzzles.h | 636 |
1 files changed, 636 insertions, 0 deletions
diff --git a/apps/plugins/puzzles/puzzles.h b/apps/plugins/puzzles/puzzles.h new file mode 100644 index 0000000000..c70b33ccbf --- /dev/null +++ b/apps/plugins/puzzles/puzzles.h | |||
@@ -0,0 +1,636 @@ | |||
1 | /* | ||
2 | * puzzles.h: header file for my puzzle collection | ||
3 | */ | ||
4 | |||
5 | #ifndef PUZZLES_PUZZLES_H | ||
6 | #define PUZZLES_PUZZLES_H | ||
7 | |||
8 | #include "plugin.h" | ||
9 | #include <tlsf.h> | ||
10 | #include "rbcompat.h" | ||
11 | #include "lib/pluginlib_exit.h" | ||
12 | |||
13 | #ifdef ROCKBOX | ||
14 | #if LCD_WIDTH < LCD_HEIGHT | ||
15 | #define PORTRAIT_SCREEN | ||
16 | #endif | ||
17 | #endif | ||
18 | |||
19 | #ifndef TRUE | ||
20 | #define TRUE 1 | ||
21 | #endif | ||
22 | #ifndef FALSE | ||
23 | #define FALSE 0 | ||
24 | #endif | ||
25 | |||
26 | #define PI 3.141592653589793238462643383279502884197169399 | ||
27 | |||
28 | #define lenof(array) ( sizeof(array) / sizeof(*(array)) ) | ||
29 | |||
30 | #undef STR | ||
31 | #define STR_INT(x) #x | ||
32 | #define STR(x) STR_INT(x) | ||
33 | |||
34 | /* NB not perfect because they evaluate arguments multiple times. */ | ||
35 | #ifndef max | ||
36 | #define max(x,y) ( (x)>(y) ? (x) : (y) ) | ||
37 | #endif /* max */ | ||
38 | #ifndef min | ||
39 | #define min(x,y) ( (x)<(y) ? (x) : (y) ) | ||
40 | #endif /* min */ | ||
41 | |||
42 | enum { | ||
43 | LEFT_BUTTON = 0x0200, | ||
44 | MIDDLE_BUTTON, | ||
45 | RIGHT_BUTTON, | ||
46 | LEFT_DRAG, | ||
47 | MIDDLE_DRAG, | ||
48 | RIGHT_DRAG, | ||
49 | LEFT_RELEASE, | ||
50 | MIDDLE_RELEASE, | ||
51 | RIGHT_RELEASE, | ||
52 | CURSOR_UP, | ||
53 | CURSOR_DOWN, | ||
54 | CURSOR_LEFT, | ||
55 | CURSOR_RIGHT, | ||
56 | CURSOR_SELECT, | ||
57 | CURSOR_SELECT2, | ||
58 | |||
59 | /* made smaller because of 'limited range of datatype' errors. */ | ||
60 | MOD_CTRL = 0x1000, | ||
61 | MOD_SHFT = 0x2000, | ||
62 | MOD_NUM_KEYPAD = 0x4000, | ||
63 | MOD_MASK = 0x7000 /* mask for all modifiers */ | ||
64 | }; | ||
65 | |||
66 | #define IS_MOUSE_DOWN(m) ( (unsigned)((m) - LEFT_BUTTON) <= \ | ||
67 | (unsigned)(RIGHT_BUTTON - LEFT_BUTTON)) | ||
68 | #define IS_MOUSE_DRAG(m) ( (unsigned)((m) - LEFT_DRAG) <= \ | ||
69 | (unsigned)(RIGHT_DRAG - LEFT_DRAG)) | ||
70 | #define IS_MOUSE_RELEASE(m) ( (unsigned)((m) - LEFT_RELEASE) <= \ | ||
71 | (unsigned)(RIGHT_RELEASE - LEFT_RELEASE)) | ||
72 | #define IS_CURSOR_MOVE(m) ( (m) == CURSOR_UP || (m) == CURSOR_DOWN || \ | ||
73 | (m) == CURSOR_RIGHT || (m) == CURSOR_LEFT ) | ||
74 | #define IS_CURSOR_SELECT(m) ( (m) == CURSOR_SELECT || (m) == CURSOR_SELECT2) | ||
75 | |||
76 | /* | ||
77 | * Flags in the back end's `flags' word. | ||
78 | */ | ||
79 | /* Bit flags indicating mouse button priorities */ | ||
80 | #define BUTTON_BEATS(x,y) ( 1 << (((x)-LEFT_BUTTON)*3+(y)-LEFT_BUTTON) ) | ||
81 | /* Flag indicating that Solve operations should be animated */ | ||
82 | #define SOLVE_ANIMATES ( 1 << 9 ) | ||
83 | /* Pocket PC: Game requires right mouse button emulation */ | ||
84 | #define REQUIRE_RBUTTON ( 1 << 10 ) | ||
85 | /* Pocket PC: Game requires numeric input */ | ||
86 | #define REQUIRE_NUMPAD ( 1 << 11 ) | ||
87 | /* end of `flags' word definitions */ | ||
88 | |||
89 | #ifdef _WIN32_WCE | ||
90 | /* Pocket PC devices have small, portrait screen that requires more vivid colours */ | ||
91 | #define SMALL_SCREEN | ||
92 | #define PORTRAIT_SCREEN | ||
93 | #define VIVID_COLOURS | ||
94 | #define STYLUS_BASED | ||
95 | #endif | ||
96 | |||
97 | #define IGNOREARG(x) ( (x) = (x) ) | ||
98 | |||
99 | typedef struct frontend frontend; | ||
100 | typedef struct config_item config_item; | ||
101 | typedef struct midend midend; | ||
102 | typedef struct random_state random_state; | ||
103 | typedef struct game_params game_params; | ||
104 | typedef struct game_state game_state; | ||
105 | typedef struct game_ui game_ui; | ||
106 | typedef struct game_drawstate game_drawstate; | ||
107 | typedef struct game game; | ||
108 | typedef struct blitter blitter; | ||
109 | typedef struct document document; | ||
110 | typedef struct drawing_api drawing_api; | ||
111 | typedef struct drawing drawing; | ||
112 | typedef struct psdata psdata; | ||
113 | |||
114 | #define ALIGN_VNORMAL 0x000 | ||
115 | #define ALIGN_VCENTRE 0x100 | ||
116 | |||
117 | #define ALIGN_HLEFT 0x000 | ||
118 | #define ALIGN_HCENTRE 0x001 | ||
119 | #define ALIGN_HRIGHT 0x002 | ||
120 | |||
121 | #define FONT_FIXED 0 | ||
122 | #define FONT_VARIABLE 1 | ||
123 | |||
124 | /* For printing colours */ | ||
125 | #define HATCH_SLASH 1 | ||
126 | #define HATCH_BACKSLASH 2 | ||
127 | #define HATCH_HORIZ 3 | ||
128 | #define HATCH_VERT 4 | ||
129 | #define HATCH_PLUS 5 | ||
130 | #define HATCH_X 6 | ||
131 | |||
132 | /* | ||
133 | * Structure used to pass configuration data between frontend and | ||
134 | * game | ||
135 | */ | ||
136 | enum { C_STRING, C_CHOICES, C_BOOLEAN, C_END }; | ||
137 | struct config_item { | ||
138 | /* | ||
139 | * `name' is never dynamically allocated. | ||
140 | */ | ||
141 | char *name; | ||
142 | /* | ||
143 | * `type' contains one of the above values. | ||
144 | */ | ||
145 | int type; | ||
146 | /* | ||
147 | * For C_STRING, `sval' is always dynamically allocated and | ||
148 | * non-NULL. For C_BOOLEAN and C_END, `sval' is always NULL. | ||
149 | * For C_CHOICES, `sval' is non-NULL, _not_ dynamically | ||
150 | * allocated, and contains a set of option strings separated by | ||
151 | * a delimiter. The delimeter is also the first character in | ||
152 | * the string, so for example ":Foo:Bar:Baz" gives three | ||
153 | * options `Foo', `Bar' and `Baz'. | ||
154 | */ | ||
155 | char *sval; | ||
156 | /* | ||
157 | * For C_BOOLEAN, this is TRUE or FALSE. For C_CHOICES, it | ||
158 | * indicates the chosen index from the `sval' list. In the | ||
159 | * above example, 0==Foo, 1==Bar and 2==Baz. | ||
160 | */ | ||
161 | int ival; | ||
162 | }; | ||
163 | |||
164 | /* | ||
165 | * Platform routines | ||
166 | */ | ||
167 | |||
168 | /* We can't use #ifdef DEBUG, because Cygwin defines it by default. */ | ||
169 | #ifdef DEBUGGING | ||
170 | #define debug(x) (debug_printf x) | ||
171 | void debug_printf(char *fmt, ...); | ||
172 | #else | ||
173 | #define debug(x) | ||
174 | #endif | ||
175 | |||
176 | void fatal(char *fmt, ...); | ||
177 | void frontend_default_colour(frontend *fe, float *output); | ||
178 | void deactivate_timer(frontend *fe); | ||
179 | void activate_timer(frontend *fe); | ||
180 | void get_random_seed(void **randseed, int *randseedsize); | ||
181 | |||
182 | /* | ||
183 | * drawing.c | ||
184 | */ | ||
185 | drawing *drawing_new(const drawing_api *api, midend *me, void *handle); | ||
186 | void drawing_free(drawing *dr); | ||
187 | void draw_text(drawing *dr, int x, int y, int fonttype, int fontsize, | ||
188 | int align, int colour, char *text); | ||
189 | void draw_rect(drawing *dr, int x, int y, int w, int h, int colour); | ||
190 | void draw_line(drawing *dr, int x1, int y1, int x2, int y2, int colour); | ||
191 | void draw_polygon(drawing *dr, int *coords, int npoints, | ||
192 | int fillcolour, int outlinecolour); | ||
193 | void draw_circle(drawing *dr, int cx, int cy, int radius, | ||
194 | int fillcolour, int outlinecolour); | ||
195 | void draw_thick_line(drawing *dr, float thickness, | ||
196 | float x1, float y1, float x2, float y2, int colour); | ||
197 | void clip(drawing *dr, int x, int y, int w, int h); | ||
198 | void unclip(drawing *dr); | ||
199 | void start_draw(drawing *dr); | ||
200 | void draw_update(drawing *dr, int x, int y, int w, int h); | ||
201 | void end_draw(drawing *dr); | ||
202 | char *text_fallback(drawing *dr, const char *const *strings, int nstrings); | ||
203 | void status_bar(drawing *dr, char *text); | ||
204 | blitter *blitter_new(drawing *dr, int w, int h); | ||
205 | void blitter_free(drawing *dr, blitter *bl); | ||
206 | /* save puts the portion of the current display with top-left corner | ||
207 | * (x,y) to the blitter. load puts it back again to the specified | ||
208 | * coords, or else wherever it was saved from | ||
209 | * (if x = y = BLITTER_FROMSAVED). */ | ||
210 | void blitter_save(drawing *dr, blitter *bl, int x, int y); | ||
211 | #define BLITTER_FROMSAVED (-1) | ||
212 | void blitter_load(drawing *dr, blitter *bl, int x, int y); | ||
213 | void print_begin_doc(drawing *dr, int pages); | ||
214 | void print_begin_page(drawing *dr, int number); | ||
215 | void print_begin_puzzle(drawing *dr, float xm, float xc, | ||
216 | float ym, float yc, int pw, int ph, float wmm, | ||
217 | float scale); | ||
218 | void print_end_puzzle(drawing *dr); | ||
219 | void print_end_page(drawing *dr, int number); | ||
220 | void print_end_doc(drawing *dr); | ||
221 | void print_get_colour(drawing *dr, int colour, int printing_in_colour, | ||
222 | int *hatch, float *r, float *g, float *b); | ||
223 | int print_mono_colour(drawing *dr, int grey); /* 0==black, 1==white */ | ||
224 | int print_grey_colour(drawing *dr, float grey); | ||
225 | int print_hatched_colour(drawing *dr, int hatch); | ||
226 | int print_rgb_mono_colour(drawing *dr, float r, float g, float b, int mono); | ||
227 | int print_rgb_grey_colour(drawing *dr, float r, float g, float b, float grey); | ||
228 | int print_rgb_hatched_colour(drawing *dr, float r, float g, float b, | ||
229 | int hatch); | ||
230 | void print_line_width(drawing *dr, int width); | ||
231 | void print_line_dotted(drawing *dr, int dotted); | ||
232 | |||
233 | /* | ||
234 | * midend.c | ||
235 | */ | ||
236 | midend *midend_new(frontend *fe, const game *ourgame, | ||
237 | const drawing_api *drapi, void *drhandle); | ||
238 | void midend_free(midend *me); | ||
239 | const game *midend_which_game(midend *me); | ||
240 | void midend_set_params(midend *me, game_params *params); | ||
241 | game_params *midend_get_params(midend *me); | ||
242 | void midend_size(midend *me, int *x, int *y, int user_size); | ||
243 | void midend_reset_tilesize(midend *me); | ||
244 | void midend_new_game(midend *me); | ||
245 | void midend_restart_game(midend *me); | ||
246 | void midend_stop_anim(midend *me); | ||
247 | int midend_process_key(midend *me, int x, int y, int button); | ||
248 | void midend_force_redraw(midend *me); | ||
249 | void midend_redraw(midend *me); | ||
250 | float *midend_colours(midend *me, int *ncolours); | ||
251 | void midend_freeze_timer(midend *me, float tprop); | ||
252 | void midend_timer(midend *me, float tplus); | ||
253 | int midend_num_presets(midend *me); | ||
254 | void midend_fetch_preset(midend *me, int n, | ||
255 | char **name, game_params **params); | ||
256 | int midend_which_preset(midend *me); | ||
257 | int midend_wants_statusbar(midend *me); | ||
258 | enum { CFG_SETTINGS, CFG_SEED, CFG_DESC, CFG_FRONTEND_SPECIFIC }; | ||
259 | config_item *midend_get_config(midend *me, int which, char **wintitle); | ||
260 | char *midend_set_config(midend *me, int which, config_item *cfg); | ||
261 | char *midend_game_id(midend *me, char *id); | ||
262 | char *midend_get_game_id(midend *me); | ||
263 | char *midend_get_random_seed(midend *me); | ||
264 | int midend_can_format_as_text_now(midend *me); | ||
265 | char *midend_text_format(midend *me); | ||
266 | char *midend_solve(midend *me); | ||
267 | int midend_status(midend *me); | ||
268 | int midend_can_undo(midend *me); | ||
269 | int midend_can_redo(midend *me); | ||
270 | void midend_supersede_game_desc(midend *me, char *desc, char *privdesc); | ||
271 | char *midend_rewrite_statusbar(midend *me, char *text); | ||
272 | void midend_serialise(midend *me, | ||
273 | void (*write)(void *ctx, void *buf, int len), | ||
274 | void *wctx); | ||
275 | char *midend_deserialise(midend *me, | ||
276 | int (*read)(void *ctx, void *buf, int len), | ||
277 | void *rctx); | ||
278 | char *identify_game(char **name, int (*read)(void *ctx, void *buf, int len), | ||
279 | void *rctx); | ||
280 | void midend_request_id_changes(midend *me, void (*notify)(void *), void *ctx); | ||
281 | /* Printing functions supplied by the mid-end */ | ||
282 | char *midend_print_puzzle(midend *me, document *doc, int with_soln); | ||
283 | int midend_tilesize(midend *me); | ||
284 | |||
285 | /* | ||
286 | * malloc.c | ||
287 | */ | ||
288 | void *smalloc(size_t size); | ||
289 | void *srealloc(void *p, size_t size); | ||
290 | void sfree(void *p); | ||
291 | char *dupstr(const char *s); | ||
292 | #define snew(type) \ | ||
293 | ( (type *) smalloc (sizeof (type)) ) | ||
294 | #define snewn(number, type) \ | ||
295 | ( (type *) smalloc ((number) * sizeof (type)) ) | ||
296 | #define sresize(array, number, type) \ | ||
297 | ( (type *) srealloc ((array), (number) * sizeof (type)) ) | ||
298 | |||
299 | /* | ||
300 | * misc.c | ||
301 | */ | ||
302 | void free_cfg(config_item *cfg); | ||
303 | void obfuscate_bitmap(unsigned char *bmp, int bits, int decode); | ||
304 | |||
305 | /* allocates output each time. len is always in bytes of binary data. | ||
306 | * May assert (or just go wrong) if lengths are unchecked. */ | ||
307 | char *bin2hex(const unsigned char *in, int inlen); | ||
308 | unsigned char *hex2bin(const char *in, int outlen); | ||
309 | |||
310 | /* Sets (and possibly dims) background from frontend default colour, | ||
311 | * and auto-generates highlight and lowlight colours too. */ | ||
312 | void game_mkhighlight(frontend *fe, float *ret, | ||
313 | int background, int highlight, int lowlight); | ||
314 | /* As above, but starts from a provided background colour rather | ||
315 | * than the frontend default. */ | ||
316 | void game_mkhighlight_specific(frontend *fe, float *ret, | ||
317 | int background, int highlight, int lowlight); | ||
318 | |||
319 | /* Randomly shuffles an array of items. */ | ||
320 | void shuffle(void *array, int nelts, int eltsize, random_state *rs); | ||
321 | |||
322 | /* Draw a rectangle outline, using the drawing API's draw_line. */ | ||
323 | void draw_rect_outline(drawing *dr, int x, int y, int w, int h, | ||
324 | int colour); | ||
325 | |||
326 | /* Draw a set of rectangle corners (e.g. for a cursor display). */ | ||
327 | void draw_rect_corners(drawing *dr, int cx, int cy, int r, int col); | ||
328 | |||
329 | void move_cursor(int button, int *x, int *y, int maxw, int maxh, int wrap); | ||
330 | |||
331 | /* Used in netslide.c and sixteen.c for cursor movement around edge. */ | ||
332 | int c2pos(int w, int h, int cx, int cy); | ||
333 | int c2diff(int w, int h, int cx, int cy, int button); | ||
334 | void pos2c(int w, int h, int pos, int *cx, int *cy); | ||
335 | |||
336 | /* Draws text with an 'outline' formed by offsetting the text | ||
337 | * by one pixel; useful for highlighting. Outline is omitted if -1. */ | ||
338 | void draw_text_outline(drawing *dr, int x, int y, int fonttype, | ||
339 | int fontsize, int align, | ||
340 | int text_colour, int outline_colour, char *text); | ||
341 | /* | ||
342 | * dsf.c | ||
343 | */ | ||
344 | int *snew_dsf(int size); | ||
345 | |||
346 | void print_dsf(int *dsf, int size); | ||
347 | |||
348 | /* Return the canonical element of the equivalence class containing element | ||
349 | * val. If 'inverse' is non-NULL, this function will put into it a flag | ||
350 | * indicating whether the canonical element is inverse to val. */ | ||
351 | int edsf_canonify(int *dsf, int val, int *inverse); | ||
352 | int dsf_canonify(int *dsf, int val); | ||
353 | int dsf_size(int *dsf, int val); | ||
354 | |||
355 | /* Allow the caller to specify that two elements should be in the same | ||
356 | * equivalence class. If 'inverse' is TRUE, the elements are actually opposite | ||
357 | * to one another in some sense. This function will fail an assertion if the | ||
358 | * caller gives it self-contradictory data, ie if two elements are claimed to | ||
359 | * be both opposite and non-opposite. */ | ||
360 | void edsf_merge(int *dsf, int v1, int v2, int inverse); | ||
361 | void dsf_merge(int *dsf, int v1, int v2); | ||
362 | void dsf_init(int *dsf, int len); | ||
363 | |||
364 | /* | ||
365 | * tdq.c | ||
366 | */ | ||
367 | |||
368 | /* | ||
369 | * Data structure implementing a 'to-do queue', a simple | ||
370 | * de-duplicating to-do list mechanism. | ||
371 | * | ||
372 | * Specification: a tdq is a queue which can hold integers from 0 to | ||
373 | * n-1, where n was some constant specified at tdq creation time. No | ||
374 | * integer may appear in the queue's current contents more than once; | ||
375 | * an attempt to add an already-present integer again will do nothing, | ||
376 | * so that that integer is removed from the queue at the position | ||
377 | * where it was _first_ inserted. The add and remove operations take | ||
378 | * constant time. | ||
379 | * | ||
380 | * The idea is that you might use this in applications like solvers: | ||
381 | * keep a tdq listing the indices of grid squares that you currently | ||
382 | * need to process in some way. Whenever you modify a square in a way | ||
383 | * that will require you to re-scan its neighbours, add them to the | ||
384 | * list with tdq_add; meanwhile you're constantly taking elements off | ||
385 | * the list when you need another square to process. In solvers where | ||
386 | * deductions are mostly localised, this should prevent repeated | ||
387 | * O(N^2) loops over the whole grid looking for something to do. (But | ||
388 | * if only _most_ of the deductions are localised, then you should | ||
389 | * respond to an empty to-do list by re-adding everything using | ||
390 | * tdq_fill, so _then_ you rescan the whole grid looking for newly | ||
391 | * enabled non-local deductions. Only if you've done that and emptied | ||
392 | * the list again finding nothing new to do are you actually done.) | ||
393 | */ | ||
394 | typedef struct tdq tdq; | ||
395 | tdq *tdq_new(int n); | ||
396 | void tdq_free(tdq *tdq); | ||
397 | void tdq_add(tdq *tdq, int k); | ||
398 | int tdq_remove(tdq *tdq); /* returns -1 if nothing available */ | ||
399 | void tdq_fill(tdq *tdq); /* add everything to the tdq at once */ | ||
400 | |||
401 | /* | ||
402 | * laydomino.c | ||
403 | */ | ||
404 | int *domino_layout(int w, int h, random_state *rs); | ||
405 | void domino_layout_prealloc(int w, int h, random_state *rs, | ||
406 | int *grid, int *grid2, int *list); | ||
407 | /* | ||
408 | * version.c | ||
409 | */ | ||
410 | extern char ver[]; | ||
411 | |||
412 | /* | ||
413 | * random.c | ||
414 | */ | ||
415 | random_state *random_new(const char *seed, int len); | ||
416 | random_state *random_copy(random_state *tocopy); | ||
417 | unsigned long random_bits(random_state *state, int bits); | ||
418 | unsigned long random_upto(random_state *state, unsigned long limit); | ||
419 | void random_free(random_state *state); | ||
420 | char *random_state_encode(random_state *state); | ||
421 | random_state *random_state_decode(const char *input); | ||
422 | /* random.c also exports SHA, which occasionally comes in useful. */ | ||
423 | #if __STDC_VERSION__ >= 199901L | ||
424 | #include <stdint.h> | ||
425 | typedef uint32_t uint32; | ||
426 | #elif UINT_MAX >= 4294967295L | ||
427 | typedef unsigned int uint32; | ||
428 | #else | ||
429 | typedef unsigned long uint32; | ||
430 | #endif | ||
431 | typedef struct { | ||
432 | uint32 h[5]; | ||
433 | unsigned char block[64]; | ||
434 | int blkused; | ||
435 | uint32 lenhi, lenlo; | ||
436 | } SHA_State; | ||
437 | void SHA_Init(SHA_State *s); | ||
438 | void SHA_Bytes(SHA_State *s, const void *p, int len); | ||
439 | void SHA_Final(SHA_State *s, unsigned char *output); | ||
440 | void SHA_Simple(const void *p, int len, unsigned char *output); | ||
441 | |||
442 | /* | ||
443 | * printing.c | ||
444 | */ | ||
445 | document *document_new(int pw, int ph, float userscale); | ||
446 | void document_free(document *doc); | ||
447 | void document_add_puzzle(document *doc, const game *game, game_params *par, | ||
448 | game_state *st, game_state *st2); | ||
449 | void document_print(document *doc, drawing *dr); | ||
450 | |||
451 | /* | ||
452 | * ps.c | ||
453 | */ | ||
454 | //psdata *ps_init(FILE *outfile, int colour); | ||
455 | //void ps_free(psdata *ps); | ||
456 | //drawing *ps_drawing_api(psdata *ps); | ||
457 | |||
458 | /* | ||
459 | * combi.c: provides a structure and functions for iterating over | ||
460 | * combinations (i.e. choosing r things out of n). | ||
461 | */ | ||
462 | typedef struct _combi_ctx { | ||
463 | int r, n, nleft, total; | ||
464 | int *a; | ||
465 | } combi_ctx; | ||
466 | |||
467 | combi_ctx *new_combi(int r, int n); | ||
468 | void reset_combi(combi_ctx *combi); | ||
469 | combi_ctx *next_combi(combi_ctx *combi); /* returns NULL for end */ | ||
470 | void free_combi(combi_ctx *combi); | ||
471 | |||
472 | /* | ||
473 | * divvy.c | ||
474 | */ | ||
475 | /* divides w*h rectangle into pieces of size k. Returns w*h dsf. */ | ||
476 | int *divvy_rectangle(int w, int h, int k, random_state *rs); | ||
477 | |||
478 | /* | ||
479 | * findloop.c | ||
480 | */ | ||
481 | struct findloopstate; | ||
482 | struct findloopstate *findloop_new_state(int nvertices); | ||
483 | void findloop_free_state(struct findloopstate *); | ||
484 | /* | ||
485 | * Callback provided by the client code to enumerate the graph | ||
486 | * vertices joined directly to a given vertex. | ||
487 | * | ||
488 | * Semantics: if vertex >= 0, return one of its neighbours; if vertex | ||
489 | * < 0, return a previously unmentioned neighbour of whatever vertex | ||
490 | * was last passed as input. Write to 'ctx' as necessary to store | ||
491 | * state. In either case, return < 0 if no such vertex can be found. | ||
492 | */ | ||
493 | typedef int (*neighbour_fn_t)(int vertex, void *ctx); | ||
494 | /* | ||
495 | * Actual function to find loops. 'ctx' will be passed unchanged to | ||
496 | * the 'neighbour' function to query graph edges. Returns FALSE if no | ||
497 | * loop was found, or TRUE if one was. | ||
498 | */ | ||
499 | int findloop_run(struct findloopstate *state, int nvertices, | ||
500 | neighbour_fn_t neighbour, void *ctx); | ||
501 | /* | ||
502 | * Query whether an edge is part of a loop, in the output of | ||
503 | * find_loops. | ||
504 | * | ||
505 | * Due to the internal storage format, if you pass u,v which are not | ||
506 | * connected at all, the output will be TRUE. (The algorithm actually | ||
507 | * stores an exhaustive list of *non*-loop edges, because there are | ||
508 | * fewer of those, so really it's querying whether the edge is on that | ||
509 | * list.) | ||
510 | */ | ||
511 | int findloop_is_loop_edge(struct findloopstate *state, int u, int v); | ||
512 | |||
513 | /* | ||
514 | * Data structure containing the function calls and data specific | ||
515 | * to a particular game. This is enclosed in a data structure so | ||
516 | * that a particular platform can choose, if it wishes, to compile | ||
517 | * all the games into a single combined executable rather than | ||
518 | * having lots of little ones. | ||
519 | */ | ||
520 | struct game { | ||
521 | const char *name; | ||
522 | const char *winhelp_topic, *htmlhelp_topic; | ||
523 | game_params *(*default_params)(void); | ||
524 | int (*fetch_preset)(int i, char **name, game_params **params); | ||
525 | void (*decode_params)(game_params *, char const *string); | ||
526 | char *(*encode_params)(const game_params *, int full); | ||
527 | void (*free_params)(game_params *params); | ||
528 | game_params *(*dup_params)(const game_params *params); | ||
529 | int can_configure; | ||
530 | config_item *(*configure)(const game_params *params); | ||
531 | game_params *(*custom_params)(const config_item *cfg); | ||
532 | char *(*validate_params)(const game_params *params, int full); | ||
533 | char *(*new_desc)(const game_params *params, random_state *rs, | ||
534 | char **aux, int interactive); | ||
535 | char *(*validate_desc)(const game_params *params, const char *desc); | ||
536 | game_state *(*new_game)(midend *me, const game_params *params, | ||
537 | const char *desc); | ||
538 | game_state *(*dup_game)(const game_state *state); | ||
539 | void (*free_game)(game_state *state); | ||
540 | int can_solve; | ||
541 | char *(*solve)(const game_state *orig, const game_state *curr, | ||
542 | const char *aux, char **error); | ||
543 | int can_format_as_text_ever; | ||
544 | int (*can_format_as_text_now)(const game_params *params); | ||
545 | char *(*text_format)(const game_state *state); | ||
546 | game_ui *(*new_ui)(const game_state *state); | ||
547 | void (*free_ui)(game_ui *ui); | ||
548 | char *(*encode_ui)(const game_ui *ui); | ||
549 | void (*decode_ui)(game_ui *ui, const char *encoding); | ||
550 | void (*changed_state)(game_ui *ui, const game_state *oldstate, | ||
551 | const game_state *newstate); | ||
552 | char *(*interpret_move)(const game_state *state, game_ui *ui, | ||
553 | const game_drawstate *ds, int x, int y, int button); | ||
554 | game_state *(*execute_move)(const game_state *state, const char *move); | ||
555 | int preferred_tilesize; | ||
556 | void (*compute_size)(const game_params *params, int tilesize, | ||
557 | int *x, int *y); | ||
558 | void (*set_size)(drawing *dr, game_drawstate *ds, | ||
559 | const game_params *params, int tilesize); | ||
560 | float *(*colours)(frontend *fe, int *ncolours); | ||
561 | game_drawstate *(*new_drawstate)(drawing *dr, const game_state *state); | ||
562 | void (*free_drawstate)(drawing *dr, game_drawstate *ds); | ||
563 | void (*redraw)(drawing *dr, game_drawstate *ds, const game_state *oldstate, | ||
564 | const game_state *newstate, int dir, const game_ui *ui, | ||
565 | float anim_time, float flash_time); | ||
566 | float (*anim_length)(const game_state *oldstate, | ||
567 | const game_state *newstate, int dir, game_ui *ui); | ||
568 | float (*flash_length)(const game_state *oldstate, | ||
569 | const game_state *newstate, int dir, game_ui *ui); | ||
570 | int (*status)(const game_state *state); | ||
571 | int can_print, can_print_in_colour; | ||
572 | void (*print_size)(const game_params *params, float *x, float *y); | ||
573 | void (*print)(drawing *dr, const game_state *state, int tilesize); | ||
574 | int wants_statusbar; | ||
575 | int is_timed; | ||
576 | int (*timing_state)(const game_state *state, game_ui *ui); | ||
577 | int flags; | ||
578 | }; | ||
579 | |||
580 | /* | ||
581 | * Data structure containing the drawing API implemented by the | ||
582 | * front end and also by cross-platform printing modules such as | ||
583 | * PostScript. | ||
584 | */ | ||
585 | struct drawing_api { | ||
586 | void (*draw_text)(void *handle, int x, int y, int fonttype, int fontsize, | ||
587 | int align, int colour, char *text); | ||
588 | void (*draw_rect)(void *handle, int x, int y, int w, int h, int colour); | ||
589 | void (*draw_line)(void *handle, int x1, int y1, int x2, int y2, | ||
590 | int colour); | ||
591 | void (*draw_polygon)(void *handle, int *coords, int npoints, | ||
592 | int fillcolour, int outlinecolour); | ||
593 | void (*draw_circle)(void *handle, int cx, int cy, int radius, | ||
594 | int fillcolour, int outlinecolour); | ||
595 | void (*draw_update)(void *handle, int x, int y, int w, int h); | ||
596 | void (*clip)(void *handle, int x, int y, int w, int h); | ||
597 | void (*unclip)(void *handle); | ||
598 | void (*start_draw)(void *handle); | ||
599 | void (*end_draw)(void *handle); | ||
600 | void (*status_bar)(void *handle, char *text); | ||
601 | blitter *(*blitter_new)(void *handle, int w, int h); | ||
602 | void (*blitter_free)(void *handle, blitter *bl); | ||
603 | void (*blitter_save)(void *handle, blitter *bl, int x, int y); | ||
604 | void (*blitter_load)(void *handle, blitter *bl, int x, int y); | ||
605 | void (*begin_doc)(void *handle, int pages); | ||
606 | void (*begin_page)(void *handle, int number); | ||
607 | void (*begin_puzzle)(void *handle, float xm, float xc, | ||
608 | float ym, float yc, int pw, int ph, float wmm); | ||
609 | void (*end_puzzle)(void *handle); | ||
610 | void (*end_page)(void *handle, int number); | ||
611 | void (*end_doc)(void *handle); | ||
612 | void (*line_width)(void *handle, float width); | ||
613 | void (*line_dotted)(void *handle, int dotted); | ||
614 | char *(*text_fallback)(void *handle, const char *const *strings, | ||
615 | int nstrings); | ||
616 | void (*draw_thick_line)(void *handle, float thickness, | ||
617 | float x1, float y1, float x2, float y2, | ||
618 | int colour); | ||
619 | }; | ||
620 | |||
621 | /* | ||
622 | * For one-game-at-a-time platforms, there's a single structure | ||
623 | * like the above, under a fixed name. For all-at-once platforms, | ||
624 | * there's a list of all available puzzles in array form. | ||
625 | */ | ||
626 | #ifdef COMBINED | ||
627 | extern const game *gamelist[]; | ||
628 | extern const int gamecount; | ||
629 | #else | ||
630 | extern const game thegame; | ||
631 | #endif | ||
632 | |||
633 | /* A little bit of help to lazy developers */ | ||
634 | #define DEFAULT_STATUSBAR_TEXT "Use status_bar() to fill this in." | ||
635 | |||
636 | #endif /* PUZZLES_PUZZLES_H */ | ||