1 /*
2  * init.c
3  *
4  * This source herein may be modified and/or distributed by anybody who
5  * so desires, with the following restrictions:
6  *    1.)  No portion of this notice shall be removed.
7  *    2.)  Credit shall not be taken for the creation of this source.
8  *    3.)  This code is not to be traded, sold, or used for personal
9  *         gain or profit.
10  *
11  */
12 
13 #include <stdio.h>
14 #include "rogue.h"
15 
16 char login_name[30];
17 char *nick_name = "";
18 char *rest_file = 0;
19 boolean cant_int = 0, did_int = 0, score_only = 0, init_curses = 0;
20 boolean save_is_interactive = 1;
21 boolean show_skull = 1;
22 #ifndef MSDOS
23 boolean ask_quit = 1;
24 #endif
25 #ifndef ORIGINAL
26 boolean pass_go = 1, do_restore = 0;
27 char org_dir[64], *game_dir = "";
28 #endif
29 #ifdef COLOR
30 char *color_str = "cbmyg";
31 boolean do_color = 1;
32 short c_buf[5];
33 short c_attr[256];
34 #endif
35 #ifdef UNIX
36 char *error_file = "rogue.esave";
37 #endif
38 #ifdef MSDOS
39 char *error_file = "rogue.err";
40 char *mac_type = "none", *cursor_str = "";
41 char *init_string = "", *term_string = "";
42 char init_str[30], term_str[30];
43 char cursor_on[10], cursor_off[10];
44 #endif
45 
46 extern char *fruit;
47 extern char *save_file;
48 extern short party_room, party_counter;
49 extern boolean jump;
50 
init(argc,argv)51 init(argc, argv)
52 int argc;
53 char *argv[];
54 {
55 	char *pn;
56 	int seed;
57 
58 #ifndef ORIGINAL
59 	md_getcwd(org_dir, 64);
60 #endif
61 	do_args(argc, argv);
62 #ifdef COLOR
63 	init_color();
64 #endif
65 	do_opts();
66 
67 	pn = md_gln();
68 	if ((!pn) || (strlen(pn) >= 30)) {
69 		clean_up(mesg[13]);
70 	}
71 	(void) strcpy(login_name, pn);
72 	if (!nick_name[0])
73 		nick_name = login_name;
74 
75 	initscr();
76 
77 #ifndef MSDOS
78 	if ((LINES < DROWS) || (COLS < DCOLS)) {
79 		clean_up(mesg[14]);
80 	}
81 #endif
82 
83 	start_window();
84 	init_curses = 1;
85 	md_heed_signals();
86 
87 	if (score_only) {
88 		message("", 0);		/* by Yasha */
89 		put_scores((object *) 0, 0);
90 	}
91 	seed = md_gseed();
92 	(void) srrandom(seed);
93 #ifndef ORIGINAL
94 	if (do_restore && save_file && *save_file)
95 		rest_file = save_file;
96 #endif
97 	if (rest_file) {
98 		restore(rest_file);
99 		return(1);
100 	}
101 	mix_colors();
102 	get_wand_and_ring_materials();
103 	make_scroll_titles();
104 
105 	level_objects.next_object = 0;
106 	level_monsters.next_monster = 0;
107 	player_init();
108 	party_counter = get_rand(1, PARTY_TIME);
109 	ring_stats(0);
110 	return(0);
111 }
112 
player_init()113 player_init()
114 {
115 	object *obj;
116 
117 	rogue.pack.next_object = 0;
118 
119 	obj = alloc_object();
120 	get_food(obj, 1);
121 	(void) add_to_pack(obj, &rogue.pack, 1);
122 
123 	obj = alloc_object();		/* initial armor */
124 	obj->what_is = ARMOR;
125 	obj->which_kind = RINGMAIL;
126 	obj->class = RINGMAIL+2;
127 	obj->is_protected = 0;
128 	obj->d_enchant = 1;
129 	(void) add_to_pack(obj, &rogue.pack, 1);
130 	do_wear(obj);
131 
132 	obj = alloc_object();		/* initial weapons */
133 	obj->what_is = WEAPON;
134 	obj->which_kind = MACE;
135 	obj->damage = "2d3";
136 	obj->hit_enchant = obj->d_enchant = 1;
137 	obj->identified = 1;
138 	(void) add_to_pack(obj, &rogue.pack, 1);
139 	do_wield(obj);
140 
141 	obj = alloc_object();
142 	obj->what_is = WEAPON;
143 	obj->which_kind = BOW;
144 	obj->damage = "1d2";
145 	obj->hit_enchant = 1;
146 	obj->d_enchant = 0;
147 	obj->identified = 1;
148 	(void) add_to_pack(obj, &rogue.pack, 1);
149 
150 	obj = alloc_object();
151 	obj->what_is = WEAPON;
152 	obj->which_kind = ARROW;
153 	obj->quantity = get_rand(25, 35);
154 	obj->damage = "1d2";
155 	obj->hit_enchant = 0;
156 	obj->d_enchant = 0;
157 	obj->identified = 1;
158 	(void) add_to_pack(obj, &rogue.pack, 1);
159 }
160 
clean_up(estr)161 clean_up(estr)
162 char *estr;
163 {
164 	if (save_is_interactive) {
165 		if (init_curses) {
166 			move(DROWS-1, 0);
167 #ifndef ORIGINAL
168 			clrtoeol();
169 #endif
170 #ifdef MSDOS
171 			move(DROWS-4, 0);
172 #endif
173 			refresh();
174 			stop_window();
175 		}
176 #if defined(JAPAN) && !defined(CURSES)
177 		raw();			/* by Yasha */
178 #endif
179 		putstr("\r\n");
180 		putstr(estr);
181 		putstr("\r\n");
182 #if defined(JAPAN) && !defined(CURSES)
183 		md_control_keyboard(1);		/* by Yasha */
184 #endif
185 	}
186 	md_exit(0);
187 }
188 
start_window()189 start_window()
190 {
191 #ifdef MSDOS
192 	if (*init_str)
193 		putstr(init_str);
194 	md_cbreak_no_echo_nonl(1);
195 #else
196 	crmode();
197 	noecho();
198 #if defined(JAPAN) && !defined(CURSES)
199 	raw();		/* by Yasha */
200 #endif
201 #ifndef BAD_NONL
202 	nonl();
203 #endif /*BAD_NONL*/
204 	md_control_keyboard(0);
205 #endif /*MSDOS*/
206 }
207 
stop_window()208 stop_window()
209 {
210 	endwin();
211 #ifndef MSDOS
212 	md_control_keyboard(1);
213 #endif
214 #ifdef MSDOS
215 	if (*term_str)
216 		putstr(term_str);
217 #endif
218 }
219 
220 #ifndef MSDOS
byebye()221 byebye()
222 {
223 	md_ignore_signals();
224 	if (ask_quit) {
225 		quit(1);
226 	} else {
227 		clean_up(mesg[12]);	/* byebye_string */
228 	}
229 	md_heed_signals();
230 }
231 #endif /*MSDOS*/
232 
233 #if defined(MSDOS) && (!defined(__TURBOC__) || __TURBOC__ >= 0x0200)
234 void
235 #endif
onintr()236 onintr()
237 {
238 	md_ignore_signals();
239 	if (cant_int) {
240 		did_int = 1;
241 	} else {
242 		check_message();
243 		message(mesg[15], 1);
244 	}
245 	md_heed_signals();
246 #if defined(MSDOS) && defined(__TURBOC__) && __TURBOC__ < 0x0200
247 	return 1;
248 #endif
249 }
250 
251 #if defined(MSDOS) && defined(__TURBOC__) && __TURBOC__ < 0x0200
ignintr()252 ignintr()
253 {
254 	return 1;
255 }
256 #endif
257 
error_save()258 error_save()
259 {
260 	save_is_interactive = 0;
261 	save_into_file(error_file);
262 	clean_up("");
263 }
264 
do_args(argc,argv)265 do_args(argc, argv)
266 int argc;
267 char *argv[];
268 {
269 	short i, j;
270 
271 	for (i = 1; i < argc; i++) {
272 		if (argv[i][0] == '-') {
273 			for (j = 1; argv[i][j]; j++) {
274 				switch(argv[i][j]) {
275 				case 's':
276 					score_only = 1;
277 					break;
278 #ifndef ORIGINAL
279 				case 'r':
280 					do_restore = 1;
281 					break;
282 #endif
283 				}
284 			}
285 		} else {
286 			rest_file = argv[i];
287 		}
288 	}
289 }
290 
291 opt envopt[] = {
292 #ifndef MSDOS
293 	{ "askquit",	&ask_quit,	NULL,		0, 0 },
294 #endif
295 	{ "jump",	&jump,		NULL,		0, 0 },
296 #ifndef ORIGINAL
297 	{ "passgo",	&pass_go,	NULL,		0, 0 },
298 	{ "tombstone",	&show_skull,	NULL,		0, 0 },
299 #else
300 	{ "skull",	&show_skull,	NULL,		0, 0 },
301 #endif
302 #ifdef COLOR
303 	{ "color",	&do_color,	NULL,		0, 0 },
304 #endif
305 #ifdef JAPAN
306 	{ "fruit",	NULL,		&fruit,		0, 0 },
307 #else
308 	{ "fruit",	NULL,		&fruit,		1, 0 },
309 #endif
310 	{ "file",	NULL,		&save_file,	0, 0 },
311 	{ "name",	NULL,		&nick_name,	0, 1 },
312 #ifndef ORIGINAL
313 	{ "directory",	NULL,		&game_dir,	0, 0 },
314 #endif
315 #ifdef COLOR
316 	{ "map",	NULL,		&color_str,	0, 0 },
317 #endif
318 #ifdef MSDOS
319 	{ "type",	NULL,		&mac_type,	0, 0 },
320 	{ "init",	NULL,		&init_string,	0, 0 },
321 	{ "term",	NULL,		&term_string,	0, 0 },
322 	{ "cursor",	NULL,		&cursor_str,	0, 0 },
323 #endif
324 	{ NULL,		NULL,		NULL,		0, 0 }
325 };
326 
327 #ifdef JAPAN
328 char *optdesc[] = {
329 #ifndef MSDOS
330 	"��λ���뤫�ɤ�����ǧ��Ȥ�",
331 #endif
332 	"��ư���ɽ����Ԥ�ʤ�",
333 #ifndef ORIGINAL
334 	"��ϩ�γѤǻߤޤ餺�˿ʤ�",
335 	"�����ཪλ������ɸ��ɽ������",
336 #else
337 	"�����ཪλ���˳�����ɽ������",
338 #endif
339 #ifdef COLOR
340 	"����饯�������顼��ɽ������",
341 #endif
342 	mesg[16],
343 	"�����֥ե�����̾",
344 	"�˥å��͡���",
345 #ifndef ORIGINAL
346 	"������ǥ��쥯�ȥ꡼̾",
347 #endif
348 #ifdef COLOR
349 	"����饯������ɽ�����ޥåԥ�",
350 #endif
351 #ifdef MSDOS
352 	"���ѵ���",
353 	"�������Ѥ��Ϥ��륷������",
354 	"�������Ѥ�λ���륷������",
355 	"�������륪�����դΥ�������",
356 #endif
357 	NULL
358 };
359 #else /*JAPAN*/
360 char *optdesc[] = {
361 #ifndef MSDOS
362 	"Ask whether quit or not on quit signal",
363 #endif
364 	"Show position only at end of run",
365 #ifndef ORIGINAL
366 	"Follow turnings in passageways",
367 	"Print out tombstone and score when killed",
368 #else
369 	"Print out skull and score when killed",
370 #endif
371 #ifdef COLOR
372 	"Show characters in map with color",
373 #endif
374 	mesg[16],
375 	"Save filename",
376 	"Your nickname",
377 #ifndef ORIGINAL
378 	"Game directory name",
379 #endif
380 #ifdef COLOR
381 	"Color mapping for characters",
382 #endif
383 #ifdef MSDOS
384 	"Machine type",
385 	"Initialize sequence in hex",
386 	"Terminate sequence in hex",
387 	"Cursor on/off sequence in hex/hex",
388 #endif
389 	NULL
390 };
391 #endif /*JAPAN*/
392 
393 #ifdef MSDOS
394 typedef struct machine { char *type, *cursor, *init, *term;} mac;
395 mac macs[] = {
396 {"pc98",  "1b5b3e356c/1b5b3e3568", "1b29301b5b3e336c1b5b3e3168", "1b5b3e316c"},
397 {"pc100", "1b5b3e3568/1b5b3e356c", "1b29301b5b3d33681b5b3e316c", "1b5b3e3168"},
398 {"ax",    "1b5b3e356c/1b5b3e3568", "", ""},
399 {"fmr",   "1b5b3076/1b5b3176", "", ""},
400 {"b16",   "1b5b3e356c/1b5b3e3568", "", ""},
401 {"if800", "1b31/1b30", "1b4e301b6e391b53202030", "1b53202031"},
402 {NULL, NULL, NULL, NULL}
403 };
404 #endif /*MSDOS*/
405 
do_opts()406 do_opts()
407 {
408 	register char *ep, *p;
409 	char envname[10];
410 	char envbuf[BUFSIZ];
411 
412 	strcpy(envname, "ROGUEOPT?");
413 	envbuf[0] = 0;
414 	for (p = "S123456789"; *p; p++) {
415 		envname[8] = *p;
416 		if (ep = md_getenv(envname)) {
417 			strcat(envbuf, ",");
418 			strcat(envbuf, ep);
419 		}
420 	}
421 	set_opts(envbuf);
422 }
423 
424 void
set_opts(env)425 set_opts(env)
426 char *env;
427 {
428 	short not, i;
429 	register char *ep, *p;
430 	opt *op;
431 #ifdef MSDOS
432 	mac *mp;
433 #endif
434 	char optname[20];
435 
436 	if (*env == 0)
437 		return;
438 	ep = env;
439 	for (;;) {
440 		while (*ep == ' ' || *ep == ',')
441 			ep++;
442 
443 		if (*ep == 0)
444 			break;
445 
446 		not = 0;
447 		if (!strncmp("no", ep, 2) || !strncmp("NO", ep, 2)) {
448 			not = 1;
449 			ep += 2;
450 		}
451 		p = optname;
452 		while (*ep && *ep != ',' && *ep != '=' && *ep != ':')
453 			*p++ = (*ep>='A'&&*ep<='Z')? (*ep++)-'A'+'a': *ep++;
454 		*p = 0;
455 		for (op = envopt; op->name; op++) {
456 			if (strncmp(op->name, optname, strlen(optname)))
457 				continue;
458 			if (op->bp)
459 				*(op->bp) = !not;
460 			if (op->cp && (*ep == '=' || *ep == ':'))
461 				env_get_value(op->cp, ep+1, op->ab, op->nc);
462 		}
463 
464 		while (*ep && *ep != ',')
465 			ep++;
466 	}
467 
468 #ifdef MSDOS
469 	for (p = mac_type; *p; p++)
470 		if (*p >= 'A' && *p <= 'Z')
471 			*p += 'a' - 'A';
472 	for (mp = macs; mp->type; mp++) {
473 		if (!strcmp(mac_type, mp->type)) {
474 			cursor_str  = mp->cursor;
475 			init_string = mp->init;
476 			term_string = mp->term;
477 			break;
478 		}
479 	}
480 	if (init_string) {
481 		p = init_string;
482 		ep = init_str;
483 		while ((i = get_hex_num(p, 2)) >= 0) {
484 			*ep++ = i;
485 			p += 2;
486 		}
487 		*ep = 0;
488 	}
489 	if (term_string) {
490 		p = term_string;
491 		ep = term_str;
492 		while ((i = get_hex_num(p, 2)) >= 0) {
493 			*ep++ = i;
494 			p += 2;
495 		}
496 		*ep = 0;
497 	}
498 	if (cursor_str) {
499 		p = cursor_str;
500 		ep = cursor_on;
501 		while ((i = get_hex_num(p, 2)) >= 0) {
502 			*ep++ = i;
503 			p += 2;
504 		}
505 		*ep = 0;
506 		if (*p)
507 			p++;
508 		ep = cursor_off;
509 		while ((i = get_hex_num(p, 2)) >= 0) {
510 			*ep++ = i;
511 			p += 2;
512 		}
513 		*ep = 0;
514 	}
515 #endif
516 
517 #ifdef COLOR
518 	init_color();
519 #endif
520 
521 #ifndef ORIGINAL
522 	if (game_dir && *game_dir)
523 		md_chdir(game_dir);
524 #endif
525 
526 #ifdef COLOR
527 	if (init_curses)
528 		repaint_screen();
529 #endif
530 }
531 
532 #ifdef COLOR
init_color()533 init_color()
534 {
535 	register short i, j;
536 	char *p;
537 
538 	if (color_str && *color_str) {
539 		for (i = 0; i < 5 && color_str[i]; i++) {
540 			j = r_index("wrgybmc?WRGYBMC", color_str[i], 0);
541 			if (j >= 0)
542 				c_buf[i] = j;
543 		}
544 		for (p = "-|#+"; *p; p++)
545 			c_attr[*p] = c_buf[0] << 8;
546 		c_attr['.'] = c_buf[1] << 8;
547 		for (i = 'A'; i <= 'Z'; i++)
548 			c_attr[i] = c_buf[2] << 8;
549 		for (p = "%!?/=)]^*:,"; *p; p++)
550 			c_attr[*p] = c_buf[3] << 8;
551 		c_attr[rogue.fchar] = c_buf[4] << 8;
552 	} else {
553 		for (i = 0; i < 5; i++)
554 			c_buf[i] = 0;
555 		for (i = 0; i < 256; i++)
556 			c_attr[i] = 0;
557 	}
558 }
559 #endif
560 
561 #ifdef MSDOS
get_hex_num(p,n)562 get_hex_num(p, n)
563 register char *p;
564 int n;
565 {
566 	int x;
567 
568 	x = 0;
569 	while (n-- > 0) {
570 		x <<= 4;
571 		if (*p >= '0' && *p <= '9')
572 			x += *p++ - '0';
573 		else if (*p >= 'a' && *p <= 'z')
574 			x += *p++ - 'a' + 10;
575 		else if (*p >= 'A' && *p <= 'Z')
576 			x += *p++ - 'A' + 10;
577 		else
578 			return -1;
579 	}
580 	return x;
581 }
582 #endif /* MSDOS */
583 
env_get_value(s,e,add_blank,no_colon)584 env_get_value(s, e, add_blank, no_colon)
585 char **s, *e;
586 boolean add_blank, no_colon;
587 {
588 	short i = 0;
589 	char *t;
590 
591 	t = e;
592 
593 	while ((*e) && (*e != ',')) {
594 #ifndef ORIGINAL
595 #ifdef EUC
596 		if (*e & 0x80) {	/* by Yasha */
597 #else
598 		if (*e >'\200' && *e <'\240' || *e >= '\340' && *e < '\360') {
599 #endif
600 			e += 2;
601 			i += 2;
602 			continue;
603 		}
604 #endif
605 		if (*e == ':' && no_colon) {
606 			*e = ';'; /* ':' reserved for score file purposes */
607 		}
608 		e++;
609 		if (++i >= 30) {
610 			break;
611 		}
612 	}
613 	if (!(*s = md_malloc(i + (add_blank ? 2 : 1)))) {
614 		clean_up(mesg[17]);
615 	}
616 	(void) strncpy(*s, t, i);
617 	if (add_blank) {
618 		(*s)[i++] = ' ';
619 	}
620 	(*s)[i] = '\0';
621 }
622