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