A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 864 lines 34 kB view raw
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 */