|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 16496 (0x4070) Types: TextFile Names: »parse.c.orig«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Galaxy/src/parse.c.orig«
/* * %W% (mrdch&amnnon) %G% */ # include "header" /* if a restored game switched players i.d. */ extern SWITCH_FLAG; extern nulluser; extern int no_new_year; char moreflg[2] = TWOZERO; /* flag to indicate if player changed during game */ char didchange[2] = TWOZERO; int changestat; planet * curpln; int overstat (), retrieve (), pversion (), getoutofhere (), restorgame (), savegame (), takepl (), endgame (), quit (), give_up (), planetsit (), planetenq (), blackout (), assign (), feedpop (), takefrom (), moveto (), detectmv (), nodetect (), leaveat (), trading (), putalm (), init_disc (), killalm (), write_enemy (), build (), set_missile (), help (), menu (), next_year (), wizwiz (), no_new (), toggle_wizard (), changeplay (); struct commands { char *str; /* the command name */ int (*cfun) (); /* the function that executes it */ char *docname; /* the file name that documents it */ char *exp; /* a short explanation */ }; struct commands ctab[] = { "os", overstat, "overstat", "Overall Situation. os || os [abcdefFikmnops]", "ps", planetsit, "plansit", "Planet Situation. ps [plid] [i]", "as", assign, "assign", "Assign people. as [plid] N (cfmbs) (cfmbs)", "en", planetenq, "planenq", "Enquire Planet. en [plid] [level] (afkmpst) T", "bo", blackout, "blackout", "Blackout a Planet. bo [plid] T", "tk", takefrom, "takefrom", "Take from. tk [plid] (k) || (N (tcfmbsv) )", "lv", leaveat, "leave_at", "Leave at. lv [plid] (k || K) || (N (tcfmbsv) )", "mv", moveto, "move_to", "Move to. mv [plid] -[plid] [>dr] NH [NH NH ...]", "bs", build, "build", "Build new ships. bs [plid] NH T || bs [plid] t T", "sm", set_missile, "set_missl", "Set missiles. sm [plid] NH", "dt", detectmv, "detect", "Detect movement / Paint ships. dt/nd [plid] T", "nd", nodetect, "paint", 0, "lm", putalm, "putalm", "Lay ALM. lm [plid] N", "dm", killalm, "killalm", "Deactivate ALM. dm [plid] N", "fd", feedpop, "feedpop", "Feed population. fd T", "tr", trading, "trade", "Trade. tr T", "rt", retrieve, "retrieve", "Retrieve invested money. rt T (tfbs) [plid]", "wr", write_enemy, "write", "Write to the enemy. wr [anything....+ return]", "mp", init_disc, "init_dis", "Refresh the screen. mp", "ny", next_year, "next_year", "Jump a year/Continue stoped game. ny", "nn", no_new, "next_year", "Stop game for a while. nn", "sv", savegame, "savegame", "Save / Restore Game. sv/rs (file name)", "rs", restorgame, "restor", 0, "gu", give_up, "give_up", "Give up this game / Ask to quit. gu/qt", "qt", quit, "quit", 0, "menu", menu, 0, 0, "help", help, "help", 0, "man", help, "help", 0, "version", pversion, 0, 0, "cp", changeplay, "chng_ply", "# Change player", "wz", wizwiz, 0, "# Get a lot of everything", "capt", takepl, 0, "# Take any planet you wish", "toggle", toggle_wizard, 0, "# Give up/regain wizardcy", "getout", getoutofhere, 0, "# Exit the game neatly and QUICK!!", 0, 0, 0, 0 }; /* * this funstion sets the active terminal to the required . */ termn (n) { if (SWITCH_FLAG) /* in a restored game, player switched */ n = !n; if (n == 0) { term0 (); } else { term1 (); } /* check if cp command was given */ if (didchange[n]) { player = !player; changestat = 1; } else changestat = 0; /* set the current planet to the active player */ if (!player) curpln = spntr; else curpln = apntr; } #define GETSTRMODE 1 #define CURSORMODE 2 /* in these buffers the input from both players is gathered */ char bufs[2][100]; /* pointers into the buffers */ int bufsp[2] = TWOZERO; /* flags to the current position of player */ int mode[2] = { CURSORMODE, CURSORMODE }; /* * The main loop. Reads chars from the two processes, stores * them in bufs, and interprets the command. When a legal * command is found, the function associated with that command * is invoked. The nature of this program requires that ALL * the relevant information to a specific command to be known * at the time of it's execution. (Any busy wait loop will cause * stagnation for the SECOND player). */ parse () { struct commands *c = ctab; char *ch; chan x; /* initialize first terminal */ termn (0); if (ctrlinit () == 0); crmode (); noecho (); say ("Sir. If you feel somewhat lost, give the \"help\" command."); cleol (22, 11); /* initialize second terminal */ termn (1); if (ctrlinit () == 0); crmode (); noecho (); say ("Sir. If you feel somewhat lost, give the \"help\" command."); cleol (22, 11); /* enter main loop */ getcommand: for (;;) { c = ctab; (void) fflush (ttys[0]); (void) fflush (ttys[1]); if (readc (&x) != sizeof (x)) bug ("read error on pipe."); termn (x.ichan); /* set terminal to where it came from */ /* * First check if it's in "more" mode . * In that case, flip back on request. */ if (moreflg[player]) { if (x.c != ' ' && x.c != '5') goto getcommand; endmore (); putmsgs ('r'); /* regular printout */ prteller (); goto getcommand; } /* esc char toggles the two stages */ if (x.c == '\033') { /* ascii esc */ if (mode[player] == GETSTRMODE) { mode[player] = CURSORMODE; curse_map (curpln); } else { mode[player] = GETSTRMODE; curse_com (curpln); cleol (22, 11 + bufsp[player]); } goto getcommand; } /* in the map mode, movement and message command and given */ if (mode[player] == CURSORMODE) { if (x.c == '-' || x.c == ' ') {/* delete messages stack */ putmsgs ('-'); /* to advance rapidly */ curse_map (curpln); goto getcommand; } /* good for ascii only. */ if ((x.c > '9') || iscntrl (x.c)) { curse_com (curpln); mode[player] = GETSTRMODE; cleol (22, 11 + bufsp[player]); } else { changeloc (x.c); goto getcommand; } } if (mode[player] == GETSTRMODE) { if (x.c == '\n' || x.c == '\r') { mode[player] = CURSORMODE; bufs[player][bufsp[player]] = '\0'; ch = bufs[player]; bufsp[player] = 0; goto parse; } else /* collect the chars */ dogetstr (x.c); } } /* find out which command was given */ parse: if (*ch) { if (Pause) { /* were having a pause. Execute harmless commands (no movements) */ if (strncmp (ch, "mv", 2) == 0) { say ("As we take a break, I cannot move a single ship, sir."); cleol (22, 11); goto getcommand; } } while (c -> str != 0) { cleol (23, 0); if (strcmpn (ch, c -> str, strlen (c -> str)) == 0) { /* enable quick return in case of error */ if (setjmp (jparse) == 0) (*c -> cfun) (ch + strlen (c -> str)); /* update time */ if (!Pause) softclock (0); if (!moreflg[player]) { cleol (22, 11); putmsgs ('r');/* regular */ prteller (); } goto getcommand; } c++; } error (); c = ctab; goto getcommand; } goto getcommand; } extern int month; /* the x/100 of the year */ prteller () { char s[10]; cleol (19, 0); pr_at (19, 4, "Planet: %s", curpln -> pid); pos (19, 25); if (teller[player]) print ("You have %d Tellers left, sir.", teller[player]); else print ("No money left, sir. So sorry.."); if (month < 10) (void) sprintf (s, "%c%d", '0', month); else (void) sprintf (s, "%d", month); if (wants_newy[player]) pr_at (19, 62, "NY"); pr_at (19, 65, "Year : %d.%s", year, s); curse_map (curpln); } changeloc (dir) char dir; { int j; /* if the terminal has the capability, flip the page over */ if (dir == '5') if (ttyc -> t_fl != 0) { flip (); more (); return; } if ((j = find_direct (dir)) < 0) return; /* illegal direction */ if (curpln -> gate[j] == NULL) return; curpln = curpln -> gate[j]; if (!player) spntr = curpln; else apntr = curpln; pr_at (19, 12, "%s", curpln -> pid); /* update position at screen */ curse_map (curpln); } /* * This function prints a message and sleeps until a character * is striked at the terminal which executed more. * * The problem is that we can't wait to a character here becaue * we want to get a character from the other terminal. * * We can use the fact that all the functions * using more() call it just before they return to parse. * More will simply set a flag to tell parse that we are in * more mode. */ more () { so (23, 56, "Hit SPACE to continue"); (void) fflush (tty); moreflg[player] = 1; } endmore () { cleol (23, 0); /* clear the "more" message */ moreflg[player] = 0; flip (); } /* * Get online help. All the commands that are listed above * have help files associated with them. In case that information * is required about some general issues, the requested file is * searced. Actually, all the manual can be obtained in that * fashion. */ help (s) char *s; { FILE * docfile; char nwcm[200]; struct commands *c = ctab; skipwhite (s); if (*s == '\0') { /* no patrameters were given */ strcpy (nwcm, "help"); help (nwcm); /* call recursivly with arg */ return; } if (*s == '-') { /* a general information was requested */ (void) sprintf (nwcm, "%s%s.doc", ONLINE, ++s); goto show_doc; } while (c -> str != 0) { /* didn't reach the last command */ if (strncmp (s, c -> str, strlen (c -> str)) == 0) { if (c -> docname == 0) break; (void) sprintf (nwcm, "%s%s.doc", ONLINE, c -> docname); show_doc: docfile = fopen (nwcm, "r"); if (docfile == NULL) { say ("I think you have the wrong name, sir. Try \"help\"."); return; } flip (); clear (); while (fgets (nwcm, 200, docfile) != NULL) print ("%s\r", nwcm); (void) fclose (docfile); more (); return; } c++; } say ("But sir !!! I don't understand that command. Try \"menu\"."); } /* * Extract from the command structure the information concerning * the syntax of the commands. */ menu (s) char *s; { struct commands *c = ctab; int wiz = 0; skipwhite (s); if (*s == 'w') { assert_wizard (); wiz = 1; } flip (); clear (); if (!wiz) print ("<plid = planet id> <N = no.> <T = Tellers> <H = ship type> <dr = direction>"); else print ("This commands are only yours to give, dear lord.\n\n\r\r"); while (c -> str != 0) { if (c -> exp != 0) { if (!wiz) { if (*c -> exp != '#') print ("\r\n%s", c -> exp); } else { if (*c -> exp == '#') print ("\r\n%s:\t\t%s", c -> str, c -> exp); } } c++; } more (); } error () { say ("Sorry sir, but I don't understand you!!"); curse_map (curpln); } /* * This function terminates the game. If it is calles with * a winner, the principal facts of the game will be recorded * on the galaxy score file. If there is no winner, the game * will just end gracefully. */ # include "score.h" endgame (mode) int mode; { int resf; char *ctime (); struct score sc; time_t time (); /* force the printout of games played -null */ if (nulluser && !iswiz[1]) mode = 1; if (mode == -1) goto noscore; resf = open (GALSCOR, 1); if (resf == -1) goto noscore; (void) lseek (resf, 0L, 2); if (mode) { strcpy (sc.win, ply1), strcpy (sc.los, ply0); } else { strcpy (sc.win, ply0), strcpy (sc.los, ply1); } sc.played_at = time (0); sc.years = year; (void) write (resf, (char *) & sc, sizeof (sc)); (void) close (resf); noscore: term0 (); doend (mode); term1 (); doend (mode); if (mode != -1) sleep (7); (void) kill (0, 9); } doend (mode) { static char *argv[] = { "IGNORED", "-t" }; clear (); if (mode != -1) { glxscore (2, argv); } ctrlreset (); (void) fflush (tty); } /* check if the capital was invaded */ check_end () { int j = capitals[0] -> whos; if (j == capitals[1] -> whos) end_game (j); } /* * A suicidal command. When all is lost. */ give_up () { end_game (!player); } /* * This function enables two players to discontinue the game * withourt any of them loosing face. Of course, they both * must agree. */ quit () { if (wants_quit[player]) { wants_quit[player] = 0; say ("Canceling last quit request."); return; } if (!wants_quit[!player]) { wants_quit[player] = 1; say ("Waiting for him to agree...."); dowrite_enemy ("I would like to quit. If offer accepted, give the \"qt\" command.", !player); return; } endgame (-1); } pversion () { extern char version[80]; say (version); } /* STOP the time */ no_new () { if (nulluser || iswiz[player] == 1) { no_new_year = 1; return; } /* We want to have a break! */ if (wants_pause[player]) { say ("Cancelling last pause request"); wants_pause[player] = 0; return; } wants_pause[player] = 1; if (wants_pause[!player]) { Pause = 1; no_new_year = 1; dowrite_enemy ("Break activated, Sir!!!", player); dowrite_enemy ("Break activated, Sir!!!", !player); return; } say ("Waiting for him to agree....."); dowrite_enemy ("Hey, let's take a break OK ?", !player); } /* * If the two players ask for a new year - so it will happen. * wizard may force one. */ next_year () { if (nulluser || iswiz[player] == 1) { no_new_year = 0; Pause = 0; softclock (1); return; } if (wants_newy[player]) { wants_newy[player] = 0; if (Pause) dowrite_enemy ("Sorry. I still need time.", !player); say ("Canceling last new_year request."); return; } if (!wants_newy[!player]) { wants_newy[player] = 1; if (Pause) { dowrite_enemy ("Let's continue the game O.K. ?", !player); say ("Waiting for him to agree..."); } return; } wants_newy[player] = 0; wants_newy[!player] = 0; no_new_year = 0; if (Pause) { Pause = 0; dowrite_enemy ("There we go again!!", player); dowrite_enemy ("There we go again!!", !player); softclock (2); return; } softclock (1); }