1 /* mac/mac.c: mac support code
2 
3    Copyright (c) 1989-1991 Curtis McCauley, James E. Wilson
4 
5    This software may be copied and distributed for educational, research, and
6    not for profit purposes provided that this copyright and statement are
7    included in all such copies. */
8 
9 #ifndef THINK_C
10 #include <types.h>
11 #include <controls.h>
12 #include <dialogs.h>
13 #include <memory.h>
14 #include <resources.h>
15 #include <files.h>
16 #include <segload.h>
17 #include <packages.h>
18 #include <menus.h>
19 #include <osutils.h>
20 #include <sysequ.h>
21 
22 #include <scrnmgr.h>
23 #include <dumpres.h>
24 
25 #else
26 
27 #include "ScrnMgr.h"
28 #include "DumpRes.h"
29 
30 #define c2pstr(x)	(char *)CtoPstr((char *)x)
31 #define p2cstr(x)	(char *)PtoCstr((char *)x)
32 
33 #endif
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #ifndef THINK_C
39 #include <strings.h>
40 #endif
41 #include <setjmp.h>
42 
43 #include "config.h"
44 #include "constant.h"
45 #include "types.h"
46 #include "externs.h"
47 #include "macrsrc.h"
48 
49 long GetCommandSet(Handle theData);
50 long GetTextEditor(Handle theData);
51 
52 void DoMacHelp(void), DoKillsDlg(void);
53 
54 static long game_flag;
55 static long exit_code;
56 
57 static short savedir, applvrefnum;
58 
59 static char **save_chars, **save_attrs;
60 static long save_cursor_h, save_cursor_v;
61 
62 #define PATHLEN					256
63 
64 #define TAB_WIDTH				8
65 
66 #define CODE_IGNORE				0
67 #define CODE_PASSTHRU			1
68 #define CODE_KEYPAD				2
69 #define CODE_ARROW				3
70 #define CODE_ENTER				4
71 
72 static unsigned char codetable[0x80] = {
73 	/*				0	1	2	3	4	5	6	7	8	9	A	B	C	D	E	F	*/
74 	/*				-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	*/
75 	/* [00] */		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,
76 	/* [10] */		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,
77 	/* [20] */		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,
78 	/* [30] */		0,	1,	1,	1,	1,	1,	1,	0,	0,	0,	0,	0,	0,	0,	0,	1,
79 	/* [40] */		1,	1,	3,	1,	1,	1,	3,	1,	3,	1,	1,	1,	4,	3,	1,	1,
80 	/* [50] */		1,	1,	1,	2,	2,	2,	2,	2,	2,	2,	1,	2,	2,	1,	1,	1,
81 	/* [60] */		0,	0,	0,	0,	0,	0,	1,	0,	1,	0,	1,	0,	1,	0,	1,	0,
82 	/* [70] */		1,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	3,	3,	3,	3,	1
83 };
84 
85 #define ARROW_UP_1				0x4D
86 #define ARROW_DOWN_1			0x48
87 #define ARROW_LEFT_1			0x46
88 #define ARROW_RIGHT_1			0x42
89 
90 #define ARROW_UP_2				0x7E
91 #define ARROW_DOWN_2			0x7D
92 #define ARROW_LEFT_2			0x7B
93 #define ARROW_RIGHT_2			0x7C
94 
95 #define CMDSET_TYPE				'CNFG'
96 #define CMDSET_ID				256
97 
98 #define TE_TYPE					'CNFG'
99 #define TE_ID					257
100 
101 #define SPIN_TICKS				15
102 
103 static long editor, cmdsetopt;
104 
105 static jmp_buf jb;
106 
107 #define ABOUT_DLOG_ID			128
108 
109 #define FM_NEW					1
110 #define FM_OPEN					2
111 #define FM_SAVE					4
112 #define FM_SAVE_AS				5
113 #define FM_QUIT					7
114 
115 #define AM_HELP					1
116 #define AM_CMD_SET				2
117 #define AM_TEXT_ED				3
118 #define AM_SCORES				5
119 
120 #define KEY_UNKNOWN				0xFF
121 #define KEY_DIR					0x90
122 #define KEY_DIR_SHIFT			0xA0
123 #define KEY_DIR_CONTROL			0xB0
124 
125 #define NEXT_FINDER				1
126 #define NEXT_NEW				2
127 #define NEXT_OPEN				3
128 #define NEXT_WAIT				4
129 #define NEXT_QUIT				5
130 
131 long savefileset;
132 char savefilename[64];
133 short savefilevol;
134 
135 #define sqc_dlg_id				258
136 #define sqc_save_item			1
137 #define sqc_quit_item			2
138 #define sqc_cancel_item			3
139 #define sqc_defbrd_item			4
140 
141 #define code_enter				0x03
142 #define code_return				0x0D
143 
144 #define errAlrtID				1024
145 
146 static short sqcdefault_item;
147 static Handle sqcdefault_handle;
148 
149 static long save_cmd_level, file_menu_level, app_menu_level;
150 static long save_cmd_enabled, file_menu_enabled, app_menu_enabled;
151 
152 #if 0
153 /* this stuff is no longer used */
154 
155 #define malloc_zone_size		0x1000
156 
157 static THz malloc_zone;
158 
159 void init_malloc_zone()
160 
161 {
162 	THz theOldZone;
163 
164 	theOldZone = GetZone();
165 
166 	InitZone(NULL, 64, (Ptr)((long) malloc_zone + malloc_zone_size),
167 		 (Ptr) malloc_zone);
168 
169 	SetZone(theOldZone);
170 
171 	return;
172 }
173 
174 void *mac_malloc(n)
175 unsigned n;
176 
177 {
178 	THz theOldZone;
179 	void *theNewPtr;
180 
181 	theOldZone = GetZone();
182 	SetZone(malloc_zone);
183 
184 	theNewPtr = (void *) NewPtrClear((Size) n);
185 
186 	SetZone(theOldZone);
187 
188 	return(theNewPtr);
189 }
190 
191 void mac_free(p)
192 void *p;
193 
194 {
195 #if 0
196 	THz theOldZone;
197 
198 	theOldZone = GetZone();
199 	SetZone(malloc_zone);
200 
201 	DisposPtr((Ptr) p);
202 
203 	SetZone(theOldZone);
204 #else
205 #pragma unused(p)
206 #endif
207 
208 	return;
209 }
210 
211 #endif
212 
mac_time()213 long mac_time()
214 
215 {
216 	long now;
217 
218 	GetDateTime((unsigned long *) &now);
219 	return(now);
220 }
221 
alert_error(message)222 void alert_error(message)
223 char *message;
224 
225 {
226 	Str255 pstr;
227 
228 	strncpy((char *)pstr, message, 255);
229 	pstr[255] = '\0';
230 	(void) c2pstr(pstr);
231 
232 	ParamText(pstr, NULL, NULL, NULL);
233 
234 	DoScreenALRT(errAlrtID, akStop, fixHalf, fixHalf);
235 
236 	return;
237 }
238 
fatal_error(message)239 void fatal_error(message)
240 char *message;
241 
242 {
243 	alert_error(message);
244 	exit(0);
245 }
246 
truncstr(pstr,wid)247 char *truncstr(pstr, wid)
248 char *pstr;
249 short wid;
250 
251 {
252 	unsigned char len;
253 
254 	if (StringWidth(pstr) > wid) {
255 		len = (unsigned char) pstr[0];
256 		if (len > 0) pstr[len] = '\311';
257 		while ( (len > 1) && (StringWidth(pstr) > wid) ) {
258 			pstr[0] = (char) --len;
259 			pstr[len] = '\311';
260 		}
261 	}
262 
263 	return(pstr);
264 }
265 
idle()266 void idle()
267 
268 {
269 	long redraw;
270 
271 	redraw = FALSE;
272 
273 	if ((!save_cmd_enabled) && (save_cmd_level > 0)) {
274 		EnableItem((MenuHandle) GetFileMHandle(), FM_SAVE);
275 		EnableItem((MenuHandle) GetFileMHandle(), FM_SAVE_AS);
276 		save_cmd_enabled = TRUE;
277 	}
278 	else if ((save_cmd_enabled) && (save_cmd_level <= 0)) {
279 		DisableItem((MenuHandle) GetFileMHandle(), FM_SAVE);
280 		DisableItem((MenuHandle) GetFileMHandle(), FM_SAVE_AS);
281 		save_cmd_enabled = FALSE;
282 	}
283 
284 	if ((!file_menu_enabled) && (file_menu_level > 0)) {
285 		EnableItem((MenuHandle) GetFileMHandle(), 0);
286 		file_menu_enabled = TRUE;
287 		redraw = TRUE;
288 	}
289 	else if ((file_menu_enabled) && (file_menu_level <= 0)) {
290 		DisableItem((MenuHandle) GetFileMHandle(), 0);
291 		file_menu_enabled = FALSE;
292 		redraw = TRUE;
293 	}
294 
295 	if ((!app_menu_enabled) && (app_menu_level > 0)) {
296 		EnableItem((MenuHandle) GetAppMHandle(), 0);
297 		app_menu_enabled = TRUE;
298 		redraw = TRUE;
299 	}
300 	else if ((app_menu_enabled) && (app_menu_level <= 0)) {
301 		DisableItem((MenuHandle) GetAppMHandle(), 0);
302 		app_menu_enabled = FALSE;
303 		redraw = TRUE;
304 	}
305 
306 	if (redraw)
307 		DrawMenuBar();
308 
309 	IdleScreenMgr();
310 }
311 
macgetkey(ch,nowait)312 int macgetkey(ch, nowait)
313 char *ch;
314 int nowait;
315 
316 {
317 	char keycode, modifiers, ascii;
318 	short h, v;
319 
320 	do {
321 
322 		if (nowait) {
323 			idle();
324 			if (!GetScreenKeys(&keycode, &modifiers, &ascii, &h, &v))
325 				return(FALSE);
326 		}
327 		else {
328 			do {
329 				idle();
330 			} while (!GetScreenKeys(&keycode, &modifiers, &ascii, &h, &v));
331 		}
332 
333 	} while ( (modifiers & maskModMouse) ||
334 			  (codetable[keycode] == CODE_IGNORE) );
335 
336 	if (ascii > 0x7F) ascii = KEY_UNKNOWN;
337 
338 	switch (codetable[keycode]) {
339 
340 		case CODE_KEYPAD:
341 			if ((ascii >= '1') && (ascii <= '9')) {
342 				ascii -= '0';
343 				if (modifiers & maskModControl)
344 					ascii += KEY_DIR_CONTROL;
345 				else if (modifiers & maskModShift)
346 					ascii += KEY_DIR_SHIFT;
347 				else
348 					ascii += KEY_DIR;
349 			}
350 			break;
351 
352 		case CODE_ARROW:
353 			switch (keycode) {
354 				case ARROW_UP_1: case ARROW_UP_2:
355 					ascii = 8;
356 					break;
357 				case ARROW_DOWN_1: case ARROW_DOWN_2:
358 					ascii = 2;
359 					break;
360 				case ARROW_LEFT_1: case ARROW_LEFT_2:
361 					ascii = 4;
362 					break;
363 				case ARROW_RIGHT_1: case ARROW_RIGHT_2:
364 					ascii = 6;
365 					break;
366 				default:
367 					ascii = 5;
368 					break;
369 			}
370 			if (modifiers & maskModControl)
371 				ascii += KEY_DIR_CONTROL;
372 			else if (modifiers & maskModShift)
373 				ascii += KEY_DIR_SHIFT;
374 			else
375 				ascii += KEY_DIR;
376 			break;
377 
378 		case CODE_ENTER:
379 			ascii = '\r';
380 			break;
381 
382 	}
383 
384 	if (ch != NULL) *ch = ascii;
385 
386 	return(TRUE);
387 }
388 
extractdir(ch,shift_flag,ctrl_flag)389 int extractdir(ch, shift_flag, ctrl_flag)
390 char ch;
391 int *shift_flag;
392 int *ctrl_flag;
393 
394 {
395 	long rc;
396 
397 	if ((ch & 0xF0) == KEY_DIR) {
398 		*shift_flag = FALSE;
399 		*ctrl_flag = FALSE;
400 		rc = ch & 0x0F;
401 	}
402 	else if ((ch & 0xF0) == KEY_DIR_SHIFT) {
403 		*shift_flag = TRUE;
404 		*ctrl_flag = FALSE;
405 		rc = ch & 0x0F;
406 	}
407 	else if ((ch & 0xF0) == KEY_DIR_CONTROL) {
408 		*shift_flag = FALSE;
409 		*ctrl_flag = TRUE;
410 		rc = ch & 0x0F;
411 	}
412 	else
413 		rc = -1;
414 
415 	return(rc);
416 }
417 
mac_save_screen()418 void mac_save_screen()
419 
420 {
421 	Rect screen;
422 
423 	screen.left = screen.top = 0;
424 	screen.right = SCRN_COLS;
425 	screen.bottom = SCRN_ROWS;
426 
427 	HLock((Handle) save_chars);
428 	HLock((Handle) save_attrs);
429 
430 	GetScreenImage(*save_chars, *save_attrs, SCRN_COLS, &screen, 0, 0);
431 	GetScreenCursor(&save_cursor_h, &save_cursor_v);
432 
433 	HUnlock((Handle) save_chars);
434 	HUnlock((Handle) save_attrs);
435 
436 	return;
437 }
438 
439 /* This restore routine only touches as much of the screen as necessary. */
440 
mac_restore_screen()441 void mac_restore_screen()
442 
443 {
444 	Rect screen;
445 	long v;
446 	char chars[SCRN_COLS], attrs[SCRN_COLS];
447 	char *c, *a, *c1, *c2, *a1, *a2;
448 
449 	HLock((Handle) save_chars);
450 	HLock((Handle) save_attrs);
451 
452 	c = *save_chars;
453 	a = *save_attrs;
454 
455 	screen.top = 0;
456 	screen.bottom = 1;
457 
458 	for (v = 0; v < SCRN_ROWS; v++) {
459 
460 		screen.left = 0;
461 		screen.right = SCRN_COLS;
462 
463 		GetScreenImage(chars, attrs, SCRN_COLS, &screen, 0, v);
464 
465 		c1 = chars;
466 		c2 = c;
467 
468 		a1 = attrs;
469 		a2 = a;
470 
471 		while (screen.left < SCRN_COLS) {
472 			if (*c1++ != *c2++) break;
473 			if (*a1++ != *a2++) break;
474 			++screen.left;
475 		}
476 
477 		c1 = chars + SCRN_COLS;
478 		c2 = c + SCRN_COLS;
479 
480 		a1 = attrs + SCRN_COLS;
481 		a2 = a + SCRN_COLS;
482 
483 		while (screen.right > screen.left) {
484 			if (*--c1 != *--c2) break;
485 			if (*--a1 != *--a2) break;
486 			--screen.right;
487 		}
488 
489 		if (screen.right > screen.left)
490 			DSetScreenImage(c, a, SCRN_COLS, &screen, screen.left, v);
491 
492 		c += SCRN_COLS;
493 		a += SCRN_COLS;
494 
495 	}
496 
497 	DSetScreenCursor(save_cursor_h, save_cursor_v);
498 
499 	HUnlock((Handle) save_chars);
500 	HUnlock((Handle) save_attrs);
501 
502 	return;
503 }
504 
mac_beep()505 void mac_beep()
506 
507 {
508 	SysBeep(15);
509 	return;
510 }
511 
macbeginwait()512 void macbeginwait()
513 
514 {
515 	BeginScreenWait(SPIN_TICKS);
516 	return;
517 }
518 
macendwait()519 void macendwait()
520 
521 {
522 	EndScreenWait();
523 	return;
524 }
525 
GetDirID(wdVRefNum,vRefNum,dirID)526 OSErr GetDirID(wdVRefNum, vRefNum, dirID)
527 short wdVRefNum;
528 short *vRefNum;
529 long *dirID;
530 
531 {
532 	OSErr err;
533 	WDPBRec wdpb;
534 
535 	wdpb.ioNamePtr = NULL;
536 	wdpb.ioVRefNum = wdVRefNum;
537 	wdpb.ioWDIndex = 0;
538 	wdpb.ioWDProcID = 0;
539 	wdpb.ioWDVRefNum = 0;
540 	err = PBGetWDInfo(&wdpb, false);
541 
542 	if (!err) {
543 		*vRefNum = wdpb.ioWDVRefNum;
544 		*dirID = wdpb.ioWDDirID;
545 	}
546 
547 	return(err);
548 }
549 
MakePath(vRefNum,dirID,fName,pathName)550 OSErr MakePath(vRefNum, dirID, fName, pathName)
551 short vRefNum;
552 long dirID;
553 char *fName;
554 char *pathName;
555 
556 {
557 	char buf[PATHLEN], *bufptr;
558 	long len;
559 	OSErr err;
560 	Str255 vNameBuf;
561 	CInfoPBRec cipb;
562 
563 	bufptr = buf + PATHLEN;
564 
565 	*--bufptr = '\0';
566 
567 	if (fName != NULL) {
568 		len = strlen(fName);
569 		strncpy(bufptr -= len, fName, len);
570 	}
571 
572 	cipb.dirInfo.ioNamePtr = vNameBuf;
573 	cipb.dirInfo.ioVRefNum = vRefNum;
574 	cipb.dirInfo.ioFDirIndex = -1;
575 
576 	do {
577 		cipb.dirInfo.ioDrDirID = dirID;
578 		err = PBGetCatInfo(&cipb, false);
579 		if (!err) {
580 			*--bufptr = ':';
581 			len = strlen(p2cstr(vNameBuf));
582 			strncpy(bufptr -= len, (char *)vNameBuf, len);
583 			dirID = cipb.dirInfo.ioDrParID;
584 		}
585 	} while ( (!err) && (dirID != fsRtParID) );
586 
587 	strcpy(pathName, bufptr);
588 
589 	return(err);
590 }
591 
checkdebugger()592 void checkdebugger()
593 
594 {
595 #ifndef THINK_C
596 #if 1
597 	char keys[128];
598 
599 	GetKeys ((KeyMap *) &keys);
600 	if (keys[4] & 0x80) Debugger();		/* if command key is down */
601 #else
602 	if (((char *) KeyMapLM)[6] & 0x80) Debugger();			/* if command key is down */
603 #endif
604 #endif
605 
606 	return;
607 }
608 
getstack(request)609 static void getstack(request)
610 long request;
611 
612 {
613 	long cursize;
614 #ifdef THINK_C
615 	Ptr newlimit;
616 #else
617 	long newlimit;
618 #endif
619 
620 	/* An extra level of indirection is apparently needed by MPW C
621 	   for accessing system globals.  */
622 #ifdef THINK_C
623 	cursize = (((long *) CurStackBase) - ((long *) ApplLimit)) - 8;
624 	if (cursize < request) {
625 		newlimit = (Ptr)(((long *) CurStackBase - request) - 8);
626 		if (newlimit > HeapEnd)
627 			ApplLimit = newlimit;
628 	}
629 #else
630 	cursize = (*((int *) CurStackBase) - *((int *) ApplLimit)) - 8;
631 	if (cursize < request) {
632 		newlimit = (*((int *) CurStackBase) - request) - 8;
633 		if (newlimit > *((int *) HeapEnd)) *((int *) ApplLimit) = newlimit;
634 	}
635 #endif
636 
637 	return;
638 }
639 
sfposition(vrefnum)640 void sfposition(vrefnum)
641 short vrefnum;
642 
643 {
644 	short v;
645 	long d;
646 
647 	GetDirID(vrefnum, &v, &d);
648 #ifdef THINK_C
649 	SFSaveDisk = -v;
650 	CurDirStore = d;
651 #else
652 	*((short *) SFSaveDisk) = -v;
653 	*((int *) CurDirStore) = d;
654 #endif
655 
656 	return;
657 }
658 
doputfile(prompt,fname,vrefnum)659 long doputfile(prompt, fname, vrefnum)
660 char *prompt;
661 char *fname;
662 short *vrefnum;
663 
664 {
665 	char p[256], f[256];
666 	SFReply reply;
667 	Point loc;
668 	long h, v;
669 
670 	CenterScreenDLOG(putDlgID, fixHalf, fixThird, &h, &v);
671 
672 	loc.h = (short) h;
673 	loc.v = (short) v;
674 
675 	strncpy(p, prompt, 255);
676 	strncpy(f, fname, 255);
677 	p[255] = '\0';
678 	f[255] = '\0';
679 	c2pstr(p);
680 	c2pstr(f);
681 
682 	SFPutFile(loc, p, f, NULL, &reply);
683 
684 	if (reply.good) {
685 		p2cstr(reply.fName);
686 		strcpy(fname, (char *)reply.fName);
687 		*vrefnum = reply.vRefNum;
688 	}
689 
690 	return(reply.good);
691 }
692 
asksavegame(ask)693 int asksavegame(ask)
694 int ask;
695 
696 {
697 	int rc;
698 
699 	if (!ask && savefileset)
700 		rc = TRUE;
701 
702 	else {
703 		rc = doputfile("Save game as:", savefilename, &savefilevol);
704 		if (rc) savefileset = TRUE;
705 	}
706 
707 	return(rc);
708 }
709 
savefilefilter(pb)710 static pascal Boolean savefilefilter(pb)
711 ParmBlkPtr pb;
712 
713 {
714 	OSType fdtype, fdcreator;
715 
716 	fdtype = pb->fileParam.ioFlFndrInfo.fdType;
717 	fdcreator = pb->fileParam.ioFlFndrInfo.fdCreator;
718 
719 	return(!((fdcreator == MORIA_FCREATOR) && (fdtype == SAVE_FTYPE)));
720 }
721 
dogetfile(fname,vrefnum)722 int dogetfile(fname, vrefnum)
723 char *fname;
724 short *vrefnum;
725 
726 {
727 	SFTypeList types;
728 	SFReply reply;
729 	Point loc;
730 	long h, v;
731 
732 	CenterScreenDLOG(getDlgID, fixHalf, fixThird, &h, &v);
733 
734 	loc.h = (short) h;
735 	loc.v = (short) v;
736 
737 	types[0] = SAVE_FTYPE;
738 
739 	SFGetFile(loc, NULL, savefilefilter, 1, types, NULL, &reply);
740 
741 	if (reply.good) {
742 		p2cstr(reply.fName);
743 		strcpy(fname, (char *)reply.fName);
744 		*vrefnum = reply.vRefNum;
745 	}
746 
747 	return(reply.good);
748 }
749 
sqcfilter(dlg,evt,item)750 static pascal Boolean sqcfilter(dlg, evt, item)
751 DialogPtr dlg;
752 EventRecord *evt;
753 short *item;
754 
755 {
756 #pragma unused(dlg)
757 	Boolean rc;
758 	char key;
759 
760 	rc = FALSE;
761 
762 	if (evt->what == keyDown) {
763 		key = evt->message & charCodeMask;
764 		if ( (key == code_enter) || (key == code_return) ) {
765 			rc = TRUE;
766 			HiliteControl((ControlHandle) sqcdefault_handle, inButton);
767 			*item = sqcdefault_item;
768 		}
769 	}
770 
771 	return(rc);
772 }
773 
currentdirectory()774 short currentdirectory()
775 
776 {
777 	short vrefnum;
778 
779 	(void) GetVol(NULL, &vrefnum);
780 	return(vrefnum);
781 }
782 
changedirectory(vrefnum)783 void changedirectory(vrefnum)
784 short vrefnum;
785 
786 {
787 	(void) GetVol(NULL, &savedir);
788 	(void) SetVol(NULL, vrefnum);
789 	return;
790 }
791 
appldirectory()792 void appldirectory()
793 
794 {
795 	(void) GetVol(NULL, &savedir);
796 	(void) SetVol(NULL, applvrefnum);
797 	return;
798 }
799 
restoredirectory()800 void restoredirectory()
801 
802 {
803 	(void) SetVol(NULL, savedir);
804 	return;
805 }
806 
mac_helpfile(filename,wait)807 void mac_helpfile(filename, wait)
808 char *filename;
809 int wait;
810 
811 {
812 	Str255 temp, temp2;	/* Buffer for line and tab-expanded line.  */
813 	short apRefNum;
814 	Handle apParam;
815 	FILE *file;
816 	int i, j, done;
817 	char ch;
818 	char *cp;		/* Source for tab expansion.  */
819 	Rect area;
820 
821 	GetAppParms(temp, &apRefNum, &apParam);
822 
823 	appldirectory();
824 	/* Ordinarily, the misc files are stored in the data fork of
825 	   the application.  */
826 #if 1
827 	file = fopen(p2cstr(temp), "r");
828 #else
829 	file = fopen("MacMoria.files", "r");
830 #endif
831 	restoredirectory();
832 
833 	if (file != NULL) {
834 
835 		while (!feof(file))
836 			if (fgets ((char *)temp, 255, file) != NULL)
837 				if (temp[0] == '#')
838 					if (strstr((char *)temp, filename) != NULL)
839 						break;
840 
841 		if (feof(file)) {
842 			(void) fclose(file);
843 			file = NULL;
844 		}
845 
846 	}
847 
848 	if (file == NULL) {
849 		sprintf((char *)temp, "Cannot find text file: %s", filename);
850 		alert_error(temp);
851 	}
852 
853 	else {
854 
855 		area.left = area.top = 0;
856 		area.right = SCRN_COLS;
857 		area.bottom = SCRN_ROWS;
858 
859 		if (wait)
860 			mac_save_screen();
861 
862 		done = FALSE;
863 
864 		while ((!done) && (!feof(file))) {
865 			DEraseScreen(&area);
866 			for (i = 0; (!done) && (i < SCRN_ROWS - 1); i++)
867 				if ((fgets((char *)temp, 255, file) != NULL) && (temp[0] != '#')) {
868 					/* Remove the trailing \n and
869 					   expand tabs.  */
870 				  	for (cp = (char *) temp, j = 0;
871 					     *cp != '\n'; cp++)
872 					  {
873 					    if ((temp2[j] = *cp) == '\t')
874 					      {
875 						do
876 						  {
877 						    temp2[j++] = ' ';
878 						  }
879 						while (j % TAB_WIDTH != 0);
880 					      }
881 					    else
882 					      j++;
883 					  }
884 					temp2[j] = '\0';
885 					DSetScreenString((char *)temp2, 0, i);
886 					}
887 				else
888 					done = TRUE;
889 			if (wait) {
890 				DSetScreenCursor(20, SCRN_ROWS - 1);
891 				DWriteScreenString(
892 					done ?
893 						"[Press any key to continue.]" :
894 						"[Press any key for next page or ESC to abort.]");
895 				macgetkey(&ch, FALSE);
896 				if (ch == ESCAPE)
897 					done = TRUE;
898 			}
899 		}
900 
901 		if (wait)
902 			mac_restore_screen();
903 
904 		fclose(file);
905 
906 	}
907 
908 	return;
909 }
910 
nextstring(loc)911 char *nextstring(loc)
912 char **loc;
913 
914 {
915 	char *str;
916 	unsigned char len;
917 
918 	len = *((unsigned char *) (*loc));
919 	str = p2cstr(*loc);
920 	*loc += len + 1;
921 
922 	return(str);
923 }
924 
925 #if 0
926 /* no longer used */
927 long allocmalloczone(restart)
928 long restart;
929 
930 {
931 	long rc;
932 
933 	if (!restart) {
934 		malloc_zone = (THz) NewPtr(malloc_zone_size);
935 		rc = malloc_zone != NULL;
936 	}
937 	else
938 		rc = TRUE;
939 
940 	if (rc && !restart)
941 		init_malloc_zone();
942 
943 	return(rc);
944 }
945 #endif
946 
allocsavearea(restart)947 int allocsavearea(restart)
948 int restart;
949 
950 {
951 	int rc;
952 
953 	if (!restart) {
954 		save_chars = (char **) NewHandle(SCRN_ROWS * SCRN_COLS);
955 		save_attrs = (char **) NewHandle(SCRN_ROWS * SCRN_COLS);
956 		rc = (save_chars != NULL) && (save_attrs != NULL);
957 	}
958 	else
959 		rc = TRUE;
960 
961 	return(rc);
962 }
963 
setupmem(restart)964 int setupmem(restart)
965 int restart;
966 
967 {
968 	int i;
969 	memtable_type *m;
970 
971 	for (i = 0, m = memtable; i < MAX_PTRS; i++, m++) {
972 
973 		if (!restart) {
974 			*m->memPtr = (char *) NewPtrClear(m->elemCnt * m->elemSiz);
975 			if (*m->memPtr == NULL) return(FALSE);
976 		}
977 
978 		else if (m->restartFlag) {
979 			memset(*m->memPtr, 0, m->elemCnt * m->elemSiz);
980 		}
981 
982 	}
983 
984 	return(TRUE);
985 }
986 
getresources(restart)987 int getresources(restart)
988 int restart;
989 
990 {
991 	int i, rc;
992 	restable_type *r;
993 
994 	for (i = 0, r = restable; i < MAX_RESOURCES; i++, r++) {
995 
996 		if (!restart) *r->memPtr = NULL;
997 
998 		if ( (!restart) || (r->restartFlag) ) {
999 
1000 			rc = LoadRes(
1001 				r->memPtr,
1002 				r->resType, r->resID,
1003 				r->elemCnt, r->elemSiz,
1004 				r->strProc);
1005 
1006 			if (!rc) return(FALSE);
1007 
1008 		}
1009 
1010 	}
1011 
1012 	return(TRUE);
1013 }
1014 
getrestart(restart)1015 int getrestart(restart)
1016 int restart;
1017 
1018 {
1019 	int i, rc;
1020 	unsigned size;
1021 	char *p, *q;
1022 
1023 	if (restart) {
1024 
1025 		size = 0;
1026 		for (i = 0; i < MAX_RESTART; i++) size += restart_vars[i].size;
1027 
1028 		p = NULL;
1029 
1030 		rc = LoadRes(
1031 			&p,
1032 			restartRsrc, restart_id,
1033 			1, size,
1034 			NULL);
1035 
1036 		if (!rc) return(FALSE);
1037 
1038 		q = p;
1039 		for (i = 0; i < MAX_RESTART; i++) {
1040 			BlockMove(q, restart_vars[i].ptr, restart_vars[i].size);
1041 			q += restart_vars[i].size;
1042 		}
1043 
1044 		DisposPtr(p);
1045 
1046 	}
1047 
1048 	return(TRUE);
1049 }
1050 
clearvars(restart)1051 int clearvars(restart)
1052 int restart;
1053 
1054 {
1055 	int i;
1056 	clrtable_type *c;
1057 
1058 	if (restart)
1059 		for (i = 0, c = clrtable; i < MAX_CLRS; i++, c++)
1060 			memset(c->ptr, 0, c->size);
1061 
1062 	return(TRUE);
1063 }
1064 
1065 #ifndef THINK_C
sleep(time)1066 unsigned sleep(time)
1067 unsigned time;
1068 
1069 {
1070 #pragma unused(time)
1071 	idle();
1072 	return(0);
1073 }
1074 #endif
1075 
makefilename(buffer,suffix,append)1076 char *makefilename(buffer, suffix, append)
1077 char *buffer, *suffix;
1078 int append;
1079 
1080 
1081 {
1082 	long len;
1083 	char *p;
1084 
1085 	len = strlen(py.misc.name) + ((append) ? strlen(suffix)+3 : 0);
1086 
1087 	if ( (strlen(py.misc.name) == 0) || (len > 31) )
1088 		strcpy(buffer, suffix);
1089 
1090 	else {
1091 		strcpy(buffer, py.misc.name);
1092 		if (append) {
1093 			strcat(buffer, "'s ");
1094 			strcat(buffer, suffix);
1095 		}
1096 		for (p = buffer; *p; p++)
1097 			if (*p == ':') *p = '.';
1098 	}
1099 
1100 	return(buffer);
1101 }
1102 
initsavedefaults()1103 void initsavedefaults()
1104 
1105 {
1106 	savefileset = FALSE;
1107 
1108 	(void) makefilename(savefilename, "Save File", FALSE);
1109 	savefilevol = currentdirectory();
1110 
1111 	return;
1112 }
1113 
setsavedefaults(name,vol)1114 void setsavedefaults(name, vol)
1115 char *name;
1116 short vol;
1117 
1118 {
1119 	savefileset = TRUE;
1120 
1121 	strncpy(savefilename, name, 63);
1122 	savefilename[63] = '\0';
1123 
1124 	savefilevol = vol;
1125 
1126 	return;
1127 }
1128 
getsavedefaults(name,vol)1129 int getsavedefaults(name, vol)
1130 char *name;
1131 short *vol;
1132 
1133 {
1134 	strcpy(name, savefilename);
1135 	*vol = savefilevol;
1136 
1137 	return(savefileset);
1138 }
1139 
getfinderfile()1140 int getfinderfile()
1141 
1142 {
1143 	short message, count, i;
1144 	AppFile appfile;
1145 
1146 	CountAppFiles(&message, &count);
1147 
1148 	for (i = 1; i <= count; i++) {
1149 		GetAppFiles(i, &appfile);
1150 		if (appfile.fType == SAVE_FTYPE) break;
1151 	}
1152 
1153 	if (i <= count) {
1154 		setsavedefaults(p2cstr(appfile.fName), appfile.vRefNum);
1155 	}
1156 
1157 	return(i <= count);
1158 }
1159 
setfileinfo(fname,vrefnum,ftype)1160 long setfileinfo(fname, vrefnum, ftype)
1161 char *fname;
1162 short vrefnum;
1163 long ftype;
1164 
1165 {
1166 	long fcreator;
1167 	char temp[64];
1168 	FileParam pb;
1169 	OSErr err;
1170 
1171 	fcreator = (ftype != INFO_FTYPE) ? MORIA_FCREATOR : editor;
1172 
1173 	strcpy(temp, fname);
1174 	(void) c2pstr(temp);
1175 
1176 	pb.ioCompletion = NULL;
1177 	pb.ioNamePtr = (unsigned char *)temp;
1178 	pb.ioVRefNum = vrefnum;
1179 	pb.ioFVersNum = 0;
1180 	pb.ioFDirIndex = 0;
1181 
1182 	err = PBGetFInfo((ParmBlkPtr) &pb, FALSE);
1183 
1184 	if (err == noErr) {
1185 		pb.ioFlFndrInfo.fdType = ftype;
1186 		pb.ioFlFndrInfo.fdCreator = fcreator;
1187 		err = PBSetFInfo((ParmBlkPtr) &pb, FALSE);
1188 	}
1189 
1190 	return(err == noErr);
1191 }
1192 
1193 #if 0
1194 long getfileage(fname, vrefnum)
1195 char *fname;
1196 short vrefnum;
1197 
1198 {
1199 	char temp[64];
1200 	FileParam pb;
1201 	OSErr err;
1202 	long age;
1203 
1204 	strcpy(temp, fname);
1205 	(void) c2pstr(temp);
1206 
1207 	pb.ioCompletion = NULL;
1208 	pb.ioNamePtr = temp;
1209 	pb.ioVRefNum = vrefnum;
1210 	pb.ioFVersNum = 0;
1211 	pb.ioFDirIndex = 0;
1212 
1213 	err = PBGetFInfo((ParmBlkPtr) &pb, FALSE);
1214 
1215 	if (err == noErr) {
1216 		GetDateTime((unsigned long *) &age);
1217 		age -= pb.ioFlMdDat;
1218 	}
1219 	else
1220 		age = 0;
1221 
1222 	return(age);
1223 }
1224 #endif
1225 
benediction()1226 void benediction()
1227 
1228 {
1229 	Rect scrn;
1230 
1231 	scrn.left = 0;
1232 	scrn.top = SCRN_ROWS-1;
1233 	scrn.right = SCRN_COLS;
1234 	scrn.bottom = SCRN_ROWS;
1235 
1236 	EraseScreen(&scrn);
1237 
1238 	SetScreenCursor(0, SCRN_ROWS-1);
1239 	WriteScreenString("Please select a command from the file menu...");
1240 
1241 	return;
1242 }
1243 
setsavecmdstatus(val,init)1244 void setsavecmdstatus(val, init)
1245 int val, init;
1246 
1247 {
1248 	save_cmd_level = val;
1249 
1250 	if (init)
1251 		save_cmd_enabled = val > 0;
1252 
1253 	return;
1254 }
1255 
enablesavecmd(flag)1256 void enablesavecmd(flag)
1257 int flag;
1258 
1259 {
1260 	save_cmd_level += flag ? 1 : -1;
1261 	return;
1262 }
1263 
setfilemenustatus(val,init)1264 void setfilemenustatus(val, init)
1265 int val, init;
1266 
1267 {
1268 	file_menu_level = val;
1269 
1270 	if (init)
1271 		file_menu_enabled = val > 0;
1272 
1273 	return;
1274 }
1275 
enablefilemenu(flag)1276 void enablefilemenu(flag)
1277 int flag;
1278 
1279 {
1280 	file_menu_level += flag ? 1 : -1;
1281 	return;
1282 }
1283 
setappmenustatus(val,init)1284 void setappmenustatus(val, init)
1285 int val, init;
1286 
1287 {
1288 	app_menu_level = val;
1289 
1290 	if (init)
1291 		app_menu_enabled = val > 0;
1292 
1293 	return;
1294 }
1295 
enableappmenu(flag)1296 void enableappmenu(flag)
1297 int flag;
1298 
1299 {
1300 	app_menu_level += flag ? 1 : -1;
1301 	return;
1302 }
1303 
savequitorcancel(next)1304 void savequitorcancel(next)
1305 int next;
1306 
1307 {
1308 	DialogPtr thedialog;
1309 	short itemhit;
1310 	short itstype;
1311 	Rect itsrect;
1312 	long h, v;
1313 	long saveOk, dialogFinished;
1314 
1315 	thedialog = GetNewDialog(sqc_dlg_id, nil, (WindowPtr) -1);
1316 
1317 	CenterScreenDLOG(sqc_dlg_id, fixHalf, fixThird, &h, &v);
1318 	MoveWindow((WindowPtr) thedialog, (short) h, (short) v, false);
1319 
1320 	if ((save_cmd_level > 0) && !total_winner) {
1321 		sqcdefault_item = sqc_save_item;
1322 		saveOk = true;
1323 	}
1324 	else {
1325 		sqcdefault_item = sqc_quit_item;
1326 		saveOk = false;
1327 	}
1328 
1329 	GetDItem(thedialog, sqcdefault_item, &itstype, &sqcdefault_handle, &itsrect);
1330 	InsetRect(&itsrect, -4, -4);
1331 
1332 	SetDItem(thedialog, sqc_defbrd_item, userItem,
1333 		 (Handle) DrawDefaultBorder, &itsrect);
1334 
1335 	ShowWindow((WindowPtr) thedialog);
1336 
1337 	do {
1338 		ModalDialog(sqcfilter, &itemhit);
1339 		if ( (!saveOk) && (itemhit == sqc_save_item) ) {
1340 			if (total_winner)
1341 				alert_error("Sorry.  Since you are a total \
1342 winner, you cannot save this game.  Your character must be retired.");
1343 			else
1344 				alert_error("Sorry.  You cannot save at this \
1345 point in the game.  It must be your turn to move in order to save.");
1346 			dialogFinished = false;
1347 		}
1348 		else
1349 			dialogFinished = (itemhit == sqc_save_item) ||
1350 						(itemhit == sqc_quit_item) ||
1351 						(itemhit == sqc_cancel_item);
1352 	} while (!dialogFinished);
1353 
1354 	DisposDialog(thedialog);
1355 
1356 	switch (itemhit) {
1357 
1358 		case sqc_save_item:
1359 			if (asksavegame(FALSE)) {
1360 				HiliteMenu(0);
1361 				(void) strcpy (died_from, "(saved)");
1362 				exit_code = next;
1363 				if (save_char(FALSE))
1364 					exit_game();
1365 				/* Should only get here if save_char fails */
1366 				UnloadSeg(save_char);
1367 				UnloadSeg(exit_game);
1368 				exit_code = NEXT_WAIT;
1369 				(void) strcpy (died_from, "(alive and well)");
1370 			}
1371 			break;
1372 
1373 		case sqc_quit_item:
1374 			HiliteMenu(0);
1375 			death = TRUE;
1376 			(void) strcpy(died_from, "Quitting.");
1377 			exit_code = next;
1378 			exit_game();
1379 			/* Should never get here */
1380 			UnloadSeg(exit_game);
1381 			exit_code = NEXT_WAIT;
1382 			(void) strcpy (died_from, "(alive and well)");
1383 			death = FALSE;
1384 			break;
1385 
1386 		default:
1387 			HiliteMenu(0);
1388 			break;
1389 
1390 	}
1391 
1392 	return;
1393 }
1394 
loaddata(restart)1395 void loaddata(restart)
1396 int restart;
1397 {
1398 	if (
1399 #if 0
1400 	    		(!allocmalloczone(restart))	||
1401 #endif
1402 			(!allocsavearea(restart))	||
1403 			(!setupmem(restart))		||
1404 			(!getresources(restart))	||
1405 			(!getrestart(restart))		||
1406 			(!clearvars(restart))			)
1407 
1408 				fatal_error("Insufficient memory to play Moria.  Sorry.");
1409 
1410 	return;
1411 }
1412 
goback()1413 void goback()
1414 
1415 {
1416 	longjmp(jb, exit_code);
1417 }
1418 
startfinder()1419 int startfinder()
1420 
1421 {
1422 	int next;
1423 	int argc;
1424 	long local_cmdsetopt;
1425 	char *argv[2];
1426 
1427 	if ((next = setjmp(jb)) != 0) return(next);
1428 
1429 	clear_screen();
1430 
1431 	local_cmdsetopt = cmdsetopt;
1432 
1433 	argc = 0;
1434 	argv[argc++] = NULL;
1435 	argv[argc++] = (char *) &local_cmdsetopt;
1436 
1437 	game_flag = TRUE;
1438 	exit_code = NEXT_WAIT;
1439 
1440 	moria_main(argc, argv);
1441 
1442 	/* should never get here */
1443 	return(NEXT_WAIT);
1444 }
1445 
startnew()1446 int startnew()
1447 
1448 {
1449 	int next;
1450 	int argc;
1451 	long local_cmdsetopt, local_newgameopt;
1452 	char *argv[3];
1453 
1454 	if ((next = setjmp(jb)) != 0) return(next);
1455 
1456 	clear_screen();
1457 
1458 	local_cmdsetopt = cmdsetopt;
1459 	local_newgameopt = '-n\0\0';
1460 
1461 	argc = 0;
1462 	argv[argc++] = NULL;
1463 	argv[argc++] = (char *) &local_cmdsetopt;
1464 	argv[argc++] = (char *) &local_newgameopt;
1465 
1466 	game_flag = TRUE;
1467 	exit_code = NEXT_WAIT;
1468 
1469 	moria_main(argc, argv);
1470 
1471 	/* should never get here */
1472 	return(NEXT_WAIT);
1473 }
1474 
startopen()1475 int startopen()
1476 
1477 {
1478 	int next;
1479 	int argc;
1480 	long local_cmdsetopt;
1481 	char *argv[2];
1482 
1483 	if ((next = setjmp(jb)) != 0) return(next);
1484 
1485 	clear_screen();
1486 
1487 	if (dogetfile(savefilename, &savefilevol)) {
1488 
1489 		savefileset = TRUE;
1490 
1491 		local_cmdsetopt = cmdsetopt;
1492 
1493 		argc = 0;
1494 		argv[argc++] = NULL;
1495 		argv[argc++] = (char *) &local_cmdsetopt;
1496 
1497 		game_flag = TRUE;
1498 		exit_code = NEXT_WAIT;
1499 
1500 		moria_main(argc, argv);
1501 
1502 	}
1503 
1504 	/* should not get here unless user cancels standard file dialog */
1505 	return(NEXT_WAIT);
1506 }
1507 
waitforchoice()1508 int waitforchoice()
1509 
1510 {
1511 	int next;
1512 
1513 	if ((next = setjmp(jb)) != 0) return(next);
1514 
1515 	game_flag = FALSE;
1516 
1517 	benediction();
1518 
1519 	do {
1520 		idle();
1521 	} while(TRUE);
1522 
1523 	return(NEXT_WAIT);
1524 }
1525 
dofmnew()1526 void dofmnew()
1527 
1528 {
1529 	if (game_flag && character_generated)
1530 		savequitorcancel(NEXT_NEW);
1531 
1532 	else {
1533 		HiliteMenu(0);
1534 		exit_code = NEXT_NEW;
1535 		goback();
1536 	}
1537 
1538 	return;
1539 }
1540 
dofmopen()1541 void dofmopen()
1542 
1543 {
1544 	if (game_flag && character_generated)
1545 		savequitorcancel(NEXT_OPEN);
1546 
1547 	else {
1548 		HiliteMenu(0);
1549 		exit_code = NEXT_OPEN;
1550 		goback();
1551 	}
1552 
1553 	return;
1554 }
1555 
dofmsave(ask)1556 void dofmsave(ask)
1557 int ask;
1558 
1559 {
1560 	if (game_flag && character_generated && total_winner) {
1561 		alert_error("Sorry.  Since you are a total winner, you cannot\
1562  save this game.  Your character must be retired.");
1563 		HiliteMenu(0);
1564 	}
1565 	else if (game_flag && character_generated && asksavegame(ask)) {
1566 		HiliteMenu(0);
1567 		(void) strcpy (died_from, "(saved)");
1568 		if (save_char(FALSE))
1569 			exit_game();
1570 		/* Should only get here if save_char fails */
1571 		UnloadSeg(save_char);
1572 		UnloadSeg(exit_game);
1573 		(void) strcpy (died_from, "(alive and well)");
1574 	}
1575 	else
1576 		HiliteMenu(0);
1577 
1578 	return;
1579 }
1580 
dofmquit()1581 void dofmquit()
1582 
1583 {
1584 	if (game_flag && character_generated)
1585 		savequitorcancel(NEXT_QUIT);
1586 
1587 	else {
1588 		HiliteMenu(0);
1589 		exit_code = NEXT_QUIT;
1590 		goback();
1591 	}
1592 
1593 	return;
1594 }
1595 
dofilemenu(item)1596 void dofilemenu(item)
1597 long item;
1598 
1599 {
1600 	switch (item) {
1601 
1602 		case FM_NEW:		dofmnew();
1603 							break;
1604 
1605 		case FM_OPEN:		dofmopen();
1606 							break;
1607 
1608 		case FM_SAVE:		dofmsave(FALSE);
1609 							break;
1610 
1611 		case FM_SAVE_AS:	dofmsave(TRUE);
1612 							break;
1613 
1614 		case FM_QUIT:		dofmquit();
1615 							break;
1616 
1617 		case closeBoxItem:	if (file_menu_level > 0) dofmquit();
1618 							break;
1619 
1620 		default:			HiliteMenu(0);
1621 							break;
1622 
1623 	}
1624 
1625 	return;
1626 }
1627 
doappmenu(item)1628 void doappmenu(item)
1629 long item;
1630 
1631 {
1632 	switch (item) {
1633 
1634 		case AM_HELP:		DoMacHelp();
1635 							UnloadSeg(DoMacHelp);
1636 							break;
1637 
1638 		case AM_CMD_SET:	ConfigScreenMgr(TRUE, CMDSET_TYPE,
1639 							CMDSET_ID, GetCommandSet);
1640 							UnloadSeg(GetCommandSet);
1641 							cmdsetopt = **((long **) GetResource(CMDSET_TYPE, CMDSET_ID));
1642 							HiliteMenu(0);
1643 							break;
1644 
1645 		case AM_TEXT_ED:	ConfigScreenMgr(TRUE, TE_TYPE, TE_ID, GetTextEditor);
1646 							UnloadSeg(GetTextEditor);
1647 							editor = **((long **) GetResource(TE_TYPE, TE_ID));
1648 							HiliteMenu(0);
1649 							break;
1650 
1651 		case AM_SCORES:		DoScoresDlg();
1652 							UnloadSeg(DoScoresDlg);
1653 							break;
1654 
1655 		default:			HiliteMenu(0);
1656 							break;
1657 
1658 	}
1659 
1660 	return;
1661 }
1662 
unloadsegments()1663 void unloadsegments()
1664 
1665 {
1666 #ifndef THINK_C
1667 	extern void create_character(),
1668 		creatures(),
1669 		exit_game(),
1670 		eat(),
1671 		file_character(),
1672 		generate_cave(),
1673 		ident_char(),
1674 		cast(),
1675 		pray(),
1676 		quaff(),
1677 		roff_recall(),
1678 		save_char(),
1679 		read_scroll(),
1680 		use(),
1681 		store_init(),
1682 		aim(),
1683 		wizard_light();
1684 
1685 	UnloadSeg(create_character);			/* Create			*/
1686 	UnloadSeg(creatures);					/* Creature			*/
1687 	UnloadSeg(exit_game);					/* Death			*/
1688 	UnloadSeg(eat);							/* Eat				*/
1689 	UnloadSeg(file_character);				/* Files			*/
1690 	UnloadSeg(generate_cave);				/* Generate			*/
1691 	UnloadSeg(ident_char);					/* Help				*/
1692 	UnloadSeg(cast);						/* Magic			*/
1693 	UnloadSeg(pray);						/* Prayer			*/
1694 	UnloadSeg(quaff);						/* Potions			*/
1695 	UnloadSeg(roff_recall);					/* Recall			*/
1696 	UnloadSeg(save_char);					/* Save				*/
1697 	UnloadSeg(read_scroll);					/* Scrolls			*/
1698 	UnloadSeg(use);							/* Staffs			*/
1699 	UnloadSeg(store_init);					/* Store			*/
1700 	UnloadSeg(aim);							/* Wands			*/
1701 	UnloadSeg(wizard_light);				/* Wizard			*/
1702 #endif
1703 
1704 	return;
1705 }
1706 
salutation()1707 void salutation()
1708 
1709 {
1710 	mac_helpfile(MORIA_MOR, FALSE);
1711 }
1712 
main()1713 int main()
1714 
1715 {
1716 	int next, savedgame, restart_flag;
1717 #ifndef THINK_C
1718 	extern void _DataInit();
1719 #endif
1720 
1721 	checkdebugger();
1722 
1723 #ifndef THINK_C
1724 	UnloadSeg(_DataInit);
1725 #endif
1726 
1727 	getstack(0x7000L);
1728 
1729   	MaxApplZone();
1730 
1731 	/* Do this early to prevent fragmentation */
1732 	loaddata(FALSE);
1733 
1734 	InitScreenMgr(SCRN_COLS, SCRN_ROWS,
1735 		"Moria", "Moria Config",
1736 		MORIA_FCREATOR, CONFIG_FTYPE,
1737 		dofilemenu, doappmenu,
1738 		twoColor);
1739 
1740 	/* Get permanently set options */
1741 	/* If user has not set them yet, a dialog will be invoked */
1742 	/* Otherwise, they will be loaded from the preferences file */
1743 
1744 	ConfigScreenMgr(FALSE, CMDSET_TYPE, CMDSET_ID, GetCommandSet);
1745 #ifndef THINK_C
1746 	UnloadSeg(GetCommandSet);
1747 #endif
1748 	cmdsetopt = **((long **) GetResource(CMDSET_TYPE, CMDSET_ID));
1749 
1750 	ConfigScreenMgr(FALSE, TE_TYPE, TE_ID, GetTextEditor);
1751 #ifndef THINK_C
1752 	UnloadSeg(GetTextEditor);
1753 #endif
1754 	editor = **((long **) GetResource(TE_TYPE, TE_ID));
1755 
1756 	DefineScreenCursor(attrColorFore, 2, GetCaretTime());
1757 	ShowScreenCursor();
1758 
1759 	/* Save the application volume */
1760 	GetVol(NULL, &applvrefnum);
1761 
1762 	/* These should be based up the menu resources */
1763 	setsavecmdstatus(0, TRUE);
1764 	setfilemenustatus(1, TRUE);
1765 	setappmenustatus(1, TRUE);
1766 
1767 	restart_flag = FALSE;
1768 
1769 	initsavedefaults ();
1770 
1771 	/* Find out if user has started from a saved game */
1772 	savedgame = getfinderfile();
1773 
1774 	if (savedgame) {
1775 		enablefilemenu(FALSE);
1776 		salutation();
1777 		pause_line(23);
1778 		enablefilemenu(TRUE);
1779 		next = NEXT_FINDER;
1780 	}
1781 	else {
1782 		salutation();
1783 		next = NEXT_WAIT;
1784 	}
1785 
1786 	do {
1787 		setsavecmdstatus(0, FALSE);
1788 		setfilemenustatus(1, FALSE);
1789 		setappmenustatus(1, FALSE);
1790 		switch (next) {
1791 			case NEXT_FINDER:
1792 				if (restart_flag) loaddata(TRUE);
1793 				next = startfinder();
1794 				unloadsegments();
1795 				restart_flag = TRUE;
1796 				break;
1797 			case NEXT_NEW:
1798 				if (restart_flag) loaddata(TRUE);
1799 				next = startnew();
1800 				unloadsegments();
1801 				restart_flag = TRUE;
1802 				break;
1803 			case NEXT_OPEN:
1804 				if (restart_flag) loaddata(TRUE);
1805 				next = startopen();
1806 				unloadsegments();
1807 				restart_flag = TRUE;
1808 				break;
1809 			case NEXT_WAIT:
1810 				next = waitforchoice();
1811 				break;
1812 			default:
1813 				msg_print("What was that?");
1814 				next = NEXT_WAIT;
1815 				break;
1816 		}
1817 	} while (next != NEXT_QUIT);
1818 
1819 	CloseScreenMgr();
1820 
1821 	/* That's all, folks... */
1822 	return(0);
1823 }
1824