1 /* $Id$ */
2 /* common.c - common functions */
3
4 #include "angband.h"
5
6 /*
7 * XXX XXX XXX Important note about "colors" XXX XXX XXX
8 *
9 * The "TERM_*" color definitions list the "composition" of each
10 * "Angband color" in terms of "quarters" of each of the three color
11 * components (Red, Green, Blue), for example, TERM_UMBER is defined
12 * as 2/4 Red, 1/4 Green, 0/4 Blue.
13 *
14 * The following info is from "Torbjorn Lindgren" (see "main-xaw.c").
15 *
16 * These values are NOT gamma-corrected. On most machines (with the
17 * Macintosh being an important exception), you must "gamma-correct"
18 * the given values, that is, "correct for the intrinsic non-linearity
19 * of the phosphor", by converting the given intensity levels based
20 * on the "gamma" of the target screen, which is usually 1.7 (or 1.5).
21 *
22 * The actual formula for conversion is unknown to me at this time,
23 * but you can use the table below for the most common gamma values.
24 *
25 * So, on most machines, simply convert the values based on the "gamma"
26 * of the target screen, which is usually in the range 1.5 to 1.7, and
27 * usually is closest to 1.7. The converted value for each of the five
28 * different "quarter" values is given below:
29 *
30 * Given Gamma 1.0 Gamma 1.5 Gamma 1.7 Hex 1.7
31 * ----- ---- ---- ---- ---
32 * 0/4 0.00 0.00 0.00 #00
33 * 1/4 0.25 0.27 0.28 #47
34 * 2/4 0.50 0.55 0.56 #8f
35 * 3/4 0.75 0.82 0.84 #d7
36 * 4/4 1.00 1.00 1.00 #ff
37 *
38 * Note that some machines (i.e. most IBM machines) are limited to a
39 * hard-coded set of colors, and so the information above is useless.
40 *
41 * Also, some machines are limited to a pre-determined set of colors,
42 * for example, the IBM can only display 16 colors, and only 14 of
43 * those colors resemble colors used by Angband, and then only when
44 * you ignore the fact that "Slate" and "cyan" are not really matches,
45 * so on the IBM, we use "orange" for both "Umber", and "Light Umber"
46 * in addition to the obvious "Orange", since by combining all of the
47 * "indeterminate" colors into a single color, the rest of the colors
48 * are left with "meaningful" values.
49 */
50
51 /*
52 * Convert a "color letter" into an "actual" color
53 * The colors are: dwsorgbuDWvyRGBU, as shown below
54 */
color_char_to_attr(char c)55 int color_char_to_attr(char c) {
56 switch (c) {
57 case 'd': return (TERM_DARK);
58 case 'w': return (TERM_WHITE);
59 case 's': return (TERM_SLATE);
60 case 'o': return (TERM_ORANGE);
61 case 'r': return (TERM_RED);
62 case 'g': return (TERM_GREEN);
63 case 'b': return (TERM_BLUE);
64 case 'u': return (TERM_UMBER);
65
66 case 'D': return (TERM_L_DARK);
67 case 'W': return (TERM_L_WHITE);
68 case 'v': return (TERM_VIOLET);
69 case 'y': return (TERM_YELLOW);
70 case 'R': return (TERM_L_RED);
71 case 'G': return (TERM_L_GREEN);
72 case 'B': return (TERM_L_BLUE);
73 case 'U': return (TERM_L_UMBER);
74
75 case 'p': return (TERM_POIS);
76 case 'f': return (TERM_FIRE);
77 case 'a': return (TERM_ACID);
78 case 'e': return (TERM_ELEC);
79 case 'c': return (TERM_COLD);
80 case 'h': return (TERM_HALF);
81 case 'm': return (TERM_MULTI);
82 case 'L': return (TERM_LITE);
83
84 case 'C': return (TERM_CONF);
85 case 'S': return (TERM_SOUN);
86 case 'H': return (TERM_SHAR);
87 case 'A': return (TERM_DARKNESS);
88 case 'M': return (TERM_SHIELDM);
89 case 'I': return (TERM_SHIELDI);
90
91 /* maybe TODO: add EXTENDED_TERM_COLOURS here too */
92 //case 'E': return TERM_CURSE; //like TERM_DARKNESS
93 //case 'N': return TERM_ANNI; //like TERM_DARKNESS
94 case 'P': return TERM_PSI;
95 case 'x': return TERM_NEXU;
96 case 'n': return TERM_NETH;
97 case 'T': return TERM_DISE;
98 case 'q': return TERM_INER;
99 case 'F': return TERM_FORC;
100 case 'V': return TERM_GRAV;
101 case 't': return TERM_TIME;
102 case 'E': return TERM_METEOR;
103 case 'N': return TERM_MANA;
104 case 'Q': return TERM_DISI;
105 case 'Y': return TERM_WATE;
106 case 'i': return TERM_ICE; //pretty similar to elec
107 case 'l': return TERM_PLAS;
108 case 'O': return TERM_DETO;
109 case 'k': return TERM_NUKE;
110 case 'K': return TERM_UNBREATH; //ugh --pretty similar to pois
111 case 'j': return TERM_HOLYORB;
112 case 'J': return TERM_HOLYFIRE;
113 case 'X': return TERM_HELLFIRE;
114 case 'z': return TERM_THUNDER;
115 //case '': return TERM_LAMP; //this is just static yellow
116 //case '': return TERM_LAMP_DARK; //this is just static l_umber
117
118 //free: Z
119 }
120
121 return (-1);
122 }
123
124 /*
125 * Convert a color to a color letter.
126 * The colors are: dwsorgbuDWvyRGBU, as shown below
127 */
color_attr_to_char(int a)128 char color_attr_to_char(int a) {
129 switch (a) {
130 case TERM_DARK: return 'd';
131 case TERM_WHITE: return 'w';
132 case TERM_SLATE: return 's';
133 case TERM_ORANGE: return 'o';
134 case TERM_RED: return 'r';
135 case TERM_GREEN: return 'g';
136 case TERM_BLUE: return 'b';
137 case TERM_UMBER: return 'u';
138
139 case TERM_L_DARK: return 'D';
140 case TERM_L_WHITE: return 'W';
141 case TERM_VIOLET: return 'v';
142 case TERM_YELLOW: return 'y';
143 case TERM_L_RED: return 'R';
144 case TERM_L_GREEN: return 'G';
145 case TERM_L_BLUE: return 'B';
146 case TERM_L_UMBER: return 'U';
147
148 case TERM_HALF: return 'h';
149 case TERM_MULTI: return 'm';
150 case TERM_POIS: return 'p';
151 case TERM_FIRE: return 'f';
152 case TERM_ACID: return 'a';
153 case TERM_ELEC: return 'e';
154 case TERM_COLD: return 'c';
155 case TERM_LITE: return 'L';
156
157 case TERM_CONF: return 'C';
158 case TERM_SOUN: return 'S';
159 case TERM_SHAR: return 'H';
160 case TERM_DARKNESS: return 'A';
161 case TERM_SHIELDM: return 'M';
162 case TERM_SHIELDI: return 'I';
163
164 /* maybe TODO: add EXTENDED_TERM_COLOURS here too */
165 //case TERM_CURSE: return 'E'; //like TERM_DARKNESS
166 //case TERM_ANNI: return 'N'; //like TERM_DARKNESS
167 case TERM_PSI: return 'P';
168 case TERM_NEXU: return 'x';
169 case TERM_NETH: return 'n';
170 case TERM_DISE: return 'T';
171 case TERM_INER: return 'q';
172 case TERM_FORC: return 'F';
173 case TERM_GRAV: return 'V';
174 case TERM_TIME: return 't';
175 case TERM_METEOR: return 'E';
176 case TERM_MANA: return 'N';
177 case TERM_DISI: return 'Q';
178 case TERM_WATE: return 'Y';
179 case TERM_ICE: return 'i';//pretty similar to elec
180 case TERM_PLAS: return 'l';
181 case TERM_DETO: return 'O';
182 case TERM_NUKE: return 'k';
183 case TERM_UNBREATH: return 'K';//ugh --pretty similar to pois
184 case TERM_HOLYORB: return 'j';
185 case TERM_HOLYFIRE: return 'J';
186 case TERM_HELLFIRE: return 'X';
187 case TERM_THUNDER: return 'z';
188 //case TERM_LAMP: return ''; //this is just static yellow
189 //case TERM_LAMP_DARK: return ''; //this is just static l_umber
190 }
191
192 return 'w';
193 }
194
mh_attr(int max)195 byte mh_attr(int max) {
196 switch (randint(max)) {
197 case 1: return (TERM_RED);
198 case 2: return (TERM_GREEN);
199 case 3: return (TERM_BLUE);
200 case 4: return (TERM_YELLOW);
201 case 5: return (TERM_ORANGE);
202 case 6: return (TERM_VIOLET);
203 case 7: return (TERM_L_RED);
204 case 8: return (TERM_L_GREEN);
205 case 9: return (TERM_L_BLUE);
206 case 10: return (TERM_UMBER);
207 case 11: return (TERM_L_UMBER);
208 case 12: return (TERM_SLATE);
209 case 13: return (TERM_WHITE);
210 case 14: return (TERM_L_WHITE);
211 case 15: return (TERM_L_DARK);
212 }
213 return (TERM_WHITE);
214 }
215
216 /*
217 * Create a new path by appending a file (or directory) to a path
218 *
219 * This requires no special processing on simple machines, except
220 * for verifying the size of the filename, but note the ability to
221 * bypass the given "path" with certain special file-names.
222 *
223 * Note that the "file" may actually be a "sub-path", including
224 * a path and a file.
225 *
226 * Note that this function yields a path which must be "parsed"
227 * using the "parse" function above.
228 */
path_build(char * buf,int max,cptr path,cptr file)229 errr path_build(char *buf, int max, cptr path, cptr file)
230 {
231 /* Special file */
232 if (file[0] == '~')
233 {
234 /* Use the file itself */
235 strnfmt(buf, max, "%s", file);
236 }
237
238 /* Absolute file, on "normal" systems */
239 else if (prefix(file, PATH_SEP) && !streq(PATH_SEP, ""))
240 {
241 /* Use the file itself */
242 strnfmt(buf, max, "%s", file);
243 }
244
245 /* No path given */
246 else if (!path[0])
247 {
248 /* Use the file itself */
249 strnfmt(buf, max, "%s", file);
250 }
251
252 /* Path and File */
253 else
254 {
255 /* Build the new path */
256 strnfmt(buf, max, "%s%s%s", path, PATH_SEP, file);
257 }
258
259 /* Success */
260 return (0);
261 }
262
263 /*
264 * version strings
265 */
266 cptr longVersion;
267 cptr shortVersion;
268
version_build()269 void version_build()
270 {
271 char temp[256];
272
273 /* Append the version number */
274 sprintf(temp, "%s %d.%d.%d.%d%s", TOMENET_VERSION_SHORT, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_EXTRA, SERVER_VERSION_TAG);
275
276 #if 0
277 /* Append the additional version info */
278 if (VERSION_EXTRA == 1)
279 strcat(temp, "-alpha");
280 else if (VERSION_EXTRA == 2)
281 strcat(temp, "-beta");
282 else if (VERSION_EXTRA == 3)
283 strcat(temp, "-development");
284 else if (VERSION_EXTRA)
285 strcat(temp, format(".%d", VERSION_EXTRA));
286 #endif
287
288 shortVersion = string_make(temp);
289
290 /* Append the date of build */
291 strcat(temp, format(" (Compiled %s %s)", __DATE__, __TIME__));
292
293 longVersion = string_make(temp);
294 }
295
296
297 /* Hrm, maybe we'd better prepare common/skills.c or sth? */
298 /* Find the realm, given a book(tval) */
find_realm(int book)299 int find_realm(int book)
300 {
301 switch (book)
302 {
303 case TV_MAGIC_BOOK:
304 return REALM_MAGERY;
305 case TV_PRAYER_BOOK:
306 return REALM_PRAYER;
307 case TV_SORCERY_BOOK:
308 return REALM_SORCERY;
309 case TV_FIGHT_BOOK:
310 return REALM_FIGHTING;
311 case TV_SHADOW_BOOK:
312 return REALM_SHADOW;
313 case TV_PSI_BOOK:
314 return REALM_PSI;
315 case TV_HUNT_BOOK:
316 return REALM_HUNT;
317 };
318 return -1;
319 }
320