1 /*
2 * Adventure A - Some really old 'n' crusty speccy game
3 * [Originally for ZX80/81/82 by Artic Computing]
4 *
5 * Compiled under z88dk by djm especially for gwl
6 *
7 * djm 19/3/2000
8 * stefano 31/05/2010
9 *
10 * Very few changes were needed to get this to work under
11 * z88dk (many changes were made to sccz80 though(!))
12 *
13 * Changes to standard source:
14 * - casts removed in structures
15 * - Few defines to make life easier
16 * - tape or disk save (-DTAPE, -DDISK)
17 * - disk save in data block mode (-DDISKBLOCK)
18 * - lowercase text taken from the oz700 port in the 'ozdev' web site
19 * - opt graphics scenes (-DPICS)
20 * - score made optional (-DCOMPUTE_SCORE)
21 *
22 * Found at: http://www.penelope.demon.co.uk/pod/
23 *
24 * From the asm source on the same site:
25 *
26 * Disassembled, annotated and converted for use with CP/M by
27 * Paul Taylor 18-Aug-1998 With Special thanks to Tim Olmstead
28 */
29
30
31 /*
32 * Using -DDISKBLOCKS on a ZX Spectrum, will require the inclusion of 'zxbasdos.lib' and few extra BASIC lines.
33 * ZX Microdrive syntax example is given:
34 *
35 * 5000 STOP
36 * 7600 LOAD *"m";d;n$ CODE a,l : STOP
37 * 7650 SAVE *"m";d;n$ CODE a,l : STOP
38 * 7900 ERASE "m";d;n$ : STOP
39 *
40 */
41
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <ctype.h>
46
47
48 #ifdef PICS
49 #include <graphics.h>
50 #include <adv_a.h>
51 #endif
52
53 #ifdef ACE
54 #include <ace.h>
55 #endif
56
57
58 #ifndef getkey
59 #include <conio.h>
60 #define getkey() getch()
61 #endif
62
63 #ifdef DISK
64 FILE *fpsave;
65 #endif
66
67 #ifdef DISKBLOCK
68 #define TAPE
69 #endif
70
71 void GetLine();
72 char i_GetCh();
73
74
75 typedef int BOOL;
76 typedef unsigned char BYTE;
77
78 #define TRUE 1
79 #define FALSE 0
80
81 int GET_TOK();
82
83 /*****
84 ; Disassembly of the file "F:\GAMES\SPECCY\A\ARTICADV\Advent_a.sna"
85 ;
86 ; Created with dZ80 v1.30a
87 ;
88 ; on Wednesday, 05 of August 1998 at 11:33 PM
89 ;
90
91
92 .org $5d6c
93
94 ROM_SAV .equ $04c2
95 ROM_LD .equ $0556
96 ROM_CLS .equ $0daf
97
98 SCRCT .equ $5c8c ; remaining scroll count (system variable)
99
100 */
101
102 /* item location codes */
103
104 #define NOTX 0xfc
105 #define ITEM_WORN 0xfd
106 #define ITEM_HELD 0xfe
107
108
109 /* offsets of game variables */
110
111 #define GVAR_NO_ITEMS 0x01
112 #define GVAR_02 0x02
113 #define GVAR_03 0x03
114 #define GVAR_04 0x04
115 #define GVAR_05 0x05
116 #define GVAR_06 0x06
117 #define GVAR_07 0x07
118 #define GVAR_08 0x08
119 #define GVAR_09 0x09
120 #define GVAR_0a 0x0a
121 #define GVAR_0b 0x0b
122 #define GVAR_0c 0x0c
123 #define GVAR_0d 0x0d
124 #define GVAR_0e 0x0e
125 #define GVAR_0f 0x0f
126 #define GVAR_10 0x10
127 #define GVAR_11 0x11
128 #define GVAR_12 0x12
129 #define GVAR_13 0x13
130 #define GVAR_14 0x14
131 #define GVAR_15 0x15
132 #define GVAR_16 0x16
133 #define GVAR_17 0x17
134 #define GVAR_18 0x18
135 #define GVAR_19 0x19
136 #define GVAR_1a 0x1a
137 #define GVAR_1b 0x1b
138 #define GVAR_1c 0x1c
139 #define GVAR_1d 0x1d
140 #define GVAR_1e 0x1e
141
142
143
144 int GVARS[0x1e]; /* workspace of $1e bytes of game variables*/
145
146 int F_NTYET;
147 int PARAM1;
148 int CMDFLG;
149 /*
150 PREDIX .equ $-$29 ; PREDIX points here
151 */
152 int VERB_TK;
153 int NOUN_TK;
154 BOOL FLAG;
155 int CUR_RM;
156
157 char strTokenBuf[4]; /* workspace of $04 bytes to hold a token*/
158
159 #ifdef COMPUTE_SCORE
160 int nScore;
161 #endif
162
163 #ifdef SPECTRUM
164 #define MAX_COL 50
165 #endif
166 #ifdef Z88
167 #define MAX_COL 79
168 #endif
169
170 #ifndef MAX_COL
171 #define MAX_COL 31
172 #endif
173
174 char chaEditLine[MAX_COL + 1];
175
176 char* pchEditLine;
177
178
179 int nRemColumns = MAX_COL;
180
181
182
183
184 typedef struct
185 {
186 int nVerbTok;
187 int nNounTok;
188 void* pPredicates;
189 void* pActions;
190 } VNDef;
191
192
193 enum blah2 { NA_DO_AUTO, NA_CONTINUE, NA_MAIN, NA_BEGIN, NA_RESTART };
194
195 int nNextParseAction;
196
197 VNDef* pvndCurrent;
198 BYTE* pPredicateCurrent;
199 BYTE* pActionCurrent;
200
201
202
203
204 /* ======================================================================
205 // game instructions
206 // ======================================================================
207 */
208
209 const char *strInstructions =
210 "Welcome to Adventure 'A' - The Planet of Death.\n"
211 "In this adventure you find yourself stranded on an alien planet. "
212 "Your aim is to escape from this planet by finding your, now captured and disabled, space ship."
213 "You will meet various hazards and dangers on your adventure, some natural, some not, all of which you must overcome to succeed.\n"
214 "Good luck, you will need it!\n\n"
215 "PRESS ANY KEY TO START\n";
216
217 /*
218 // ======================================================================
219 // response messages
220 // ======================================================================
221 */
222
223 const char* straMsg[] =
224 {
225 "It shows a man climbing down a pit using a rope\n",
226 "How? I can't reach\n",
227 "It has fallen to the floor\n",
228 "How?\n",
229 "Its too wide. I fell and broke my neck\n",
230 "Ugh! He is all slimy\n",
231 "He vanished in a puff of smoke\n",
232 "You also broke the mirror\n",
233 "Computer says: 2 west,2 south for space flight\n",
234 "It has weakened it\n",
235 "It had no effect\n",
236 "I fell and knocked myself out.\n",
237 "The bars look loose\n",
238 "What with?\n",
239 "I see a gold coin\n",
240 "Brrr. The waters too cold\n",
241 "The fuse has just blown\n",
242 "The lift has been activated\n",
243 "I see nothing special\n",
244 "Keep off the middle men, one may be shocking!\n",
245 "Vanity waltz!\n",
246 "Try help\n",
247 "Points of compass\n",
248 "Try looking around\n",
249 "I can see a steep slope\n",
250 "An alarm sounds. The security guard shot me for trespassing.\n",
251 "I can see a rope hanging down the chimney.\n",
252 "I am not that daft. It is too deep.\n",
253 "The space ship blew up and killed me.\n",
254 "The ship has flown into the large lift and is hovering there.\nThere are four buttons outside the window marked 1,2,3 and 4\n",
255 "The lift has taken me up to a plateau.\nCongratulations, you have managed to complete this adventure\nwithout getting killed.\n",
256 "The lift has become electrified\n",
257 "I have been electrocuted\n",
258 "It is a good job i was wearing rubber soled boots.\n",
259 "I would kill myself if i did.\n",
260 "I have turned green and dropped dead.\n",
261 "The green man awoke and throttled me.\n",
262 "The guard woke and shot me.\n",
263 "What at?\n"};
264
265
266
267 /*
268 // ======================================================================
269 // room descriptions
270 // ======================================================================
271 */
272
273 const char* straRoom[] =
274 {
275 "I am on a mountain plateau\nTo the north there is a steep cliff.\nObvious exits are down, east and west.\n",
276
277 "I am at the edge of a deep pit\nObvious exits are east\n",
278
279 "I am in a damp limestone cave with stalactites hanging down.\nThe exit is to the west\nThere is a passage to the north\n",
280
281 "I am in a dense forest\nThere is a rope hanging from one tree\nObvious exits are south and west\n",
282
283 "I am beside a lake\nExits are east and north. There is a ravine to the west\n",
284
285 "I am in a strange house\nThe door is to the north\n",
286
287 "I am in an old shed\nThe exit is to the east\n",
288
289 "I am in a maze. There are passages everywhere.\n",
290
291 "I am in a maze. There are passages everywhere.\n",
292
293 "I am in a maze. There are passages everywhere.\n",
294
295 "I am in a maze. There are passages everywhere.\n",
296
297 "I am in an ice cavern.\nThere is an exit to the east.\n",
298
299 "I am in a quiet cavern.\nThere are exits west, east and south.\n",
300
301 "I am in a wind tunnel.\nThere is a closed door at the end.\nThere is also an exit to the west.\n",
302
303 "I am in a room with a computer in\nThe computer is working and has a keyboard\nThe exit is west\n",
304
305 "I am in a passage\nThere is a force field to the south : beware of security\nThere are exits to north,east and west\n",
306
307 "I am in a large hanger\nThere is a locked door to the west\nThere are also exits east,north and south\n",
308
309 "I am in a tall lift. The buttons are very high\nThe exit is west\n",
310
311 "I am in the lift control room\nThere are three switches on the wall. They are all off\nA sign says : 5,4 no dusty bin rules\nThe exit is east\n",
312
313 "I am in a prison cell\n",
314
315 "I am in a space ship. There is no visible exit\nThere is a small open window in the side\nThere are also two buttons,one marked main and the other aux.\n"};
316
317
318
319 /*
320 // ======================================================================
321 // item descriptions
322 // ======================================================================
323 */
324
325 #define MAX_ITEM 28
326
327 const char* straItem[MAX_ITEM] =
328 {
329 "a pair of boots",
330 "a starter motor",
331 "a key",
332 "a laser gun",
333 "an out of order sign",
334 "a metal bar",
335 "a gold coin",
336 "a mirror",
337 "broken glass",
338 "a pair of slimy gloves",
339 "a rope",
340 "a floor board",
341 "a broken floor board",
342 "stalactites",
343 "a block of ice",
344 "a pool of water",
345 "a small green man sleeping on the mirror",
346 "a sleeping green man",
347 "a locked door",
348 "an open door",
349 "a barred window",
350 "a hole in the wall",
351 "a small but powerfull space ship",
352 "a sleeping security man",
353 "a piece of sharp flint",
354 "some stones",
355 "a drawing on the wall",
356 "a loudspeaker with dance music coming out"};
357
358
359
360 /*
361 // ======================================================================
362 // initial positions of items - 1 int per item, holds room number
363 // NOTX indicates item doesn't exist yet
364 // ======================================================================
365 */
366
367 const int naItemStart[MAX_ITEM] =
368 {
369 0x05, 0x11, 0x0e, 0x06, 0x11, NOTX, NOTX, 0x0c,
370 NOTX, 0x0d, NOTX, 0x05, NOTX, NOTX, 0x0b, NOTX,
371 0x0c, NOTX, 0x13, NOTX, 0x13, NOTX, 0x10, 0x10,
372 0x00, 0x01, 0x02, 0x0f
373 };
374
375 /*
376 // ======================================================================
377 // current positions of items - 1 int per item, holds room number
378 // initialized from naItemStart at start, updated during the game
379 // NOTX indicates item doesn't exist yet
380 // ======================================================================
381 */
382
383 int naItemLoc[MAX_ITEM];
384
385
386
387 /*
388 // the commands and their synonyms
389 // each token is 4 characters, followed by a 1 byte token code
390 // first define the token codes
391 */
392
393 #define TOK_DOWN 0x01
394 #define TOK_NORT 0x02
395 #define TOK_SOUT 0x03
396 #define TOK_EAST 0x04
397 #define TOK_WEST 0x05
398 #define TOK_GET 0x0d
399 #define TOK_DROP 0x0e
400 #define TOK_FIRE 0x0f
401 #define TOK_BOOT 0x10
402 #define TOK_STAR 0x11
403 #define TOK_KEY 0x12
404 #define TOK_GUN 0x13
405 #define TOK_USED 0x14
406 #define TOK_BAR 0x15
407 #define TOK_COIN 0x16
408 #define TOK_MIRR 0x17
409 #define TOK_BROK 0x18
410 #define TOK_GLOV 0x19
411 #define TOK_ROPE 0x1a
412 #define TOK_BOAR 0x1b
413 #define TOK_STAL 0x1c
414 #define TOK_ICE 0x1d
415 #define TOK_WATE 0x1e
416 #define TOK_MAN 0x1f
417 #define TOK_DOOR 0x20
418 #define TOK_OPEN 0x21
419 #define TOK_WIND 0x22
420 #define TOK_SHIP 0x23
421 #define TOK_SECU 0x24
422 #define TOK_FLIN 0x25
423 #define TOK_STON 0x26
424 #define TOK_DRAW 0x27
425 #define TOK_HELP 0x28
426 #define TOK_INVE 0x29
427 #define TOK_QUIT 0x2a
428 #define TOK_YES 0x2b
429 #define TOK_NO 0x2c
430 #define TOK_COMP 0x2d
431 #define TOK_TYPE 0x2e
432 #define TOK_TURN 0x2f
433 #define TOK_HAND 0x30
434 #define TOK_KILL 0x31
435 #define TOK_DANC 0x32
436 #define TOK_REMO 0x33
437 #define TOK_BREA 0x34
438 #define TOK_BRIB 0x35
439 #define TOK_USE 0x36
440 #define TOK_PUSH 0x37
441 #define TOK_THRE 0x38
442 #define TOK_TWO 0x39
443 #define TOK_ONE 0x3a
444 #define TOK_MEND 0x3b
445 #define TOK_FOUR 0x3c
446 #define TOK_LOOK 0x3d
447 #define TOK_STAN 0x3e
448 #define TOK_TREE 0x3f
449 #define TOK_CUT 0x40
450 #define TOK_WEAR 0x41
451 #define TOK_CROS 0x42
452 #define TOK_JUMP 0x43
453 #define TOK_RAVI 0x44
454 #define TOK_UP 0x45
455 #define TOK_FUSE 0x46
456 #define TOK_REDE 0x47
457 #define TOK_MAIN 0x48
458 #define TOK_AUX 0x49
459 #define TOK_FIEL 0x4a
460
461
462
463 /* now map the codes to their character representations */
464
465 typedef struct
466 {
467 char strWord[5];
468 int nCode;
469 } TOKEN;
470
471 #define MAX_TOK 111
472
473 const TOKEN taToken[MAX_TOK] =
474 {
475 { "DOWN", TOK_DOWN },
476 { "D ", TOK_DOWN },
477 { "NORT", TOK_NORT },
478 { "N ", TOK_NORT },
479 { "SOUT", TOK_SOUT },
480 { "S ", TOK_SOUT },
481 { "EAST", TOK_EAST },
482 { "E ", TOK_EAST },
483 { "WEST", TOK_WEST },
484 { "W ", TOK_WEST },
485 { "GET ", TOK_GET },
486 { "TAKE", TOK_GET },
487 { "PICK", TOK_GET },
488 { "DROP", TOK_DROP },
489 { "PUT ", TOK_DROP },
490 { "FIRE", TOK_FIRE },
491 { "SHOO", TOK_FIRE },
492 { "BOOT", TOK_BOOT },
493 { "STAR", TOK_STAR },
494 { "MOTO", TOK_STAR },
495 { "KEY ", TOK_KEY },
496 { "LASE", TOK_GUN },
497 { "GUN ", TOK_GUN },
498 { "USED", TOK_USED },
499 { "BAR ", TOK_BAR },
500 { "BARS", TOK_BAR },
501 { "GOLD", TOK_COIN },
502 { "COIN", TOK_COIN },
503 { "MIRR", TOK_MIRR },
504 { "BROK", TOK_BROK },
505 { "GLOV", TOK_GLOV },
506 { "ROPE", TOK_ROPE },
507 { "FLOO", TOK_BOAR },
508 { "BOAR", TOK_BOAR },
509 { "PLAN", TOK_BOAR },
510 { "STAL", TOK_STAL },
511 { "BLOC", TOK_ICE },
512 { "ICE ", TOK_ICE },
513 { "POOL", TOK_WATE },
514 { "WATE", TOK_WATE },
515 { "LAKE", TOK_WATE },
516 { "SLEE", TOK_MAN },
517 { "GREE", TOK_MAN },
518 { "MAN ", TOK_MAN },
519 { "DOOR", TOK_DOOR },
520 { "OPEN", TOK_OPEN },
521 { "UNLO", TOK_OPEN },
522 { "WIND", TOK_WIND },
523 { "SMAL", TOK_SHIP },
524 { "SPAC", TOK_SHIP },
525 { "SHIP", TOK_SHIP },
526 { "SECU", TOK_SECU },
527 { "FLIN", TOK_FLIN },
528 { "STON", TOK_STON },
529 { "DRAW", TOK_DRAW },
530 { "HELP", TOK_HELP },
531 { "INVE", TOK_INVE },
532 { "I ", TOK_INVE },
533 { "QUIT", TOK_QUIT },
534 { "STOP", TOK_QUIT },
535 { "ABOR", TOK_QUIT },
536 { "YES ", TOK_YES },
537 { "Y ", TOK_YES },
538 { "NO ", TOK_NO },
539 { "COMP", TOK_COMP },
540 { "KEYB", TOK_COMP },
541 { "TYPE", TOK_TYPE },
542 { "TURN", TOK_TURN },
543 { "HAND", TOK_HAND },
544 { "KILL", TOK_KILL },
545 { "DANC", TOK_DANC },
546 { "WALT", TOK_DANC },
547 { "REMO", TOK_REMO },
548 { "KICK", TOK_BREA },
549 { "BREA", TOK_BREA },
550 { "HIT ", TOK_BREA },
551 { "BANG", TOK_BREA },
552 { "BRIB", TOK_BRIB },
553 { "USE ", TOK_USE },
554 { "WITH", TOK_USE },
555 { "PUSH", TOK_PUSH },
556 { "THRE", TOK_THRE },
557 { "3 ", TOK_THRE },
558 { "TWO ", TOK_TWO },
559 { "2 ", TOK_TWO },
560 { "ONE ", TOK_ONE },
561 { "1 ", TOK_ONE },
562 { "MEND", TOK_MEND },
563 { "FIX ", TOK_MEND },
564 { "REPA", TOK_MEND },
565 { "FOUR", TOK_FOUR },
566 { "4 ", TOK_FOUR },
567 { "LOOK", TOK_LOOK },
568 { "STAN", TOK_STAN },
569 { "TREE", TOK_TREE },
570 { "CUT ", TOK_CUT },
571 { "SAW ", TOK_CUT },
572 { "WEAR", TOK_WEAR },
573 { "CROS", TOK_CROS },
574 { "JUMP", TOK_JUMP },
575 { "RAVI", TOK_RAVI },
576 { "UP ", TOK_UP },
577 { "U ", TOK_UP },
578 { "CLIM", TOK_UP },
579 { "FUSE", TOK_FUSE },
580 { "REDE", TOK_REDE },
581 { "R ", TOK_REDE },
582 { "MAIN", TOK_MAIN },
583 { "AUX ", TOK_AUX },
584 { "FIEL", TOK_FIEL },
585 { "SHIE", TOK_FIEL }
586 };
587
588
589
590
591
592
593
594
595
596
597
598
599
600 /*
601 // the directional information, one list for each room
602 // each list entry is of the form <token code>,<room number>
603 // each list is terminated with $ff
604 */
605
606 const BYTE DIR_00[] =
607 {
608 TOK_DOWN,0x03,
609 TOK_EAST,0x02,
610 TOK_WEST,0x01,
611 0xff
612 };
613 const BYTE DIR_01[] =
614 {
615 TOK_EAST,0x00,
616 0xff
617 };
618 const BYTE DIR_02[] =
619 {
620 TOK_NORT,0x07,
621 TOK_WEST,0x00,
622 0xff
623 };
624 const BYTE DIR_03[] =
625 {
626 TOK_SOUT,0x04,
627 TOK_WEST,0x00,
628 0xff
629 };
630 const BYTE DIR_04[] =
631 {
632 TOK_NORT,0x03,
633 TOK_EAST,0x05,
634 0xff
635 };
636 const BYTE DIR_05[] =
637 {
638 TOK_NORT,0x04,
639 0xff
640 };
641 const BYTE DIR_06[] =
642 {
643 0xff
644 };
645 const BYTE DIR_07[] =
646 {
647 TOK_DOWN,0x07,
648 TOK_NORT,0x08,
649 TOK_SOUT,0x07,
650 TOK_EAST,0x07,
651 TOK_WEST,0x07,
652 0xff
653 };
654 const BYTE DIR_08[] =
655 {
656 TOK_DOWN,0x07,
657 TOK_NORT,0x07,
658 TOK_SOUT,0x09,
659 TOK_EAST,0x07,
660 TOK_WEST,0x07,
661 0xff
662 };
663 const BYTE DIR_09[] =
664 {
665 TOK_DOWN,0x07,
666 TOK_NORT,0x07,
667 TOK_SOUT,0x07,
668 TOK_EAST,0x0a,
669 TOK_WEST,0x07,
670 0xff
671 };
672 const BYTE DIR_0A[] =
673 {
674 TOK_DOWN,0x07,
675 TOK_NORT,0x02,
676 TOK_SOUT,0x07,
677 TOK_EAST,0x07,
678 TOK_WEST,0x0b,
679 0xff
680 };
681 const BYTE DIR_0B[] =
682 {
683 TOK_EAST,0x07,
684 0xff
685 };
686 const BYTE DIR_0C[] =
687 {
688 TOK_SOUT,0x0f,
689 TOK_EAST,0x0d,
690 TOK_WEST,0x13,
691 0xff
692 };
693 const BYTE DIR_0D[] =
694 {
695 0xff
696 };
697 const BYTE DIR_0E[] =
698 {
699 TOK_WEST,0x0d,
700 0xff
701 };
702 const BYTE DIR_0F[] =
703 {
704 TOK_EAST,0x13,
705 TOK_WEST,0x13,
706 0xff
707 };
708 const BYTE DIR_10[] =
709 {
710 TOK_NORT,0x0f,
711 TOK_SOUT,0x13,
712 TOK_EAST,0x11,
713 0xff
714 };
715 const BYTE DIR_11[] =
716 {
717 TOK_WEST,0x10,
718 0xff
719 };
720 const BYTE DIR_12[] =
721 {
722 TOK_EAST,0x10,
723 0xff
724 };
725 const BYTE DIR_13[] =
726 {
727 0xff
728 };
729
730
731 /* this vector array contains an address for every room */
732
733 const BYTE* DIR_V[] =
734 {
735 DIR_00,
736 DIR_01,
737 DIR_02,
738 DIR_03,
739 DIR_04,
740 DIR_05,
741 DIR_06,
742 DIR_07,
743 DIR_08,
744 DIR_09,
745 DIR_0A,
746 DIR_0B,
747 DIR_0C,
748 DIR_0D,
749 DIR_0E,
750 DIR_0F,
751 DIR_10,
752 DIR_11,
753 DIR_12,
754 DIR_13,
755 DIR_13 /* room 0x14 shares room 0x13's data - it's just an 0xff anyway */
756 };
757
758
759
760
761
762
763
764 /* index codes of predicates */
765
766 #define COM_CHKROOM 0x00
767 #define COM_CHKHERE 0x01
768 #define COM_CHKRAND 0x02
769 #define COM_CHKAWAY 0x03
770 #define COM_CHKWORN 0x04
771 #define COM_CHKSETF 0x05
772 #define COM_TSTGVAR 0x06
773 #define COM_CHKCLRF 0x07
774 #define COM_CHKHELD 0x08
775
776 /* a table of predicates */
777
778 BOOL CHKROOM();
779 BOOL CHKHERE();
780 BOOL CHKRAND();
781 BOOL CHKAWAY();
782 BOOL CHKWORN();
783 BOOL CHKSETF();
784 BOOL TSTGVAR();
785 BOOL CHKCLRF();
786 BOOL CHKHELD();
787
788 #ifdef SCCZ80
789 int *PRED_V[] =
790 #else
791 const BOOL (*PRED_V[])(void) =
792 #endif
793 {
794 CHKROOM, /* $00 */
795 CHKHERE, /* $01 */
796 CHKRAND, /* $02 */
797 CHKAWAY, /* $03 */
798 CHKWORN, /* $04 */
799 CHKSETF, /* $05 */
800 TSTGVAR, /* $06 */
801 CHKCLRF, /* $07 */
802 CHKHELD /* $08 */
803 };
804
805 /*
806 // list of predicate entries
807 // first byte is the index of the predicate, see PRED_V
808 // second byte is stored in PARAM1
809 // subsequent bytes of entry are terminated with a 0xff
810 */
811
812
813 const BYTE A_GD_BOOT[] =
814 {
815 COM_CHKHERE,0x00,
816 0xff
817 };
818 const BYTE A_GD_STAR[] =
819 {
820 COM_CHKHERE,0x01,
821 0xff
822 };
823 const BYTE A_GD_KEY[] =
824 {
825 COM_CHKHERE,0x02,
826 0xff
827 };
828 const BYTE A_GD_GUN[] =
829 {
830 COM_CHKHERE,0x03,
831 0xff
832 };
833 const BYTE A_GD_BAR[] =
834 {
835 COM_CHKHERE,0x05,
836 0xff
837 };
838 const BYTE A_GD_COIN[] =
839 {
840 COM_CHKHERE,0x06,
841 0xff
842 };
843 const BYTE A_G_MIRR_1[] =
844 {
845 COM_CHKHERE,0x07,
846 COM_CHKAWAY,0x10,
847 0xff
848 };
849 const BYTE A_GD_MIRR_2[] =
850 {
851 COM_CHKHERE,0x08,
852 0xff
853 };
854 const BYTE A_GD_GLOV[] =
855 {
856 COM_CHKHERE,0x09,
857 0xff
858 };
859 const BYTE A_GD_ROPE[] =
860 {
861 COM_CHKHERE,0x0a,
862 0xff
863 };
864 const BYTE A_GD_BOAR_1[] =
865 {
866 COM_CHKHERE,0x0b,
867 0xff
868 };
869 const BYTE A_GD_BOAR_2[] =
870 {
871 COM_CHKHERE,0x0c,
872 0xff
873 };
874 const BYTE A_GD_STAL[] =
875 {
876 COM_CHKHERE,0x0d,
877 0xff
878 };
879 const BYTE A_GD_ICE[] =
880 {
881 COM_CHKHERE,0x0e,
882 0xff
883 };
884 const BYTE A_GD_FLIN[] =
885 {
886 COM_CHKHERE,0x18,
887 0xff
888 };
889 const BYTE A_GD_STON[] =
890 {
891 COM_CHKHERE,0x19,
892 0xff
893 };
894 const BYTE A_D_MIRR[] =
895 {
896 COM_CHKHERE,0x07,
897 0xff
898 };
899 const BYTE A_DRAW_STAL[] =
900 {
901 COM_CHKROOM,0x02,
902 0xff
903 };
904 const BYTE A_U_ICE_1[] =
905 {
906 COM_CHKROOM,0x02,
907 COM_CHKHERE,0x0e,
908 0xff
909 };
910 const BYTE A_CUT_ROPE[] =
911 {
912 COM_CHKROOM,0x03,
913 0xff
914 };
915 const BYTE A_USE_FLIN[] =
916 {
917 COM_CHKROOM,0x03,
918 COM_CHKHERE,0x18,
919 0xff
920 };
921 const BYTE A_C_RAVI_1[] =
922 {
923 COM_CHKROOM,0x04,
924 0xff
925 };
926 const BYTE A_C_RAVI_2[] =
927 {
928 COM_CHKROOM,0x06,
929 0xff
930 };
931 const BYTE A_C_RAVI_3[] =
932 {
933 COM_CHKROOM,0x04,
934 COM_CHKHERE,0x0b,
935 0xff
936 };
937 const BYTE A_USE_BOAR[] =
938 {
939 COM_CHKROOM,0x06,
940 COM_CHKHERE,0x0b,
941 0xff
942 };
943 const BYTE A_DOWN[] =
944 {
945 COM_CHKROOM,0x0b,
946 0xff
947 };
948 const BYTE A_U_ICE_2[] =
949 {
950 COM_CHKROOM,0x0b,
951 COM_CHKHELD,0x0e,
952 0xff
953 };
954 const BYTE A_G_MAN_1[] =
955 {
956 COM_CHKHERE,0x10,
957 COM_CHKHERE,0x09,
958 COM_CHKWORN,0x09,
959 0xff
960 };
961 const BYTE A_G_MAN_2[] =
962 {
963 COM_CHKHERE,0x10,
964 COM_CHKHERE,0x09,
965 0xff
966 };
967 const BYTE A_G_MAN_3[] =
968 {
969 COM_CHKHERE,0x10,
970 0xff
971 };
972 const BYTE A_KD_MAN_1[] =
973 {
974 COM_CHKHERE,0x11,
975 0xff
976 };
977 const BYTE A_G_MIRR_3[] =
978 {
979 COM_CHKHERE,0x07,
980 COM_CHKAWAY,0x10,
981 0xff
982 };
983 const BYTE A_K_MAN_2[] =
984 {
985 COM_CHKHERE,0x10,
986 0xff
987 };
988 const BYTE A_U_GUN_1[] =
989 {
990 COM_CHKHERE,0x10,
991 COM_CHKHERE,0x03,
992 0xff
993 };
994 const BYTE A_U_GUN_2[] =
995 {
996 COM_CHKHERE,0x11,
997 COM_CHKHERE,0x03,
998 COM_CHKHELD,0x11,
999 0xff
1000 };
1001 const BYTE A_U_GUN_3[] =
1002 {
1003 COM_CHKHERE,0x11,
1004 COM_CHKHERE,0x03,
1005 0xff
1006 };
1007 const BYTE A_TYPE_HELP[] =
1008 {
1009 COM_CHKROOM,0x0e,
1010 0xff
1011 };
1012 const BYTE A_FIRE_GUN[] =
1013 {
1014 COM_CHKROOM,0x0f,
1015 0xff
1016 };
1017 const BYTE A_FIEL_1[] =
1018 {
1019 COM_CHKROOM,0x0f,
1020 COM_CHKCLRF,GVAR_07,
1021 COM_CHKHERE,0x03,
1022 0xff
1023 };
1024 const BYTE A_FIEL_2[] =
1025 {
1026 COM_CHKSETF,GVAR_07,
1027 COM_CHKCLRF,GVAR_08,
1028 COM_CHKROOM,0x0f,
1029 COM_CHKHERE,0x03,
1030 0xff
1031 };
1032 const BYTE A_FIEL_3[] =
1033 {
1034 COM_CHKSETF,GVAR_08,
1035 COM_CHKROOM,0x0f,
1036 COM_CHKHERE,0x03,
1037 0xff
1038 };
1039 const BYTE A_DANC_1[] =
1040 {
1041 COM_CHKROOM,0x0f,
1042 COM_CHKHELD,0x07,
1043 COM_CHKSETF,GVAR_08,
1044 0xff
1045 };
1046 const BYTE A_DANC_2[] =
1047 {
1048 COM_CHKROOM,0x0f,
1049 0xff
1050 };
1051 const BYTE A_O_DOOR_1[] =
1052 {
1053 COM_CHKROOM,0x10,
1054 0xff
1055 };
1056 const BYTE A_USE_KEY[] =
1057 {
1058 COM_CHKROOM,0x10,
1059 COM_CHKHERE,0x02,
1060 0xff
1061 };
1062 const BYTE A_K_SECU[] =
1063 {
1064 COM_CHKROOM,0x10,
1065 COM_CHKHERE,0x03,
1066 0xff
1067 };
1068 const BYTE A_LUP_BREA[] =
1069 {
1070 COM_CHKROOM,0x13,
1071 0xff
1072 };
1073 const BYTE A_UP[] =
1074 {
1075 COM_CHKROOM,0x13,
1076 COM_CHKHERE,0x15,
1077 0xff
1078 };
1079 const BYTE A_BRSEC[] =
1080 {
1081 COM_CHKROOM,0x13,
1082 0xff
1083 };
1084 const BYTE A_U_COIN[] =
1085 {
1086 COM_CHKROOM,0x13,
1087 COM_CHKHERE,0x06,
1088 0xff
1089 };
1090 const BYTE A_B_DOOR[] =
1091 {
1092 COM_CHKROOM,0x13,
1093 COM_CHKHERE,0x13,
1094 0xff
1095 };
1096 const BYTE A_G_COIN[] =
1097 {
1098 COM_CHKROOM,0x04,
1099 COM_CHKAWAY,0x06,
1100 0xff
1101 };
1102 #define A_L_WATE A_G_COIN
1103 const BYTE A_WATE_1[] =
1104 {
1105 COM_CHKROOM,0x04,
1106 COM_CHKAWAY,0x06,
1107 COM_CHKWORN,0x00,
1108 COM_CHKHERE,0x00,
1109 0xff
1110 };
1111 const BYTE A_WATE_2[] =
1112 {
1113 COM_CHKROOM,0x04,
1114 COM_CHKAWAY,0x06,
1115 COM_CHKHERE,0x00,
1116 0xff
1117 };
1118 const BYTE A_O_DOOR_2[] =
1119 {
1120 COM_CHKROOM,0x0d,
1121 0xff
1122 };
1123 const BYTE A_PUSH_THRE[] =
1124 {
1125 COM_CHKROOM,0x12,
1126 COM_CHKCLRF,GVAR_09,
1127 COM_CHKCLRF,GVAR_0a,
1128 0xff
1129 };
1130 const BYTE A_PUSH_DIG[] =
1131 {
1132 COM_CHKROOM,0x12,
1133 COM_CHKCLRF,GVAR_0a,
1134 0xff
1135 };
1136 const BYTE A_PUSH_TWO[] =
1137 {
1138 COM_CHKROOM,0x12,
1139 COM_TSTGVAR,GVAR_09,0x01,
1140 COM_CHKCLRF,GVAR_0a,
1141 0xff
1142 };
1143 const BYTE A_PUSH_ONE[] =
1144 {
1145 COM_CHKROOM,0x12,
1146 COM_TSTGVAR,GVAR_09,0x02,
1147 COM_CHKCLRF,GVAR_0a,
1148 0xff
1149 };
1150 const BYTE A_MEND_FUSE[] =
1151 {
1152 COM_CHKROOM,0x12,
1153 COM_CHKSETF,GVAR_0a,
1154 0xff
1155 };
1156 const BYTE A_USE_BAR[] =
1157 {
1158 COM_CHKROOM,0x12,
1159 COM_CHKHERE,0x05,
1160 COM_CHKSETF,GVAR_0a,
1161 0xff
1162 };
1163 const BYTE A_LOOK[] =
1164 {
1165 COM_CHKROOM,0x0b,
1166 0xff
1167 };
1168 const BYTE A_HELP_1[] =
1169 {
1170 COM_CHKROOM,0x11,
1171 0xff
1172 };
1173 const BYTE A_HELP_2[] =
1174 {
1175 COM_CHKROOM,0x0f,
1176 0xff
1177 };
1178 const BYTE A_HELP_3[] =
1179 {
1180 COM_CHKROOM,0x0e,
1181 0xff
1182 };
1183 const BYTE A_HELP_4[] =
1184 {
1185 COM_CHKROOM,0x07,
1186 0xff
1187 };
1188 const BYTE A_HELP_5[] =
1189 {
1190 COM_CHKROOM,0x08,
1191 0xff
1192 };
1193 const BYTE A_HELP_6[] =
1194 {
1195 COM_CHKROOM,0x09,
1196 0xff
1197 };
1198 const BYTE A_HELP_7[] =
1199 {
1200 COM_CHKROOM,0x0a,
1201 0xff
1202 };
1203 const BYTE A_HELP_8[] =
1204 {
1205 COM_CHKROOM,0x14,
1206 COM_CHKSETF,GVAR_0c,
1207 0xff
1208 };
1209 const BYTE A_LUP[] =
1210 {
1211 COM_CHKSETF,GVAR_0b,
1212 COM_CHKROOM,0x0c,
1213 0xff
1214 };
1215 const BYTE A_WEST[] =
1216 {
1217 COM_CHKROOM,0x0d,
1218 0xff
1219 };
1220 const BYTE A_JUMP[] =
1221 {
1222 COM_CHKROOM,0x01,
1223 0xff
1224 };
1225 const BYTE A_USEROP[] =
1226 {
1227 COM_CHKROOM,0x01,
1228 COM_CHKHELD,0x0a,
1229 0xff
1230 };
1231 const BYTE A_UPROPE[] =
1232 {
1233 COM_CHKROOM,0x0c,
1234 COM_CHKSETF,GVAR_0b,
1235 0xff
1236 };
1237 const BYTE A_SHIP[] =
1238 {
1239 COM_CHKHERE,0x16,
1240 0xff
1241 };
1242 const BYTE A_P_MAUX[] =
1243 {
1244 COM_CHKROOM,0x14,
1245 COM_CHKHERE,0x01,
1246 0xff
1247 };
1248 const BYTE A_P_32[] =
1249 {
1250 COM_CHKROOM,0x14,
1251 COM_CHKSETF,GVAR_0c,
1252 0xff
1253 };
1254 const BYTE A_P_41[] =
1255 {
1256 COM_CHKROOM,0x14,
1257 COM_CHKSETF,GVAR_0c,
1258 COM_TSTGVAR,GVAR_09,0x03,
1259 0xff
1260 };
1261 const BYTE A_PSH_ONE_2[] =
1262 {
1263 COM_CHKROOM,0x14,
1264 COM_CHKSETF,GVAR_0c,
1265 COM_CHKWORN,0x00,
1266 COM_TSTGVAR,GVAR_09,0x03,
1267 0xff
1268 };
1269
1270
1271
1272 /*
1273 // list of predicate entries for Auto Commands
1274 // first byte is the index of the predicate, see PRED_V
1275 // second byte is stored in PARAM1
1276 // subsequent bytes of entry are terminated with a $ff
1277 // check if we have turned green and died
1278 */
1279 const BYTE A_CHGRN[] =
1280 {
1281 COM_TSTGVAR,GVAR_05,0x01, /* if game variable 0x05 = 1 */
1282 COM_CHKSETF,GVAR_06, /* and game variable 0x06 is set */
1283 0xff
1284 };
1285
1286 /* check if the small green man is to throttle us (version 1) */
1287 const BYTE A_CHTHR[] =
1288 {
1289 COM_TSTGVAR,GVAR_02,0x01, /* if game variable 0x02 = 1 */
1290 COM_CHKHERE,0x10, /* and is-present the small green man sleeping on the mirror */
1291 0xff
1292 };
1293
1294 /* check if the small green man is to throttle us (version 2) */
1295 const BYTE A_C2THR[] =
1296 {
1297 COM_TSTGVAR,GVAR_02,0x01, /* if game variable 0x02 = 1 */
1298 COM_CHKHERE,0x11, /* and is-present the sleeping green man (moved off mirror) */
1299 0xff
1300 };
1301
1302 /* check if we're to be shot by the security guard */
1303 const BYTE A_SHOT[] =
1304 {
1305 COM_TSTGVAR,GVAR_02,0x01, /* if game variable 0x02 = 1 */
1306 COM_CHKHERE,0x17, /* and is-present the sleeping security man */
1307 0xff
1308 };
1309
1310 /* check if ice has melted */
1311 const BYTE A_MELTD[] =
1312 {
1313 COM_TSTGVAR,GVAR_02,0x01, /* if game variable 0x02 = 1 */
1314 COM_CHKHERE,0x0e, /* and is-present the block of ice */
1315 0xff
1316 };
1317
1318 /* an empty action entry */
1319 const BYTE A_NULL[] = { 0Xff };
1320
1321 const BYTE A_MISC[] = { 0xff }; /* used for auto commands - no predicates required */
1322
1323
1324
1325
1326 #define I_SH_INVE 0x00 /* terminates bytecode processing */
1327 #define I_SH_REMO 0x01
1328 #define I_SH_GET 0x02
1329 #define I_SH_DROP 0x03
1330 #define I_SH_WEAR 0x04
1331 #define I_SH_MSG 0x05
1332 #define I_SH_REDE 0x06 /* terminates bytecode processing */
1333 #define I_SH_AUTO 0x07 /* terminates bytecode processing */
1334 #define I_SH_GOTO 0x08
1335 #define I_SH_SETF 0x09
1336 #define I_SH_CLRF 0x0a
1337 #define I_SH_SWAP 0x0b
1338 #define I_SH_DEAD 0x0c /* terminates bytecode processing */
1339 #define I_SH_OK 0x0d /* terminates bytecode processing */
1340 #define I_SH_QUIT 0x0e /* terminates bytecode processing */
1341 #define I_SH_SETV 0x0f
1342 #define I_SH_CREA 0x10
1343 #define I_SH_DEST 0x11
1344 #define I_SH_ADSC 0x12
1345 #define I_SH_SCOR 0x13
1346 #define I_SH_FAIL1 0x14
1347 #define I_SH_TELL 0x15
1348 #define I_SH_FAIL2 0x16
1349 #define I_SH_FAIL3 0x17
1350 #define I_SH_FAIL4 0x18
1351
1352
1353
1354 /* bytecodes for the various commands a user can enter */
1355
1356 const BYTE SGET_00[] = { I_SH_GET,0x00,I_SH_OK };
1357 const BYTE SGET_01[] = { I_SH_GET,0x01,I_SH_OK };
1358 const BYTE SGET_02[] = { I_SH_GET,0x02,I_SH_OK };
1359 const BYTE SGET_03[] = { I_SH_GET,0x03,I_SH_OK };
1360 const BYTE SGET_05[] = { I_SH_GET,0x05,I_SH_OK };
1361 const BYTE SGET_06[] = { I_SH_GET,0x06,I_SH_OK };
1362 const BYTE SGET_07[] = { I_SH_GET,0x07,I_SH_OK };
1363 const BYTE SGET_08[] = { I_SH_GET,0x08,I_SH_OK };
1364 const BYTE SGET_09[] = { I_SH_GET,0x09,I_SH_OK };
1365 const BYTE SGET_0A[] = { I_SH_GET,0x0a,I_SH_OK };
1366 const BYTE SGET_0B[] = { I_SH_GET,0x0b,I_SH_OK };
1367 const BYTE SGET_0C[] = { I_SH_GET,0x0c,I_SH_OK };
1368 const BYTE SGET_0D[] = { I_SH_GET,0x0d,I_SH_OK };
1369 const BYTE SGET_0E[] = { I_SH_GET,0x0e,I_SH_SETV,GVAR_02,0x09,I_SH_OK };
1370 const BYTE SGET_18[] = { I_SH_GET,0x18,I_SH_OK };
1371 const BYTE SGET_19[] = { I_SH_GET,0x19,I_SH_OK };
1372 const BYTE SINVENT[] = { I_SH_INVE,0x07 }; /* the 0x07 is ignored */
1373 const BYTE SQUIT[] = { I_SH_QUIT };
1374 const BYTE SPUT_00[] = { I_SH_DROP,0x00,I_SH_OK };
1375 const BYTE SPUT_01[] = { I_SH_DROP,0x01,I_SH_OK };
1376 const BYTE SPUT_02[] = { I_SH_DROP,0x02,I_SH_OK };
1377 const BYTE SPUT_03[] = { I_SH_DROP,0x03,I_SH_OK };
1378 const BYTE SPUT_05[] = { I_SH_DROP,0x05,I_SH_OK };
1379 const BYTE SPUT_06[] = { I_SH_DROP,0x06,I_SH_OK };
1380 const BYTE SPUT_07[] = { I_SH_DROP,0x07,I_SH_OK };
1381 const BYTE SPUT_08[] = { I_SH_DROP,0x08,I_SH_OK };
1382 const BYTE SPUT_09[] = { I_SH_DROP,0x09,I_SH_OK };
1383 const BYTE SPUT_0A[] = { I_SH_DROP,0x0a,I_SH_OK };
1384 const BYTE SPUT_0B[] = { I_SH_DROP,0x0b,I_SH_OK };
1385 const BYTE SPUT_0C[] = { I_SH_DROP,0x0c,I_SH_OK };
1386 const BYTE SPUT_0D[] = { I_SH_DROP,0x0d,I_SH_OK };
1387 const BYTE SPUT_0E[] = { I_SH_DROP,0x0e,I_SH_OK };
1388 const BYTE SPUT_18[] = { I_SH_DROP,0x18,I_SH_OK };
1389 const BYTE SPUT_19[] = { I_SH_DROP,0x19,I_SH_OK };
1390 const BYTE SLK_DRW[] = { I_SH_MSG,0x00,I_SH_AUTO };
1391 const BYTE SBRK_ST[] = { I_SH_MSG,0x01,I_SH_AUTO };
1392 const BYTE SUSE_IC[] = { I_SH_CREA,0x0d,I_SH_MSG,0x02,I_SH_AUTO };
1393 const BYTE SCUT_RP[] = { I_SH_MSG,0x03,I_SH_AUTO };
1394 const BYTE SUSE_FL[] = { I_SH_CREA,0x0a,I_SH_MSG,0x02,I_SH_AUTO };
1395 const BYTE SWR_00[] = { I_SH_WEAR,0x00,I_SH_OK };
1396 const BYTE SRM_00[] = { I_SH_REMO,0x00,I_SH_OK };
1397 const BYTE SCR_RV[] = { I_SH_MSG,0x03,I_SH_AUTO };
1398 const BYTE SUSE_BO[] = { I_SH_GOTO,0x06,I_SH_REDE };
1399 const BYTE SUS2_BO[] = { I_SH_GOTO,0x04,I_SH_DEST,0x0b,I_SH_CREA,0x0c,I_SH_REDE };
1400 const BYTE SJMP_RV[] = { I_SH_MSG,0x04,I_SH_DEAD };
1401 const BYTE SUSE_I2[] = { I_SH_GOTO,0x0c,I_SH_DROP,0x0e,I_SH_SWAP,0x0e,I_SH_SETV,GVAR_02,0x07,I_SH_REDE };
1402 const BYTE SGET_MN[] = { I_SH_GET,0x10,I_SH_SWAP,0x10,I_SH_MSG,0x05,I_SH_SETV,GVAR_05,0x0a,I_SH_CLRF,GVAR_06,I_SH_AUTO };
1403 const BYTE SGET_M2[] = { I_SH_GET,0x10,I_SH_SWAP,0x10,I_SH_OK };
1404 const BYTE SPUT_11[] = { I_SH_DROP,0x11,I_SH_OK };
1405 const BYTE SGE2_07[] = { I_SH_GET,0x07,I_SH_OK };
1406 const BYTE SGE2_08[] = { I_SH_GET,0x08,I_SH_OK };
1407 const BYTE SPU2_07[] = { I_SH_DROP,0x07,I_SH_OK };
1408 const BYTE SPU2_08[] = { I_SH_DROP,0x08,I_SH_OK };
1409 const BYTE SDO_HOW[] = { I_SH_MSG,0x03,I_SH_AUTO };
1410 const BYTE SUSE_GN[] = { I_SH_DEST,0x10,I_SH_SWAP,0x07,I_SH_MSG,0x06,I_SH_MSG,0x07,I_SH_AUTO };
1411 const BYTE SFIR_GN[] = { I_SH_MSG,0x26,I_SH_AUTO };
1412 const BYTE SUS2_GN[] = { I_SH_DEST,0x11,I_SH_MSG,0x06,I_SH_AUTO };
1413 const BYTE SHLP_CM[] = { I_SH_MSG,0x08,I_SH_AUTO };
1414 const BYTE SFLD_1[] = { I_SH_SETF,GVAR_07,I_SH_MSG,0x09,I_SH_AUTO };
1415 const BYTE SFLD_2[] = { I_SH_SETF,GVAR_08,I_SH_MSG,0x09,I_SH_AUTO };
1416 const BYTE SFLD_3[] = { I_SH_MSG,0x0a,I_SH_AUTO };
1417 const BYTE SDANCE[] = { I_SH_GOTO,0x10,I_SH_SETV,GVAR_02,0x09,I_SH_REDE };
1418 const BYTE SDANCE2[] = { I_SH_MSG,0x0b,I_SH_GOTO,0x13,I_SH_REDE };
1419 const BYTE SUSE_KY[] = { I_SH_GOTO,0x12,I_SH_REDE };
1420 const BYTE SKIL_SG[] = { I_SH_DEST,0x17,I_SH_OK };
1421 const BYTE SLK_UP[] = { I_SH_MSG,0x0c,I_SH_AUTO };
1422 const BYTE SBRK_BA[] = { I_SH_SWAP,0x14,I_SH_CREA,0x05,I_SH_REDE };
1423 const BYTE SGO_UP[] = { I_SH_GOTO,0x0c,I_SH_SWAP,0x14,I_SH_REDE };
1424 const BYTE SBRBSEC[] = { I_SH_MSG,0x0d,I_SH_AUTO };
1425 const BYTE SUSE_CN[] = { I_SH_SWAP,0x12,I_SH_DEST,0x06,I_SH_REDE };
1426 const BYTE SBDOOR[] = { I_SH_GOTO,0x0c,I_SH_SWAP,0x12,I_SH_REDE };
1427 const BYTE SLK_WAT[] = { I_SH_MSG,0x0e,I_SH_AUTO };
1428 const BYTE SGET_CN[] = { I_SH_MSG,0x01,I_SH_AUTO };
1429 const BYTE SWATER2[] = { I_SH_MSG,0x0f,I_SH_AUTO };
1430 const BYTE SWATER1[] = { I_SH_CREA,0x06,I_SH_GET,0x06,I_SH_OK };
1431 const BYTE SL2_WAT[] = { I_SH_MSG,0x0f,I_SH_AUTO };
1432 const BYTE SODOOR2[] = { I_SH_GOTO,0x0e,I_SH_REDE };
1433 const BYTE SPSH3A[] = { I_SH_SETV,GVAR_09,0x01,I_SH_OK };
1434 const BYTE SPSHDG[] = { I_SH_MSG,0x10,I_SH_CLRF,GVAR_09,I_SH_SETF,GVAR_0a,I_SH_AUTO };
1435 const BYTE SPSH2A[] = { I_SH_SETV,GVAR_09,0x02,I_SH_OK };
1436 const BYTE SPSH1A[] = { I_SH_MSG,0x11,I_SH_SETV,GVAR_09,0x03,I_SH_AUTO };
1437 const BYTE SMNDFUS[] = { I_SH_MSG,0x0d,I_SH_AUTO };
1438 const BYTE SUSE_BA[] = { I_SH_CLRF,GVAR_0a,I_SH_DEST,0x05,I_SH_OK };
1439 const BYTE SLOOK1[] = { I_SH_MSG,0x18,I_SH_AUTO };
1440 const BYTE SHELP1[] = { I_SH_MSG,0x13,I_SH_AUTO };
1441 const BYTE SHELP2[] = { I_SH_MSG,0x14,I_SH_AUTO };
1442 const BYTE SHELP3[] = { I_SH_MSG,0x15,I_SH_AUTO };
1443 const BYTE SHELP4[] = { I_SH_MSG,0x16,I_SH_AUTO };
1444 const BYTE SLK_UP2[] = { I_SH_MSG,0x1a,I_SH_AUTO };
1445 const BYTE SQUIET[] = { I_SH_GOTO,0x0c,I_SH_SETV,GVAR_02,0x07,I_SH_REDE };
1446 const BYTE SWR_09[] = { I_SH_WEAR,0x09,I_SH_OK };
1447 const BYTE SRM_09[] = { I_SH_REMO,0x09,I_SH_OK };
1448 const BYTE SREDE[] = { I_SH_REDE };
1449 const BYTE SJUMP_D[] = { I_SH_MSG,0x03,I_SH_AUTO };
1450 const BYTE SUSE_RP[] = { I_SH_SETF,GVAR_0b,I_SH_DROP,0x0a,I_SH_GOTO,0x0c,I_SH_REDE };
1451 const BYTE SJUMP[] = { I_SH_MSG,0x1b,I_SH_AUTO };
1452 const BYTE SUP_ROP[] = { I_SH_GOTO,0x01,I_SH_REDE };
1453 const BYTE SSHIP[] = { I_SH_GOTO,0x14,I_SH_REDE };
1454 const BYTE SPSH_MN[] = { I_SH_MSG,0x1c,I_SH_DEAD };
1455 const BYTE SPSH_AU[] = { I_SH_SETF,GVAR_0c,I_SH_MSG,0x1d,I_SH_AUTO };
1456 const BYTE SPSH_32[] = { I_SH_MSG,0x19,I_SH_DEAD };
1457 const BYTE SPSH_4[] = { I_SH_MSG,0x1e,I_SH_QUIT };
1458 const BYTE SPSH_1B[] = { I_SH_MSG,0x1f,I_SH_MSG,0x20,I_SH_DEAD };
1459 const BYTE SPSH_1C[] = { I_SH_MSG,0x1f,I_SH_MSG,0x21,I_SH_MSG,0x1e,I_SH_QUIT };
1460 const BYTE SHELP5[] = { I_SH_MSG,0x17,I_SH_AUTO };
1461 const BYTE SLOOK2[] = { I_SH_MSG,0x12,I_SH_AUTO };
1462
1463
1464
1465
1466
1467 /*
1468 // list of available verb/noun combinations
1469 // along with their defining predicates and
1470 // command lists
1471 // terminated with a zero byte
1472
1473 // for each entry:
1474 // 1st = verb token code
1475 // 2nd = noun token code
1476 // 3rd = address of predicate list entry
1477 // 4th = address of system command list entry
1478 */
1479
1480 const VNDef vndDefinitions[] =
1481 {
1482 { TOK_GET, TOK_BOOT, A_GD_BOOT, SGET_00 },
1483 { TOK_GET, TOK_STAR, A_GD_STAR, SGET_01 },
1484 { TOK_GET, TOK_KEY, A_GD_KEY, SGET_02 },
1485 { TOK_GET, TOK_GUN, A_GD_GUN, SGET_03 },
1486 { TOK_GET, TOK_BAR, A_GD_BAR, SGET_05 },
1487 { TOK_GET, TOK_COIN, A_GD_COIN, SGET_06 },
1488 { TOK_GET, TOK_MIRR, A_G_MIRR_1, SGET_07 },
1489 { TOK_GET, TOK_MIRR, A_GD_MIRR_2, SGET_08 },
1490 { TOK_GET, TOK_BROK, A_GD_MIRR_2, SGET_08 },
1491 { TOK_GET, TOK_GLOV, A_GD_GLOV, SGET_09 },
1492 { TOK_GET, TOK_ROPE, A_GD_ROPE, SGET_0A },
1493 { TOK_GET, TOK_BOAR, A_GD_BOAR_1, SGET_0B },
1494 { TOK_GET, TOK_BOAR, A_GD_BOAR_2, SGET_0C },
1495 { TOK_GET, TOK_BROK, A_GD_BOAR_2, SGET_0C },
1496 { TOK_GET, TOK_STAL, A_GD_STAL, SGET_0D },
1497 { TOK_GET, TOK_ICE, A_GD_ICE, SGET_0E },
1498 { TOK_GET, TOK_FLIN, A_GD_FLIN, SGET_18 },
1499 { TOK_GET, TOK_STON, A_GD_STON, SGET_19 },
1500 { TOK_INVE, 0xff, A_MISC, SINVENT },
1501 { TOK_QUIT, 0xff, A_MISC, SQUIT },
1502 { TOK_DROP, TOK_BOOT, A_GD_BOOT, SPUT_00 },
1503 { TOK_DROP, TOK_STAR, A_GD_STAR, SPUT_01 },
1504 { TOK_DROP, TOK_KEY, A_GD_KEY, SPUT_02 },
1505 { TOK_DROP, TOK_GUN, A_GD_GUN, SPUT_03 },
1506 { TOK_DROP, TOK_BAR, A_GD_BAR, SPUT_05 },
1507 { TOK_DROP, TOK_COIN, A_GD_COIN, SPUT_06 },
1508 { TOK_DROP, TOK_MIRR, A_D_MIRR, SPUT_07 },
1509 { TOK_DROP, TOK_MIRR, A_GD_MIRR_2, SPUT_08 },
1510 { TOK_DROP, TOK_BROK, A_GD_MIRR_2, SPUT_08 },
1511 { TOK_DROP, TOK_GLOV, A_GD_GLOV, SPUT_09 },
1512 { TOK_DROP, TOK_ROPE, A_GD_ROPE, SPUT_0A },
1513 { TOK_DROP, TOK_BOAR, A_GD_BOAR_1, SPUT_0B },
1514 { TOK_DROP, TOK_BOAR, A_GD_BOAR_2, SPUT_0C },
1515 { TOK_FIRE, TOK_BROK, A_GD_BOAR_2, SPUT_0C },
1516 { TOK_DROP, TOK_STAL, A_GD_STAL, SPUT_0D },
1517 { TOK_DROP, TOK_ICE, A_GD_ICE, SPUT_0E },
1518 { TOK_DROP, TOK_FLIN, A_GD_FLIN, SPUT_18 },
1519 { TOK_DROP, TOK_STON, A_GD_STON, SPUT_19 },
1520 { TOK_LOOK, TOK_DRAW, A_DRAW_STAL, SLK_DRW },
1521 { TOK_BREA, TOK_STAL, A_DRAW_STAL, SBRK_ST },
1522 { TOK_USE, TOK_ICE, A_U_ICE_1, SUSE_IC },
1523 { TOK_CUT, TOK_ROPE, A_CUT_ROPE, SCUT_RP },
1524 { TOK_USE, TOK_FLIN, A_USE_FLIN, SUSE_FL },
1525 { TOK_WEAR, TOK_BOOT, A_MISC, SWR_00 },
1526 { TOK_REMO, TOK_BOOT, A_MISC, SRM_00 },
1527 { TOK_CROS, TOK_RAVI, A_C_RAVI_1, SCR_RV },
1528 { TOK_CROS, TOK_RAVI, A_C_RAVI_2, SCR_RV },
1529 { TOK_USE, TOK_BOAR, A_C_RAVI_3, SUSE_BO },
1530 { TOK_USE, TOK_BOAR, A_USE_BOAR, SUS2_BO },
1531 { TOK_JUMP, TOK_RAVI, A_C_RAVI_3, SJMP_RV },
1532 { TOK_JUMP, TOK_RAVI, A_C_RAVI_2, SJMP_RV },
1533 { TOK_DOWN, 0xff, A_DOWN, SCR_RV },
1534 { TOK_USE, TOK_ICE, A_U_ICE_2, SUSE_I2 },
1535 { TOK_GET, TOK_MAN, A_G_MAN_1, SGET_MN },
1536 { TOK_GET, TOK_MAN, A_G_MAN_2, SGET_M2 },
1537 { TOK_GET, TOK_MAN, A_G_MAN_3, SGET_MN },
1538 { TOK_DROP, TOK_MAN, A_KD_MAN_1, SPUT_11 },
1539 { TOK_GET, TOK_MIRR, A_G_MIRR_3, SGE2_07 },
1540 { TOK_GET, TOK_BROK, A_GD_MIRR_2, SGE2_08 },
1541 { TOK_DROP, TOK_MIRR, A_D_MIRR, SPU2_07 },
1542 { TOK_DROP, TOK_BROK, A_GD_MIRR_2, SPU2_08 },
1543 { TOK_KILL, TOK_MAN, A_K_MAN_2, SDO_HOW },
1544 { TOK_KILL, TOK_MAN, A_KD_MAN_1, SDO_HOW },
1545 { TOK_USE, TOK_GUN, A_U_GUN_1, SUSE_GN },
1546 { TOK_USE, TOK_GUN, A_U_GUN_2, SFIR_GN },
1547 { TOK_USE, TOK_GUN, A_U_GUN_3, SUS2_GN },
1548 { TOK_TYPE, TOK_HELP, A_TYPE_HELP, SHLP_CM },
1549 { TOK_FIRE, TOK_GUN, A_FIRE_GUN, SFIR_GN },
1550 { TOK_FIEL, 0xff, A_FIEL_1, SFLD_1 },
1551 { TOK_FIEL, 0xff, A_FIEL_2, SFLD_2 },
1552 { TOK_FIEL, 0xff, A_FIEL_3, SFLD_3 },
1553 { TOK_DANC, 0xff, A_DANC_1, SDANCE },
1554 { TOK_DANC, 0xff, A_DANC_2, SDANCE2 },
1555 { TOK_OPEN, TOK_DOOR, A_O_DOOR_1, SDO_HOW },
1556 { TOK_USE, TOK_KEY, A_USE_KEY, SUSE_KY },
1557 { TOK_KILL, TOK_SECU, A_K_SECU, SKIL_SG },
1558 { TOK_LOOK, TOK_UP, A_LUP_BREA, SLK_UP },
1559 { TOK_BREA, TOK_BAR, A_LUP_BREA, SBRK_BA },
1560 { TOK_UP, 0xff, A_UP, SGO_UP },
1561 { TOK_BRIB, TOK_SECU, A_BRSEC, SBRBSEC },
1562 { TOK_USE, TOK_COIN, A_U_COIN, SUSE_CN },
1563 { TOK_DOOR, 0xff, A_B_DOOR, SBDOOR },
1564 { TOK_LOOK, TOK_WATE, A_L_WATE, SLK_WAT },
1565 { TOK_GET, TOK_COIN, A_G_COIN, SGET_CN },
1566 { TOK_WATE, 0xff, A_WATE_1, SWATER1 },
1567 { TOK_WATE, 0xff, A_WATE_2, SWATER2 },
1568 { TOK_WATE, 0xff, A_L_WATE, SL2_WAT },
1569 { TOK_OPEN, TOK_DOOR, A_O_DOOR_2, SODOOR2 },
1570 { TOK_PUSH, TOK_THRE, A_PUSH_THRE, SPSH3A },
1571 { TOK_PUSH, TOK_THRE, A_PUSH_DIG, SPSHDG },
1572 { TOK_PUSH, TOK_TWO, A_PUSH_TWO, SPSH2A },
1573 { TOK_PUSH, TOK_TWO, A_PUSH_DIG, SPSHDG },
1574 { TOK_PUSH, TOK_ONE, A_PUSH_ONE, SPSH1A },
1575 { TOK_PUSH, TOK_ONE, A_PUSH_DIG, SPSHDG },
1576 { TOK_MEND, TOK_FUSE, A_MEND_FUSE, SMNDFUS },
1577 { TOK_USE, TOK_BAR, A_USE_BAR, SUSE_BA },
1578 { TOK_LOOK, 0xff, A_LOOK, SLOOK1 },
1579 { TOK_HELP, 0xff, A_HELP_1, SHELP1 },
1580 { TOK_HELP, 0xff, A_HELP_2, SHELP2 },
1581 { TOK_HELP, 0xff, A_HELP_3, SHELP3 },
1582 { TOK_HELP, 0xff, A_HELP_4, SHELP4 },
1583 { TOK_HELP, 0xff, A_HELP_5, SHELP4 },
1584 { TOK_HELP, 0xff, A_HELP_6, SHELP4 },
1585 { TOK_HELP, 0xff, A_HELP_7, SHELP4 },
1586 { TOK_HELP, 0xff, A_HELP_8, SHELP1 },
1587 { TOK_LOOK, TOK_UP, A_LUP, SLK_UP2 },
1588 { TOK_WEST, 0xff, A_WEST, SQUIET },
1589 { TOK_NORT, 0xff, A_HELP_2, SQUIET },
1590 { TOK_WEAR, TOK_GLOV, A_MISC, SWR_09 },
1591 { TOK_REMO, TOK_GLOV, A_MISC, SRM_09 },
1592 { TOK_REDE, 0xff, A_MISC, SREDE },
1593 { TOK_DOWN, 0xff, A_JUMP, SJUMP_D },
1594 { TOK_USE, TOK_ROPE, A_USEROP, SUSE_RP },
1595 { TOK_JUMP, 0xff, A_JUMP, SJUMP },
1596 { TOK_UP, TOK_ROPE, A_UPROPE, SUP_ROP },
1597 { TOK_SHIP, 0xff, A_SHIP, SSHIP },
1598 { TOK_PUSH, TOK_MAIN, A_P_MAUX, SPSH_MN },
1599 { TOK_PUSH, TOK_AUX, A_P_MAUX, SPSH_AU },
1600 { TOK_PUSH, TOK_THRE, A_P_32, SPSH_32 },
1601 { TOK_PUSH, TOK_TWO, A_P_32, SPSH_32 },
1602 { TOK_PUSH, TOK_FOUR, A_P_41, SPSH_4 },
1603 { TOK_PUSH, TOK_ONE, A_PSH_ONE_2, SPSH_1C },
1604 { TOK_PUSH, TOK_ONE, A_P_41, SPSH_1B },
1605 { TOK_HELP, 0xff, A_MISC, SHELP5 },
1606 { TOK_LOOK, 0xff, A_MISC, SLOOK2 },
1607 { 0x00, 0x00, 0, 0 }
1608 };
1609
1610
1611
1612
1613
1614
1615 /* bytecodes for the auto commands */
1616 const BYTE STURNGR[] = { I_SH_MSG,0x23,I_SH_DEAD };
1617 const BYTE STHROTL[] = { I_SH_MSG,0x24,I_SH_DEAD };
1618 const BYTE SSHOT[] = { I_SH_MSG,0x25,I_SH_DEAD };
1619 const BYTE SMELT_I[] = { I_SH_SWAP,0x0e,I_SH_TELL };
1620 const BYTE STELLME[] = { I_SH_TELL };
1621
1622
1623
1624 /*
1625 // list of auto command combinations
1626 // terminated with a zero byte
1627 // these processed at the end of each parse cycle
1628
1629 // for each entry:
1630 // 1st = verb token code (wildcard, matches any verb)
1631 // 2nd = noun token code (wildcard, matches any noun)
1632 // 3rd = address of predicate list entry
1633 // 4th = unknown address
1634 */
1635
1636 const VNDef AUT_LST[] =
1637 {
1638 { 0xff, 0xff, A_CHGRN, STURNGR },
1639 { 0xff, 0xff, A_CHTHR, STHROTL },
1640 { 0xff, 0xff, A_C2THR, STHROTL },
1641 { 0xff, 0xff, A_SHOT, SSHOT },
1642 { 0xff, 0xff, A_MELTD, SMELT_I },
1643 { 0xff, 0xff, A_NULL, STELLME }
1644 };
1645
1646
1647
1648 /*
1649 // ======================================================================
1650 // output a character to the display
1651 // ======================================================================
1652 */
1653
i_PutCh(char ch)1654 void i_PutCh(char ch)
1655 {
1656 putchar(ch);
1657
1658 if (ch == '\n')
1659 nRemColumns = MAX_COL;
1660
1661 }
1662
1663 /*
1664 // ======================================================================
1665 // throw a new line on the display
1666 // ======================================================================
1667 */
1668
PrintCR()1669 void PrintCR()
1670 {
1671 i_PutCh('\n');
1672 }
1673
1674 /*
1675 // ======================================================================
1676 // clear the screen
1677 // ======================================================================
1678 */
1679
ClearScr()1680 void ClearScr()
1681 {
1682 putchar(12);
1683 #ifdef PICS
1684 clg();
1685 #endif
1686 /*
1687 int n;
1688 for (n = 0; n < 50; ++n)
1689 printf("\n");
1690
1691 nRemColumns = MAX_COL;
1692 */
1693 }
1694
1695 /*
1696 // ======================================================================
1697 // print the zero-terminated string pointed to by HL
1698 // performing word-wrap and scrolling if necessary
1699 // ======================================================================
1700 */
1701
PrintStr(unsigned char * hl)1702 void PrintStr(unsigned char* hl)
1703 {
1704 unsigned char ch;
1705 unsigned char *temphl;
1706 int b;
1707
1708
1709 for (;;)
1710 {
1711 ch = *hl++;
1712 if (ch == 0)
1713 return;
1714
1715 switch (ch)
1716 {
1717 case '\n':
1718 PrintCR();
1719 break;
1720
1721 case ' ':
1722 break;
1723
1724 default:
1725 --hl;
1726 temphl = hl;
1727 b = 0;
1728
1729 for (;;)
1730 {
1731 ch = *hl;
1732 if ((ch == ' ') || (ch == '\0') || (ch == '\n'))
1733 break;
1734 ++b;
1735 ++hl;
1736 }
1737
1738 if (b > nRemColumns)
1739 PrintCR();
1740
1741 hl = temphl;
1742
1743 for (;;)
1744 {
1745 ch = *hl;
1746 if ((ch == ' ') || (ch == '\0') || (ch == '\n'))
1747 break;
1748
1749 i_PutCh(ch);
1750 ++hl;
1751 }
1752
1753 if ((nRemColumns - b) != 0)
1754 {
1755 i_PutCh(' ');
1756 nRemColumns = nRemColumns - b - 1;
1757 }
1758 else
1759 nRemColumns = nRemColumns - b;
1760
1761 break;
1762 }
1763 }
1764 }
1765
1766
1767
1768
1769 /****
1770
1771 ; main program starts here
1772
1773 START ld hl,GVARS ; zero all game variables
1774 ld b,$1e
1775 INITLP ld (hl),$00
1776 inc hl
1777 djnz INITLP
1778
1779 ld hl,$0000
1780 ld (SCORE),hl
1781 call PrintInstr ; display instructions
1782
1783 // copied to main - initialize naItemLoc
1784
1785 ld ix,GVARS ; initialize ix to point at the game variables
1786 ld (CUR_RM),$00 ; set current room to 0 (starting room)
1787 push hl ; save hl (points at naItemLoc)
1788 jr RESTG ; skip message data...
1789
1790 RESTG_M .text "WANT TO RESTORE A GAME?"
1791 .byte $0d,$00
1792
1793 RESTG ld hl,RESTG_M ; prompt - restore game?
1794 call PrintStr ; print it
1795 pop hl ; restore hl (points at naItemLoc)
1796 call i_GetCh
1797
1798 cp 'Y'
1799 call z,LCASS ; user typed 'Y', go and restore game
1800
1801
1802 ; main execution loop
1803
1804 MAIN call ClearScr
1805 xor a
1806 cp (ix+$00) ; if (ix+$00) is zero,
1807 jr z,ROOM ; go and display the room description
1808 cp (ix+$03) ; if (ix+$03) is zero,
1809 jr z,DARK_CH ; go straight to the dark check
1810 dec (ix+$03) ; otherwise, decrement (ix+$03)
1811
1812 DARK_CH ld a,(naItemLoc) ; get location of item $00
1813 cp (CUR_RM) ; check whether it's in the current room
1814 jr z,ROOM ; if it is, it's not dark
1815 push hl
1816 jr DARK ; skip message data...
1817
1818 DARK_M .text "EVERYTHING IS DARK.I CANT SEE."
1819 .byte $0d,$00
1820
1821 DARK ld hl,DARK_M ; say it's dark and we can't see
1822 call PrintStr
1823 pop hl
1824 xor a
1825 cp (ix+$04) ; if (ix+$04) is zero,
1826 jr z,DARK_ND ; go straight to ????????
1827 dec (ix+$04) ; otherwise, decrement (ix+$04)
1828
1829 DARK_ND jr DO_AUTO ; (96)
1830
1831
1832 ****/
1833
1834
1835 /* display description for current room */
1836
ShowRoom()1837 void ShowRoom()
1838 {
1839 int nItem;
1840
1841 #ifdef PICS
1842 switch(CUR_RM)
1843 {
1844 case 0:
1845 draw_profile(60, 60, 160, mountain);
1846 draw_profile(63, 63, 152, mountain);
1847 draw(135,73,175,71);
1848 draw_profile(80, 80, 240, tree2);
1849 draw_profile(80, 120, 80, mountain);
1850 draw_profile(60, 110, 200, tree2);
1851 break;
1852 case 3:
1853 for (nItem = 1; nItem < 5; ++nItem) {
1854 draw_profile(nItem*10-rand()%100, 20+rand()%40, 170+nItem*20, tree2);
1855 draw_profile(60-rand()%100, nItem+rand()%40, 170+nItem*20, tree1);
1856 }
1857 break;
1858 case 4:
1859 draw_profile(50, 20, 160, lake);
1860 break;
1861 case 5:
1862 //draw_profile(50, 20, 240, strange_house);
1863 break;
1864 case 6:
1865 draw_profile(60, 3, 180, shed);
1866 break;
1867 case 7:
1868 case 8:
1869 case 9:
1870 case 10:
1871 draw_profile(60, 60, 240, maze);
1872 break;
1873 case 14:
1874 draw_profile(20, 100, 200, keyboard);
1875 break;
1876 case 19:
1877 draw_profile(60, 20, 160, jail);
1878 break;
1879
1880 }
1881 #endif
1882
1883 PrintStr(straRoom[CUR_RM]);
1884
1885 FLAG = FALSE;
1886 for (nItem = 0; nItem < MAX_ITEM; ++nItem)
1887 {
1888 if (naItemLoc[nItem] == CUR_RM)
1889 {
1890 if (!FLAG)
1891 {
1892 PrintStr("I can also see :\n");
1893 FLAG = TRUE;
1894 }
1895 PrintStr(straItem[nItem]);
1896 PrintCR();
1897 }
1898 }
1899
1900 nNextParseAction = NA_DO_AUTO;
1901 }
1902 /*****
1903
1904 // ======================================================================
1905 // perform regular automatic functions, e.g. the little green man
1906 // ======================================================================
1907
1908 void DO_AUTO()
1909 {
1910 ld hl,AUT_LST ; select the auto command list (wildcards, every command matches)
1911 jp PARS_LP ; and restart parser
1912
1913
1914 ***/
1915
1916 /*
1917 // ======================================================================
1918 // system command - TELL command
1919 // generates the "tell me what to do" prompt
1920 // ======================================================================
1921 */
1922
SH_TELL()1923 void SH_TELL()
1924 {
1925 BYTE* pDirections;
1926
1927 if (GVARS[GVAR_02] > 0)
1928 --GVARS[GVAR_02];
1929
1930 if (GVARS[GVAR_05] > 0)
1931 --GVARS[GVAR_05];
1932
1933 /***
1934 {
1935 char sz[256];
1936 sprintf(sz, "02 = %u\n", GVARS[0x02]);
1937 PrintStr(sz);
1938 }
1939 ***/
1940
1941 PrintStr("Tell me what to do \n");
1942
1943 GetLine();
1944 F_NTYET = FALSE;
1945 /*
1946 // ======================================================================
1947 // fetch verb token from the input buffer
1948 // ======================================================================
1949 */
1950
1951 pchEditLine = chaEditLine;
1952
1953 for (;;)
1954 {
1955 VERB_TK = GET_TOK();
1956 if (VERB_TK == 0xff)
1957 {
1958 BOOL bDont = FALSE;
1959 if ((*pchEditLine == '\n') || (*pchEditLine == '\0'))
1960 bDont = TRUE;
1961 else
1962 {
1963 for (;;)
1964 {
1965 if (*pchEditLine == ' ')
1966 {
1967 ++pchEditLine;
1968 goto verb_outer_continue;
1969 }
1970 else if ((*pchEditLine == '\n') || (*pchEditLine == '\0'))
1971 {
1972 bDont = TRUE;
1973 break;
1974 }
1975 ++pchEditLine;
1976 }
1977 }
1978
1979 if (bDont)
1980 {
1981 PrintStr("I don't understand\n");
1982 nNextParseAction = NA_DO_AUTO;
1983 return;
1984 }
1985 }
1986 else
1987 break; /* verb ok */
1988
1989 verb_outer_continue:
1990 continue;
1991 }
1992
1993 /* verb recognized */
1994 NOUN_TK = 0xff; /* assume noun unrecognized before reading on */
1995
1996
1997 /* trim off excess characters from the verb */
1998 for (;;)
1999 {
2000 char ch = *pchEditLine;
2001
2002 if (ch == ' ')
2003 break;
2004
2005 if (ch == '\0')
2006 goto P_DIR;
2007
2008 if (ch == '\n')
2009 goto P_DIR;
2010
2011 ++pchEditLine;
2012 }
2013
2014 /*
2015 // ======================================================================
2016 // fetch noun token from the input buffer
2017 // ======================================================================
2018 */
2019
2020 for (;;)
2021 {
2022 ++pchEditLine;
2023 NOUN_TK = GET_TOK();
2024
2025
2026 if (NOUN_TK != 0xff)
2027 break;
2028
2029 for (;;)
2030 {
2031 char ch = *pchEditLine;
2032
2033 if (ch == ' ')
2034 break;
2035
2036 if (ch == '\0')
2037 goto P_DIR;
2038
2039 if (ch == '\n')
2040 goto P_DIR;
2041
2042 ++pchEditLine;
2043 }
2044 }
2045
2046 /*
2047 // ======================================================================
2048 // attempt to parse a direction verb
2049 // ======================================================================
2050 */
2051
2052 P_DIR:
2053
2054 pDirections = DIR_V[CUR_RM];
2055
2056 for (;;)
2057 {
2058 int nDir = *pDirections;
2059
2060 if (nDir == 0xff)
2061 break;
2062
2063 if (nDir == VERB_TK)
2064 {
2065 CUR_RM = pDirections[1];
2066 nNextParseAction = NA_MAIN;
2067 return;
2068 }
2069
2070 pDirections += 2;
2071 }
2072
2073 pvndCurrent = vndDefinitions;
2074 CMDFLG = FALSE;
2075 nNextParseAction = NA_BEGIN;
2076 }
2077
2078 extern const void *SYS_V[];
2079
PARSE_LP()2080 void PARSE_LP()
2081 {
2082 int nVerbTok = pvndCurrent->nVerbTok;
2083
2084 if (nVerbTok == 0)
2085 {
2086 if (!CMDFLG)
2087 {
2088 if (VERB_TK < TOK_GET) /* direction? */
2089 PrintStr("I can't go in that direction\n");
2090 else if (F_NTYET)
2091 PrintStr("I can't do that yet\n");
2092 else
2093 PrintStr("I can't\n");
2094 }
2095 nNextParseAction = NA_DO_AUTO;
2096 return;
2097 }
2098
2099 if ((nVerbTok == 0xff) || (nVerbTok == VERB_TK))
2100 {
2101 int nNounTok = pvndCurrent->nNounTok;
2102
2103 if ((nNounTok == 0xff) || (nNounTok == NOUN_TK))
2104 {
2105 int nPred;
2106 pPredicateCurrent = (BYTE*) pvndCurrent->pPredicates;
2107
2108 while ((nPred = *pPredicateCurrent++) != 0xff)
2109 {
2110 BOOL (*pfn)() = PRED_V[nPred];
2111 PARAM1 = *pPredicateCurrent;
2112 if (!pfn())
2113 {
2114 F_NTYET = TRUE;
2115 nNextParseAction = NA_CONTINUE;
2116 return;
2117 }
2118 ++pPredicateCurrent;
2119 }
2120 /* execute command */
2121 pActionCurrent = (BYTE*) pvndCurrent->pActions;
2122 CMDFLG = TRUE;
2123
2124 nNextParseAction = NA_CONTINUE;
2125
2126 for (;;)
2127 {
2128 if (*pActionCurrent == 0xff)
2129 return;
2130 else
2131 {
2132 void (*pfn)() = (void*) (SYS_V[*pActionCurrent++]);
2133
2134 PARAM1 = *pActionCurrent;
2135 pfn();
2136
2137 if (nNextParseAction != NA_CONTINUE)
2138 return;
2139
2140 ++pActionCurrent;
2141 }
2142 }
2143
2144
2145
2146 PrintStr("Executed!\n");
2147 }
2148 }
2149
2150 nNextParseAction = NA_CONTINUE;
2151 return;
2152 }
2153
2154
2155
2156
2157
2158
2159
2160 /* predicates */
2161
2162
2163 /*
2164 // predicate CHKROOM - this tests the current room number to make sure it's the specified room number.
2165 // if it is, we move on to the next command, otherwise we trigger a "i can't do that yet" response.
2166 // this handler interprets PARAM1 as the room number
2167 */
2168
CHKROOM()2169 BOOL CHKROOM()
2170 {
2171 return PARAM1 == CUR_RM;
2172 }
2173
2174
2175 /*
2176 // predicate for GET and DROP commands
2177 // this handler interprets PARAM1 as the item number
2178 */
2179
CHKHERE()2180 BOOL CHKHERE()
2181 {
2182 int nLoc = naItemLoc[PARAM1];
2183
2184 return (nLoc == CUR_RM) || (nLoc >= ITEM_WORN);
2185 }
2186
2187 /*
2188 // predicate CHKRAND - randomly allows or disallows the user's command.
2189 // if allowed, we move on to the next command, otherwise we trigger a "i can't do that yet" response.
2190 */
2191
CHKRAND()2192 BOOL CHKRAND()
2193 {
2194 return (rand() % 256) < PARAM1;
2195 }
2196
2197
2198 /*
2199 // predicate CHKAWAY - checks that the specified item is not carried, held or in the current room.
2200 // if it is NOT, we move on to the next command, otherwise we trigger a "i can't do that yet" response.
2201 // this handler interprets PARAM1 as the item number
2202 */
2203
CHKAWAY()2204 BOOL CHKAWAY()
2205 {
2206 return !CHKHERE();
2207 }
2208
2209
2210 /*
2211 // predicate CHKWORN - checks that the specified item is being worn.
2212 // if it is, we move on to the next command, otherwise we trigger a "i can't do that yet" response.
2213 // this handler interprets PARAM1 as the item number
2214 */
2215
CHKWORN()2216 BOOL CHKWORN()
2217 {
2218 return naItemLoc[PARAM1] == ITEM_WORN;
2219 }
2220
2221
2222 /*
2223 // predicate CHKSETF - checks the game variable specified by PARAM1.
2224 // if it is non-zero, we move on to the next command, otherwise we trigger a "i can't do that yet" response.
2225 // this handler interprets PARAM1 as the game variable number
2226 // used by "field" and "look up"
2227 */
2228
CHKSETF()2229 BOOL CHKSETF()
2230 {
2231 return !!GVARS[PARAM1];
2232 }
2233
2234
2235
2236 /*
2237 // predicate TSTGVAR - compares the game variable specified by PARAM1 with the value specified as
2238 // the next byte after the command.
2239 // if it is equal, we move on to the next command, otherwise we trigger a "i can't do that yet" response.
2240 // this handler interprets PARAM1 as the game variable number
2241 */
2242
TSTGVAR()2243 BOOL TSTGVAR()
2244 {
2245 int nParam2 = *++pPredicateCurrent;
2246 return GVARS[PARAM1] == nParam2;
2247 }
2248
2249
2250 /*
2251 // predicate CHKCLRF - checks the game variable specified by PARAM1.
2252 // if it is zero, we move on to the next command, otherwise we trigger a "i can't do that yet" response.
2253 // this handler interprets PARAM1 as the game variable number
2254 */
2255
CHKCLRF()2256 BOOL CHKCLRF()
2257 {
2258 return !CHKSETF();
2259 }
2260
2261
2262 /*
2263 // predicate CHKHELD - checks that the specified item is being carried (or worn!).
2264 // if it is, we move on to the next command, otherwise we trigger a "i can't do that yet" response.
2265 // this handler interprets PARAM1 as the item number
2266 */
2267
CHKHELD()2268 BOOL CHKHELD()
2269 {
2270 return (naItemLoc[PARAM1] == ITEM_HELD) || (naItemLoc[PARAM1] == ITEM_WORN);
2271 }
2272
2273
2274 /***
2275
2276
2277
2278
2279
2280
2281 ; fetch location for an item
2282 ; item number is in PARAM1
2283 ; location is returned in A
2284 ; address of location entry is returned in HL
2285
2286 GET_LOC ld hl,naItemLoc
2287 ld b,$00
2288 ld c,(PARAM1)
2289 add hl,bc
2290 ld a,(hl)
2291 ret
2292
2293
2294
2295
2296 ***/
2297
2298
2299
SH_INVE()2300 void SH_INVE()
2301 {
2302 int bNothing=TRUE;
2303 int nItem;
2304 int nLoc;
2305
2306 PrintStr("I have with me the following:\n");
2307
2308 for (nItem = 0; nItem < MAX_ITEM; ++nItem)
2309 {
2310 nLoc = naItemLoc[nItem];
2311
2312 if (nLoc >= ITEM_WORN)
2313 {
2314 bNothing = FALSE;
2315 PrintStr(straItem[nItem]);
2316 if (nLoc == ITEM_WORN)
2317 PrintStr(" which i am wearing");
2318 PrintCR();
2319 }
2320 }
2321
2322 if (bNothing)
2323 PrintStr("Nothing at all\n");
2324
2325 nNextParseAction = NA_DO_AUTO;
2326 }
2327
2328
2329 /*
2330 // ======================================================================
2331 // system command - REMOVE command
2332 // item to be removed is specified in PARAM1
2333 // ======================================================================
2334 */
2335
SH_REMO()2336 void SH_REMO()
2337 {
2338 if (naItemLoc[PARAM1] == ITEM_WORN)
2339 {
2340 if (GVARS[GVAR_NO_ITEMS] == 6)
2341 {
2342 PrintStr("I cant. My hands are full\n");
2343 nNextParseAction = NA_DO_AUTO;
2344 }
2345 else
2346 {
2347 naItemLoc[PARAM1] = ITEM_HELD;
2348 ++GVARS[GVAR_NO_ITEMS];
2349 }
2350 }
2351 else
2352 {
2353 PrintStr("I am not wearing it\n");
2354 nNextParseAction = NA_DO_AUTO;
2355 }
2356 }
2357
2358
2359
2360
2361 /*
2362 // ======================================================================
2363 // system command - GET command
2364 // item to be got is specified in PARAM1
2365 // ======================================================================
2366 */
2367
SH_GET()2368 void SH_GET()
2369 {
2370 if (GVARS[GVAR_NO_ITEMS] == 6)
2371 {
2372 PrintStr("I can't carry any more\n");
2373 nNextParseAction = NA_DO_AUTO;
2374 }
2375 else if (naItemLoc[PARAM1] == CUR_RM)
2376 {
2377 naItemLoc[PARAM1] = ITEM_HELD;
2378 ++GVARS[GVAR_NO_ITEMS];
2379 }
2380 else if ((naItemLoc[PARAM1] == ITEM_WORN) || (naItemLoc[PARAM1] == ITEM_HELD))
2381 {
2382 PrintStr("I already have it\n");
2383 nNextParseAction = NA_DO_AUTO;
2384 }
2385 else
2386 {
2387 PrintStr("I don't see it here\n");
2388 nNextParseAction = NA_DO_AUTO;
2389 }
2390 }
2391
2392 /*
2393 // ======================================================================
2394 // system command - DROP command
2395 // item to be dropped is specified in PARAM1
2396 // ======================================================================
2397 */
2398
SH_DROP()2399 void SH_DROP()
2400 {
2401 if (naItemLoc[PARAM1] == CUR_RM)
2402 {
2403 PrintStr("I don't have it\n");
2404 nNextParseAction = NA_DO_AUTO;
2405 }
2406 else if (naItemLoc[PARAM1] == ITEM_WORN)
2407 {
2408 naItemLoc[PARAM1] = CUR_RM;
2409 }
2410 else if (naItemLoc[PARAM1] == ITEM_HELD)
2411 {
2412 --GVARS[GVAR_NO_ITEMS];
2413 naItemLoc[PARAM1] = CUR_RM;
2414 }
2415 else
2416 {
2417 PrintStr("I don't have it\n");
2418 nNextParseAction = NA_DO_AUTO;
2419 }
2420 }
2421
2422
2423 /*
2424 // ======================================================================
2425 // system command - WEAR command
2426 // item to be worn is specified in PARAM1
2427 // ======================================================================
2428 */
2429
SH_WEAR()2430 void SH_WEAR()
2431 {
2432 if (naItemLoc[PARAM1] == ITEM_HELD)
2433 {
2434 naItemLoc[PARAM1] = ITEM_WORN;
2435 --GVARS[GVAR_NO_ITEMS];
2436 }
2437 else if (naItemLoc[PARAM1] == ITEM_WORN)
2438 {
2439 PrintStr("I am already wearing it\n");
2440 nNextParseAction = NA_DO_AUTO;
2441 }
2442 else
2443 {
2444 PrintStr("I don't have it\n");
2445 nNextParseAction = NA_DO_AUTO;
2446 }
2447 }
2448
2449
2450 /*
2451 // ======================================================================
2452 // system command - display a response
2453 // index of response to be displayed is specified in PARAM1
2454 // ======================================================================
2455 */
2456
2457
SH_MSG()2458 BOOL SH_MSG()
2459 {
2460 PrintStr(straMsg[PARAM1]);
2461 return TRUE;
2462 }
2463
2464
2465 /*
2466 // ======================================================================
2467 // system command - REDE
2468 // redescribe current room, terminating execution of system commands
2469 // ======================================================================
2470 */
2471
SH_REDE()2472 void SH_REDE()
2473 {
2474 nNextParseAction = NA_MAIN;
2475 }
2476
2477 /*
2478 // ======================================================================
2479 // exactly the same effect as SH_FAIL - it halts further system command
2480 // processing,
2481 // and proceeds to execute the auto commands.
2482 // ======================================================================
2483 */
2484
SH_AUTO()2485 void SH_AUTO()
2486 {
2487 nNextParseAction = NA_DO_AUTO;
2488 }
2489
2490 /*
2491 // ======================================================================
2492 // system command - go directly to specific room (do not pass go)
2493 // index of room is specified in PARAM1
2494 // NB: room description not automatically displayed
2495 // ======================================================================
2496 */
2497
SH_GOTO()2498 void SH_GOTO()
2499 {
2500 CUR_RM = PARAM1;
2501 }
2502
2503
2504 /*
2505 // ======================================================================
2506 // system command SETF - set game variable to $ff
2507 // index of variable to set is specified in PARAM1
2508 // ======================================================================
2509 */
2510
SH_SETF()2511 void SH_SETF()
2512 {
2513 GVARS[PARAM1] = 0xff;
2514 }
2515
2516
2517 /*
2518 // ======================================================================
2519 // system command CLRF - clear game variable to $00
2520 // index of variable to clear is specified in PARAM1
2521 // ======================================================================
2522 */
2523
SH_CLRF()2524 void SH_CLRF()
2525 {
2526 GVARS[PARAM1] = 0x00;
2527 }
2528
2529 /*
2530 // ======================================================================
2531 // system command - SWAP
2532 // swap an item's location with the location of the following item
2533 // item to be swapped is specified in PARAM1
2534 // ======================================================================
2535 */
2536
SH_SWAP()2537 void SH_SWAP()
2538 {
2539 int nTemp = naItemLoc[PARAM1];
2540 naItemLoc[PARAM1] = naItemLoc[PARAM1 + 1];
2541 naItemLoc[PARAM1 + 1] = nTemp;
2542 }
2543
2544 /*
2545 // ======================================================================
2546 // system command - DEAD
2547 // immediately terminate game, stop executing system commands
2548 // ======================================================================
2549 */
2550
SH_DEAD()2551 void SH_DEAD()
2552 {
2553
2554 PrintStr("Do you wish to try again?\n");
2555
2556 for (;;)
2557 {
2558 char ch;
2559
2560 PrintStr("Answer yes or no\n");
2561 ch = i_GetCh();
2562 if (ch == 'Y')
2563 {
2564 nNextParseAction = NA_RESTART;
2565 return;
2566 }
2567 if (ch == 'N')
2568 {
2569 exit(0);
2570 }
2571 }
2572 }
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582 /* display "OK.." prompt and cease processing system commands */
2583
2584
SH_OK()2585 void SH_OK()
2586 {
2587 PrintStr("OK..\n");
2588 nNextParseAction = NA_DO_AUTO;
2589 }
2590
2591
2592
2593
SH_QUIT()2594 void SH_QUIT()
2595 {
2596
2597 /* TAPE and DISKBLOCK mode save */
2598 #ifdef TAPE
2599 PrintStr("Do you want to save the game?\n");
2600
2601 if (i_GetCh() == 'Y')
2602 {
2603 /* save */
2604 #ifdef DISKBLOCK
2605 PrintStr("\nPrepare disc or cartrige, then press a key\n");
2606 #else
2607 PrintStr("\nStart tape, then press a key\n");
2608 #endif
2609 i_GetCh();
2610
2611 #ifdef DISKBLOCK
2612 rnd_erase("GVARS.SAV");
2613 rnd_saveblock("GVARS.SAV", GVARS, sizeof(GVARS));
2614 #else
2615 tape_save_block(GVARS, sizeof(GVARS), 1);
2616 #endif
2617
2618 #ifdef COMPUTE_SCORE
2619 #ifdef DISKBLOCK
2620 rnd_erase("SCORE.SAV");
2621 rnd_saveblock("SCORE.SAV", &nScore, sizeof(nScore));
2622 #else
2623 tape_save_block(&nScore, sizeof(nScore), 2);
2624 #endif
2625 #endif
2626
2627 #ifdef DISKBLOCK
2628 rnd_erase("ITEMS.SAV");
2629 rnd_erase("ROOM.SAV");
2630 rnd_saveblock("ITEMS.SAV", &naItemLoc, sizeof(naItemLoc));
2631 rnd_saveblock("ROOM.SAV", &CUR_RM, sizeof(CUR_RM));
2632 #else
2633 tape_save_block(naItemLoc, sizeof(naItemLoc), 3);
2634 tape_save_block(&CUR_RM, sizeof(CUR_RM), 4);
2635 #endif
2636
2637 #endif
2638
2639
2640 /* Save game to DISK with standard C functions */
2641 #ifdef DISK
2642 PrintStr("Do you want to save the game?\n");
2643
2644 if (i_GetCh() == 'Y')
2645 {
2646 /* save */
2647 fpsave=fopen("adv_a.sav","wb");
2648 fwrite(GVARS, sizeof(GVARS),1, fpsave);
2649 #ifdef COMPUTE_SCORE
2650 fwrite(&nScore, sizeof(nScore),1, fpsave);
2651 #endif
2652 fwrite(naItemLoc, sizeof(naItemLoc),1, fpsave);
2653 fwrite(&CUR_RM, sizeof(CUR_RM),1, fpsave);
2654 fclose(fpsave);
2655 #endif
2656
2657 PrintStr("Do you wish to continue?\n");
2658
2659 if (i_GetCh() == 'Y')
2660 {
2661 nNextParseAction = NA_DO_AUTO;
2662 return;
2663 }
2664 #ifdef TAPE
2665 }
2666 #endif
2667 #ifdef DISK
2668 }
2669 #endif
2670
2671 SH_DEAD();
2672 }
2673
2674
2675
2676
2677
2678 /*
2679 // ======================================================================
2680 // system command SETV - set game variable to a specific value
2681 // index of variable to set is specified in PARAM1
2682 // the new value is specified as the byte after this command
2683 // ======================================================================
2684 */
2685
SH_SETV()2686 void SH_SETV()
2687 {
2688 int nParam2 = *++pActionCurrent;
2689
2690 GVARS[PARAM1] = nParam2;
2691 }
2692
2693
2694 /*
2695 // ======================================================================
2696 // system command CREA - create item in current room
2697 // index of item to be created is specified in PARAM1
2698 // ======================================================================
2699 */
2700
SH_CREA()2701 void SH_CREA()
2702 {
2703 naItemLoc[PARAM1] = CUR_RM;
2704 }
2705
2706
2707 /*
2708 // ======================================================================
2709 // system command DEST - destroy item in current room
2710 // index of item to be destoyed is specified in PARAM1
2711 // ======================================================================
2712 */
2713
SH_DEST()2714 void SH_DEST()
2715 {
2716 naItemLoc[PARAM1] = NOTX;
2717 }
2718
2719
2720
2721
2722
2723
2724 /* clean-up and abort execution of system commands, continuing with auto commands */
2725
SH_FAIL()2726 void SH_FAIL()
2727 {
2728 nNextParseAction = NA_DO_AUTO;
2729 }
2730
2731
2732 /*
2733 // ======================================================================
2734 // system command ADSC - add value to the current score.
2735 // value to be added is specified in PARAM1
2736 // ======================================================================
2737 */
2738
SH_ADSC()2739 void SH_ADSC()
2740 {
2741 #ifdef COMPUTE_SCORE
2742 nScore += PARAM1;
2743 #endif
2744 }
2745
SH_SCOR()2746 void SH_SCOR()
2747 {
2748 #ifdef COMPUTE_SCORE
2749 char szScore[32];
2750
2751 PrintStr("You have a score of ");
2752
2753 #ifndef printn
2754 sprintf(szScore, "%04x", nScore); // hex! (really)
2755 PrintStr(szScore);
2756 #else
2757 printn(nScore,16,stdout);
2758 #endif
2759 PrintCR();
2760 #endif
2761 }
2762
2763 /* addresses of various system function handlers */
2764
2765 const void* SYS_V[] =
2766 {
2767 SH_INVE,
2768 SH_REMO,
2769 SH_GET,
2770 SH_DROP,
2771 SH_WEAR,
2772 SH_MSG,
2773 SH_REDE,
2774 SH_AUTO,
2775 SH_GOTO,
2776 SH_SETF,
2777 SH_CLRF,
2778 SH_SWAP,
2779 SH_DEAD,
2780 SH_OK,
2781 SH_QUIT,
2782 SH_SETV,
2783 SH_CREA,
2784 SH_DEST,
2785 SH_ADSC,
2786 SH_SCOR,
2787 SH_FAIL,
2788 SH_TELL,
2789 SH_FAIL,
2790 SH_FAIL,
2791 SH_FAIL
2792 };
2793
2794 /*
2795 // ======================================================================
2796 // fetch command token from the input buffer, starting at position HL
2797 // on return, A contains the token code (or $ff if not recognized)
2798 // and HL points to the character after the token
2799 // ======================================================================
2800 */
2801
GET_TOK()2802 int GET_TOK()
2803 {
2804 char *pchTokenBuffer = strTokenBuf;
2805 int nResult = 0xff;
2806 int n;
2807
2808 strncpy(strTokenBuf, " ", 4); /* clear the token buffer to spaces */
2809
2810 for (n = 0; n < 4; ++n)
2811 {
2812 char ch = *pchEditLine;
2813 if (ch == ' ')
2814 break;
2815
2816 if (ch == '\0')
2817 break;
2818
2819 if (ch == '\n')
2820 break;
2821
2822 *pchTokenBuffer++ = ch;
2823 ++pchEditLine;
2824 }
2825
2826 for (n = 0; n < MAX_TOK; ++n)
2827 {
2828 if (strncmp(strTokenBuf, taToken[n].strWord, 4) == 0)
2829 {
2830 nResult = taToken[n].nCode;
2831 break;
2832 }
2833 }
2834
2835 return nResult;
2836 }
2837
2838
2839 /***
2840
2841
2842
2843 ; ======================================================================
2844
2845
2846
2847 LCASS push hl
2848 jr LCASS_1 ; (16)
2849
2850 LCASS_M .text "READY CASSETTE"
2851 .byte $0d,$00
2852
2853 LCASS_1 ld hl,LCASS_M
2854 call PrintStr
2855 pop hl
2856 call i_GetCh
2857 push ix
2858 ld ix,FLAG
2859 ld de,$0029
2860 ld a,$ff
2861 scf
2862 call ROM_LD
2863 ld ix,naItemLoc
2864 ld de,$001d
2865 ld a,$ff
2866 scf
2867 call ROM_LD
2868 pop ix
2869 ret
2870
2871 ****/
2872 /*
2873 // ======================================================================
2874 // fetch key from buffer
2875 // waits for keypress, returns ascii code in A
2876 // ======================================================================
2877 */
2878
i_GetCh()2879 char i_GetCh()
2880 {
2881 return toupper(fgetc(stdin));
2882 }
2883
2884 /***
2885
2886 ; unused keyboard-reading code (left over from ZX81 version?)
2887
2888 push de
2889 ld d,a
2890 ld a,$7f
2891 in a,($fe)
2892 rra
2893 jr c,ZX_END2
2894 ld a,$fe
2895 in a,($fe)
2896 rra
2897 jr c,ZX_END2
2898 ld a,$01
2899 or a
2900
2901 ZX_END ld a,d
2902 pop de
2903 ret
2904
2905 ZX_END2 xor a
2906 jr ZX_END ; (-6)
2907
2908
2909 ***/
2910
2911 /*
2912 // ======================================================================
2913 // get a line of input from the user
2914 // store the data in the buffer pointed to by HL
2915 // ======================================================================
2916 */
2917
GetLine()2918 void GetLine()
2919 {
2920 fgets(chaEditLine, MAX_COL, stdin);
2921 strupr(chaEditLine);
2922 }
2923
2924
2925 /*
2926 // ======================================================================
2927 // clear screen, display instructions and wait for keypress
2928 // ======================================================================
2929 */
2930
PrintInstr()2931 void PrintInstr()
2932 {
2933 ClearScr();
2934 PrintStr(strInstructions);
2935 i_GetCh();
2936 }
2937
2938
2939
2940
2941 /****
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957 ****/
2958
2959
2960
2961
2962 /****
2963
2964 ; spurious data found in the original game
2965
2966 GARBAGE .word $5200,$4c4f,$5220,$004f
2967
2968
2969 .end
2970 ****/
2971
2972
2973
2974
main()2975 int main()
2976 {
2977 int n;
2978
2979 printf("%cE",27);
2980 for (;;) /* restart game loop */
2981 {
2982 /* initialize the game variables */
2983 for (n = 0; n <= 0x1e; ++n)
2984 GVARS[n] = 0;
2985
2986 #ifdef COMPUTE_SCORE
2987 nScore = 0;
2988 #endif
2989
2990 PrintInstr();
2991
2992 /* copy data from naItemStart to naItemLoc at start of game */
2993 for (n = 0; n < MAX_ITEM; ++n)
2994 naItemLoc[n] = naItemStart[n];
2995
2996 CUR_RM = 0;
2997
2998 #ifdef TAPE
2999 PrintStr("Want to restore a game?\n");
3000 if (i_GetCh() == 'Y')
3001 {
3002 /* restore */
3003 #ifdef DISKBLOCK
3004 rnd_loadblock("GVARS.SAV", GVARS, sizeof(GVARS));
3005 #else
3006 tape_load_block(GVARS, sizeof(GVARS), 1);
3007 #endif
3008 #ifdef COMPUTE_SCORE
3009 #ifdef DISKBLOCK
3010 rnd_loadblock("SCORE.SAV", &nScore, sizeof(nScore));
3011 #else
3012 tape_load_block(&nScore, sizeof(nScore), 2);
3013 #endif
3014 #endif
3015 #ifdef DISKBLOCK
3016 rnd_loadblock("ITEMS.SAV", &naItemLoc, sizeof(naItemLoc));
3017 rnd_loadblock("ROOM.SAV", &CUR_RM, sizeof(CUR_RM));
3018 #else
3019 tape_load_block(naItemLoc, sizeof(naItemLoc), 3);
3020 tape_load_block(&CUR_RM, sizeof(CUR_RM), 4);
3021 #endif
3022 }
3023 #endif
3024
3025 #ifdef DISK
3026 PrintStr("Want to restore a game?\n");
3027 if (i_GetCh() == 'Y')
3028 {
3029 /* restore */
3030 fpsave=fopen("adv_a.sav","rb");
3031 fread(GVARS, sizeof(GVARS),1, fpsave);
3032 #ifdef COMPUTE_SCORE
3033 fread(&nScore, sizeof(nScore),1, fpsave);
3034 #endif
3035 fread(naItemLoc, sizeof(naItemLoc),1, fpsave);
3036 fread(&CUR_RM, sizeof(CUR_RM),1, fpsave);
3037 fclose(fpsave);
3038 }
3039 #endif
3040
3041 /*
3042 PrintStr("Restore not supported\n");
3043 PrintStr("Press a key");
3044 i_GetCh();
3045 */
3046
3047 for (;;) /* main loop */
3048 {
3049 ClearScr();
3050
3051 if (GVARS[0] == 0)
3052 {
3053 ShowRoom();
3054 }
3055 else
3056 {
3057 if (GVARS[3] > 0)
3058 --GVARS[3];
3059
3060 if (naItemLoc[0] == CUR_RM)
3061 {
3062 ShowRoom();
3063 }
3064 else
3065 {
3066 PrintStr("Everything is dark. I can't see.\n");
3067 if (GVARS[4] > 0)
3068 --GVARS[4];
3069
3070 nNextParseAction = NA_DO_AUTO;
3071 }
3072 }
3073
3074 for (;;) /* parse loop */
3075 {
3076 switch (nNextParseAction)
3077 {
3078 case NA_DO_AUTO:
3079 pvndCurrent = AUT_LST;
3080 break;
3081 case NA_CONTINUE:
3082 ++pvndCurrent;
3083 break;
3084 case NA_MAIN:
3085 case NA_RESTART:
3086 goto outer_cont;
3087 break;
3088 case NA_BEGIN:
3089 break;
3090 default:
3091 PrintStr("Error\n");
3092 ++pvndCurrent;
3093 break;
3094 }
3095
3096 PARSE_LP();
3097 }
3098
3099 outer_cont:
3100 if (nNextParseAction == NA_RESTART)
3101 break;
3102 }
3103 }
3104
3105 return 0;
3106 }
3107