A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
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#include <stdbool.h>
12
13#define PI 3.141592653589793238462643383279502884197169399
14#define ROOT2 1.414213562373095048801688724209698078569672
15
16#define lenof(array) ( sizeof(array) / sizeof(*(array)) )
17
18#define STR_INT(x) #x
19#define STR(x) STR_INT(x)
20
21/* An upper bound on the length of sprintf'ed integers (signed or unsigned). */
22#define MAX_DIGITS(x) (sizeof(x) * CHAR_BIT / 3 + 2)
23
24/* NB not perfect because they evaluate arguments multiple times. */
25#ifndef max
26#define max(x,y) ( (x)>(y) ? (x) : (y) )
27#endif /* max */
28#ifndef min
29#define min(x,y) ( (x)<(y) ? (x) : (y) )
30#endif /* min */
31
32enum {
33 LEFT_BUTTON = 0x0200,
34 MIDDLE_BUTTON,
35 RIGHT_BUTTON,
36 LEFT_DRAG,
37 MIDDLE_DRAG,
38 RIGHT_DRAG,
39 LEFT_RELEASE,
40 MIDDLE_RELEASE,
41 RIGHT_RELEASE,
42 CURSOR_UP,
43 CURSOR_DOWN,
44 CURSOR_LEFT,
45 CURSOR_RIGHT,
46 CURSOR_SELECT,
47 CURSOR_SELECT2,
48 /* UI_* are special keystrokes generated by front ends in response
49 * to menu actions, never passed to back ends */
50 UI_LOWER_BOUND,
51 UI_QUIT,
52 UI_NEWGAME,
53 UI_SOLVE,
54 UI_UNDO,
55 UI_REDO,
56 UI_UPPER_BOUND,
57
58 /* made smaller because of 'limited range of datatype' errors. */
59 MOD_CTRL = 0x1000,
60 MOD_SHFT = 0x2000,
61 MOD_NUM_KEYPAD = 0x4000,
62 MOD_MASK = 0x7000 /* mask for all modifiers */
63};
64
65#define IS_MOUSE_DOWN(m) ( (unsigned)((m) - LEFT_BUTTON) <= \
66 (unsigned)(RIGHT_BUTTON - LEFT_BUTTON))
67#define IS_MOUSE_DRAG(m) ( (unsigned)((m) - LEFT_DRAG) <= \
68 (unsigned)(RIGHT_DRAG - LEFT_DRAG))
69#define IS_MOUSE_RELEASE(m) ( (unsigned)((m) - LEFT_RELEASE) <= \
70 (unsigned)(RIGHT_RELEASE - LEFT_RELEASE))
71#define IS_CURSOR_MOVE(m) ( (m) == CURSOR_UP || (m) == CURSOR_DOWN || \
72 (m) == CURSOR_RIGHT || (m) == CURSOR_LEFT )
73#define IS_CURSOR_SELECT(m) ( (m) == CURSOR_SELECT || (m) == CURSOR_SELECT2)
74#define IS_UI_FAKE_KEY(m) ( (m) > UI_LOWER_BOUND && (m) < UI_UPPER_BOUND )
75#define STRIP_BUTTON_MODIFIERS(m) ( (unsigned)(m) & ~MOD_MASK )
76
77/*
78 * Flags in the back end's `flags' word.
79 */
80/* Bit flags indicating mouse button priorities */
81#define BUTTON_BEATS(x,y) ( 1 << (((x)-LEFT_BUTTON)*3+(y)-LEFT_BUTTON) )
82/* Flag indicating that Solve operations should be animated */
83#define SOLVE_ANIMATES ( 1 << 9 )
84/* Pocket PC: Game requires right mouse button emulation */
85#define REQUIRE_RBUTTON ( 1 << 10 )
86/* Pocket PC: Game requires numeric input */
87#define REQUIRE_NUMPAD ( 1 << 11 )
88/* end of `flags' word definitions */
89
90#define IGNOREARG(x) ( (x) = (x) )
91
92typedef struct frontend frontend;
93typedef struct config_item config_item;
94typedef struct midend midend;
95typedef struct random_state random_state;
96typedef struct game_params game_params;
97typedef struct game_state game_state;
98typedef struct game_ui game_ui;
99typedef struct game_drawstate game_drawstate;
100typedef struct game game;
101typedef struct blitter blitter;
102typedef struct document document;
103typedef struct drawing_api drawing_api;
104typedef struct drawing drawing;
105typedef struct psdata psdata;
106
107#define ALIGN_VNORMAL 0x000
108#define ALIGN_VCENTRE 0x100
109
110#define ALIGN_HLEFT 0x000
111#define ALIGN_HCENTRE 0x001
112#define ALIGN_HRIGHT 0x002
113
114#define FONT_FIXED 0
115#define FONT_VARIABLE 1
116
117/* For printing colours */
118#define HATCH_SLASH 1
119#define HATCH_BACKSLASH 2
120#define HATCH_HORIZ 3
121#define HATCH_VERT 4
122#define HATCH_PLUS 5
123#define HATCH_X 6
124
125/*
126 * Structure used to pass configuration data between frontend and
127 * game
128 */
129enum { C_STRING, C_CHOICES, C_BOOLEAN, C_END };
130struct config_item {
131 /* Not dynamically allocated: the GUI display name for the option */
132 const char *name;
133 /* Not dynamically allocated: the keyword identifier for the
134 * option. Only examined in the case where this structure is being
135 * used for options that appear in config files, i.e. the
136 * get_prefs method fills this in but configure does not. */
137 const char *kw;
138 /* Value from the above C_* enum */
139 int type;
140 union {
141 struct { /* if type == C_STRING */
142 /* Always dynamically allocated and non-NULL */
143 char *sval;
144 } string;
145 struct { /* if type == C_CHOICES */
146 /*
147 * choicenames is non-NULL, not dynamically allocated, and
148 * contains a set of option strings separated by a
149 * delimiter. The delimiter is also the first character in
150 * the string, so for example ":Foo:Bar:Baz" gives three
151 * options `Foo', `Bar' and `Baz'.
152 */
153 const char *choicenames;
154 /*
155 * choicekws is non-NULL, not dynamically allocated, and
156 * contains a parallel list of keyword strings used to
157 * represent the enumeration in config files. As with 'kw'
158 * above, this is only expected to be set by get_prefs.
159 */
160 const char *choicekws;
161 /*
162 * Indicates the chosen index from the options in
163 * choicenames. In the above example, 0==Foo, 1==Bar and
164 * 2==Baz.
165 */
166 int selected;
167 } choices;
168 struct {
169 bool bval;
170 } boolean;
171 } u;
172};
173
174/*
175 * Structure used to communicate the presets menu from midend to
176 * frontend. In principle, it's also used to pass the same information
177 * from game to midend, though games that don't specify a menu
178 * hierarchy (i.e. most of them) will use the simpler fetch_preset()
179 * function to return an unstructured list.
180 *
181 * A tree of these structures always belongs to the midend, and only
182 * the midend should ever need to free it. The front end should treat
183 * them as read-only.
184 */
185struct preset_menu_entry {
186 char *title;
187 /* Exactly one of the next two fields is NULL, depending on
188 * whether this entry is a submenu title or an actual preset */
189 game_params *params;
190 struct preset_menu *submenu;
191 /* Every preset menu entry has a number allocated by the mid-end,
192 * so that midend_which_preset() can return a value that
193 * identifies an entry anywhere in the menu hierarchy. The values
194 * will be allocated reasonably densely from 1 upwards (so it's
195 * reasonable for the front end to use them as array indices if it
196 * needs to store GUI state per menu entry), but no other
197 * guarantee is given about their ordering.
198 *
199 * Entries containing submenus have ids too - not only the actual
200 * presets are numbered. */
201 int id;
202};
203struct preset_menu {
204 int n_entries; /* number of entries actually in use */
205 int entries_size; /* space currently allocated in this array */
206 struct preset_menu_entry *entries;
207};
208/* For games which do want to directly return a tree of these, here
209 * are convenience routines (in midend.c) for constructing one. These
210 * assume that 'title' and 'encoded_params' are already dynamically
211 * allocated by the caller; the resulting preset_menu tree takes
212 * ownership of them. */
213struct preset_menu *preset_menu_new(void);
214struct preset_menu *preset_menu_add_submenu(struct preset_menu *parent,
215 char *title);
216void preset_menu_add_preset(struct preset_menu *menu,
217 char *title, game_params *params);
218/* Helper routine front ends can use for one of the ways they might
219 * want to organise their preset menu usage */
220game_params *preset_menu_lookup_by_id(struct preset_menu *menu, int id);
221
222/*
223 * Small structure specifying a UI button in a keyboardless front
224 * end. The button will have the text of "label" written on it, and
225 * pressing it causes the value "button" to be passed to
226 * midend_process_key() as if typed at the keyboard.
227 *
228 * If `label' is NULL (which it likely will be), a generic label can
229 * be generated with the button2label() function.
230 */
231typedef struct key_label {
232 /* What should be displayed to the user by the frontend. Backends
233 * can set this field to NULL and have it filled in by the midend
234 * with a generic label. Dynamically allocated, but frontends
235 * should probably use free_keys() to free instead. */
236 char *label;
237 int button; /* passed to midend_process_key when button is pressed */
238} key_label;
239
240/*
241 * Platform routines
242 */
243
244/* We can't use #ifdef DEBUG, because Cygwin defines it by default. */
245#ifdef DEBUGGING
246#define debug(x) (debug_printf x)
247void debug_printf(const char *fmt, ...);
248#else
249#define debug(x)
250#endif
251
252void fatal(const char *fmt, ...);
253void frontend_default_colour(frontend *fe, float *output);
254void deactivate_timer(frontend *fe);
255void activate_timer(frontend *fe);
256void get_random_seed(void **randseed, int *randseedsize);
257
258/*
259 * drawing.c
260 */
261drawing *drawing_new(const drawing_api *api, midend *me, void *handle);
262void drawing_free(drawing *dr);
263void draw_text(drawing *dr, int x, int y, int fonttype, int fontsize,
264 int align, int colour, const char *text);
265void draw_rect(drawing *dr, int x, int y, int w, int h, int colour);
266void draw_line(drawing *dr, int x1, int y1, int x2, int y2, int colour);
267void draw_polygon(drawing *dr, const int *coords, int npoints,
268 int fillcolour, int outlinecolour);
269void draw_polygon_fallback(drawing *dr, const int *coords, int npoints,
270 int fillcolour, int outlinecolour);
271void draw_circle(drawing *dr, int cx, int cy, int radius,
272 int fillcolour, int outlinecolour);
273void draw_thick_line(drawing *dr, float thickness,
274 float x1, float y1, float x2, float y2, int colour);
275void clip(drawing *dr, int x, int y, int w, int h);
276void unclip(drawing *dr);
277void start_draw(drawing *dr);
278void draw_update(drawing *dr, int x, int y, int w, int h);
279void end_draw(drawing *dr);
280char *text_fallback(drawing *dr, const char *const *strings, int nstrings);
281void status_bar(drawing *dr, const char *text);
282blitter *blitter_new(drawing *dr, int w, int h);
283void blitter_free(drawing *dr, blitter *bl);
284void blitter_save(drawing *dr, blitter *bl, int x, int y);
285void blitter_load(drawing *dr, blitter *bl, int x, int y);
286void print_begin_doc(drawing *dr, int pages);
287void print_begin_page(drawing *dr, int number);
288void print_begin_puzzle(drawing *dr, float xm, float xc,
289 float ym, float yc, int pw, int ph, float wmm,
290 float scale);
291void print_end_puzzle(drawing *dr);
292void print_end_page(drawing *dr, int number);
293void print_end_doc(drawing *dr);
294void print_get_colour(drawing *dr, int colour, bool printing_in_colour,
295 int *hatch, float *r, float *g, float *b);
296int print_mono_colour(drawing *dr, int grey); /* 0==black, 1==white */
297int print_grey_colour(drawing *dr, float grey);
298int print_hatched_colour(drawing *dr, int hatch);
299int print_rgb_mono_colour(drawing *dr, float r, float g, float b, int mono);
300int print_rgb_grey_colour(drawing *dr, float r, float g, float b, float grey);
301int print_rgb_hatched_colour(drawing *dr, float r, float g, float b,
302 int hatch);
303void print_line_width(drawing *dr, int width);
304void print_line_dotted(drawing *dr, bool dotted);
305
306/*
307 * midend.c
308 */
309midend *midend_new(frontend *fe, const game *ourgame,
310 const drawing_api *drapi, void *drhandle);
311void midend_free(midend *me);
312const game *midend_which_game(midend *me);
313void midend_set_params(midend *me, game_params *params);
314game_params *midend_get_params(midend *me);
315void midend_size(midend *me, int *x, int *y, bool user_size,
316 double device_pixel_ratio);
317void midend_reset_tilesize(midend *me);
318void midend_new_game(midend *me);
319void midend_restart_game(midend *me);
320void midend_stop_anim(midend *me);
321enum { PKR_QUIT = 0, PKR_SOME_EFFECT, PKR_NO_EFFECT, PKR_UNUSED };
322int midend_process_key(midend *me, int x, int y, int button);
323key_label *midend_request_keys(midend *me, int *nkeys);
324const char *midend_current_key_label(midend *me, int button);
325void midend_force_redraw(midend *me);
326void midend_redraw(midend *me);
327float *midend_colours(midend *me, int *ncolours);
328void midend_freeze_timer(midend *me, float tprop);
329void midend_timer(midend *me, float tplus);
330struct preset_menu *midend_get_presets(midend *me, int *id_limit);
331int midend_which_preset(midend *me);
332bool midend_wants_statusbar(midend *me);
333enum { CFG_SETTINGS, CFG_SEED, CFG_DESC, CFG_PREFS, CFG_FRONTEND_SPECIFIC };
334config_item *midend_get_config(midend *me, int which, char **wintitle);
335const char *midend_set_config(midend *me, int which, config_item *cfg);
336const char *midend_game_id(midend *me, const char *id);
337char *midend_get_game_id(midend *me);
338char *midend_get_random_seed(midend *me);
339bool midend_can_format_as_text_now(midend *me);
340char *midend_text_format(midend *me);
341const char *midend_solve(midend *me);
342int midend_status(midend *me);
343bool midend_can_undo(midend *me);
344bool midend_can_redo(midend *me);
345void midend_supersede_game_desc(midend *me, const char *desc,
346 const char *privdesc);
347char *midend_rewrite_statusbar(midend *me, const char *text);
348void midend_serialise(midend *me,
349 void (*write)(void *ctx, const void *buf, int len),
350 void *wctx);
351const char *midend_deserialise(midend *me,
352 bool (*read)(void *ctx, void *buf, int len),
353 void *rctx);
354const char *midend_load_prefs(
355 midend *me, bool (*read)(void *ctx, void *buf, int len), void *rctx);
356void midend_save_prefs(midend *me,
357 void (*write)(void *ctx, const void *buf, int len),
358 void *wctx);
359const char *identify_game(char **name,
360 bool (*read)(void *ctx, void *buf, int len),
361 void *rctx);
362void midend_request_id_changes(midend *me, void (*notify)(void *), void *ctx);
363bool midend_get_cursor_location(midend *me, int *x, int *y, int *w, int *h);
364
365/* Printing functions supplied by the mid-end */
366const char *midend_print_puzzle(midend *me, document *doc, bool with_soln);
367int midend_tilesize(midend *me);
368
369/*
370 * malloc.c
371 */
372void *smalloc(size_t size);
373void *srealloc(void *p, size_t size);
374void sfree(void *p);
375char *dupstr(const char *s);
376#define snew(type) \
377 ( (type *) smalloc (sizeof (type)) )
378#define snewn(number, type) \
379 ( (type *) smalloc ((number) * sizeof (type)) )
380#define sresize(array, number, type) \
381 ( (type *) srealloc ((array), (number) * sizeof (type)) )
382
383/*
384 * misc.c
385 */
386void free_cfg(config_item *cfg);
387void free_keys(key_label *keys, int nkeys);
388void obfuscate_bitmap(unsigned char *bmp, int bits, bool decode);
389char *fgetline(FILE *fp);
390char *make_prefs_path(const char *dir, const char *sep,
391 const game *game, const char *suffix);
392int n_times_root_k(int n, int k);
393
394/* allocates output each time. len is always in bytes of binary data.
395 * May assert (or just go wrong) if lengths are unchecked. */
396char *bin2hex(const unsigned char *in, int inlen);
397unsigned char *hex2bin(const char *in, int outlen);
398
399/* Returns 0 or 1 if the environment variable is set, or dflt if not.
400 * dflt may be a third value if it needs to be. */
401int getenv_bool(const char *name, int dflt);
402
403/* Mixes two colours in specified proportions. */
404void colour_mix(const float src1[3], const float src2[3], float p,
405 float dst[3]);
406/* Sets (and possibly dims) background from frontend default colour,
407 * and auto-generates highlight and lowlight colours too. */
408void game_mkhighlight(frontend *fe, float *ret,
409 int background, int highlight, int lowlight);
410/* As above, but starts from a provided background colour rather
411 * than the frontend default. */
412void game_mkhighlight_specific(frontend *fe, float *ret,
413 int background, int highlight, int lowlight);
414
415/* Randomly shuffles an array of items. */
416void shuffle(void *array, int nelts, int eltsize, random_state *rs);
417
418/* Draw a rectangle outline, using the drawing API's draw_polygon. */
419void draw_rect_outline(drawing *dr, int x, int y, int w, int h,
420 int colour);
421
422/* Draw a set of rectangle corners (e.g. for a cursor display). */
423void draw_rect_corners(drawing *dr, int cx, int cy, int r, int col);
424
425char *move_cursor(int button, int *x, int *y, int maxw, int maxh, bool wrap,
426 bool *visible);
427
428/* Used in netslide.c and sixteen.c for cursor movement around edge. */
429int c2pos(int w, int h, int cx, int cy);
430int c2diff(int w, int h, int cx, int cy, int button);
431void pos2c(int w, int h, int pos, int *cx, int *cy);
432
433/* Draws text with an 'outline' formed by offsetting the text
434 * by one pixel; useful for highlighting. Outline is omitted if -1. */
435void draw_text_outline(drawing *dr, int x, int y, int fonttype,
436 int fontsize, int align,
437 int text_colour, int outline_colour, const char *text);
438
439/* Copies text left-justified with spaces. Length of string must be
440 * less than buffer size. */
441void copy_left_justified(char *buf, size_t sz, const char *str);
442
443/* Returns a generic label based on the value of `button.' To be used
444 whenever a `label' field returned by the request_keys() game
445 function is NULL. Dynamically allocated, to be freed by caller. */
446char *button2label(int button);
447
448/* Swap two regions of memory. The two regions must not
449 * overlap. (Note: the natural name for this might be "memswap", but
450 * the mem* namespace is reserved for future expansion by the C99
451 * standard per clause 7.26.11.1.) */
452void swap_regions(void *av, void *bv, size_t size);
453
454/* comparator for sorting ints with qsort() */
455int compare_integers(const void *av, const void *bv);
456
457/*
458 * dsf.c
459 */
460typedef struct DSF DSF;
461DSF *dsf_new(int size);
462void dsf_free(DSF *dsf);
463
464void dsf_copy(DSF *to, DSF *from);
465
466/* Basic dsf operations, return the canonical element of a class,
467 * check if two elements are in the same class, and return the size of
468 * a class. These work on all types of dsf. */
469int dsf_canonify(DSF *dsf, int n);
470bool dsf_equivalent(DSF *dsf, int n1, int n2);
471int dsf_size(DSF *dsf, int n);
472
473/* Merge two elements and their classes. Not legal on a flip dsf. */
474void dsf_merge(DSF *dsf, int n1, int n2);
475
476/* Special dsf that tracks the minimal element of every equivalence
477 * class, and a function to query it. */
478DSF *dsf_new_min(int size);
479int dsf_minimal(DSF *dsf, int n);
480
481/* Special dsf that tracks whether pairs of elements in the same class
482 * have flipped sense relative to each other. Merge function takes an
483 * argument saying whether n1 and n2 are opposite to each other;
484 * canonify function will report whether n is opposite to the returned
485 * element. */
486DSF *dsf_new_flip(int size);
487void dsf_merge_flip(DSF *dsf, int n1, int n2, bool flip);
488int dsf_canonify_flip(DSF *dsf, int n, bool *flip);
489
490/* Reinitialise a dsf to the starting 'all elements distinct' state. */
491void dsf_reinit(DSF *dsf);
492
493/*
494 * tdq.c
495 */
496
497/*
498 * Data structure implementing a 'to-do queue', a simple
499 * de-duplicating to-do list mechanism.
500 *
501 * Specification: a tdq is a queue which can hold integers from 0 to
502 * n-1, where n was some constant specified at tdq creation time. No
503 * integer may appear in the queue's current contents more than once;
504 * an attempt to add an already-present integer again will do nothing,
505 * so that that integer is removed from the queue at the position
506 * where it was _first_ inserted. The add and remove operations take
507 * constant time.
508 *
509 * The idea is that you might use this in applications like solvers:
510 * keep a tdq listing the indices of grid squares that you currently
511 * need to process in some way. Whenever you modify a square in a way
512 * that will require you to re-scan its neighbours, add them to the
513 * list with tdq_add; meanwhile you're constantly taking elements off
514 * the list when you need another square to process. In solvers where
515 * deductions are mostly localised, this should prevent repeated
516 * O(N^2) loops over the whole grid looking for something to do. (But
517 * if only _most_ of the deductions are localised, then you should
518 * respond to an empty to-do list by re-adding everything using
519 * tdq_fill, so _then_ you rescan the whole grid looking for newly
520 * enabled non-local deductions. Only if you've done that and emptied
521 * the list again finding nothing new to do are you actually done.)
522 */
523typedef struct tdq tdq;
524tdq *tdq_new(int n);
525void tdq_free(tdq *tdq);
526void tdq_add(tdq *tdq, int k);
527int tdq_remove(tdq *tdq); /* returns -1 if nothing available */
528void tdq_fill(tdq *tdq); /* add everything to the tdq at once */
529
530/*
531 * laydomino.c
532 */
533int *domino_layout(int w, int h, random_state *rs);
534void domino_layout_prealloc(int w, int h, random_state *rs,
535 int *grid, int *grid2, int *list);
536/*
537 * version.c
538 */
539extern char ver[];
540
541/*
542 * random.c
543 */
544random_state *random_new(const char *seed, int len);
545random_state *random_copy(random_state *tocopy);
546unsigned long random_bits(random_state *state, int bits);
547unsigned long random_upto(random_state *state, unsigned long limit);
548void random_free(random_state *state);
549char *random_state_encode(random_state *state);
550random_state *random_state_decode(const char *input);
551/* random.c also exports SHA, which occasionally comes in useful. */
552#if HAVE_STDINT_H
553#include <stdint.h>
554typedef uint32_t uint32;
555#elif UINT_MAX >= 4294967295L
556typedef unsigned int uint32;
557#else
558typedef unsigned long uint32;
559#endif
560typedef struct {
561 uint32 h[5];
562 unsigned char block[64];
563 int blkused;
564 uint32 lenhi, lenlo;
565} SHA_State;
566void SHA_Init(SHA_State *s);
567void SHA_Bytes(SHA_State *s, const void *p, int len);
568void SHA_Final(SHA_State *s, unsigned char *output);
569void SHA_Simple(const void *p, int len, unsigned char *output);
570
571/*
572 * printing.c
573 */
574document *document_new(int pw, int ph, float userscale);
575void document_free(document *doc);
576void document_add_puzzle(document *doc, const game *game, game_params *par,
577 game_ui *ui, game_state *st, game_state *st2);
578int document_npages(const document *doc);
579void document_begin(const document *doc, drawing *dr);
580void document_end(const document *doc, drawing *dr);
581void document_print_page(const document *doc, drawing *dr, int page_nr);
582void document_print(const document *doc, drawing *dr);
583
584/*
585 * ps.c
586 */
587psdata *ps_init(FILE *outfile, bool colour);
588void ps_free(psdata *ps);
589drawing *ps_drawing_api(psdata *ps);
590
591/*
592 * combi.c: provides a structure and functions for iterating over
593 * combinations (i.e. choosing r things out of n).
594 */
595typedef struct _combi_ctx {
596 int r, n, nleft, total;
597 int *a;
598} combi_ctx;
599
600combi_ctx *new_combi(int r, int n);
601void reset_combi(combi_ctx *combi);
602combi_ctx *next_combi(combi_ctx *combi); /* returns NULL for end */
603void free_combi(combi_ctx *combi);
604
605/*
606 * divvy.c
607 */
608/* divides w*h rectangle into pieces of size k. Returns w*h dsf. */
609DSF *divvy_rectangle(int w, int h, int k, random_state *rs);
610/* Same, but only tries once, and may fail. (Exposed for test program.) */
611DSF *divvy_rectangle_attempt(int w, int h, int k, random_state *rs);
612
613/*
614 * findloop.c
615 */
616struct findloopstate;
617struct findloopstate *findloop_new_state(int nvertices);
618void findloop_free_state(struct findloopstate *);
619/*
620 * Callback provided by the client code to enumerate the graph
621 * vertices joined directly to a given vertex.
622 *
623 * Semantics: if vertex >= 0, return one of its neighbours; if vertex
624 * < 0, return a previously unmentioned neighbour of whatever vertex
625 * was last passed as input. Write to 'ctx' as necessary to store
626 * state. In either case, return < 0 if no such vertex can be found.
627 */
628typedef int (*neighbour_fn_t)(int vertex, void *ctx);
629/*
630 * Actual function to find loops. 'ctx' will be passed unchanged to
631 * the 'neighbour' function to query graph edges. Returns false if no
632 * loop was found, or true if one was.
633 */
634bool findloop_run(struct findloopstate *state, int nvertices,
635 neighbour_fn_t neighbour, void *ctx);
636/*
637 * Query whether an edge is part of a loop, in the output of
638 * find_loops.
639 *
640 * Due to the internal storage format, if you pass u,v which are not
641 * connected at all, the output will be true. (The algorithm actually
642 * stores an exhaustive list of *non*-loop edges, because there are
643 * fewer of those, so really it's querying whether the edge is on that
644 * list.)
645 */
646bool findloop_is_loop_edge(struct findloopstate *state, int u, int v);
647
648/*
649 * Alternative query function, which returns true if the u-v edge is a
650 * _bridge_, i.e. a non-loop edge, i.e. an edge whose removal would
651 * disconnect a currently connected component of the graph.
652 *
653 * If the return value is true, then the numbers of vertices that
654 * would be in the new components containing u and v are written into
655 * u_vertices and v_vertices respectively.
656 */
657bool findloop_is_bridge(
658 struct findloopstate *pv, int u, int v, int *u_vertices, int *v_vertices);
659
660/*
661 * Helper function to sort an array. Differs from standard qsort in
662 * that it takes a context parameter that is passed to the compare
663 * function.
664 *
665 * I wrap it in a macro so that you only need to give the element
666 * count of the array. The element size is determined by sizeof.
667 */
668typedef int (*arraysort_cmpfn_t)(const void *av, const void *bv, void *ctx);
669void arraysort_fn(void *array, size_t nmemb, size_t size,
670 arraysort_cmpfn_t cmp, void *ctx);
671#define arraysort(array, nmemb, cmp, ctx) \
672 arraysort_fn(array, nmemb, sizeof(*(array)), cmp, ctx)
673
674/*
675 * Data structure containing the function calls and data specific
676 * to a particular game. This is enclosed in a data structure so
677 * that a particular platform can choose, if it wishes, to compile
678 * all the games into a single combined executable rather than
679 * having lots of little ones.
680 */
681struct game {
682 const char *name;
683 const char *winhelp_topic, *htmlhelp_topic;
684 game_params *(*default_params)(void);
685 bool (*fetch_preset)(int i, char **name, game_params **params);
686 struct preset_menu *(*preset_menu)(void);
687 void (*decode_params)(game_params *, char const *string);
688 char *(*encode_params)(const game_params *, bool full);
689 void (*free_params)(game_params *params);
690 game_params *(*dup_params)(const game_params *params);
691 bool can_configure;
692 config_item *(*configure)(const game_params *params);
693 game_params *(*custom_params)(const config_item *cfg);
694 const char *(*validate_params)(const game_params *params, bool full);
695 char *(*new_desc)(const game_params *params, random_state *rs,
696 char **aux, bool interactive);
697 const char *(*validate_desc)(const game_params *params, const char *desc);
698 game_state *(*new_game)(midend *me, const game_params *params,
699 const char *desc);
700 game_state *(*dup_game)(const game_state *state);
701 void (*free_game)(game_state *state);
702 bool can_solve;
703 char *(*solve)(const game_state *orig, const game_state *curr,
704 const char *aux, const char **error);
705 bool can_format_as_text_ever;
706 bool (*can_format_as_text_now)(const game_params *params);
707 char *(*text_format)(const game_state *state);
708 config_item *(*get_prefs)(game_ui *ui);
709 void (*set_prefs)(game_ui *ui, const config_item *cfg);
710 game_ui *(*new_ui)(const game_state *state);
711 void (*free_ui)(game_ui *ui);
712 char *(*encode_ui)(const game_ui *ui);
713 void (*decode_ui)(game_ui *ui, const char *encoding,
714 const game_state *state);
715 key_label *(*request_keys)(const game_params *params, int *nkeys);
716 void (*changed_state)(game_ui *ui, const game_state *oldstate,
717 const game_state *newstate);
718 const char *(*current_key_label)(const game_ui *ui,
719 const game_state *state, int button);
720 char *(*interpret_move)(const game_state *state, game_ui *ui,
721 const game_drawstate *ds, int x, int y, int button);
722 game_state *(*execute_move)(const game_state *state, const char *move);
723 int preferred_tilesize;
724 void (*compute_size)(const game_params *params, int tilesize,
725 const game_ui *ui, int *x, int *y);
726 void (*set_size)(drawing *dr, game_drawstate *ds,
727 const game_params *params, int tilesize);
728 float *(*colours)(frontend *fe, int *ncolours);
729 game_drawstate *(*new_drawstate)(drawing *dr, const game_state *state);
730 void (*free_drawstate)(drawing *dr, game_drawstate *ds);
731 void (*redraw)(drawing *dr, game_drawstate *ds, const game_state *oldstate,
732 const game_state *newstate, int dir, const game_ui *ui,
733 float anim_time, float flash_time);
734 float (*anim_length)(const game_state *oldstate,
735 const game_state *newstate, int dir, game_ui *ui);
736 float (*flash_length)(const game_state *oldstate,
737 const game_state *newstate, int dir, game_ui *ui);
738 void (*get_cursor_location)(const game_ui *ui,
739 const game_drawstate *ds,
740 const game_state *state,
741 const game_params *params,
742 int *x, int *y, int *w, int *h);
743 int (*status)(const game_state *state);
744 bool can_print, can_print_in_colour;
745 void (*print_size)(const game_params *params, const game_ui *ui,
746 float *x, float *y);
747 void (*print)(drawing *dr, const game_state *state, const game_ui *ui,
748 int tilesize);
749 bool wants_statusbar;
750 bool is_timed;
751 bool (*timing_state)(const game_state *state, game_ui *ui);
752 int flags;
753};
754
755#define GET_HANDLE_AS_TYPE(dr, type) ((type*)((dr)->handle))
756
757struct drawing {
758 const drawing_api *api;
759 void *handle;
760};
761
762/*
763 * Data structure containing the drawing API implemented by the
764 * front end and also by cross-platform printing modules such as
765 * PostScript.
766 */
767struct drawing_api {
768 /*
769 * API version. Increment this when there is a breaking change to
770 * this API which requires front ends to change.
771 *
772 * There is expliclty not a public LATEST_API_VERSION define, so
773 * that front end authors will need to manually intervene when the
774 * version number changes. Naturally, this should be done
775 * sparingly.
776 *
777 * If a function is ever added to this API, please move this field
778 * to the _end_ of the structure, so that changes thereafter will
779 * shift the position of the version and lead to a compilation
780 * error if old implementations are not updated. Then remove this
781 * comment.
782 *
783 * The latest version number is 1.
784 *
785 * Change log:
786 *
787 * Version 1 (2024-08-14): Introduction of version number, in
788 * conjunction with changing every API function to take `drawing
789 * *` instead of `void *`. See commit f379130 for the detailed
790 * rationale behind this change.
791 */
792 int version;
793
794 void (*draw_text)(drawing *dr, int x, int y, int fonttype, int fontsize,
795 int align, int colour, const char *text);
796 void (*draw_rect)(drawing *dr, int x, int y, int w, int h, int colour);
797 void (*draw_line)(drawing *dr, int x1, int y1, int x2, int y2,
798 int colour);
799 void (*draw_polygon)(drawing *dr, const int *coords, int npoints,
800 int fillcolour, int outlinecolour);
801 void (*draw_circle)(drawing *dr, int cx, int cy, int radius,
802 int fillcolour, int outlinecolour);
803 void (*draw_update)(drawing *dr, int x, int y, int w, int h);
804 void (*clip)(drawing *dr, int x, int y, int w, int h);
805 void (*unclip)(drawing *dr);
806 void (*start_draw)(drawing *dr);
807 void (*end_draw)(drawing *dr);
808 void (*status_bar)(drawing *dr, const char *text);
809 blitter *(*blitter_new)(drawing *dr, int w, int h);
810 void (*blitter_free)(drawing *dr, blitter *bl);
811 void (*blitter_save)(drawing *dr, blitter *bl, int x, int y);
812 void (*blitter_load)(drawing *dr, blitter *bl, int x, int y);
813 void (*begin_doc)(drawing *dr, int pages);
814 void (*begin_page)(drawing *dr, int number);
815 void (*begin_puzzle)(drawing *dr, float xm, float xc,
816 float ym, float yc, int pw, int ph, float wmm);
817 void (*end_puzzle)(drawing *dr);
818 void (*end_page)(drawing *dr, int number);
819 void (*end_doc)(drawing *dr);
820 void (*line_width)(drawing *dr, float width);
821 void (*line_dotted)(drawing *dr, bool dotted);
822 char *(*text_fallback)(drawing *dr, const char *const *strings,
823 int nstrings);
824 void (*draw_thick_line)(drawing *dr, float thickness,
825 float x1, float y1, float x2, float y2,
826 int colour);
827};
828
829/*
830 * For one-game-at-a-time platforms, there's a single structure
831 * like the above, under a fixed name. For all-at-once platforms,
832 * there's a list of all available puzzles in array form.
833 */
834#ifdef COMBINED
835extern const game *gamelist[];
836extern const int gamecount;
837/* Also pre-declare every individual 'struct game' we expect */
838#define GAME(x) extern const game x;
839#include "generated-games.h"
840#undef GAME
841#else
842extern const game thegame;
843#endif
844
845/*
846 * Special string values to return from interpret_move.
847 *
848 * MOVE_UI_UPDATE is for the case where the game UI has been updated
849 * but no actual move is being appended to the undo chain.
850 *
851 * MOVE_NO_EFFECT is for when the key was understood by the puzzle,
852 * but it happens that there isn't effect, not even a UI change.
853 *
854 * MOVE_UNUSED is for keys that the puzzle has no use for at all.
855 *
856 * Each must be declared as a non-const char, but should never
857 * actually be modified by anyone.
858 */
859extern char MOVE_UI_UPDATE[], MOVE_NO_EFFECT[], MOVE_UNUSED[];
860
861/* A little bit of help to lazy developers */
862#define DEFAULT_STATUSBAR_TEXT "Use status_bar() to fill this in."
863
864#endif /* PUZZLES_PUZZLES_H */