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