1 /* Random definitions used everywhere in Xconq. 2 Copyright (C) 1987-1989, 1991-1997, 1999 Stanley T. Shebs. 3 Copyright (C) 2004-2005 Eric A. McDonald. 4 5 Xconq is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2, or (at your option) 8 any later version. See the file COPYING. */ 9 10 /*! \file kernel/misc.h 11 * \brief Random definitions used everywhere in Xconq. 12 * 13 * This file contains miscellaneous macro and constant definitions. 14 */ 15 16 #ifndef TRUE 17 #define TRUE (1) 18 #endif 19 #ifndef FALSE 20 #define FALSE (0) 21 #endif 22 23 #ifndef CONST 24 /*! \brief const definiton. 25 * 26 * This is how we do optional const decls. */ 27 #define CONST const 28 #endif /* CONST */ 29 30 #ifndef ABS 31 /*! \brief Absolute value. 32 * 33 * If the system does not define an absolute value 34 * macro, use this definition. The absolute value of a 35 * number is the number stripped of it's sign and expressed 36 * as a positive number. I.e. ABS(-3) == 3, ABS(3) == 3. 37 * \param x is the number of which to take the absolute value. 38 * \return the absolute value of x. 39 */ 40 #define ABS(x) (((x) < 0) ? (0 - (x)) : (x)) 41 #endif 42 43 #ifndef min 44 /*! \brief Minimum value. 45 * 46 * If the system doesn't define a minimum value macro or 47 * function, use this one. Find the smaller of two numbers. 48 * \param x is a number. 49 * \param y is a number. 50 * \return the smaller of the two numbers. 51 */ 52 #define min(x,y) (((x) < (y)) ? (x) : (y)) 53 #endif 54 55 #ifndef max 56 /*! \brief Maximum value. 57 * 58 * If the system doesn't define a maximum value macro or 59 * function, use this one. Find the larger of two numbers. 60 * \param x is a number. 61 * \param y is a number. 62 * \return the larger of the two numbers. 63 */ 64 #define max(x,y) (((x) > (y)) ? (x) : (y)) 65 #endif 66 67 /*! \brief Is between. 68 * 69 * Determines if a number is between two other numbers (inclusive). 70 * \param lo is the low value to check 71 * \param n is the number to be checked 72 * \param hi is the high value to check 73 * \return 74 * - true if n is between lo and hi (inclusive); 75 * - false otherwise. 76 */ 77 #define between(lo,n,hi) \ 78 ((lo) <= (n) && (n) <= (hi)) 79 80 /*! \brief Limit value. 81 * 82 * Limits the value of the paramter to be between a high and low 83 * value (inclusive). 84 * \param lo is the low value 85 * \param n is the number to limit 86 * \param hi is the high value 87 * \return 88 * - lo if n is less than lo; 89 * - n if n is between lo and hi; 90 * - hi if n is greater than hi. 91 */ 92 #define limitn(lo,n,hi) ((n) \ 93 < (lo) ? (lo) : ((n) > (hi) ? (hi) : (n))) 94 95 /*! \brief Random true/false. 96 * 97 * \return true or false randomly 98 */ 99 #define flip_coin() \ 100 (xrandom(257) % 2) 101 102 /*! \brief Average. 103 * 104 * Calculates the average value. Note that if sum of 105 * the numbers is greater than the range of the fundamental 106 * type,the answer will be wrong. 107 * \param a is a number 108 * \param b is a number 109 * \return the average of a and b 110 */ 111 #define avg(a,b) \ 112 (((a) + (b)) / 2) 113 114 /*! \brief Decompose a dice spec integer representation. 115 * 116 * Given an integer, determine if it could be a dice spec 117 * representation. If not, then return the value in the offset 118 * field. If so, then fill out the number of dice, number of spots 119 * per die, and offset fields. 120 */ 121 #define DICE(N,NUMDICE,SPOTS,OFFSET) \ 122 (((N) >> 14 == 0 || (N) >> 14 == 3) ? \ 123 (NUMDICE = 0, SPOTS = 0, OFFSET = (N)) : \ 124 (NUMDICE = ((N) >> 11) & 0x07, SPOTS = ((N) >> 7) & 0x0f, OFFSET = (N) & 0x7f)) 125 126 //! Normalize a number on a scale between -range and +range. 127 128 #define normalize_on_pmscale(n,max,range) \ 129 ((max) ? (((n) * (range)) / (max)) : 0) 130 131 #ifndef isspace 132 /*! \brief Is space. 133 * 134 * If the system doesn't provide a definition of isspace, this 135 * will define it. If a charact si a space, newline, tab or 136 * carraige return, this is a space. 137 * \param c is character to test. 138 * \return 139 * - true if c is a space, tab, newline, or carriage return; 140 * - false otherwise. 141 */ 142 #define isspace(c) \ 143 ((c) == ' ' || (c) == '\n' || (c) == '\t' || (c) == '\r') 144 #endif 145 146 #define lowercase(c) (isupper(c) ? tolower(c) : (c)) 147 148 #define uppercase(c) (islower(c) ? toupper(c) : (c)) 149 150 /*! \brief Is string empty. 151 * 152 * This tests a string to see if it has anything in it. 153 * \param s is a char* to a null terminated string, or 154 * a null. 155 * \return 156 * - true if an empty string; 157 * - false otherwise. 158 */ 159 #define empty_string(s) \ 160 ((s) == NULL || s[0] == '\0') 161 162 /*! \brief ??? */ 163 extern char spbuf[]; 164 /*! \brief ??? */ 165 extern char tmpbuf[]; 166 167 /*! \brief Table of Packed Booleans. 168 * 169 * This structure contains an array of packed booleans. 170 * 171 */ 172 173 typedef struct a_packed_bool_table { 174 int rdim1size; /* Reduced size of the first table dimension. */ 175 int dim2size; /* Normal size of the second dimension. */ 176 short sizeofint; /* Precalculated sizeof(int) in bits. */ 177 short whichway; /* Which packing direction is more efficient? */ 178 int *pbools; /* Pointer to the packed booleans. */ 179 } PackedBoolTable; 180 181 /*! \brief Get a boolean value from a table of packed booleans. 182 */ 183 184 #ifdef get_packed_bool 185 #undef get_packed_bool 186 #endif 187 #define get_packed_bool(tbl,m,n) \ 188 (((tbl)->pbools[((tbl)->whichway ? (m) : (n)) * (tbl)->rdim1size + ((tbl)->whichway ? (n) : (m)) / (tbl)->sizeofint] & (1 << ((tbl)->whichway ? (n) : (m)) % (tbl)->sizeofint)) ? TRUE : FALSE) 189 190 /*! \brief Set a boolean value in a table of packed booleans. 191 */ 192 193 #ifdef set_packed_bool 194 #undef set_packed_bool 195 #endif 196 #define set_packed_bool(tbl,m,n,boolval) \ 197 ((boolval) ? ((tbl)->pbools[((tbl)->whichway ? (m) : (n)) * (tbl)->rdim1size + ((tbl)->whichway ? (n) : (m)) / (tbl)->sizeofint] |= (1 << ((tbl)->whichway ? (n) : (m)) % (tbl)->sizeofint)) : ((tbl)->pbools[((tbl)->whichway ? (m) : (n)) * (tbl)->rdim1size + ((tbl)->whichway ? (n) : (m)) / (tbl)->sizeofint] &= ~(1 << ((tbl)->whichway ? (n) : (m)) % (tbl)->sizeofint))) 198 199 /*! \brief Validate a supposed table of packed booleans. 200 */ 201 202 #ifdef valid_packed_bool_table 203 #undef valid_packed_bool_table 204 #endif 205 #define valid_packed_bool_table(tbl) \ 206 (((tbl) != NULL) && ((tbl)->pbools != NULL) && ((tbl)->sizeofint > 0) && ((tbl)->rdim1size >= 0) && ((tbl)->dim2size > 0)) 207 208 /*! \brief Prototypes of functions used in the packed boolean implementation. 209 */ 210 211 extern PackedBoolTable* create_packed_bool_table(int m, int n); 212 extern void init_packed_bool_table(PackedBoolTable* tbl); 213 extern void destroy_packed_bool_table(PackedBoolTable* tbl); 214 215 /* Debugging definitions. */ 216 /* If asserts are off, then an appropriate user diagnostic will be 217 generated and/or a flow control statement will be used. If asserts are on, 218 then we obviously get the debugging benefits and abortive behavior. */ 219 220 #define assert_warning(cond, msg) \ 221 { assert(cond); if (!(cond)) run_warning(msg); } 222 #define assert_warning_break(cond, msg) \ 223 { assert(cond); if (!(cond)) { run_warning(msg); break; } } 224 #define assert_warning_continue(cond, msg) \ 225 { assert(cond); if (!(cond)) { run_warning(msg); continue; } } 226 #define assert_warning_goto(cond, msg, label) \ 227 { assert(cond); if (!(cond)) { run_warning(msg); goto label; } } 228 #define assert_warning_return(cond, msg, retval) \ 229 { assert(cond); if (!(cond)) { run_warning(msg); return retval; } } 230 #define assert_error(cond, msg) \ 231 { assert(cond); if (!(cond)) run_error(msg); } 232 #define assert_break(cond) \ 233 { assert(cond); if (!(cond)) break; } 234 #define assert_continue(cond) \ 235 { assert(cond); if (!(cond)) continue; } 236 #define assert_goto(cond, label) \ 237 { assert(cond); if (!(cond)) goto label; } 238 #define assert_return(cond, retval) \ 239 { assert(cond); if (!(cond)) return retval; } 240 241 #ifdef DEBUGGING 242 243 /* Debugging definitions. */ 244 245 #define Dprintf if (Debug && dfp) debug_printf 246 #define DMprintf if (DebugM && dmfp) debugm_printf 247 #define DGprintf if (DebugG && dgfp) debugg_printf 248 249 #define Dprintlisp(X) if (Debug && dfp) fprintlisp(dfp, (X)) 250 #define DMprintlisp(X) if (DebugM && dmfp) fprintlisp(dmfp, (X)) 251 #define DGprintlisp(X) if (DebugG && dgfp) fprintlisp(dgfp, (X)) 252 253 /* If the debug flags are not macros, then declare them as globals. */ 254 255 #ifndef Debug 256 extern int Debug; 257 #endif 258 #ifndef DebugM 259 extern int DebugM; 260 #endif 261 #ifndef DebugG 262 extern int DebugG; 263 #endif 264 265 extern FILE *dfp; 266 extern FILE *dmfp; 267 extern FILE *dgfp; 268 269 #else /* DEBUGGING */ 270 271 /* Make defns and calls vanish if possible. */ 272 273 #define Dprintf if (0) debug_printf 274 #define DMprintf if (0) debugm_printf 275 #define DGprintf if (0) debugg_printf 276 277 #define Dprintlisp(X) 278 #define DMprintlisp(X) 279 #define DGprintlisp(X) 280 281 #define Debug (0) 282 #define DebugM (0) 283 #define DebugG (0) 284 285 #define dfp stdout 286 #define dmfp stdout 287 #define dgfp stdout 288 289 #endif /* DEBUGGING */ 290 291 /*! \brief Library path. 292 * 293 * List of paths for the library. 294 */ 295 typedef struct a_library_path { 296 char *path; /*!< Path */ 297 struct a_library_path *next; /*!< Pointer to next path */ 298 } LibraryPath; 299 300 /*! \brief Library path list. 301 * 302 * List of \ref a_library_path "LibraryPath's" to Xconq libraries (games) 303 */ 304 extern LibraryPath *xconq_libs; 305 306 /*! \brief Last user library. 307 * 308 * Pointer to last \ref a_library_path "LibraryPath" loaded by user. 309 */ 310 extern LibraryPath *last_user_xconq_lib; 311 312 /*! \brief Iterate library paths. 313 * 314 * This defines a for loop header to walk through 315 * all library paths in a library path list. 316 * \param p is a \ref a_library_path "LibraryPath" iteration variable.. 317 */ 318 #define for_all_library_paths(p) \ 319 for (p = xconq_libs; p != NULL; p = p->next) 320 321 extern void init_xrandom(int seed); 322 extern int xrandom(int m); 323 extern int probability(int prob); 324 extern int roll_dice(int n); 325 extern int multiply_dice(int dice, int mult); 326 327 extern int prob_fraction(int n); 328 329 extern void *xmalloc(int amt); 330 extern void report_malloc(void); 331 extern void tprintf(char *buf, char *str, ...); 332 extern void tnprintf(char *buf, int n, char *str, ...); 333 extern int select_by_weight(int *arr, int numvals); 334 extern char *copy_string(char *str); 335 extern char *pad_blanks(char *str, int n); 336 extern int iindex(int ch, char *str); 337 extern long idifftime(time_t t1, time_t t0); 338 extern void case_panic(char *str, int var); 339 extern int isqrt(int i); 340 extern void init_debug_to_stdout(void); 341 extern void update_debugging(void); 342 extern void toggle_debugging(int *flagp); 343 extern void debug_printf(char *str, ...); 344 extern void debugm_printf(char *str, ...); 345 extern void debugg_printf(char *str, ...); 346 347 extern void prealloc_debug(void); 348 349 extern void record_activity_start(char *type, int detail); 350 extern void record_activity_end(char *type, int detail); 351 extern void dump_activity_trace(void); 352 353 extern void vtprintf(char *buf, char *str, va_list ap); 354 355 extern void log_warning(char *typ, char *str); 356 357 /* Needed for emergency game savers. */ 358 extern int write_entire_game_state(char *fname); 359 360 /* Called from various places. */ 361 extern char *find_name(char *fname); 362 363 /* New wrapper for fopen defined in mac.c and unix.c. */ 364 extern FILE *open_file(char *filename, char *mode); 365 366 /* For coordinated saving of network games. */ 367 extern void save_game(char *fname); 368 369 /* Needed by Unix and Windows. */ 370 extern void close_displays(void); 371