1 /*
2  * Z88DK NOTES:
3  *
4  * - Borrowed from the examples directory of the Amsterdam Compiler Kit:
5  *   https://github.com/davidgiven/ack
6  *
7  * - startrek.c was written by David Ahl and converted to C by Chris Nystrom.
8  *   See http://www.cactus.org/%7Enystrom/startrek.html for more info.
9  *   There are still numerous errors present in the conversion from basic.
10  *   (eg, computing (int)(z1+0.5) makes no sense when z1 is already an integer)
11  *   Bug: When a new game is started new_game() is called, meaning the stack
12  *   continuously grows with each new game.
13  *
14  * - Replaced time() with a pause for keypress plus loop counter to get
15  *   entropy for initial seed.  On builds with the command line enabled
16  *   the initial seed is taken from an optional command line argument.
17  *
18  * - Changed double to double_t to eliminate compiler warnings.
19  *
20  * - K&R 'register' declaration changed to int.
21  *
22  * - Disable printf converters except %sdf
23  *
24  * - Used fflush(stdin) to clear input buffers prior to reading stdin
25  *   for more comfortable behaviour.
26  *
27  * - Instructions stored as text rather than loaded from disk.
28  */
29 
30 // zcc +cpm -vn -SO3 -clib=sdcc_iy --max-allocs-per-node200000 --opt-code-size startrek.c -o startrek -lm -create-app
31 // zcc +zx -vn -SO3 -startup=4 -clib=sdcc_iy --max-allocs-per-node200000 --opt-code-size startrek.c -o startrek -lm -create-app
32 
33 #pragma printf = "%s %d %f"
34 
35 #pragma output CLIB_MALLOC_HEAP_SIZE   = 0            // do not create malloc heap
36 #pragma output CLIB_STDIO_HEAP_SIZE    = 0            // do not create stdio heap (cannot open files)
37 #pragma output CLIB_EXIT_STACK_SIZE    = 0            // do not reserve space for registering atexit() functions
38 #pragma output CRT_ENABLE_COMMANDLINE  = 3            // create command line
39 
40 #ifdef __SPECTRUM
41 
42 #pragma output CRT_ORG_CODE            = 30000        // move ORG to 30000
43 #pragma output REGISTER_SP             = -1           // indicate crt should not modify stack location
44 #pragma output CRT_ENABLE_EIDI         = 0x01         // disable interrupts at start
45 
46 #endif
47 
48 /*
49  * startrek.c
50  *
51  * Super Star Trek Classic (v1.1)
52  * Retro Star Trek Game
53  * C Port Copyright (C) 1996  <Chris Nystrom>
54  *
55  * This program is free software; you can redistribute it and/or modify
56  * in any way that you wish. _Star Trek_ is a trademark of Paramount
57  * I think.
58  *
59  * This program is distributed in the hope that it will be useful,
60  * but WITHOUT ANY WARRANTY; without even the implied warranty of
61  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
62  *
63  * This is a C port of an old BASIC program: the classic Super Star Trek
64  * game. It comes from the book _BASIC Computer Games_ edited by David Ahl
65  * of Creative Computing fame. It was published in 1978 by Workman Publishing,
66  * 1 West 39 Street, New York, New York, and the ISBN is: 0-89489-052-3.
67  *
68  * See http://www.cactus.org/~nystrom/startrek.html for more info.
69  *
70  * Contact Author of C port at:
71  *
72  * Chris Nystrom
73  * 1013 Prairie Dove Circle
74  * Austin, Texas  78758
75  *
76  * E-Mail: cnystrom@gmail.com, nystrom@cactus.org
77  *
78  * BASIC -> Conversion Issues
79  *
80  *     - String Names changed from A$ to sA
81  *     - Arrays changed from G(8,8) to g[9][9] so indexes can
82  *       stay the same.
83  *
84  * Here is the original BASIC header:
85  *
86  * SUPER STARTREK - MAY 16, 1978 - REQUIRES 24K MEMORY
87  *
88  ***        **** STAR TREK ****        ****
89  *** SIMULATION OF A MISSION OF THE STARSHIP ENTERPRISE,
90  *** AS SEEN ON THE STAR TREK TV SHOW.
91  *** ORIGINAL PROGRAM BY MIKE MAYFIELD, MODIFIED VERSION
92  *** PUBLISHED IN DEC'S "101 BASIC GAMES", BY DAVE AHL.
93  *** MODIFICATIONS TO THE LATTER (PLUS DEBUGGING) BY BOB
94  *** LEEDOM - APRIL & DECEMBER 1974,
95  *** WITH A LITTLE HELP FROM HIS FRIENDS . . .
96  *** COMMENTS, EPITHETS, AND SUGGESTIONS SOLICITED --
97  *** SEND TO:  R. C. LEEDOM
98  ***           WESTINGHOUSE DEFENSE & ELECTRONICS SYSTEMS CNTR.
99  ***           BOX 746, M.S. 338
100  ***           BALTIMORE, MD  21203
101  ***
102  *** CONVERTED TO MICROSOFT 8 K BASIC 3/16/78 BY JOHN BORDERS
103  *** LINE NUMBERS FROM VERSION STREK7 OF 1/12/75 PRESERVED AS
104  *** MUCH AS POSSIBLE WHILE USING MULTIPLE STATMENTS PER LINE
105  *
106  */
107 
108 #include <stdio.h>
109 #include <stdlib.h>
110 #include <string.h>
111 #include <math.h>
112 #include <input.h>
113 // #include <time.h>
114 
115 #ifndef FALSE
116 #define FALSE        0
117 #endif
118 
119 #ifndef TRUE
120 #define TRUE         1
121 #endif
122 
123 /* Standard Line Length */
124 
125 #define MAXLEN     64
126 
127 /* Standard Terminal Sizes */
128 
129 #define MAXROW      24
130 #define MAXCOL      80
131 
132 /* Standard Page Size */
133 
134 #define MAXLINES    66
135 
136 /* Useful typedefs */
137 
138 typedef int bool;
139 typedef char line[MAXCOL];
140 typedef char string[MAXLEN];
141 
142 /* Function Declarations */
143 
144 void intro(void);
145 void new_game(void);
146 void initialize(void);
147 void new_quadrant(void);
148 void course_control(void);
149 void complete_maneuver(void);
150 void exceed_quadrant_limits(void);
151 void maneuver_energy(void);
152 void short_range_scan(void);
153 void long_range_scan(void);
154 void phaser_control(void);
155 void photon_torpedoes(void);
156 void torpedo_hit(void);
157 void damage_control(void);
158 void sheild_control(void);
159 void library_computer(void);
160 void galactic_record(void);
161 void status_report(void);
162 void torpedo_data(void);
163 void nav_data(void);
164 void dirdist_calc(void);
165 void galaxy_map(void);
166 void end_of_time(void);
167 void resign_commision(void);
168 void won_game(void);
169 void end_of_game(void);
170 void klingons_move(void);
171 void klingons_shoot(void);
172 void repair_damage(void);
173 void find_empty_place(void);
174 void insert_in_quadrant(void);
175 void get_device_name(void);
176 void string_compare(void);
177 void quadrant_name(void);
178 int function_d(int i);
179 int function_r(void);
180 void mid_str(char *a, char *b, int x, int y);
181 int cint(double_t d);
182 void compute_vector(void);
183 void sub1(void);
184 void sub2(void);
185 void showfile(char *filename);
186 int openfile(char * sFilename, char * sMode);
187 void closefile(void);
188 int getline_l(char *s);
189 int randomize(void);
190 int get_rand(int iSpread);
191 double_t rnd(void);
192 
193 /* Global Variables */
194 
195 int b3;                           /* Starbases in Quadrant */
196 int b4, b5;                 /* Starbase Location in sector */
197 int b9;                                 /* Total Starbases */
198 
199 /* @@@ int c[2][10] = */  /* Used for location and movement */
200 int c[3][10] = /* modified to match MS BASIC array indicies */
201    {
202      { 0 },
203      { 0, 0, -1, -1, -1,  0,  1, 1, 1, 0 },
204      { 1, 1,  1,  0, -1, -1, -1, 0, 1, 1 }
205    };
206 
207 int d0;                                     /* Docked flag */
208 int d1;                              /* Damage Repair Flag */
209 int e;                                   /* Current Energy */
210 int e0 = 3000;                          /* Starting Energy */
211 int g[9][9];                                     /* Galaxy */
212 int g5;                              /* Quadrant name flag */
213 int k[4][4];                               /* Klingon Data */
214 int k3;                            /* Klingons in Quadrant */
215 int k7;                               /* Klingons at start */
216 int k9;                             /* Total Klingons left */
217 int n;                       /* Number of secors to travel */
218 int p;                            /* Photon Torpedoes left */
219 int p0 = 10;                    /* Photon Torpedo capacity */
220 int q1, q2;             /* Quadrant Position of Enterprise */
221 int r1, r2;              /* Temporary Location Corrdinates */
222 int s;                             /* Current shield value */
223 int s3;                               /* Stars in quadrant */
224 int s8;                         /* Quadrant locating index */
225 int s9 = 200;                             /* Klingon Power */
226 int t0;                               /* Starting Stardate */
227 int t9;                                     /* End of time */
228 int z[9][9];                /* Cumulative Record of Galaxy */
229 int z3;                     /* string_compare return value */
230 int z1, z2;                /* Temporary Sector Coordinates */
231 int z4, z5;              /* Temporary quadrant coordinates */
232 
233 double_t a, c1;                   /* Used by Library Computer */
234 double_t d[9];                                /* Damage Array */
235 double_t d4;         /* Used for computing damage repair time */
236 double_t s1, s2;     /* Current Sector Position of Enterprise */
237 double_t t;                               /* Current Stardate */
238 double_t w1;                                   /* Warp Factor */
239 double_t x, y, x1, x2;            /* Navigational coordinates */
240 
241 char sA[4];                       /* An Object in a Sector */
242 char sC[7];                                   /* Condition */
243 char sQ[194];                /* Visual Display of Quadrant */
244 
245 string sG2;                 /* Used to pass string results */
246 
247 // FILE *stream;    /** Z88DK many targets without file io **/
248 bool bFlag = FALSE;         /* Prevent multiple file opens */
249 
250 void
reads(char * buffer)251 reads(char* buffer)
252 {
253   fflush(stdout);
254   fflush(stdin);
255 
256   if (fgets(buffer, MAXLEN, stdin) != 0) return;
257 
258   printf("\nEOF..bye!\n");
259   exit(-1);
260 }
261 
262 /* Main Program */
263 
264 int
main(int argc,char * argv[])265 main(int argc, char *argv[])
266 {
267   int tmp;
268 
269   intro();
270 
271   srand(tmp = (--argc) ? atoi(argv[1]) : randomize());
272   printf("Playing Game Number %d.\n\n", tmp);
273 
274   t = (get_rand(20) + 20) * 100;
275 
276   new_game();
277 
278   /* @@@ exit(0);  */ /* causes a warning in C++ */
279   return(0);
280 }
281 
282 void
intro(void)283 intro(void)
284 {
285   string sTemp;
286 
287   printf ("\n\n");
288   printf (" *************************************\n");
289   printf (" *                                   *\n");
290   printf (" *                                   *\n");
291   printf (" *      * * Super Star Trek * *      *\n");
292   printf (" *                                   *\n");
293   printf (" *                                   *\n");
294   printf (" *************************************\n\n\n\n\n");
295 
296   printf("\nDo you need instructions (y/n): ");
297 
298   reads(sTemp);
299 
300   if (sTemp[0] == 'y' || sTemp[0] == 'Y')
301     showfile("startrek.doc");
302 
303   printf ("\n\n\n\n");
304   printf("                         ------*------\n");
305   printf("         -------------   `---  ------'\n");
306   printf("         `-------- --'      / /\n");
307   printf("                  \\\\-------  --\n");
308   printf("                  '-----------'\n");
309   printf("\n       The USS Enterprise --- NCC - 1701\n\n\n");
310 }
311 
312 void
new_game(void)313 new_game(void)
314 {
315   string sTemp;
316 
317   initialize();
318 
319   new_quadrant();
320 
321   short_range_scan();
322 
323   while(1)
324     {
325       if (s + e <= 10 && (e < 10 || d[7] < 0))
326         {
327           printf("\n** Fatal Error **   ");
328           printf("You've just stranded your ship in space.\n\n");
329           printf("You have insufficient maneuvering energy,");
330           printf(" and Shield Control is presently\n");
331           printf("incapable of cross circuiting to engine room!!\n\n");
332           end_of_time();
333         }
334 
335       printf("Command? ");
336 
337       reads(sTemp);
338       printf("\n");
339 
340       if (! strncmp(sTemp, "nav", 3))
341         course_control();
342       else if (! strncmp(sTemp, "srs", 3))
343         short_range_scan();
344       else if (! strncmp(sTemp, "lrs", 3))
345         long_range_scan();
346       else if (! strncmp(sTemp, "pha", 3))
347         phaser_control();
348       else if (! strncmp(sTemp, "tor", 3))
349         photon_torpedoes();
350       else if (! strncmp(sTemp, "she", 3))
351         sheild_control();
352       else if (! strncmp(sTemp, "dam", 3))
353         damage_control();
354       else if (! strncmp(sTemp, "com", 3))
355         library_computer();
356       else if (! strncmp(sTemp, "xxx", 3))
357         resign_commision();
358       else
359     {
360           printf("Enter one of the following:\n\n");
361       printf("  nav - To Set Course\n");
362       printf("  srs - Short Range Sensors\n");
363       printf("  lrs - Long Range Sensors\n");
364       printf("  pha - Phasers\n");
365       printf("  tor - Photon Torpedoes\n");
366       printf("  she - Sheild Control\n");
367       printf("  dam - Damage Control\n");
368       printf("  com - Library Computer\n");
369       printf("  xxx - Resign Command\n");
370       printf("\n");
371     }
372     }
373 }
374 
375 void
initialize(void)376 initialize(void)
377 {
378   int i, j;
379   char sX[2] = "";
380   char sX0[4] = "is";
381 
382   /* InItialize time */
383 
384   /* @@@ t0 = t; */
385   t0 = (int)t;
386   t9 = 25 + get_rand(10);
387 
388   /* Initialize Enterprise */
389 
390   d0 = 0;
391   e = e0;
392   p = p0;
393   s = 0;
394 
395   q1 = function_r();
396   q2 = function_r();
397   s1 = (double_t) function_r();
398   s2 = (double_t) function_r();
399 
400   for (i = 1; i <= 8; i++)
401     d[i] = 0.0;
402 
403   /* Setup What Exists in Galaxy */
404 
405   for (i = 1; i <= 8; i++)
406     for (j = 1; j <= 8; j++)
407       {
408         k3 = 0;
409         z[i][j] = 0;
410         r1 = get_rand(100);
411         if (r1 > 98)
412           k3 = 3;
413         else if (r1 > 95)
414           k3 = 2;
415         else if (r1 > 80)
416           k3 = 1;
417 
418         k9 = k9 + k3;
419         b3 = 0;
420 
421         if (get_rand(100) > 96)
422           b3 = 1;
423 
424         b9 = b9 + b3;
425 
426         g[i][j] = k3 * 100 + b3 * 10 + function_r();
427       }
428 
429   if (k9 > t9)
430     t9 = k9 + 1;
431 
432   if (b9 == 0)
433     {
434       if (g[q1][q2] < 200)
435         {
436           g[q1][q2] = g[q1][q2] + 100;
437           k9++;
438         }
439 
440       g[q1][q2] = g[q1][q2] + 10;
441       b9++;
442 
443       q1 = function_r();
444       q2 = function_r();
445     }
446 
447   k7 = k9;
448 
449   if (b9 != 1)
450     {
451       strcpy(sX, "s");
452       strcpy(sX0, "are");
453     }
454 
455   printf("Your orders are as follows:\n\n");
456   printf("   Destroy the %d Klingon warships which have invaded\n", k9);
457   printf(" the galaxy before they can attack Federation Headquarters\n");
458   printf(" on stardate %d. This gives you %d days. There %s\n",
459     t0 + t9, t9, sX0);
460   printf(" %d starbase%s in the galaxy for resupplying your ship.\n\n",
461     b9, sX);
462 
463   printf("Hit any key to accept command. ");
464   fflush(stdin);   /** Z88DK **/
465   getchar();
466 }
467 
468 void
new_quadrant(void)469 new_quadrant(void)
470 {
471   int i;
472 
473   z4 = q1;
474   z5 = q2;
475   k3 = 0;
476   b3 = 0;
477   s3 = 0;
478   g5 = 0;
479   d4 = (double_t) get_rand(100) / 100 / 50;
480   z[q1][q2] = g[q1][q2];
481 
482   if (q1 >= 1 && q1 <= 8 && q2 >= 1 && q2 <= 8)
483     {
484       quadrant_name();
485 
486       if (t0 != t)
487         printf("Now entering %s quadrant...\n\n", sG2);
488       else
489         {
490           printf("\nYour mission begins with your starship located\n");
491           printf("in the galactic quadrant %s.\n\n", sG2);
492         }
493     }
494 
495   /* @@@ k3 = g[q1][q2] * .01; */
496   k3 = (int)(g[q1][q2] * .01);
497   /* @@@ b3 = g[q1][q2] * .1 - 10 * k3; */
498   b3 = (int)(g[q1][q2] * .1 - 10 * k3);
499   s3 = g[q1][q2] - 100 * k3 - 10 * b3;
500 
501   if (k3 > 0)
502     {
503       printf("Combat Area  Condition Red\n");
504 
505       if (s < 200)
506         printf("Shields Dangerously Low\n");
507     }
508 
509   for (i = 1; i <= 3; i++)
510     {
511       k[i][1] = 0;
512       k[i][2] = 0;
513       k[i][3] = 0;
514     }
515 
516   for (i = 0; i <= 192; i++)
517     sQ[i] = ' ';
518 
519   sQ[193] = '\0';
520 
521   /* Position Enterprise, then Klingons, Starbases, and stars */
522 
523   strcpy(sA, "<*>");
524   /* @@@ z1 = cint(s1); */
525   z1 = (int)s1;
526   /* @@@ z2 = cint(s2); */
527   z2 = (int)s2;
528   insert_in_quadrant();
529 
530   if (k3 > 0)
531     {
532       for (i = 1; i <= k3; i++)
533         {
534           find_empty_place();
535 
536           strcpy(sA, "+K+");
537           z1 = r1;
538           z2 = r2;
539           insert_in_quadrant();
540 
541           k[i][1] = r1;
542           k[i][2] = r2;
543           k[i][3] = 100 + get_rand(200);
544         }
545     }
546 
547   if (b3 > 0)
548     {
549       find_empty_place();
550 
551       strcpy(sA, ">!<");
552       z1 = r1;
553       z2 = r2;
554       insert_in_quadrant();
555 
556       b4 = r1;
557       b5 = r2;
558     }
559 
560   for (i = 1; i <= s3; i++)
561     {
562       find_empty_place();
563 
564       strcpy(sA, " * ");
565       z1 = r1;
566       z2 = r2;
567       insert_in_quadrant();
568     }
569 }
570 
571 void
course_control(void)572 course_control(void)
573 {
574   int i;
575   /* @@@ int c2, c3, q4, q5; */
576   int q4, q5;
577   string sTemp;
578   double_t c1;
579   char sX[4] = "8";
580 
581   printf("Course (0-9): ");
582 
583   reads(sTemp);
584 
585   printf("\n");
586 
587   c1 = atof(sTemp);
588 
589   if (c1 == 9.0)
590     c1 = 1.0;
591 
592   if (c1 < 0 || c1 > 9.0)
593     {
594       printf("Lt. Sulu roports:\n");
595       printf("  Incorrect course data, sir!\n\n");
596       return;
597     }
598 
599   if (d[1] < 0.0)
600     strcpy(sX, "0.2");
601 
602   printf("Warp Factor (0-%s): ", sX);
603 
604   reads(sTemp);
605 
606   printf("\n");
607 
608   w1 = atof(sTemp);
609 
610   if (d[1] < 0.0 && w1 > 0.21)
611     {
612       printf("Warp Engines are damaged. ");
613       printf("Maximum speed = Warp 0.2.\n\n");
614       return;
615     }
616 
617   if (w1 <= 0.0)
618     return;
619 
620   if (w1 > 8.1)
621     {
622       printf("Chief Engineer Scott reports:\n");
623       printf("  The engines won't take warp %4.1f!\n\n", w1);
624       return;
625     }
626 
627   n = cint(w1 * 8.0); /* @@@ note: this is a real round in the original basic */
628 
629   if (e - n < 0)
630     {
631       printf("Engineering reports:\n");
632       printf("  Insufficient energy available for maneuvering");
633       printf(" at warp %4.1f!\n\n", w1);
634 
635       if (s >= n && d[7] >= 0.0)
636         {
637           printf("Deflector Control Room acknowledges:\n");
638           printf("  %d units of energy presently deployed to shields.\n", s);
639         }
640 
641       return;
642     }
643 
644   klingons_move();
645 
646   repair_damage();
647 
648   strcpy(sA, "   ");
649   /* @@@ z1 = cint(s1); */
650   z1 = (int)s1;
651   /* @@@ z2 = cint(s2); */
652   z2 = (int)s2;
653   insert_in_quadrant();
654 
655   /* @@@ c2 = cint(c1); */
656   /* @@@ c3 = c2 + 1; */
657 
658   /* @@@ x1 = c[0][c2] + (c[0][c3] - c[0][c2]) * (c1 - c2); */
659   /* @@@ x2 = c[1][c2] + (c[1][c3] - c[1][c2]) * (c1 - c2); */
660 
661   x1 = c[1][(int)c1] + (c[1][(int)c1 + 1] - c[1][(int)c1]) * (c1 - (int)c1);
662   x2 = c[2][(int)c1] + (c[2][(int)c1 + 1] - c[2][(int)c1]) * (c1 - (int)c1);
663 
664   x = s1;
665   y = s2;
666   q4 = q1;
667   q5 = q2;
668 
669   for (i = 1; i <= n; i++)
670     {
671       s1 = s1 + x1;
672       s2 = s2 + x2;
673 
674       /* @@@ z1 = cint(s1); */
675       z1 = (int)s1;
676       /* @@@ z2 = cint(s2); */
677       z2 = (int)s2;
678 
679       if (z1 < 1 || z1 >= 9 || z2 < 1 || z2 >= 9)
680         {
681           exceed_quadrant_limits();
682           complete_maneuver();
683           return;
684         }
685 
686       string_compare();
687 
688       if (z3 != 1) /* Sector not empty */
689         {
690           s1 = s1 - x1;
691           s2 = s2 - x2;
692           printf("Warp Engines shut down at sector ");
693           printf("%d, %d due to bad navigation.\n\n", z1, z2);
694           i = n + 1;
695         }
696     }
697 
698   complete_maneuver();
699 }
700 
701 void
complete_maneuver(void)702 complete_maneuver(void)
703 {
704   double_t t8;
705 
706   strcpy(sA, "<*>");
707   /* @@@ z1 = cint(s1); */
708   z1 = (int)s1;
709   /* @@@ z2 = cint(s2); */
710   z2 = (int)s2;
711   insert_in_quadrant();
712 
713   maneuver_energy();
714 
715   t8 = 1.0;
716 
717   if (w1 < 1.0)
718     t8 = w1;
719 
720   t = t + t8;
721 
722   if (t > t0 + t9)
723     end_of_time();
724 
725   short_range_scan();
726 }
727 
728 void
exceed_quadrant_limits(void)729 exceed_quadrant_limits(void)
730 {
731   int x5 = 0;   /* Outside galaxy flag */
732 
733   /* @@@ x = (8 * (q1 - 1)) + x + (n * x1); */
734   x = (8 * q1) + x + (n * x1);
735   /* @@@ y = (8 * (q2 - 1)) + y + (n * x2); */
736   y = (8 * q2) + y + (n * x2);
737 
738   /* @@@ q1 = cint(x / 8.0); */
739   q1 = (int)(x / 8.0);
740   /* @@@ q2 = cint(y / 8.0); */
741   q2 = (int)(y / 8.0);
742 
743   /* @@@ s1 = x - ((q1 - 1) * 8); */
744   s1 = x - (q1 * 8);
745   /* @@@ s2 = y - ((q2 - 1) * 8); */
746   s2 = y - (q2 * 8);
747 
748   /* @@@ if (cint(s1) == 0) */
749   if ((int)s1 == 0)
750     {
751       q1 = q1 - 1;
752       s1 = s1 + 8.0;
753     }
754 
755   /* @@@ if (cint(s2) == 0) */
756   if ((int)s2 == 0)
757     {
758       q2 = q2 - 1;
759       s2 = s2 + 8.0;
760     }
761 
762   /* check if outside galaxy */
763 
764   if (q1 < 1)
765     {
766       x5 = 1;
767       q1 = 1;
768       s1 = 1.0;
769     }
770 
771   if (q1 > 8)
772     {
773       x5 = 1;
774       q1 = 8;
775       s1 = 8.0;
776     }
777 
778   if (q2 < 1)
779     {
780       x5 = 1;
781       q2 = 1;
782       s2 = 1.0;
783     }
784 
785   if (q2 > 8)
786     {
787       x5 = 1;
788       q2 = 8;
789       s2 = 8.0;
790     }
791 
792   if (x5 == 1)
793     {
794       printf("LT. Uhura reports:\n");
795       printf("  Message from Starfleet Command:\n\n");
796       printf("  Permission to attempt crossing of galactic perimeter\n");
797       printf("  is hereby *denied*. Shut down your engines.\n\n");
798       printf("Chief Engineer Scott reports:\n");
799       /* @@@ printf("  Warp Engines shut down at sector %d, ", cint(s1)); */
800       printf("  Warp Engines shut down at sector %d, ", (int)s1);
801       /* @@@ printf("%d of quadrant %d, %d.\n\n", cint(s2), q1, q2); */
802       printf("%d of quadrant %d, %d.\n\n", (int)s2, q1, q2);
803     }
804   /* else
805      new_quadrant(); @@@ this causes bugs when bouncing off galaxy walls.
806                          basically, if you bounce very far, your quadrant contents
807                          won't match your LRS.  Cool huh? */
808 
809 
810   maneuver_energy();
811 
812   /* this section has a different order in the original.
813   t = t + 1;
814 
815   if (t > t0 + t9)
816     end_of_time();
817   */
818 
819   if (t > t0 + t9)
820     end_of_time();
821 
822   /* @@@ what does this do?? It's in the original.
823   if (8 * q1 + q2 = 8 * q4 + q5)
824     {
825       complete_maneuver();
826     }
827   */
828 
829   t = t + 1;
830 
831   new_quadrant();
832 }
833 
834 void
maneuver_energy(void)835 maneuver_energy(void)
836 {
837   e = e - n - 10;
838 
839   if (e >= 0)
840     return;
841 
842   printf("Shield Control supplies energy to complete maneuver.\n\n");
843 
844   s = s + e;
845   e = 0;
846 
847   if (s <= 0)
848     s = 0;
849 }
850 
851 void
short_range_scan(void)852 short_range_scan(void)
853 {
854   int i, j;
855 
856   strcpy(sC, "GREEN");
857 
858   if (e < e0 * .1)
859     strcpy(sC, "YELLOW");
860 
861   if (k3 > 0)
862     strcpy(sC, "*RED*");
863 
864   /* @@@ need to clear the docked flag here */
865   d0 = 0;
866 
867   /* @@@ for (i = s1 - 1; i <= s1 + 1; i++) */
868   for (i = (int)(s1 - 1); i <= (int)(s1 + 1); i++)
869     /* @@@ for (j = s2 - 1; j <= s2 + 1; j++) */
870     for (j = (int)(s2 - 1); j <= (int)(s2 + 1); j++)
871       if (i >= 1 && i <= 8 && j >= 1 && j <= 8)
872         {
873           strcpy(sA, ">!<");
874           z1 = i;
875           z2 = j;
876           string_compare();
877           if (z3 == 1)
878             {
879               d0 = 1;
880               strcpy(sC, "DOCKED");
881               e = e0;
882               p = p0;
883               printf("Shields dropped for docking purposes.\n");
884               s = 0;
885             }
886         }
887 
888   if (d[2] < 0.0)
889     {
890       printf("\n*** Short Range Sensors are out ***\n");
891       return;
892     }
893 
894   printf("------------------------\n");
895   for (i = 0; i < 8; i++)
896     {
897       for (j = 0; j < 24; j++)
898         putchar(sQ[i * 24 + j]);
899 
900       if (i == 0)
901     printf("    Stardate            %d\n", (int) t);
902       if (i == 1)
903     printf("    Condition           %s\n", sC);
904       if (i == 2)
905     printf("    Quadrant            %d, %d\n", q1, q2);
906       if (i == 3)
907     /* @@@ printf("    Sector              %d, %d\n", cint(s1), cint(s2)); */
908     printf("    Sector              %d, %d\n", (int)s1, (int)s2);
909       if (i == 4)
910     printf("    Photon Torpedoes    %d\n", p);
911       if (i == 5)
912     printf("    Total Energy        %d\n", e + s);
913       if (i == 6)
914     printf("    Shields             %d\n", s);
915       if (i == 7)
916     printf("    Klingons Remaining  %d\n", k9);
917     }
918   printf("------------------------\n\n");
919 
920   return;
921 }
922 
923 void
long_range_scan(void)924 long_range_scan(void)
925 {
926   int i, j;
927 
928   if (d[3] < 0.0)
929     {
930       printf("Long Range Sensors are inoperable.\n");
931       return;
932     }
933 
934   printf("Long Range Scan for Quadrant %d, %d\n\n", q1, q2);
935 
936   for (i = q1 - 1; i <= q1 + 1; i++)
937     {
938       printf("--------------------\n:");
939       for (j = q2 - 1; j <= q2 + 1; j++)
940         if (i > 0 && i <= 8 && j > 0 && j <= 8)
941           {
942             z[i][j] = g[i][j];
943             printf(" %3.3d :", z[i][j]);
944           }
945         else
946           printf(" *** :");
947       printf("\n");
948     }
949 
950     printf("--------------------\n\n");
951 }
952 
953 void
phaser_control(void)954 phaser_control(void)
955 {
956   int i;
957   int iEnergy;
958   int h1, h;
959   string sTemp;
960 
961   if (d[4] < 0.0)
962     {
963       printf("Phasers Inoperative\n\n");
964       return;
965     }
966 
967   if (k3 <= 0)
968     {
969       printf("Science Officer Spock reports:\n");
970       printf("  'Sensors show no enemy ships in this quadrant'\n\n");
971       return;
972     }
973 
974   if (d[8] < 0.0)
975     /* @@@ printf("Computer failure happers accuracy.\n"); */
976     printf("Computer failure hampers accuracy.\n");
977 
978   printf("Phasers locked on target;\n");
979   printf("Energy available = %d units\n\n", e);
980 
981   printf("Number of units to fire: ");
982 
983   reads(sTemp);
984 
985   printf("\n");
986 
987   iEnergy = atoi(sTemp);
988 
989   if (iEnergy <= 0)
990     return;
991 
992   if (e - iEnergy < 0)
993     {
994       printf("Not enough energy available.\n\n");
995       return;
996     }
997 
998   e = e - iEnergy;
999 
1000   if (d[8] < 0.0)
1001     /* @@@ iEnergy = iEnergy * rnd(); */
1002     iEnergy = (int)(iEnergy * rnd());
1003 
1004   h1 = iEnergy / k3;
1005 
1006   for (i = 1; i <= 3; i++)
1007     {
1008       if (k[i][3] > 0)
1009         {
1010           /* @@@ h = (h1 / function_d(0) * (rnd() + 2)); */
1011 
1012           h = (int)(h1 / function_d(0) * (rnd() + 2));
1013 
1014           if (h <= .15 * k[i][3])
1015             {
1016               printf("Sensors show no damage to enemy at ");
1017               printf("%d, %d\n\n", k[i][1], k[i][2]);
1018             }
1019           else
1020             {
1021               k[i][3] = k[i][3] - h;
1022               printf("%d unit hit on Klingon at sector ", h);
1023               printf("%d, %d\n", k[i][1], k[i][2]);
1024               if (k[i][3] <= 0)
1025                 {
1026                   printf("*** Klingon Destroyed ***\n\n");
1027                   k3--;
1028                   k9--;
1029                   z1 = k[i][1];
1030                   z2 = k[i][2];
1031                   strcpy(sA, "   ");
1032                   insert_in_quadrant();
1033                   k[i][3] = 0;
1034                   g[q1][q2] = g[q1][q2] - 100;
1035                   z[q1][q2] = g[q1][q2];
1036                   if (k9 <= 0)
1037                     won_game();
1038                 }
1039               else
1040                 /* @@@ printf("\n"); */
1041                 printf("   (Sensors show %d units remaining.)\n\n", k[i][3]);
1042             }
1043         }
1044     }
1045 
1046   klingons_shoot();
1047 }
1048 
1049 void
photon_torpedoes(void)1050 photon_torpedoes(void)
1051 {
1052   /* @@@ int c2, c3, x3, y3, x5; */
1053   int x3, y3, x5;
1054   string sTemp;
1055   double_t c1;
1056 
1057   if (p <= 0)
1058     {
1059       printf("All photon torpedoes expended\n");
1060       return;
1061     }
1062 
1063   if (d[5] < 0.0)
1064     {
1065       printf("Photon Tubes not operational\n");
1066       return;
1067     }
1068 
1069   printf("Course (0-9): ");
1070 
1071   reads(sTemp);
1072 
1073   printf("\n");
1074 
1075   c1 = atof(sTemp);
1076 
1077   if (c1 == 9.0)
1078     c1 = 1.0;
1079 
1080   /* @@@ if (c1 < 0 || c1 > 9.0) */
1081   if (c1 < 1.0 || c1 > 9.0)
1082     {
1083       printf("Ensign Chekov roports:\n");
1084       printf("  Incorrect course data, sir!\n\n");
1085       return;
1086     }
1087 
1088   e = e - 2;
1089   p--;
1090 
1091   /* @@@ c2 = cint(c1); */
1092   /* @@@ c3 = c2 + 1; */
1093 
1094   /* @@@ x1 = c[0][c2] + (c[0][c3] - c[0][c2]) * (c1 - c2); */
1095   /* @@@ x2 = c[1][c2] + (c[1][c3] - c[1][c2]) * (c1 - c2); */
1096 
1097   x1 = c[1][(int)c1] + (c[1][(int)c1 + 1] - c[1][(int)c1]) * (c1 - (int)c1);
1098   x2 = c[2][(int)c1] + (c[2][(int)c1 + 1] - c[2][(int)c1]) * (c1 - (int)c1);
1099 
1100   x = s1 + x1;
1101   y = s2 + x2;
1102 
1103   x3 = cint(x); /* @@@ note: this is a true integer round in the MS BASIC version */
1104   y3 = cint(y); /* @@@ note: this is a true integer round in the MS BASIC version */
1105 
1106   x5 = 0;
1107 
1108   printf("Torpedo Track:\n");
1109 
1110   while (x3 >= 1 && x3 <= 8 && y3 >= 1 && y3 <= 8)
1111     {
1112       printf("    %d, %d\n", x3, y3);
1113 
1114       strcpy(sA, "   ");
1115       z1 = x3;
1116       z2 = y3;
1117 
1118       string_compare();
1119 
1120       if (z3 == 0)
1121         {
1122           torpedo_hit();
1123           klingons_shoot();
1124           return;
1125         }
1126 
1127       x = x + x1;
1128       y = y + x2;
1129 
1130       x3 = cint(x); /* @@@ note: this is a true integer round in the MS BASIC version */
1131       y3 = cint(y); /* @@@ note: this is a true integer round in the MS BASIC version */
1132     }
1133 
1134   printf("Torpedo Missed\n\n");
1135 
1136   klingons_shoot();
1137 }
1138 
1139 void
torpedo_hit(void)1140 torpedo_hit(void)
1141 {
1142   int i, x3, y3;
1143 
1144   x3 = cint(x); /* @@@ note: this is a true integer round in the MS BASIC version */
1145   y3 = cint(y); /* @@@ note: this is a true integer round in the MS BASIC version */
1146 
1147   z3 = 0;
1148 
1149   strcpy(sA, " * ");
1150   string_compare();
1151 
1152   if (z3 == 1)
1153     {
1154       printf("Star at %d, %d absorbed torpedo energy.\n\n", x3, y3);
1155       return;
1156     }
1157 
1158   strcpy(sA, "+K+");
1159   string_compare();
1160 
1161   if (z3 == 1)
1162     {
1163       printf("*** Klingon Destroyed ***\n\n");
1164       k3--;
1165       k9--;
1166 
1167       if (k9 <= 0)
1168         won_game();
1169 
1170       for (i=0; i<=3; i++)
1171         if (x3 == k[i][1] && y3 == k[i][2])
1172           k[i][3] = 0;
1173     }
1174 
1175   strcpy(sA, ">!<");
1176   string_compare();
1177 
1178   if (z3 == 1)
1179     {
1180       printf("*** Starbase Destroyed ***\n");
1181       b3--;
1182       b9--;
1183 
1184       if (b9 <= 0 && k9 <= t - t0 - t9)
1185         {
1186           printf("That does it, Captain!!");
1187           printf("You are hereby relieved of command\n");
1188           printf("and sentanced to 99 stardates of hard");
1189           printf("labor on Cygnus 12!!\n");
1190           resign_commision();
1191         }
1192 
1193       printf("Starfleet Command reviewing your record to consider\n");
1194       printf("court martial!\n\n");
1195 
1196       d0 = 0;    /* Undock */
1197     }
1198 
1199   z1 = x3;
1200   z2 = y3;
1201   strcpy(sA,"   ");
1202   insert_in_quadrant();
1203 
1204   g[q1][q2] = (k3 * 100) + (b3 * 10) + s3;
1205   z[q1][q2] = g[q1][q2];
1206 }
1207 
1208 void
damage_control(void)1209 damage_control(void)
1210 {
1211   int a1;
1212   double_t d3 = 0.0;
1213   int i;
1214 
1215   if (d[6] < 0.0)
1216     {
1217       printf("Damage Control report not available.\n");
1218 
1219       if (d0 == 0)
1220         return;
1221 
1222       d3 = 0.0;
1223       for (i = 1; i <= 8; i++)
1224         if (d[i] < 0.0)
1225           d3 = d3 + .1;
1226 
1227       if (d3 == 0.0)
1228         return;
1229 
1230       d3 = d3 + d4;
1231       if (d3 >= 1.0)
1232         d3 = 0.9;
1233 
1234       printf("\nTechnicians standing by to effect repairs to your");
1235       /* @@@ printf("ship; Will you authorize the repair order (Y/N)? "); */
1236       printf("ship;\nEstimated time to repair: %4.2f stardates.\n", d3);
1237       printf("Will you authorize the repair order (Y/N)? ");
1238 
1239       a1 = getchar();
1240 
1241       if (a1 == 'Y' || a1 == 'y')
1242         {
1243           for (i = 1; i <= 8; i++)
1244             if (d[i] < 0.0)
1245               d[i] = 0.0;
1246 
1247           t = t + d3 + 0.1;
1248         }
1249     }
1250 
1251   printf("Device            State of Repair\n");
1252 
1253   for (r1 = 1; r1 <= 8; r1++)
1254     {
1255       get_device_name();
1256       printf(sG2);
1257       /* @@@ for (i = 1; i < 25 - strlen(sG2); i++) */
1258       for (i = 1; i < 25 - (int)strlen(sG2); i++)
1259       printf(" ");
1260       /* @@@ printf("%4.1f\n", d[r1]); */
1261       printf("%4.2f\n", d[r1]);
1262     }
1263 
1264   printf("\n");
1265 }
1266 
1267 void
sheild_control(void)1268 sheild_control(void)
1269 {
1270   int i;
1271   string sTemp;
1272 
1273   if (d[7] < 0.0)
1274     {
1275       printf("Sheild Control inoperable\n");
1276       return;
1277     }
1278 
1279   printf("Energy available = %d\n\n", e + s);
1280 
1281   printf("Input number of units to shields: ");
1282 
1283   reads(sTemp);
1284 
1285   printf("\n");
1286 
1287   i = atoi(sTemp);
1288 
1289   if (i < 0 || s == i)
1290     {
1291       printf("<Sheilds Unchanged>\n\n");
1292       return;
1293     }
1294 
1295   if (i >= e + s)
1296     {
1297       printf("Sheild Control Reports:\n");
1298       printf("  'This is not the Federation Treasury.'\n");
1299       printf("<Sheilds Unchanged>\n\n");
1300       return;
1301     }
1302 
1303   e = e + s - i;
1304   s = i;
1305 
1306   printf("Deflector Control Room report:\n");
1307   printf("  'Shields now at %d units per your command.'\n\n", s);
1308 }
1309 
1310 void
library_computer(void)1311 library_computer(void)
1312 {
1313   string sTemp;
1314 
1315   if (d[8] < 0.0)
1316     {
1317       printf("Library Computer inoperable\n");
1318       return;
1319     }
1320 
1321   printf("Computer active and awaiting command: ");
1322 
1323   reads(sTemp);
1324   printf("\n");
1325 
1326   if (! strncmp(sTemp, "0", 1))
1327     galactic_record();
1328   else if (! strncmp(sTemp, "1", 1))
1329     status_report();
1330   else if (! strncmp(sTemp, "2", 1))
1331     torpedo_data();
1332   else if (! strncmp(sTemp, "3", 1))
1333     nav_data();
1334   else if (! strncmp(sTemp, "4", 1))
1335     dirdist_calc();
1336   else if (! strncmp(sTemp, "5", 1))
1337     galaxy_map();
1338   else
1339     {
1340       printf("Functions available from Library-Computer:\n\n");
1341       printf("   0 = Cumulative Galactic Record\n");
1342       printf("   1 = Status Report\n");
1343       printf("   2 = Photon Torpedo Data\n");
1344       printf("   3 = Starbase Nav Data\n");
1345       printf("   4 = Direction/Distance Calculator\n");
1346       printf("   5 = Galaxy 'Region Name' Map\n\n");
1347     }
1348 }
1349 
1350 void
galactic_record(void)1351 galactic_record(void)
1352 {
1353   int i, j;
1354 
1355   printf("\n     Computer Record of Galaxy for Quadrant %d,%d\n\n", q1, q2);
1356   printf("     1     2     3     4     5     6     7     8\n");
1357 
1358   for (i = 1; i <= 8; i++)
1359   {
1360     printf("   ----- ----- ----- ----- ----- ----- ----- -----\n");
1361 
1362     printf("%d", i);
1363 
1364     for (j = 1; j <= 8; j++)
1365     {
1366       printf("   ");
1367 
1368       if (z[i][j] == 0)
1369         printf("***");
1370       else
1371         printf("%3.3d", z[i][j]);
1372     }
1373 
1374     printf("\n");
1375   }
1376 
1377   printf("   ----- ----- ----- ----- ----- ----- ----- -----\n\n");
1378 }
1379 
1380 void
status_report(void)1381 status_report(void)
1382 {
1383   char sX[2] = "";
1384 
1385   printf("   Status Report:\n\n");
1386 
1387   if (k9 > 1)
1388     strcpy(sX, "s");
1389 
1390   printf("Klingon%s Left: %d\n", sX, k9);
1391 
1392   printf("Mission must be completed in %4.1f stardates\n",
1393     /* @@@ .1 * cint((t0 + t9 - t) * 10)); */
1394     .1 * (int)((t0 + t9 - t) * 10));
1395 
1396   if (b9 < 1)
1397   {
1398     printf("Your stupidity has left you on your own in the galaxy\n");
1399     printf(" -- you have no starbases left!\n");
1400   }
1401   else
1402   {
1403     strcpy(sX, "s");
1404     if (b9 < 2)
1405       strcpy(sX, "");
1406 
1407     printf("The Federation is maintaining %d starbase%s in the galaxy\n",
1408       b9, sX);
1409   }
1410 
1411   printf("\n");
1412 }
1413 
1414 void
torpedo_data(void)1415 torpedo_data(void)
1416 {
1417   int i;
1418   char sX[2] = "";
1419 
1420   if (k3 <= 0)
1421   {
1422     printf("Science Officer Spock reports:\n");
1423     printf("  'Sensors show no enemy ships in this quadrant.'\n\n");
1424     return;
1425   }
1426 
1427   if (k3 > 1)
1428     strcpy(sX, "s");
1429 
1430   printf("From Enterprise to Klingon battlecriuser%s:\n\n", sX);
1431 
1432   for (i = 1; i <= 3; i++)
1433   {
1434     if (k[i][3] > 0)
1435     {
1436       w1 = k[i][1];
1437       x  = k[i][2];
1438       c1 = s1;
1439       a  = s2;
1440 
1441       compute_vector();
1442     }
1443   }
1444 }
1445 
1446 void
nav_data(void)1447 nav_data(void)
1448 {
1449   if (b3 <= 0)
1450   {
1451     printf("Mr. Spock reports,\n");
1452     printf("  'Sensors show no starbases in this quadrant.'\n\n");
1453     return;
1454   }
1455 
1456   w1 = b4;
1457   x  = b5;
1458   c1 = s1;
1459   a  = s2;
1460 
1461   compute_vector();
1462 }
1463 
1464 void
dirdist_calc(void)1465 dirdist_calc(void)
1466 {
1467   string sTemp;
1468 
1469   printf("Direction/Distance Calculator\n\n");
1470   printf("You are at quadrant %d,%d sector %d,%d\n\n", q1, q2,
1471     /* @@@ cint(s1), cint(s2)); */
1472     (int)s1, (int)s2);
1473 
1474   printf("Please enter initial X coordinate: ");
1475   reads(sTemp);
1476   c1 = atoi(sTemp);
1477 
1478   printf("Please enter initial Y coordinate: ");
1479   reads(sTemp);
1480   a = atoi(sTemp);
1481 
1482   printf("Please enter final X coordinate: ");
1483   reads(sTemp);
1484   w1 = atoi(sTemp);
1485 
1486   printf("Please enter final Y coordinate: ");
1487   reads(sTemp);
1488   x = atoi(sTemp);
1489 
1490   compute_vector();
1491 }
1492 
1493 void
galaxy_map(void)1494 galaxy_map(void)
1495 {
1496   int i, j, j0;
1497 
1498   g5 = 1;
1499 
1500   printf("\n                   The Galaxy\n\n");
1501   printf("    1     2     3     4     5     6     7     8\n");
1502 
1503   for (i = 1; i <= 8; i++)
1504   {
1505     printf("  ----- ----- ----- ----- ----- ----- ----- -----\n");
1506 
1507     printf("%d ", i);
1508 
1509     z4 = i;
1510     z5 = 1;
1511     quadrant_name();
1512 
1513     j0 = (int)(11 - (strlen(sG2) / 2));
1514 
1515     for (j = 0; j < j0; j++)
1516       printf(" ");
1517 
1518     printf(sG2);
1519 
1520     for (j = 0; j < j0; j++)
1521       printf(" ");
1522 
1523     if (! (strlen(sG2) % 2))
1524       printf(" ");
1525 
1526     z5 = 5;
1527     quadrant_name();
1528 
1529     j0 = (int)(12 - (strlen(sG2) / 2));
1530 
1531     for (j = 0; j < j0; j++)
1532       printf(" ");
1533 
1534     printf(sG2);
1535 
1536     printf("\n");
1537   }
1538 
1539   printf("  ----- ----- ----- ----- ----- ----- ----- -----\n\n");
1540 
1541 }
1542 
1543 void
compute_vector(void)1544 compute_vector(void)
1545 {
1546   x = x - a;
1547   a = c1 - w1;
1548 
1549   if (x <= 0.0)
1550   {
1551     if (a > 0.0)
1552     {
1553       c1 = 3.0;
1554       sub2();
1555       return;
1556     }
1557     else
1558     {
1559       c1 = 5.0;
1560       sub1();
1561       return;
1562     }
1563   }
1564   else if (a < 0.0)
1565   {
1566     c1 = 7.0;
1567     sub2();
1568     return;
1569   }
1570   else
1571   {
1572     c1 = 1.0;
1573     sub1();
1574     return;
1575   }
1576 }
1577 
1578 void
sub1(void)1579 sub1(void)
1580 {
1581   x = fabs(x);
1582   a = fabs(a);
1583 
1584   if (a <= x)
1585     printf("  DIRECTION = %4.2f\n", c1 + (a / x));
1586   else
1587     printf("  DIRECTION = %4.2f\n", c1 + (((a * 2) - x) / a));
1588 
1589   printf("  DISTANCE = %4.2f\n\n", (x > a) ? x : a);
1590 }
1591 
1592 void
sub2(void)1593 sub2(void)
1594 {
1595   x = fabs(x);
1596   a = fabs(a);
1597 
1598   if (a >= x)
1599     printf("  DIRECTION = %4.2f\n", c1 + (x / a));
1600   else
1601     /* @@@ printf("  DIRECTION = %4.2f\n\n", c1 + (((x * 2) - a) / x)); */
1602     printf("  DIRECTION = %4.2f\n", c1 + (((x * 2) - a) / x));
1603 
1604   /* @@@ printf("  DISTANCE = %4.2f\n", (x > a) ? x : a); */
1605   printf("  DISTANCE = %4.2f\n\n", (x > a) ? x : a);
1606 }
1607 
1608 void
ship_destroyed(void)1609 ship_destroyed(void)
1610 {
1611   printf("The Enterprise has been destroyed.\n");
1612   printf("The Federation will be conquered.\n\n");
1613 
1614   end_of_time();
1615 }
1616 
1617 void
end_of_time(void)1618 end_of_time(void)
1619 {
1620   printf("It is stardate %d.\n\n", (int) t);
1621 
1622   resign_commision();
1623 }
1624 
1625 void
resign_commision(void)1626 resign_commision(void)
1627 {
1628   printf("There were %d Klingon Battlecruisers left at the end\n", k9);
1629   printf("of your mission.\n\n");
1630 
1631   end_of_game();
1632 }
1633 
1634 void
won_game(void)1635 won_game(void)
1636 {
1637   printf("Congradulations, Captain!  The last Klingon Battle Cruiser\n");
1638   printf("menacing the Federation has been destoyed.\n\n");
1639 
1640   if (t - t0 > 0)
1641     printf("Your efficiency rating is %4.2f\n", 1000 * pow(k7 / (t - t0), 2));
1642 
1643   end_of_game();
1644 }
1645 
1646 void
end_of_game(void)1647 end_of_game(void)
1648 {
1649   string sTemp;
1650 
1651   if (b9 > 0)
1652     {
1653       printf("The Federation is in need of a new starship commander for\n");
1654       printf("a similar mission.\n\n");
1655       printf("If there is a volunteer, let him step forward and");
1656       printf(" enter 'aye':\n");
1657 
1658       reads(sTemp);
1659       printf("\n");
1660 
1661       if (! strncmp(sTemp, "aye", 3))
1662         new_game();
1663     }
1664 
1665   exit(0);
1666 }
1667 
1668 void
klingons_move(void)1669 klingons_move(void)
1670 {
1671   int i;
1672 
1673   for (i = 1; i <= 3; i++)
1674     {
1675       if (k[i][3] > 0)
1676         {
1677           strcpy(sA, "   ");
1678           z1 = k[i][1];
1679           z2 = k[i][2];
1680           insert_in_quadrant();
1681 
1682           find_empty_place();
1683 
1684           k[i][1] = z1;
1685           k[i][2] = z2;
1686           strcpy(sA, "+K+");
1687           insert_in_quadrant();
1688         }
1689     }
1690 
1691   klingons_shoot();
1692 }
1693 
1694 void
klingons_shoot(void)1695 klingons_shoot(void)
1696 {
1697   int h, i;
1698 
1699   if (k3 <= 0)
1700     return;
1701 
1702   if (d0 != 0)
1703     {
1704       printf("Starbase shields protect the Enterprise\n\n");
1705       return;
1706     }
1707 
1708   for (i = 1; i <= 3; i++)
1709     {
1710       if (k[i][3] > 0)
1711         {
1712           h = (int) ((k[i][3] / function_d(i)) * (2 + rnd()));
1713           s = s - h;
1714           /* @@@ k[i][3] = k[i][3] / (3 + rnd()); */
1715           k[i][3] = (int)(k[i][3] / (3 + rnd()));
1716 
1717           printf("%d unit hit on Enterprise from sector ", h);
1718           printf("%d, %d\n", k[i][1], k[i][2]);
1719 
1720               if (s <= 0)
1721                 {
1722                   printf("\n");
1723                   ship_destroyed();
1724                 }
1725 
1726               printf("    <Shields down to %d units>\n\n", s);
1727 
1728           if (h >= 20)
1729             {
1730               if (rnd() <= 0.6 || (h / s) > 0.2)
1731                 {
1732                   r1 = function_r();
1733                   d[r1] = d[r1] - (h / s) - (0.5 * rnd());
1734 
1735                   get_device_name();
1736 
1737                   printf("Damage Control reports\n");
1738                   printf("   '%s' damaged by hit\n\n", sG2);
1739                 }
1740             }
1741         }
1742     }
1743 }
1744 
1745 void
repair_damage(void)1746 repair_damage(void)
1747 {
1748   int i;
1749   double_t d6;              /* Repair Factor */
1750 
1751   d6 = w1;
1752 
1753   if (w1 >= 1.0)
1754     d6 = w1 / 10;
1755 
1756   for (i = 1; i <= 8; i++)
1757     {
1758       if (d[i] < 0.0)
1759         {
1760           d[i] = d[i] + d6;
1761           if (d[i] > -0.1 && d[i] < 0)
1762             d[i] = -0.1;
1763           else if (d[i] >= 0.0)
1764             {
1765               if (d1 != 1)
1766                 d1 = 1;
1767 
1768               printf("Damage Control report:\n");
1769               r1 = i;
1770               get_device_name();
1771               printf("    %s repair completed\n\n", sG2);
1772             }
1773         }
1774     }
1775 
1776   if (rnd() <= 0.2)
1777     {
1778       r1 = function_r();
1779 
1780       if (rnd() < .6)
1781         {
1782           d[r1] = d[r1] - (rnd() * 5.0 + 1.0);
1783           printf("Damage Control report:\n");
1784           get_device_name();
1785           printf("    %s damaged\n\n", sG2);
1786         }
1787       else
1788         {
1789           d[r1] = d[r1] + (rnd() * 3.0 + 1.0);
1790           printf("Damage Control report:\n");
1791           get_device_name();
1792           printf("    %s state of repair improved\n\n", sG2);
1793         }
1794     }
1795 }
1796 
1797 /* Misc Functions and Subroutines */
1798 
1799 void
find_empty_place(void)1800 find_empty_place(void)
1801 {
1802   /* @@@ while (z3 == 0) this is a nasty one.*/
1803   do
1804     {
1805       r1 = function_r();
1806       r2 = function_r();
1807 
1808       strcpy(sA, "   ");
1809 
1810       z1 = r1;
1811       z2 = r2;
1812 
1813       string_compare();
1814     } while (z3 == 0);
1815 
1816   z3 = 0;
1817 }
1818 
1819 void
insert_in_quadrant(void)1820 insert_in_quadrant(void)
1821 {
1822   int i, j = 0;
1823 
1824   /* @@@ s8 = ((z2 - 1) * 3) + ((z1 - 1) * 24) + 1; */
1825   s8 = ((int)(z2 - 0.5) * 3) + ((int)(z1 - 0.5) * 24) + 1;
1826 
1827   for (i = s8 - 1; i <= s8 + 1; i++)
1828     sQ[i] = sA[j++];
1829 
1830   return;
1831 }
1832 
1833 void
get_device_name(void)1834 get_device_name(void)
1835 {
1836   static char * device_name[] = {
1837     "", "Warp Engines","Short Range Sensors","Long Range Sensors",
1838     "Phaser Control","Photon Tubes","Damage Control","Sheild Control",
1839     "Library-Computer"};
1840 
1841   if (r1 < 0 || r1 > 8)
1842     r1 = 0;
1843 
1844   strcpy(sG2, device_name[r1]);
1845 
1846   return;
1847 }
1848 
1849 void
string_compare(void)1850 string_compare(void)
1851 {
1852   int i;
1853   char sB[4];
1854 
1855   z1 = (int)(z1 + 0.5);
1856   z2 = (int)(z2 + 0.5);
1857 
1858   s8 = ((z2 - 1) * 3) + ((z1 - 1) * 24) + 1;
1859 
1860   mid_str(sB, sQ, s8, 3);
1861 
1862   i = strncmp(sB, sA, 3);
1863 
1864   if (i == 0)
1865     z3 = 1;
1866   else
1867     z3 = 0;
1868 
1869   return;
1870 }
1871 
1872 void
quadrant_name(void)1873 quadrant_name(void)
1874 {
1875   static char * quad_name[] = {"","Antares","Rigel","Procyon","Vega",
1876     "Canopus","Altair","Sagittarius","Pollux","Sirius","Deneb","Capella",
1877     "Betelgeuse","Aldebaran","Regulus","Arcturus","Spica"};
1878 
1879   static char * sect_name[] = {""," I"," II"," III"," IV"};
1880 
1881   if (z4 < 1 || z4 > 8 || z5 < 1 || z5 > 8)
1882     strcpy(sG2, "Unknown");
1883 
1884   if (z5 <= 4)
1885     strcpy(sG2, quad_name[z4]);
1886   else
1887     strcpy(sG2, quad_name[z4+8]);
1888 
1889   if (g5 != 1)
1890     {
1891       if (z5 > 4)
1892       z5 = z5 - 4;
1893       strcat(sG2, sect_name[z5]);
1894     }
1895 
1896   return;
1897 }
1898 
1899 int
function_d(int i)1900 function_d(int i)
1901 {
1902   int j;
1903 
1904   /* @@@ j = sqrt(pow((k[i][1] - s1), 2) + pow((k[i][2] - s2), 2)); */
1905 
1906   j = (int)sqrt(pow(k[i][1] - s1, 2) + pow(k[i][2] - s2, 2));
1907 
1908   return j;
1909 }
1910 
1911 int
function_r(void)1912 function_r(void)
1913 {
1914   return(get_rand(8));
1915 }
1916 
1917 void
mid_str(char * a,char * b,int x,int y)1918 mid_str(char *a, char *b, int x, int y)
1919 {
1920   --x;
1921   y += x;
1922 
1923   /* @@@ while (x < y && x <= strlen(b)) */
1924   while (x < y && x <= (int)strlen(b))
1925     *a++ = *(b + x++);
1926 
1927   *a = '\0';
1928 }
1929 
1930 /* Round off floating point numbers instead of truncating */
1931 
1932 int
cint(double_t d)1933 cint (double_t d)
1934 {
1935   int i;
1936 
1937   i = (int) (d + 0.5);
1938 
1939   return(i);
1940 }
1941 
1942 /******** Z88DK: not all targets have file io
1943 
1944 void
1945 showfile(char *filename)
1946 {
1947   line lBuffer;
1948   int iRow = 0;
1949 
1950   if (openfile(filename, "r") != 0)
1951     return;
1952 
1953   while (getline_l(lBuffer) != 0)
1954     {
1955       printf(lBuffer);
1956 
1957       if (iRow++ > MAXROW - 3)
1958         {
1959           getchar();
1960           iRow = 0;
1961         }
1962     }
1963 
1964   closefile();
1965 }
1966 
1967 int
1968 openfile(char * sFilename, char * sMode)
1969 {
1970   if (bFlag || (stream = fopen (sFilename, sMode)) == NULL)
1971     {
1972       fprintf (stderr, "\nError - Unable to open file: %s.\n\n", sFilename);
1973       return 1;
1974     }
1975 
1976   bFlag = TRUE;
1977 
1978   return 0;
1979 }
1980 
1981 void
1982 closefile(void)
1983 {
1984   if (! bFlag)
1985     fclose(stream);
1986 
1987   bFlag = FALSE;
1988 }
1989 
1990 int
1991 getline_l(char *s)
1992 {
1993   fflush(stdout);
1994   if (fgets(s, MAXCOL, stream) == NULL)
1995     return(0);
1996   else
1997     return(strlen(s));
1998 }
1999 
2000 **********/
2001 
2002 const unsigned char *instr[] = {
2003 "\n\n",
2004 "1. When you see _Command?_ printed, enter one of the legal",
2005 "   commands (nav, srs, lrs, pha, tor, she, dam, com, or xxx).",
2006 "",
2007 "2. If you should type in an illegal command, you'll get a",
2008 "   short list of the legal commands printed out.",
2009 "",
2010 "3. Some commands require you to enter data (for example, the",
2011 "   'nav' command comes back with 'Course(1-9) ?'.) If you type",
2012 "   in illegal data (like negative numbers), that command will",
2013 "   be aborted.",
2014 "",
2015 "  The galaxy is divided into an 8 X 8 quadrant grid, and each",
2016 "quadrant is further divided into an 8 x 8 sector grid.",
2017 "",
2018 "  You will be assigned a starting point somewhere in the",
2019 "galaxy to begin a tour of duty as commander of the starship",
2020 "_Enterprise_; your mission: to seek out and destroy the fleet",
2021 "of Klingon warships which are menacing the United Federation",
2022 "of Planets.",
2023 "",
2024 "  You have the following commands available to you as Captain",
2025 "of the Starship Enterprise:",
2026 "",
2027 "\\nav\\ Command = Warp Engine Control --",
2028 "",
2029 "  Course is in a circular numerical vector        4  3  2",
2030 "  arrangement as shown. Integer and real           . . .",
2031 "  values may be used. (Thus course 1.5 is           ...",
2032 "  half-way between 1 and 2.                     5 ---*--- 1",
2033 "                                                    ...",
2034 "  Values may approach 9.0, which itself is         . . .",
2035 "  equivalent to 1.0.                              6  7  8",
2036 "",
2037 "  One warp factor is the size of one quadrant.     COURSE",
2038 "  Therefore, to get from quadrant 6,5 to 5,5",
2039 "  you would use course 3, warp factor 1.",
2040 "",
2041 "\\srs\\ Command = Short Range Sensor Scan",
2042 "",
2043 "  Shows you a scan of your present quadrant.",
2044 "",
2045 "  Symbology on your sensor screen is as follows:",
2046 "    <*> = Your starship's position",
2047 "    +K+ = Klingon battlecruiser",
2048 "    >!< = Federation starbase (Refuel/Repair/Re-Arm here)",
2049 "     *  = Star",
2050 "",
2051 "  A condensed 'Status Report' will also be presented.",
2052 "",
2053 "\\lrs\\ Command = Long Range Sensor Scan",
2054 "",
2055 "  Shows conditions in space for one quadrant on each side of",
2056 " the Enterprise (which is in the middle of the scan). The",
2057 " scan is coded in the form \###\ where the units digit is",
2058 " the number of stars, the tens digit is the number of",
2059 " starbases, and the hundreds digit is the number of Klingons.",
2060 "",
2061 "  Example - 207 = 2 Klingons, No Starbases, & 7 stars.",
2062 "",
2063 "\\pha\\ Command = Phaser Control.",
2064 "",
2065 "  Allows you to destroy the Klingon Battle Cruisers by",
2066 " zapping them with suitably large units of energy to deplete",
2067 " their shield power. (Remember, Klingons have phasers, too!)",
2068 "",
2069 "\\tor\\ Command = Photon Torpedo Control",
2070 "",
2071 "  Torpedo course is the same  as used in warp engine control.",
2072 " If you hit the Klingon vessel, he is destroyed and cannot",
2073 " fire back at you. If you miss, you are subject to the phaser",
2074 " fire of all other Klingons in the quadrant.",
2075 "",
2076 "  The Library-Computer (\com\ command) has an option to",
2077 " compute torpedo trajectory for you (option 2).",
2078 "",
2079 "\\she\\ Command = Shield Control",
2080 "",
2081 "  Defines the number of energy units to be assigned to the",
2082 " shields. Energy is taken from total ship's energy. Note that",
2083 " the status display total energy includes shield energy.",
2084 "",
2085 "\\dam\\ Command = Damage Control report",
2086 "  Gives the state of repair of all devices. Where a negative",
2087 " 'State of Repair' shows that the device is temporarily",
2088 " damaged.",
2089 "",
2090 "\\com\\ Command = Library-Computer",
2091 "  The Library-Computer contains six options:",
2092 "  Option 0 = Cumulative Galactic Record",
2093 "    This option shows computer memory of the results of all",
2094 "   previous short and long range sensor scans.",
2095 "  Option 1 = Status Report",
2096 "    This option shows the number of Klingons, stardates, and",
2097 "   starbases remaining in the game.",
2098 "  Option 2 = Photon Torpedo Data",
2099 "    Which gives directions and distance from Enterprise to",
2100 "   all Klingons in your quadrant.",
2101 "  Option 3 = Starbase Nav Data",
2102 "    This option gives direction and distance to any starbase",
2103 "   in your quadrant.",
2104 "  Option 4 = Direction/Distance Calculator",
2105 "    This option allows you to enter coordinates for direction/",
2106 "   distance calculations.",
2107 "  Option 5 = Galactic /Region Name/ Map",
2108 "    This option prints the names of the sixteen major galactic",
2109 "   regions referred to in the game.",
2110 "\n",
2111 0 };
2112 
2113 void
showfile(char * filename)2114 showfile(char *filename)
2115 {
2116   int iRow, i;
2117 
2118   for (i = iRow = 0; instr[i]; ++i, ++iRow)
2119   {
2120      printf("%s\n", instr[i]);
2121 
2122      if (iRow++ > MAXROW - 3)
2123      {
2124         getchar();
2125         iRow = 0;
2126      }
2127   }
2128 }
2129 
2130 /* Generate seed with the timer */
2131 int
randomize(void)2132 randomize(void)
2133 {
2134 /*
2135    unsigned int i;
2136 
2137 //  time_t timer;
2138 //  srand ((unsigned) time (&timer));
2139 
2140    printf("Any key to continue...\n\n");
2141 
2142    in_wait_nokey();
2143    for (i=0; !in_test_key(); ++i) ;
2144    in_wait_nokey();
2145 
2146    return i;
2147 */
2148 
2149    return 0x1234;
2150 }
2151 
2152 /* Returns an integer from 1 to iSpread */
2153 int
get_rand(int iSpread)2154 get_rand(int iSpread)
2155 {
2156   return((rand() % iSpread) + 1);
2157 }
2158 
2159 double_t
rnd(void)2160 rnd(void)
2161 {
2162   double_t d;
2163 
2164   d = rand() / (double_t) RAND_MAX;
2165 
2166   return(d);
2167 }
2168