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