First round of changes from Stas Sergeev.
[super-star-trek.git] / sst.c
diff --git a/sst.c b/sst.c
index af932a0dbcb000c7e1e3ba7f260ece91f3cda2bc..888b7ec4780b01333e7a04905a7dbef65e07d6c5 100644 (file)
--- a/sst.c
+++ b/sst.c
@@ -1,18 +1,13 @@
 #define INCLUDED       // Define externs here\r
-#include "sst.h"\r
 #include <ctype.h>\r
-#include <stdarg.h>\r
-#ifdef MSDOS\r
-#include <dos.h>\r
+#include <getopt.h>\r
+#include "sst.h"\r
+\r
+#ifndef SSTDOC\r
+#define SSTDOC "sst.doc"\r
 #endif\r
-#include <time.h>\r
        \r
-int getch(void);\r
-\r
 static char line[128], *linep = line;\r
-static int linecount;  /* for paging */\r
-\r
-static void clearscreen(void);\r
 \r
 /* Compared to original version, I've changed the "help" command to\r
    "call" and the "terminate" command to "quit" to better match\r
@@ -39,7 +34,7 @@ static void clearscreen(void);
    2. deathray improvement (but keeping original failure alternatives)\r
 \r
    3. Tholian Web\r
-\r
+s\r
    4. Enemies can ram the Enterprise. Regular Klingons and Romulans can\r
       move in Expert and Emeritus games. This code could use improvement.\r
 \r
@@ -103,7 +98,7 @@ static void listCommands(int x) {
 \r
 static void helpme(void) {\r
        int i, j;\r
-       char cmdbuf[32];\r
+       char cmdbuf[32], *cp;\r
        char linebuf[132];\r
        FILE *fp;\r
        /* Give help on commands */\r
@@ -130,37 +125,41 @@ static void helpme(void) {
                strcpy(cmdbuf, " ABBREV");\r
        }\r
        else {\r
-               strcpy(cmdbuf, "  Mnemonic:  ");\r
-               j = 0;\r
-               while ((cmdbuf[j+13] = toupper(commands[i][j])) != 0) j++;\r
+           for (j = 0; commands[i][j]; j++)\r
+               cmdbuf[j] = toupper(commands[i][j]);\r
+           cmdbuf[j] = '\0';\r
        }\r
-       fp = fopen("sst.doc", "r");\r
+       fp = fopen(SSTDOC, "r");\r
        if (fp == NULL) {\r
                prout("Spock-  \"Captain, that information is missing from the");\r
                prout("   computer. You need to find SST.DOC and put it in the");\r
                prout("   current directory.\"");\r
                return;\r
        }\r
-       i = strlen(cmdbuf);\r
-       do {\r
-               if (fgets(linebuf, 132, fp) == NULL) {\r
+       for (;;) {\r
+           if (fgets(linebuf, sizeof(linebuf), fp) == NULL) {\r
                        prout("Spock- \"Captain, there is no information on that command.\"");\r
                        fclose(fp);\r
                        return;\r
                }\r
-       } while (strncmp(linebuf, cmdbuf, i) != 0);\r
+           if (linebuf[0] == '%' && linebuf[1] == '%'&& linebuf[2] == ' ') {\r
+               for (cp = linebuf+3; isspace(*cp); cp++)\r
+                       continue;\r
+               linebuf[strlen(linebuf)-1] = '\0';\r
+               if (strcmp(cp, cmdbuf) == 0)\r
+                   break;\r
+           }\r
+       }\r
 \r
        skip(1);\r
        prout("Spock- \"Captain, I've found the following information:\"");\r
        skip(1);\r
 \r
-       do {\r
-               if (linebuf[0]!=12) { // ignore page break lines \r
-                       linebuf[strlen(linebuf)-1] = '\0'; // No \n at end\r
-                       prout(linebuf);\r
-               }\r
-               fgets(linebuf,132,fp);\r
-       } while (strstr(linebuf, "******")==NULL);\r
+       while (fgets(linebuf, sizeof(linebuf),fp)) {\r
+               if (strstr(linebuf, "******"))\r
+                       break;\r
+               proutc(linebuf);\r
+       }\r
        fclose(fp);\r
 }\r
 \r
@@ -191,6 +190,7 @@ static void makemoves(void) {
                        }\r
                        else prout("UNRECOGNIZED COMMAND.");\r
                }\r
+               commandhook(commands[i], TRUE);\r
                switch (i) { /* command switch */\r
                        case 0:                 // srscan\r
                                srscan(1);\r
@@ -217,7 +217,8 @@ static void makemoves(void) {
                                }\r
                                break;\r
                        case 6:                 // dock\r
-                               dock();\r
+                               dock(1);\r
+                                if (ididit) attack(0);\r
                                break;\r
                        case 7:                 // damages\r
                                dreprt();\r
@@ -315,6 +316,7 @@ static void makemoves(void) {
                                helpme();       // get help\r
                                break;\r
                }\r
+               commandhook(commands[i], FALSE);\r
                for (;;) {\r
                        if (alldone) break;             // Game has ended\r
 #ifdef DEBUG\r
@@ -346,24 +348,30 @@ static void makemoves(void) {
 \r
 \r
 int main(int argc, char **argv) {\r
-       int i;\r
+    int i, option, usecurses = TRUE;\r
        int hitme;\r
        char ch;\r
-       prelim();\r
-\r
-       if (argc > 1) {\r
-               fromcommandline = 1;\r
-               line[0] = '\0';\r
-               while (--argc > 0) {\r
-                       strcat(line, *(++argv));\r
-                       strcat(line, " ");\r
-               }\r
-       }\r
-       else fromcommandline = 0;\r
 \r
+       while ((option = getopt(argc, argv, "t")) != -1) {\r
+           switch (option) {\r
+           case 't':\r
+               usecurses = FALSE;\r
+               break;\r
+           default:\r
+               fprintf(stderr, "usage: sst [-t] [startcommand...].\n");\r
+               exit(0);\r
+           }\r
+       }\r
 \r
+       iostart(usecurses);\r
+       prelim(); \r
+       line[0] = '\0';\r
+       for (i = optind; i < argc;  i++) {\r
+               strcat(line, argv[i]);\r
+               strcat(line, " ");\r
+       }\r
        while (TRUE) { /* Play a game */\r
-               setup();\r
+               setup(line[0] == '\0');\r
                if (alldone) {\r
                        score();\r
                        alldone = 0;\r
@@ -384,7 +392,8 @@ int main(int argc, char **argv) {
                if (!ja()) break;\r
        }\r
        skip(1);\r
-       prout("May the Great Bird of the Galaxy roost upon your home planet.");\r
+       ioend();\r
+       puts("May the Great Bird of the Galaxy roost upon your home planet.");\r
 }\r
 \r
 \r
@@ -403,22 +412,26 @@ void cramen(int i) {
                case IHBLANK: s = "Black hole"; break;\r
                case IHT: s = "Tholian"; break;\r
                case IHWEB: s = "Tholian web"; break;\r
+                case IHQUEST: s = "Stranger"; break;\r
                default: s = "Unknown??"; break;\r
        }\r
        proutn(s);\r
 }\r
 \r
-void cramlc(int key, int x, int y) {\r
-       if (key == 1) proutn(" Quadrant");\r
-       else if (key == 2) proutn(" Sector");\r
-       proutn(" %d - %d", x, y);\r
+char *cramlc(enum loctype key, int x, int y) {\r
+       static char buf[32];\r
+       buf[0] = '\0';\r
+       if (key == quadrant) strcpy(buf, "Quadrant ");\r
+       else if (key == sector) strcpy(buf, "Sector ");\r
+       sprintf(buf+strlen(buf), "%d-%d", x, y);\r
+       return buf;\r
 }\r
 \r
 void crmena(int i, int enemy, int key, int x, int y) {\r
        if (i == 1) proutn("***");\r
        cramen(enemy);\r
-       proutn(" at");\r
-       cramlc(key, x, y);\r
+       proutn(" at ");\r
+       proutn(cramlc(key, x, y));\r
 }\r
 \r
 void crmshp(void) {\r
@@ -455,14 +468,12 @@ void iran10(int *i, int *j) {
 }\r
 \r
 void chew(void) {\r
-       linecount = 0;\r
        linep = line;\r
        *linep = 0;\r
 }\r
 \r
 void chew2(void) {\r
        /* return IHEOL next time */\r
-       linecount = 0;\r
        linep = line+1;\r
        *linep = 0;\r
 }\r
@@ -471,8 +482,6 @@ int scan(void) {
        int i;\r
        char *cp;\r
 \r
-       linecount = 0;\r
-\r
        // Init result\r
        aaitem = 0.0;\r
        *citem = 0;\r
@@ -483,8 +492,7 @@ int scan(void) {
                        chew();\r
                        return IHEOL;\r
                }\r
-               fgets(line, sizeof(line), stdin);\r
-               line[strlen(line)-1] = '\0';\r
+               getline(line, sizeof(line));\r
                linep = line;\r
        }\r
        // Skip leading white space\r
@@ -496,6 +504,7 @@ int scan(void) {
        }\r
        if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') {\r
                // treat as a number\r
+           i = 0;\r
            if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {\r
                linep = line; // Invalid numbers are ignored\r
                *linep = 0;\r
@@ -528,93 +537,6 @@ int ja(void) {
        }\r
 }\r
 \r
-void cramf(double x, int w, int d) {\r
-       char buf[64];\r
-       sprintf(buf, "%*.*f", w, d, x);\r
-       proutn(buf);\r
-}\r
-\r
-double square(double i) { return i*i; }\r
-                                                                       \r
-static void clearscreen(void) {\r
-       /* Somehow we need to clear the screen */\r
-#ifdef __BORLANDC__\r
-       extern void clrscr(void);\r
-       clrscr();\r
-#else\r
-       proutn("\033[2J");      /* Hope for an ANSI display */\r
-#endif\r
-}\r
-\r
-/* We will pull these out in case we want to do something special later */\r
-\r
-void pause(int i) {\r
-       putchar('\n');\r
-       if (i==1) {\r
-               if (skill > 2)\r
-                       prout("[ANOUNCEMENT ARRIVING...]");\r
-               else\r
-                       prout("[IMPORTANT ANNOUNCEMENT ARRIVING -- HIT SPACE BAR TO CONTINUE]");\r
-               getch();\r
-       }\r
-       else {\r
-               if (skill > 2)\r
-                       proutn("[CONTINUE?]");\r
-               else\r
-                       proutn("[HIT SPACE BAR TO CONTINUE]");\r
-               getch();\r
-               proutn("\r                           \r");\r
-       }\r
-       if (i != 0) {\r
-               clearscreen();\r
-       }\r
-       linecount = 0;\r
-}\r
-\r
-\r
-void skip(int i) {\r
-       while (i-- > 0) {\r
-               linecount++;\r
-               if (linecount >= 23)\r
-                       pause(0);\r
-               else\r
-                       putchar('\n');\r
-       }\r
-}\r
-\r
-\r
-void proutn(char *fmt, ...) {\r
-    va_list ap;\r
-    va_start(ap, fmt);\r
-    vprintf(fmt, ap);\r
-    va_end(ap);\r
-}\r
-\r
-void prout(char *fmt, ...) {\r
-    va_list ap;\r
-    va_start(ap, fmt);\r
-    vprintf(fmt, ap);\r
-    va_end(ap);\r
-    skip(1);\r
-}\r
-\r
-void prouts(char *fmt, ...) {\r
-       clock_t endTime;\r
-       char *s, buf[BUFSIZ];\r
-       /* print slowly! */\r
-       va_list ap;\r
-       va_start(ap, fmt);\r
-       vsprintf(buf, fmt, ap);\r
-       va_end(ap);\r
-       skip(1);\r
-       for (s = buf; *s; s++) {\r
-               endTime = clock() + CLOCKS_PER_SEC*0.05;\r
-               while (clock() < endTime) ;\r
-               putchar(*s);\r
-               fflush(stdout);\r
-       }\r
-}\r
-\r
 void huh(void) {\r
        chew();\r
        skip(1);\r
@@ -680,7 +602,7 @@ void debugme(void) {
                                case FSCMOVE: proutn("SC Move         "); break;\r
                                case FSCDBAS: proutn("SC Base Destroy "); break;\r
                        }\r
-                       cramf(future[i]-game.state.date, 8, 2);\r
+                       proutn("%.2f", future[i]-game.state.date);\r
                        chew();\r
                        proutn("  ?");\r
                        key = scan();\r