32
32
* Several of the arrays for Angband are built from "template" files in
33
* the "lib/file" directory, from which quick-load binary "image" files
34
* are constructed whenever they are not present in the "lib/data"
35
* directory, or if those files become obsolete, if we are allowed.
33
* the "lib/edit" directory.
37
35
* Warning -- the "ascii" file parsers use a minor hack to collect the
38
36
* name and text information in a single pass. Thus, the game will not
39
37
* be able to load any template file with more than 20K of names or 60K
40
38
* of text, even though technically, up to 64K should be legal.
42
* The "init1.c" file is used only to parse the ascii template files,
43
* to create the binary image files. If you include the binary image
44
* files instead of the ascii template files, then you can undefine
45
* "ALLOW_TEMPLATES", saving about 20K by removing "init1.c". Note
46
* that the binary image files are extremely system dependant.
52
44
* Find the default paths to all of our important sub-directories.
54
* The purpose of each sub-directory is described in "variable.c".
56
46
* All of the sub-directories should, by default, be located inside
57
* the main "lib" directory, whose location is very system dependant.
47
* the main directory, whose location is very system dependant and is
48
* set by the ANGBAND_PATH environment variable, if it exists. (On multi-
49
* user systems such as Linux this is not the default - see config.h for
59
* This function takes a writable buffer, initially containing the
60
* "path" to the "lib" directory, for example, "/pkg/lib/angband/",
52
* This function takes a writable buffers, initially containing the
53
* "path" to the "config", "lib" and "data" directories, for example,
54
* "/etc/angband/", "/usr/share/angband" and "/var/games/angband" -
61
55
* or a system dependant string, for example, ":lib:". The buffer
62
56
* must be large enough to contain at least 32 more characters.
64
58
* Various command line options may allow some of the important
65
59
* directories to be changed to user-specified directories, most
66
* importantly, the "info" and "user" and "save" directories,
60
* importantly, the "apex" and "user" and "save" directories,
67
61
* but this is done after this function, see "main.c".
69
63
* In general, the initial path should end in the appropriate "PATH_SEP"
110
99
/*** Prepare the paths ***/
112
/* Save the main directory */
113
ANGBAND_DIR = string_make(path);
115
101
/* Build path names */
116
ANGBAND_DIR_EDIT = string_make(format("%sedit", path));
117
ANGBAND_DIR_FILE = string_make(format("%sfile", path));
118
ANGBAND_DIR_HELP = string_make(format("%shelp", path));
119
ANGBAND_DIR_INFO = string_make(format("%sinfo", path));
120
ANGBAND_DIR_PREF = string_make(format("%spref", path));
121
ANGBAND_DIR_XTRA = string_make(format("%sxtra", path));
102
ANGBAND_DIR_EDIT = string_make(format("%sedit", configpath));
103
ANGBAND_DIR_FILE = string_make(format("%sfile", libpath));
104
ANGBAND_DIR_HELP = string_make(format("%shelp", libpath));
105
ANGBAND_DIR_INFO = string_make(format("%sinfo", libpath));
106
ANGBAND_DIR_PREF = string_make(format("%spref", configpath));
107
ANGBAND_DIR_XTRA = string_make(format("%sxtra", libpath));
123
109
/* Build xtra/ paths */
124
110
ANGBAND_DIR_XTRA_FONT = string_make(format("%s" PATH_SEP "font", ANGBAND_DIR_XTRA));
147
133
ANGBAND_DIR_APEX = string_make(buf);
149
135
/* Build the path to the user specific sub-directory */
150
path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "bone");
151
ANGBAND_DIR_BONE = string_make(buf);
153
/* Build the path to the user specific sub-directory */
154
path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "data");
155
ANGBAND_DIR_DATA = string_make(buf);
157
/* Build the path to the user specific sub-directory */
158
136
path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "save");
159
137
ANGBAND_DIR_SAVE = string_make(buf);
161
#else /* USE_PRIVATE_PATHS */
139
#else /* !USE_PRIVATE_PATHS */
163
141
/* Build pathnames */
164
ANGBAND_DIR_APEX = string_make(format("%sapex", path));
165
ANGBAND_DIR_BONE = string_make(format("%sbone", path));
166
ANGBAND_DIR_DATA = string_make(format("%sdata", path));
167
ANGBAND_DIR_SAVE = string_make(format("%ssave", path));
142
ANGBAND_DIR_APEX = string_make(format("%sapex", datapath));
143
ANGBAND_DIR_SAVE = string_make(format("%ssave", datapath));
169
145
#endif /* USE_PRIVATE_PATHS */
173
#ifdef PRIVATE_USER_PATH
176
* Create an ".angband/" directory in the users home directory.
150
* Create any missing directories. We create only those dirs which may be
151
* empty (user/, save/, apex/, info/, help/). The others are assumed
152
* to contain required files and therefore must exist at startup
153
* (edit/, pref/, file/, xtra/).
178
* ToDo: Add error handling.
179
155
* ToDo: Only create the directories when actually writing files.
181
void create_user_dirs(void)
157
void create_needed_dirs(void)
184
char subdirpath[1024];
187
/* Get an absolute path from the filename */
188
path_build(dirpath, sizeof(dirpath), PRIVATE_USER_PATH, "");
190
/* Create the ~/.angband/ directory */
191
mkdir(dirpath, 0700);
193
/* Build the path to the variant-specific sub-directory */
194
path_build(subdirpath, sizeof(subdirpath), dirpath, VERSION_NAME);
196
/* Create the directory */
197
mkdir(subdirpath, 0700);
199
#ifdef USE_PRIVATE_PATHS
200
/* Build the path to the scores sub-directory */
201
path_build(dirpath, sizeof(dirpath), subdirpath, "scores");
203
/* Create the directory */
204
mkdir(dirpath, 0700);
206
/* Build the path to the savefile sub-directory */
207
path_build(dirpath, sizeof(dirpath), subdirpath, "bone");
209
/* Create the directory */
210
mkdir(dirpath, 0700);
212
/* Build the path to the savefile sub-directory */
213
path_build(dirpath, sizeof(dirpath), subdirpath, "data");
215
/* Create the directory */
216
mkdir(dirpath, 0700);
218
/* Build the path to the savefile sub-directory */
219
path_build(dirpath, sizeof(dirpath), subdirpath, "save");
221
/* Create the directory */
222
mkdir(dirpath, 0700);
223
#endif /* USE_PRIVATE_PATHS */
161
path_build(dirpath, sizeof(dirpath), ANGBAND_DIR_USER, "");
162
if (!dir_create(dirpath)) quit_fmt("Cannot create '%s'", dirpath);
164
path_build(dirpath, sizeof(dirpath), ANGBAND_DIR_SAVE, "");
165
if (!dir_create(dirpath)) quit_fmt("Cannot create '%s'", dirpath);
167
path_build(dirpath, sizeof(dirpath), ANGBAND_DIR_APEX, "");
168
if (!dir_create(dirpath)) quit_fmt("Cannot create '%s'", dirpath);
170
path_build(dirpath, sizeof(dirpath), ANGBAND_DIR_INFO, "");
171
if (!dir_create(dirpath)) quit_fmt("Cannot create '%s'", dirpath);
173
path_build(dirpath, sizeof(dirpath), ANGBAND_DIR_HELP, "");
174
if (!dir_create(dirpath)) quit_fmt("Cannot create '%s'", dirpath);
226
#endif /* PRIVATE_USER_PATH */
232
179
* Hack -- help give useful error messages
286
/*** Initialize from binary image files ***/
290
* Initialize a "*_info" array, by parsing a binary "image" file
292
static bool init_info_raw(const char *fname, header *head)
295
ang_file *fh = file_open(fname, MODE_READ, -1);
297
if (!fh) return FALSE;
299
/* Read and verify the header */
300
if (!file_read(fh, (char *)(&test), sizeof(header)) ||
301
(test.v_major != head->v_major) ||
302
(test.v_minor != head->v_minor) ||
303
(test.v_patch != head->v_patch) ||
304
(test.v_extra != head->v_extra) ||
305
(test.info_num != head->info_num) ||
306
(test.info_len != head->info_len) ||
307
(test.head_size != head->head_size) ||
308
(test.info_size != head->info_size))
316
* Accept the header - these are the only parts we need to copy
317
* from the saved structure, as the rest is either identical (see
318
* above test), or not restorable (function hooks, data pointers).
320
head->name_size = test.name_size;
321
head->text_size = test.text_size;
323
/* Allocate and read the "*_info" array */
324
head->info_ptr = C_RNEW(head->info_size, char);
325
file_read(fh, head->info_ptr, head->info_size);
329
/* Allocate and read the "*_name" array */
330
head->name_ptr = C_RNEW(head->name_size, char);
331
file_read(fh, head->name_ptr, head->name_size);
336
/* Allocate and read the "*_text" array */
337
head->text_ptr = C_RNEW(head->text_size, char);
338
file_read(fh, head->text_ptr, head->text_size);
347
* Initialize the header of an *_info.raw file.
234
* Initialize the header of an *_info array.
349
236
static void init_header(header *head, int num, int len)
351
/* Save the "version" */
352
head->v_major = VERSION_MAJOR;
353
head->v_minor = VERSION_MINOR;
354
head->v_patch = VERSION_PATCH;
355
head->v_extra = VERSION_EXTRA;
357
/* Save the "record" information */
358
head->info_num = num;
359
head->info_len = len;
361
/* Save the size of "*_head" and "*_info" */
362
head->head_size = sizeof(header);
363
head->info_size = head->info_num * head->info_len;
365
/* Clear post-parsing evaluation function */
366
head->eval_info_post = NULL;
368
/* Clear the template emission functions */
369
head->emit_info_txt_index = NULL;
370
head->emit_info_txt_always = NULL;
238
/* Save the "version" */
239
head->v_major = VERSION_MAJOR;
240
head->v_minor = VERSION_MINOR;
241
head->v_patch = VERSION_PATCH;
242
head->v_extra = VERSION_EXTRA;
244
/* Save the "record" information */
245
head->info_num = num;
246
head->info_len = len;
248
/* Save the size of "*_head" and "*_info" */
249
head->head_size = sizeof(header);
250
head->info_size = head->info_num * head->info_len;
252
/* Clear post-parsing evaluation function */
253
head->eval_info_post = NULL;
255
/* Clear the template emission functions */
256
head->emit_info_txt_index = NULL;
257
head->emit_info_txt_always = NULL;
408
294
char txt_file[1024];
413
/* Build the filenames */
414
path_build(raw_file, sizeof(raw_file), ANGBAND_DIR_DATA, format("%s.raw", filename));
301
/* Build the filename */
415
302
path_build(txt_file, sizeof(txt_file), ANGBAND_DIR_EDIT, format("%s.txt", filename));
418
#ifdef ALLOW_TEMPLATES
420
/* If the raw file's more recent than the text file, load it */
421
if (file_newer(raw_file, txt_file) &&
422
init_info_raw(raw_file, head))
424
/* Post processing the data */
425
if (head->eval_info_post) eval_info(head->eval_info_post, head);
430
/*** Make the fake arrays ***/
432
304
/* Allocate the "*_info" array */
433
305
head->info_ptr = C_ZNEW(head->info_size, char);
482
353
file_close(fout);
488
/*** Dump the binary image file ***/
491
fh = file_open(raw_file, MODE_WRITE, FTYPE_RAW);
497
plog_fmt("Cannot write the '%s' file!", raw_file);
502
file_write(fh, (const char *) head, head->head_size);
504
/* Dump the "*_info" array */
505
if (head->info_size > 0)
506
file_write(fh, head->info_ptr, head->info_size);
508
/* Dump the "*_name" array */
509
if (head->name_size > 0)
510
file_write(fh, head->name_ptr, head->name_size);
512
/* Dump the "*_text" array */
513
if (head->text_size > 0)
514
file_write(fh, head->text_ptr, head->text_size);
520
/*** Kill the fake arrays ***/
522
/* Free the "*_info" array */
523
FREE(head->info_ptr);
525
/* MegaHack -- Free the "fake" arrays */
356
/* Copy the parsed data into the real array from the fakes */
357
fake_name = head->name_ptr;
358
head->name_ptr = C_ZNEW(head->name_size, char);
359
memcpy(head->name_ptr, fake_name, head->name_size);
361
fake_text = head->text_ptr;
362
head->text_ptr = C_ZNEW(head->text_size, char);
363
memcpy(head->text_ptr, fake_text, head->text_size);
365
/* Free the fake arrays */
528
FREE(head->name_ptr);
529
FREE(head->text_ptr);
533
#endif /* ALLOW_TEMPLATES */
536
/*** Load the binary image file ***/
538
if (!init_info_raw(raw_file, head))
539
quit(format("Cannot load '%s.raw' file.", filename));
719
528
/* Init the header */
720
529
init_header(&r_head, z_info->r_max, sizeof(monster_race));
722
#ifdef ALLOW_TEMPLATES
724
531
/* Save a pointer to the parsing function */
725
532
r_head.parse_info_txt = parse_r_info;
727
534
/* Save a pointer to the evaluate power function*/
728
535
r_head.eval_info_post = eval_r_power;
730
#ifdef ALLOW_TEMPLATES_OUTPUT
732
/* Save a pointer to the evaluate power function*/
733
r_head.emit_info_txt_index = emit_r_info_index;
734
#endif /* ALLOW_TEMPLATES_OUTPUT */
736
#endif /* ALLOW_TEMPLATES */
537
/* Save a pointer to the text file output function*/
538
if (arg_rebalance) r_head.emit_info_txt_index = emit_r_info_index;
738
540
err = init_info("monster", &r_head);