From mipos3!intelca!oliveb!ames!ll-xn!husc6!mit-eddie!uw-beaver!tektronix!tekgen!tekred!games-request Wed Jul 1 10:35:24 PDT 1987 Article 16 of comp.sources.games: Path: td2cad!mipos3!intelca!oliveb!ames!ll-xn!husc6!mit-eddie!uw-beaver!tektronix!tekgen!tekred!games-request From: games-request@tekred.TEK.COM Newsgroups: comp.sources.games Subject: v01i068: xmille - mille bournes for X-windows, Part01/03 Message-ID: <1358@tekred.TEK.COM> Date: 30 Jun 87 17:27:12 GMT Expires: 30 Jul 87 17:19:24 GMT Sender: billr@tekred.TEK.COM Lines: 2369 Approved: billr@tekred.TEK.COM Submitted by: keithp@copper.TEK.COM (Keith Packard) Comp.sources.games: Volume 1, Issue 68 Archive-name: xmille/Part01 [The following note is from the author... -br] [Well, after a letter arrived from Ken Arnold, I found out that these sources are public domain, so I'm posting the whole mess. This and the next two articles make up xmille - a mille bournes program that has a fun user-interface. The last article will be a uuencoded compress'ed shar file. I know this sounds a bit silly, but in compressed form it's only 60K while in uncompressed form it's 600K, about what you'd expect from bitmaps. So, you'll need to uudecode and uncompress it and *then* un-shar it. Make a directory, un-shar the files in it and type 'make'. Then fix the porting problems and flame me for a crummy distribution. I'll ignore those. Don't spend too much time playing, your manager will start to suspect things when you start talking about 'coup-fourre's' in meetings... keith packard keithp@copper.tek.com] #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh README <<'END_OF_README' XNotes on porting xmille: X X The bitmaps in 'cards' are set up for a color display, they probably Xwill not be readable in monocrome without a bit of editing. Also, the Xcard display routines insist on color, so those will need fixing as well. X X The major porting headache of mille is roll.c. You'll probably Xhave to fix it for your machine, it's terrible now -- but that's what came Xwith it and it works on *my* machine... X X I'll cheerfully accept bug reports in xmille, and may even be Xwilling to maintain a current version; but I wash my hands of this mess by Xputting it into the public domain, I don't care what you do with it. X X May 28, 1987 X X keith packard X X keithp@copper.tek.com (at least for now) X X reed!dinadan!keith (at home) X END_OF_README if test 736 -ne `wc -c MANIFEST <<'END_OF_MANIFEST' File Name Archive # Description ----------------------------------------------------------- MANIFEST 1 This shipping list Makefile 2 README 1 animate.c 2 background.h 2 card.h 2 cards.Z.uu 3 compressed shar file of bitmaps color.h 2 comp.c 1 control 1 curses_ui.c 1 drawcard.c 1 end.c 1 extern.c 2 fill 1 init.c 2 mille.c 2 mille.h 2 misc.c 2 move.c 2 print.c 2 roll.c 2 save.c 2 table.c 2 types.c 2 ui.c 1 ui.h 2 varpush.c 2 END_OF_MANIFEST if test 974 -ne `wc -c comp.c <<'END_OF_comp.c' X# include "mille.h" X X/* X * @(#)comp.c 1.1 (Berkeley) 4/1/82 X */ X X# define V_VALUABLE 40 X Xcalcmove() { X X reg CARD card; X reg int *value; X reg PLAY *pp, *op; X reg bool foundend, cango, canstop, foundlow; X reg unsgn int i, count200, badcount, nummin, nummax, diff; X reg int curmin, curmax; X reg CARD safe, oppos; X int valbuf[HAND_SZ], count[NUM_CARDS]; X bool playit[HAND_SZ]; X X Message (""); X pp = &Player[COMP]; X op = &Player[PLAYER]; X safe = 0; X cango = 0; X canstop = FALSE; X foundend = FALSE; X for (i = 0; i < NUM_CARDS; i++) X count[i] = 0; X for (i = 0; i < HAND_SZ; i++) { X card = pp->hand[i]; X switch (card) { X case C_STOP: case C_CRASH: X case C_FLAT: case C_EMPTY: X if (playit[i] = canplay(pp, op, card)) X canstop = TRUE; X goto norm; X case C_LIMIT: X if ((playit[i] = canplay(pp, op, card)) X && Numseen[C_25] == Numcards[C_25] X && Numseen[C_50] == Numcards[C_50]) X canstop = TRUE; X goto norm; X case C_25: case C_50: case C_75: X case C_100: case C_200: X if ((playit[i] = canplay(pp, op, card)) X && pp->mileage + Value[card] == End) X foundend = TRUE; X goto norm; X default: X playit[i] = canplay(pp, op, card); Xnorm: X if (playit[i]) X ++cango; X break; X case C_GAS_SAFE: case C_DRIVE_SAFE: X case C_SPARE_SAFE: case C_RIGHT_WAY: X if (pp->battle == opposite(card) X || (pp->speed == C_LIMIT && card == C_RIGHT_WAY)) { X Movetype = M_PLAY; X Card_no = i; X return; X } X ++safe; X playit[i] = TRUE; X break; X } X ++count[card]; X } X if (pp->hand[0] == C_INIT && Topcard > Deck) { X Movetype = M_DRAW; X return; X } X if (Debug) X fprintf(outf, "CALCMOVE: cango = %d, canstop = %d, safe = %d\n", cango, canstop, safe); X if (foundend) X foundend = !check_ext(TRUE); X for (i = 0; safe && i < HAND_SZ; i++) { X if (issafety(pp->hand[i])) { X if (onecard(op) || (foundend && cango && !canstop)) { X if (Debug) X fprintf(outf, "CALCMOVE: onecard(op) = %d, foundend = %d\n", onecard(op), foundend); Xplaysafe: X Movetype = M_PLAY; X Card_no = i; X return; X } X oppos = opposite(pp->hand[i]); X if (Numseen[oppos] == Numcards[oppos]) X goto playsafe; X else if (!cango X && (op->can_go || !pp->can_go || Topcard < Deck)) { X card = (Topcard - Deck) - roll(1, 10); X if ((!pp->mileage) != (!op->mileage)) X card -= 7; X if (Debug) X fprintf(outf, "CALCMOVE: card = %d, DECK_SZ / 4 = %d\n", card, DECK_SZ / 4); X if (card < DECK_SZ / 4) X goto playsafe; X } X safe--; X playit[i] = cango; X } X } X if (!pp->can_go && !isrepair(pp->battle)) X Numneed[opposite(pp->battle)]++; Xredoit: X foundlow = (cango || count[C_END_LIMIT] != 0 X || Numseen[C_LIMIT] == Numcards[C_LIMIT] X || pp->safety[S_RIGHT_WAY] != S_UNKNOWN); X foundend = FALSE; X count200 = pp->nummiles[C_200]; X badcount = 0; X curmax = -1; X curmin = 101; X nummin = -1; X nummax = -1; X value = valbuf; X for (i = 0; i < HAND_SZ; i++) { X card = pp->hand[i]; X if (issafety(card) || playit[i] == (cango != 0)) { X if (Debug) X fprintf(outf, "CALCMOVE: switch(\"%s\")\n", C_name[card]); X switch (card) { X case C_25: case C_50: X diff = End - pp->mileage; X /* avoid getting too close */ X if (Topcard > Deck && cango && diff <= 100 X && diff / Value[card] > count[card] X && (card == C_25 || diff % 50 == 0)) { X if (card == C_50 && diff - 50 == 25 X && count[C_25] > 0) X goto okay; X *value = 0; X if (--cango <= 0) X goto redoit; X break; X } Xokay: X *value = (Value[card] >> 3); X if (pp->speed == C_LIMIT) X ++*value; X else X --*value; X if (!foundlow X && (card == C_50 || count[C_50] == 0)) { X *value = (pp->mileage ? 10 : 20); X foundlow = TRUE; X } X goto miles; X case C_200: X if (++count200 > 2) { X *value = 0; X break; X } X case C_75: case C_100: X *value = (Value[card] >> 3); X if (pp->speed == C_LIMIT) X --*value; X else X ++*value; Xmiles: X if (pp->mileage + Value[card] > End) X *value = (End == 700 ? card : 0); X else if (pp->mileage + Value[card] == End) { X *value = (foundend ? card : V_VALUABLE); X foundend = TRUE; X } X break; X case C_END_LIMIT: X if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN) X *value = (pp->safety[S_RIGHT_WAY] == S_PLAYED ? -1 : 1); X else if (pp->speed == C_LIMIT && End - pp->mileage <= 50) X *value = 1; X else if (pp->speed == C_LIMIT X || Numseen[C_LIMIT] != Numcards[C_LIMIT]) { X safe = S_RIGHT_WAY; X oppos = C_LIMIT; X goto repair; X } X else { X *value = 0; X --count[C_END_LIMIT]; X } X break; X case C_REPAIRS: case C_SPARE: case C_GAS: X safe = safety(card) - S_CONV; X oppos = opposite(card); X if (pp->safety[safe] != S_UNKNOWN) X *value = (pp->safety[safe] == S_PLAYED ? -1 : 1); X else if (pp->battle != oppos X && (Numseen[oppos] == Numcards[oppos] || Numseen[oppos] + count[card] > Numcards[oppos])) { X *value = 0; X --count[card]; X } X else { Xrepair: X *value = Numcards[oppos] * 6; X *value += (Numseen[card] - Numseen[oppos]); X if (!cango) X *value /= (count[card]*count[card]); X count[card]--; X } X break; X case C_GO: X if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN) X *value = (pp->safety[S_RIGHT_WAY] == S_PLAYED ? -1 : 2); X else if (pp->can_go X && Numgos + count[C_GO] == Numneed[C_GO]) { X *value = 0; X --count[C_GO]; X } X else { X *value = Numneed[C_GO] * 3; X *value += (Numseen[C_GO] - Numgos); X *value /= (count[C_GO] * count[C_GO]); X count[C_GO]--; X } X break; X case C_LIMIT: X if (op->mileage + 50 >= End) { X *value = (End == 700 && !cango); X break; X } X if (canstop || (cango && !op->can_go)) X *value = 1; X else { X *value = (pp->safety[S_RIGHT_WAY] != S_UNKNOWN ? 2 : 3); X safe = S_RIGHT_WAY; X oppos = C_END_LIMIT; X goto normbad; X } X break; X case C_CRASH: case C_EMPTY: case C_FLAT: X safe = safety(card) - S_CONV; X oppos = opposite(card); X *value = (pp->safety[safe]!=S_UNKNOWN ? 3 : 4); Xnormbad: X if (op->safety[safe] == S_PLAYED) X *value = -1; X else { X *value *= (Numneed[oppos] + Numseen[oppos] + 2); X if (!pp->mileage || foundend || onecard(op)) X *value += 5; X if (op->mileage == 0 || onecard(op)) X *value += 5; X if (op->speed == C_LIMIT) X *value -= 3; X if (cango && pp->safety[safe] != S_UNKNOWN) X *value += 3; X if (!cango) X *value /= ++badcount; X } X break; X case C_STOP: X if (op->safety[S_RIGHT_WAY] == S_PLAYED) X *value = -1; X else { X *value = (pp->safety[S_RIGHT_WAY] != S_UNKNOWN ? 3 : 4); X *value *= (Numcards[C_STOP] + Numseen[C_GO]); X if (!pp->mileage || foundend || onecard(op)) X *value += 5; X if (!cango) X *value /= ++badcount; X if (op->mileage == 0) X *value += 5; X if ((card == C_LIMIT X && op->speed == C_LIMIT) || (!op->can_go)) X *value -= 5; X if (cango && pp->safety[S_RIGHT_WAY] != S_UNKNOWN) X *value += 5; X } X break; X case C_GAS_SAFE: case C_DRIVE_SAFE: X case C_SPARE_SAFE: case C_RIGHT_WAY: X *value = cango ? 0 : 101; X break; X case C_INIT: X *value = 0; X } X } X else X *value = cango ? 0 : 101; X if (card != C_INIT) { X if (*value >= curmax) { X nummax = i; X curmax = *value; X } X if (*value <= curmin) { X nummin = i; X curmin = *value; X } X } X if (Debug) X debug(i, "%3d %-14s",*value,C_name[pp->hand[i]]); X value++; X } X if (!pp->can_go && !isrepair(pp->battle)) X Numneed[opposite(pp->battle)]++; X if (cango) { X ComputerStatus ("PLAY\n"); X if (Debug) X getmove(); X if (!Debug || Movetype == M_DRAW) { X Movetype = M_PLAY; X Card_no = nummax; X } X } X else { X ComputerStatus ("DISCARD\n"); X if (Debug) X getmove(); X if (!Debug || Movetype == M_DRAW) { X Movetype = M_DISCARD; X Card_no = nummin; X } X } X ComputerCard (pp->hand[Card_no]); X} X Xonecard(pp) Xreg PLAY *pp; { X X reg CARD bat, spd, card; X X bat = pp->battle; X spd = pp->speed; X card = -1; X if (pp->can_go || ((isrepair(bat) || bat == C_STOP X || spd == C_LIMIT) && Numseen[S_RIGHT_WAY] != 0) X || Numseen[safety(bat)] != 0) X switch (End - pp->mileage) { X case 200: X if (pp->nummiles[C_200] == 2) X return FALSE; X card = C_200; X case 100: X case 75: X if (card == -1) X card = (End - pp->mileage == 75 ? C_75 : C_100); X if (spd == C_LIMIT) X return Numseen[S_RIGHT_WAY] == 0; X case 50: X case 25: X if (card == -1) X card = (End - pp->mileage == 25 ? C_25 : C_50); X return Numseen[card] != Numcards[card]; X } X return FALSE; X} X Xcanplay(pp, op, card) Xreg PLAY *pp, *op; Xreg CARD card; { X X switch (card) { X case C_200: X if (pp->nummiles[C_200] == 2) X break; X case C_75: case C_100: X if (pp->speed == C_LIMIT) X break; X case C_50: X if (pp->mileage + Value[card] > End) X break; X case C_25: X if (pp->can_go) X return TRUE; X break; X case C_EMPTY: case C_FLAT: case C_CRASH: X case C_STOP: X if (op->can_go && op->safety[safety(card) - S_CONV] != S_PLAYED) X return TRUE; X break; X case C_LIMIT: X if (op->speed != C_LIMIT && op->safety[S_RIGHT_WAY] != S_PLAYED X && op->mileage + 50 < End) X return TRUE; X break; X case C_GAS: case C_SPARE: case C_REPAIRS: X if (pp->battle == opposite(card)) X return TRUE; X break; X case C_GO: X if (!pp->can_go X && (isrepair(pp->battle) || pp->battle == C_STOP)) X return TRUE; X break; X case C_END_LIMIT: X if (pp->speed == C_LIMIT) X return TRUE; X } X return FALSE; X} END_OF_comp.c if test 9582 -ne `wc -c curses_ui.c <<'END_OF_curses_ui.c' X/* X * ui.c X * X * curses interface routines for mille X */ X X# include "mille.h" X#undef TRUE X#undef FALSE X# include "ui.h" X#ifdef CTRL X# undef CTRL X#endif X#define CTRL(x) (x - 'A' + 1) X XWINDOW *Board, *Miles, *Score; X Xchar *C_fmt = "%-18.18s"; /* format for printing cards */ Xchar Initstr[100]; /* initial string for error field */ Xchar *_cn[NUM_CARDS] = { /* Card name buffer */ X "", X "25", X "50", X "75", X "100", X "200", X "Out of Gas", X "Flat Tire", X "Accident", X "Stop", X "Speed Limit", X "Gasoline", X "Spare Tire", X "Repairs", X "Go", X "End of Limit", X "Extra Tank", X "Puncture Proof", X "Driving Ace", X "Right of Way" X }, X **C_name = &_cn[1]; /* Card names */ X XMessage (string) Xchar *string; X{ X wmove (Score, ERR_Y, ERR_X); X waddstr (Score, string); X wclrtoeol (Score); X} X Xdebug (pos, string, a0, a1, a2) X{ X mvprintw (pos+6, 2, string, a0, a1, a2); X} X XComputerStatus (string) X{ X mvaddstr (MOVE_Y + 1, MOVE_X, string); X} X XComputerCard (type) Xint type; X{ X mvprintw (MOVE_Y + 2, MOVE_X, "%16s", C_name[type]); X} X X XPrompt (string) Xchar *string; X{ X mvaddstr (MOVE_Y, MOVE_X, string); X clrtoeol (); X refresh (); X} X Xchar * XGetpromptedInput (string) Xchar *string; X{ X static char buf[1024]; X char *sp; X X sp = buf; X Prompt (string); X leaveok (Board, FALSE); X while ((*sp = readch()) != '\n') { X if (*sp == _tty.sg_kill) { X sp = buf; X break; X } X else if (*sp == _tty.sg_erase) { X if (--sp < buf) X sp = buf; X else { X addch('\b'); X /* X * if the previous char was a control X * char, cover up two characters. X */ X if (*sp < ' ') X addch('\b'); X clrtoeol(); X } X } X else X addstr(unctrl(*sp++)); X refresh(); X } X *sp = '\0'; X leaveok (Board, TRUE); X return buf; X} X Xnewboard() X{ X werase(Board); X werase(Score); X mvaddstr(5, 0, "--HAND--"); X mvaddch(6, 0, 'P'); X mvaddch(7, 0, '1'); X mvaddch(8, 0, '2'); X mvaddch(9, 0, '3'); X mvaddch(10, 0, '4'); X mvaddch(11, 0, '5'); X mvaddch(12, 0, '6'); X mvaddstr(13, 0, "--BATTLE--"); X mvaddstr(15, 0, "--SPEED--"); X mvaddstr(5, 20, "--DECK--"); X mvaddstr(7, 20, "--DISCARD--"); X mvaddstr(13, 20, "--BATTLE--"); X mvaddstr(15, 20, "--SPEED--"); X wmove(Miles, 0, 0); X if (winch(Miles) != '-') { X werase(Miles); X mvwaddstr(Miles, 0, 0, "--MILEAGE--"); X mvwaddstr(Miles, 0, 41, "--MILEAGE--"); X } X else { X wmove(Miles, 1, 0); X wclrtobot(Miles); X } X newscore(); X stdscr = Board; X} X Xnewscore() { X X reg int i; X X stdscr = Score; X move(0, 22); X if (inch() != 'Y') { X erase(); X mvaddstr(0, 22, "You Comp Value"); X mvaddstr(1, 2, "Milestones Played"); X mvaddstr(2, 8, "Each Safety"); X mvaddstr(3, 5, "All 4 Safeties"); X mvaddstr(4, 3, "Each Coup Fourre"); X mvaddstr(2, 37, "100"); X mvaddstr(3, 37, "300"); X mvaddstr(4, 37, "300"); X } X else { X move(5, 1); X clrtobot(); X } X for (i = 0; i < SCORE_Y; i++) X mvaddch(i, 0, '|'); X move(SCORE_Y - 1, 1); X while (addch('_') != ERR) X continue; X if (WIndow == W_FULL || Finished) { X mvaddstr(5, 5, "Trip Completed"); X mvaddstr(6, 10, "Safe Trip"); X mvaddstr(7, 5, "Delayed Action"); X mvaddstr(8, 10, "Extension"); X mvaddstr(9, 11, "Shut-Out"); X mvaddstr(10, 21, "---- ---- -----"); X mvaddstr(11, 9, "Hand Total"); X mvaddstr(12, 20, "----- -----"); X mvaddstr(13, 6, "Overall Total"); X mvaddstr(14, 15, "Games"); X mvaddstr(5, 37, "400"); X mvaddstr(6, 37, "300"); X mvaddstr(7, 37, "300"); X mvaddstr(8, 37, "200"); X mvaddstr(9, 37, "500"); X } X else { X mvaddstr(5, 21, "---- ---- -----"); X mvaddstr(6, 9, "Hand Total"); X mvaddstr(7, 20, "----- -----"); X mvaddstr(8, 6, "Overall Total"); X mvaddstr(9, 15, "Games"); X mvaddstr(11, 2, "p: pick"); X mvaddstr(12, 2, "u: use #"); X mvaddstr(13, 2, "d: discard #"); X mvaddstr(14, 2, "w: toggle window"); X mvaddstr(11, 21, "q: quit"); X mvaddstr(12, 21, "o: order hand"); X mvaddstr(13, 21, "s: save"); X mvaddstr(14, 21, "r: reprint"); X } X stdscr = Board; X} X Xinit_ui () X{ X initscr(); X# ifdef attron X# define CA cursor_address X# endif X if (!CA) { X printf("Sorry. Need cursor addressing to play mille\n"); X exit(-1); X } X delwin(stdscr); X stdscr = Board = newwin(BOARD_Y, BOARD_X, 0, 0); X Score = newwin(SCORE_Y, SCORE_X, 0, 40); X Miles = newwin(MILES_Y, MILES_X, 17, 0); X#ifdef attron X idlok(Board, TRUE); X idlok(Score, TRUE); X idlok(Miles, TRUE); X#endif X leaveok(Score, TRUE); X leaveok(Miles, TRUE); X clearok(curscr, TRUE); X crmode(); X noecho(); X} X XError (string, arg) Xchar *string; X{ X stdscr = Score; X mvprintw (Score, ERR_Y, ERR_X, string, arg); X clrtoeol (); X stdscr = Board; X} X Xfinish_ui () X{ X mvcur(0, COLS - 1, LINES - 1, 0); X endwin(); X} X Xupdate_ui () X{ X refresh (); X} X XBeep () X{ X putchar ('\007'); X} X XCARD Xgetcard() X{ X reg char c, c1; X X for (;;) { X while ((c = readch()) == '\n' || c == '\r' || c == ' ') X continue; X if (islower(c)) X c = toupper(c); X if (c == _tty.sg_kill || c == _tty.sg_erase) X return -1; X addstr(unctrl(c)); X clrtoeol(); X switch (c) { X case '1': case '2': case '3': X case '4': case '5': case '6': X c -= '0'; X break; X case '0': case 'P': case 'p': X c = 0; X break; X default: X putchar(''); X addch('\b'); X if (!isprint(c)) X addch('\b'); X c = -1; X break; X } X refresh(); X if (c >= 0) { X while ((c1=readch()) != '\r' && c1 != '\n' && c1 != ' ') X if (c1 == _tty.sg_kill) X return -1; X else if (c1 == _tty.sg_erase) { X addch('\b'); X clrtoeol(); X refresh(); X goto cont; X } X else X write(0, "", 1); X return c; X } Xcont: ; X } X} X X X/* X * Get a yes or no answer to the given question. Saves are X * also allowed. Return TRUE if the answer was yes, FALSE if no. X */ Xgetyn(prompt) Xreg char *prompt; { X X reg char c; X X Saved = FALSE; X for (;;) { X leaveok(Board, FALSE); X mvaddstr(MOVE_Y, MOVE_X, prompt); X clrtoeol(); X refresh(); X switch (c = readch()) { X case 'n': case 'N': X addch('N'); X refresh(); X leaveok(Board, TRUE); X return FALSE; X case 'y': case 'Y': X addch('Y'); X refresh(); X leaveok(Board, TRUE); X return TRUE; X case 's': case 'S': X addch('S'); X refresh(); X Saved = save(); X continue; X default: X addstr(unctrl(c)); X refresh(); X putchar(''); X break; X } X } X} X Xreadch() X{ X reg int cnt; X static char c; X X for (cnt = 0; read(0, &c, 1) <= 0; cnt++) X if (cnt > 100) X exit(1); X return c; X} X X Xgetmove() X{ X reg char c, *sp; X static char moveprompt[] = ">>:Move:"; X#ifdef EXTRAP X static bool last_ex = FALSE; /* set if last command was E */ X X if (last_ex) { X undoex(); X prboard(); X last_ex = FALSE; X } X#endif X for (;;) { X stand(MOVE_Y, MOVE_X, moveprompt); X clrtoeol(); X move(MOVE_Y, MOVE_X + sizeof moveprompt); X leaveok(Board, FALSE); X refresh(); X while ((c = readch()) == _tty.sg_kill || c == _tty.sg_erase) X continue; X if (islower(c)) X c = toupper(c); X if (isprint(c) && !isspace(c)) { X addch(c); X refresh(); X } X switch (c) X { X case 'P': /* Pick */ X Movetype = M_DRAW; X goto ret; X case 'U': /* Use Card */ X case 'D': /* Discard Card */ X if ((Card_no = getcard()) < 0) X break; X Movetype = (c == 'U' ? M_PLAY : M_DISCARD); X goto ret; X case 'O': /* Order */ X Order = !Order; X Movetype = M_ORDER; X goto ret; X case 'Q': /* Quit */ X rub(); /* Same as a rubout */ X break; X case 'W': /* WIndow toggle */ X WIndow = nextwin(WIndow); X newscore(); X prscore(TRUE); X wrefresh(Score); X break; X case 'R': /* Redraw screen */ X case CTRL('L'): X clearok(curscr, TRUE); X newboard(); X prboard(); X break; X case 'S': /* Save game */ X On_exit = FALSE; X save(); X break; X case 'E': /* Extrapolate */ X#ifdef EXTRAP X if (last_ex) X break; X Finished = TRUE; X if (WIndow != W_FULL) X newscore(); X prscore(FALSE); X wrefresh(Score); X last_ex = TRUE; X Finished = FALSE; X#else X error("%c: command not implemented", c); X#endif X break; X case '\r': /* Ignore RETURNs and */ X case '\n': /* Line Feeds */ X case ' ': /* Spaces */ X case '\0': /* and nulls */ X break; X case 'Z': /* Debug code */ X if (geteuid() == ARNOLD) { X if (!Debug && outf == NULL) { X char buf[40]; Xover: X mvaddstr(MOVE_Y, MOVE_X, "file: "); X clrtoeol(); X leaveok(Board, FALSE); X refresh(); X sp = buf; X while ((*sp = readch()) != '\n') { X if (*sp == _tty.sg_kill) X goto over; X else if (*sp == _tty.sg_erase) { X if (--sp < buf) X sp = buf; X else { X addch('\b'); X if (*sp < ' ') X addch('\b'); X clrtoeol(); X } X } X else X addstr(unctrl(*sp++)); X refresh(); X } X *sp = '\0'; X leaveok(Board, TRUE); X if ((outf = fopen(buf, "w")) == NULL) X perror(buf); X setbuf(outf, 0); X } X Debug = !Debug; X break; X } X /* FALLTHROUGH */ X default: X error("unknown command: %s", unctrl(c)); X break; X } X } Xret: X leaveok(Board, TRUE); X} X X X# define COMP_STRT 20 X# define CARD_STRT 2 X Xprboard() { X X reg PLAY *pp; X reg int i, j, k, temp; X X for (k = 0; k < 2; k++) { X pp = &Player[k]; X temp = k * COMP_STRT + CARD_STRT; X for (i = 0; i < NUM_SAFE; i++) X if (pp->safety[i] == S_PLAYED) { X mvaddstr(i, temp, C_name[i + S_CONV]); X if (pp->coups[i]) X mvaddch(i, temp - CARD_STRT, '*'); X } X mvprintw(14, temp, C_fmt, C_name[pp->battle]); X mvprintw(16, temp, C_fmt, C_name[pp->speed]); X for (i = C_25; i <= C_200; ) { X reg char *name; X reg int end; X X name = C_name[i]; X temp = k * 40; X end = pp->nummiles[i++]; X for (j = 0; j < end; j++) X mvwaddstr(Miles, i, (j << 2) + temp, name); X } X } X prscore(TRUE); X temp = CARD_STRT; X pp = &Player[PLAYER]; X for (i = 0; i < HAND_SZ; i++) X mvprintw(i + 6, temp, C_fmt, C_name[pp->hand[i]]); X mvprintw(6, COMP_STRT + CARD_STRT, "%2d", Topcard - Deck); X mvprintw(8, COMP_STRT + CARD_STRT, C_fmt, C_name[Discard]); X if (End == 1000) { X static char ext[] = "Extension"; X X stand(EXT_Y, EXT_X, ext); X } X wrefresh(Board); X wrefresh(Miles); X wrefresh(Score); X} X X/* X * Put str at (y,x) in standout mode X */ Xstand(y, x, str) Xreg int y, x; Xreg char *str; { X X standout(); X mvaddstr(y, x, str); X standend(); X return TRUE; X} X Xprscore(for_real) Xreg bool for_real; { X X reg PLAY *pp; X reg int x; X reg char *Score_fmt = "%4d"; X X stdscr = Score; X for (pp = Player; pp < &Player[2]; pp++) { X x = (pp - Player) * 6 + 21; X mvprintw(1, x, Score_fmt, pp->mileage); X mvprintw(2, x, Score_fmt, pp->safescore); X if (pp->safescore == 400) X mvaddstr(3, x + 1, "300"); X else X mvaddch(3, x + 3, '0'); X mvprintw(4, x, Score_fmt, pp->coupscore); X if (WIndow == W_FULL || Finished) { X#ifdef EXTRAP X if (for_real) X finalscore(pp); X else X extrapolate(pp); X#else X finalscore(pp); X#endif X mvprintw(11, x, Score_fmt, pp->hand_tot); X mvprintw(13, x, Score_fmt, pp->total); X mvprintw(14, x, Score_fmt, pp->games); X } X else { X mvprintw(6, x, Score_fmt, pp->hand_tot); X mvprintw(8, x, Score_fmt, pp->total); X mvprintw(9, x, Score_fmt, pp->games); X } X } X stdscr = Board; X} X XFlushInput () X{ X raw(); /* Flush input */ X noraw(); X X} END_OF_curses_ui.c if test 10994 -ne `wc -c drawcard.c <<'END_OF_drawcard.c' X/* X * drawcard.c X * X * display cards on the table X */ X X# include "mille.h" X# include "ui.h" X# include "card.h" X Xstruct card_init { X short *bits; X short *mask; X int color; X}; X Xextern short go_bits[], go_mask_bits[]; Xextern short stop_bits[], stop_mask_bits[]; Xextern short right_bits[], right_mask_bits[]; Xextern short speed_bits[], speed_mask_bits[]; Xextern short end_bits[], end_mask_bits[]; Xextern short accident_bits[], accident_mask_bits[]; Xextern short repairs_bits[], repairs_mask_bits[]; Xextern short ace_bits[], ace_mask_bits[]; Xextern short flat_bits[], flat_mask_bits[]; Xextern short spare_bits[], spare_mask_bits[]; Xextern short puncture_bits[], puncture_mask_bits[]; Xextern short out_bits[], out_mask_bits[]; Xextern short gas_bits[], gas_mask_bits[]; Xextern short extra_bits[], extra_mask_bits[]; Xextern short miles_mask_bits[]; Xextern short _25_bits[], _50_bits[], _75_bits[], _100_bits[], _200_bits[]; X Xstruct card_init card_inits[NUM_CARDS] = { X{ _25_bits, miles_mask_bits, BLUE_COLOR, }, X{ _50_bits, miles_mask_bits, BLUE_COLOR, }, X{ _75_bits, miles_mask_bits, BLUE_COLOR, }, X{ _100_bits, miles_mask_bits, BLUE_COLOR, }, X{ _200_bits, miles_mask_bits, BLUE_COLOR, }, X{ out_bits, out_mask_bits, RED_COLOR, }, X{ flat_bits, flat_mask_bits, RED_COLOR, }, X{ accident_bits, accident_mask_bits, RED_COLOR, }, X{ stop_bits, stop_mask_bits, RED_COLOR, }, X{ speed_bits, speed_mask_bits, RED_COLOR, }, X{ gas_bits, gas_mask_bits, GREEN_COLOR, }, X{ spare_bits, spare_mask_bits, GREEN_COLOR, }, X{ repairs_bits, repairs_mask_bits, GREEN_COLOR, }, X{ go_bits, go_mask_bits, GREEN_COLOR, }, X{ end_bits, end_mask_bits, GREEN_COLOR, }, X{ extra_bits, extra_mask_bits, BLUE_COLOR, }, X{ puncture_bits, puncture_mask_bits, BLUE_COLOR, }, X{ ace_bits, ace_mask_bits, BLUE_COLOR, }, X{ right_bits, right_mask_bits, RED_COLOR, }, X}; X Xextern short deck_red_bits[], deck_blue_bits[], deck_mask_bits[]; X Xextern short blank_bits[]; X Xstruct card cards[NUM_CARDS]; X Xstruct card backside; Xstruct card eraseCard; X X Xinit_cards () X{ X int i; X for (i = 0; i < NUM_CARDS; i++) { X cards[i].planes[2].bits = XStoreBitmap (WIDTH, HEIGHT, card_inits[i].bits); X cards[i].planes[2].pixel = colorMap[card_inits[i].color].pixel; X cards[i].planes[1].bits = XStoreBitmap (WIDTH, HEIGHT, card_inits[i].mask); X cards[i].planes[1].pixel = colorMap[BLACK_COLOR].pixel; X cards[i].planes[0].bits = fill; X cards[i].planes[0].pixel = colorMap[WHITE_COLOR].pixel; X cards[i].nPlanes = 3; X } X backside.planes[3].bits = XStoreBitmap (WIDTH, HEIGHT, deck_red_bits); X backside.planes[3].pixel = colorMap[RED_COLOR].pixel; X backside.planes[2].bits = XStoreBitmap (WIDTH, HEIGHT, deck_blue_bits); X backside.planes[2].pixel = colorMap[BLUE_COLOR].pixel; X backside.planes[1].bits = XStoreBitmap (WIDTH, HEIGHT, deck_mask_bits); X backside.planes[1].pixel = colorMap[BLACK_COLOR].pixel; X backside.planes[0].bits = fill; X backside.planes[0].pixel = colorMap[GREEN_COLOR].pixel; X backside.nPlanes = 4; X eraseCard.planes[0].bits = XStoreBitmap (WIDTH, HEIGHT, blank_bits); X eraseCard.planes[0].pixel = colorMap[GREY_COLOR].pixel; X eraseCard.nPlanes = 1; X} X XdisplayCard (card, x, y) Xint card; Xint x, y; X{ X if (card < 0 || card >= NUM_CARDS) { X cardDisplay (&eraseCard, x, y); X } else { X cardDisplay (&cards[card], x, y); X } X} X Xstruct displayed { X struct displayed *next; X struct card *card; X int x, y; X int flag; X}; X Xstatic struct displayed *onscreen; X XcardDisplay (c, x, y) Xstruct card *c; X{ X int i; X struct displayed *d, *p; X char *malloc (); X X p = 0; X for (d = onscreen; d; d = d->next) { X if (d->x == x && d->y == y) { X if (d->card == c) X return; X if (p) { X p->next = d->next; X d->next = onscreen; X onscreen = d; X } X goto gotim; X } X p = d; X } X d = (struct displayed *) malloc (sizeof (struct displayed)); X d->x = x; X d->y = y; X if (p) X p->next = d; X else X onscreen = d; X d->next = 0; Xgotim: ; X d->card = c; X drawIm (c, x, y); X} X Xstatic XdrawIm (c, x, y) Xstruct card *c; Xint x, y; X{ X int i; X X for (i = 0; i < c->nPlanes; i++) { X XPixFill (xwindow, x, y, WIDTH, HEIGHT, X c->planes[i].pixel, c->planes[i].bits, GXcopy, AllPlanes); X } X} X XcardRedisplay (x, y, w, h) X{ X struct displayed *d; X X for (d = onscreen; d; d = d->next) X d->flag = 0; X redisplaybelow (onscreen, x, y, w, h); X} X Xstatic Xredisplaybelow (d, x, y, w, h) Xstruct displayed *d; X{ X int x2, y2; X X x2 = x + w; X y2 = y + h; X for (; d; d = d->next) { X if ((d->x <= x2 && x <= (d->x + WIDTH)) && X (d->y <= y2 && y <= (d->y + HEIGHT))) X { X if (d->flag == 0) { X drawIm (d->card, d->x, d->y); X d->flag = 1; X redisplaybelow (d->next, d->x, d->y, WIDTH, HEIGHT); X } X } X } X X} X XcardEraseAll () X{ X struct displayed *d, *n; X X for (d = onscreen; d; d = n) { X n = d->next; X free (d); X } X onscreen = 0; X} END_OF_drawcard.c if test 4771 -ne `wc -c end.c <<'END_OF_end.c' X# include "mille.h" X X/* X * @(#)end.c 1.1 (Berkeley) 4/1/82 X */ X X/* X * print out the score as if it was final, and add the totals for X * the end-of-games points to the user who deserves it (if any). X */ Xfinalscore(pp) Xreg PLAY *pp; { X X reg int temp, tot, num; X X num = pp - Player; X for (tot = 4; tot <= 8; tot++) { X InScore (tot, num, " 0 "); X } X if (pp->mileage == End) { X InScore (4, num, " 400 "); X tot = SC_TRIP; X if (pp->nummiles[C_200] == 0) { X InScore (5, num, " 300 "); X tot = SC_TRIP + SC_SAFE; X } X if (Topcard <= Deck) { X InScore (6, num, " 300 "); X tot += SC_DELAY; X } X if (End == 1000) { X InScore (7, num, " 200 "); X tot += SC_EXTENSION; X } X if (Player[other(num)].mileage == 0) { X InScore (8, num, " 500 "); X tot += SC_SHUT_OUT; X } X pp->total += tot; X pp->hand_tot += tot; X } X} X X# ifdef EXTRAP Xstatic int Last_tot[2]; /* last tot used for extrapolate */ X X/* X * print out the score as if it was final, and add the totals for X * the end-of-games points to the user who deserves it (if any). X */ Xextrapolate(pp) Xreg PLAY *pp; { X X reg int x, num, tot, count; X X#ifdef NOTYET X num = pp - Player; X tot += SC_TRIP + SC_DELAY + SC_EXT; X x = num * 6 + 21 + 3; X for (tot = 5; tot <= 9; tot++) X mvaddch(tot, x, '0'); X x -= 2; X pp = &Player[other(num)]; X for (count = 0, tot = 0; tot < NUM_SAFE; tot++) X if (pp->safety[tot] != S_PLAYED) X count += SC_SAFE; X mvprintw(3, x, "%3d", count); X tot += count; X if (count == 400) { X mvaddstr(4, x, "30"); X tot += SC_ALL_SAFE; X } X pp = &Player[num]; X for (count = 0, tot = 0; tot < NUM_SAFE; tot++) X if (pp->safety[tot] != S_PLAYED) X count += SC_COUP / 10; X mvprintw(4, x - 1, "%3d", count); X tot += count; X tot += 1000 - pp->mileage; X mvaddstr(5, x, "40"); X mvaddstr(7, x, "30"); X mvaddstr(8, x, "20"); X if (pp->nummiles[C_200] == 0) { X mvaddstr(6, x, "30"); X tot = SC_TRIP + SC_SAFE; X } X if (Player[other(num)].mileage == 0) { X mvaddstr(9, x, "50"); X tot += SC_SHUT_OUT; X } X pp->total += tot; X pp->hand_tot += tot; X Last_tot[num] = tot; X#endif X} X Xundoex() { X X reg PLAY *pp; X reg int i; X X i = 0; X for (pp = Player; pp < &Player[2]; pp++) { X pp->total -= Last_tot[i]; X pp->hand_tot -= Last_tot[i++]; X } X} X# endif END_OF_end.c if test 2207 -ne `wc -c fill <<'END_OF_fill' X#define fill_width 100 X#define fill_height 150 Xstatic short fill_bits[] = { X 0x0000, 0x0000, 0x0000, 0x0000, X 0x0000, 0x0000, 0xfff0, 0xff00, X 0xffff, 0xffff, 0xffff, 0xffff, X 0x0fff, 0xfff0, 0xffc0, 0xffff, X 0xffff, 0xffff, 0xffff, 0x3fff, X 0xfff0, 0xfff0, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff0, X 0xfff8, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff1, 0xfff8, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff1, 0xfffc, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff3, 0xfffc, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff3, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffe, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff7, 0xfffe, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff7, X 0xfffe, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff7, 0xfffe, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff7, 0xfffc, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff3, 0xfffc, 0xffff, 0xffff, X 0xffff, 0xffff, 0xffff, 0xfff3, X 0xfff8, 0xffff, 0xffff, 0xffff, X 0xffff, 0xffff, 0xfff1, 0xfff8, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xffff, 0xfff1, 0xfff0, 0xffff, X 0xffff, 0xffff, 0xffff, 0xffff, X 0xfff0, 0xffc0, 0xffff, 0xffff, X 0xffff, 0xffff, 0x3fff, 0xfff0, X 0xff00, 0xffff, 0xffff, 0xffff, X 0xffff, 0x0fff, 0xfff0, 0x0000, X 0x0000, 0x0000, 0x0000, 0x0000, X 0x0000, 0xfff0}; END_OF_fill if test 9266 -ne `wc -c ui.c <<'END_OF_ui.c' X/* X * ui.c X * X * interface routines for mille X */ X X# include "mille.h" X# include "ui.h" X X#ifdef CTRL X# undef CTRL X#endif X#define CTRL(x) (x - 'A' + 1) X X# include "background.h" X# include "card.h" X Xstruct color colorMap[NUM_COLOR] = { X "black", 0, X "white", 0, X "red", 0, X "green", 0, X "light gray", 0, X "blue", 0, X}; X Xchar *C_fmt = "%-18.18s"; /* format for printing cards */ Xchar Initstr[100]; /* initial string for error field */ Xchar *_cn[NUM_CARDS] = { /* Card name buffer */ X "", X "25", X "50", X "75", X "100", X "200", X "Out of Gas", X "Flat Tire", X "Accident", X "Stop", X "Speed Limit", X "Gasoline", X "Spare Tire", X "Repairs", X "Go", X "End of Limit", X "Extra Tank", X "Puncture Proof", X "Driving Ace", X "Right of Way" X }, X **C_name = &_cn[1]; /* Card names */ X XWindow xwindow; XFontInfo *font; XBitmap fill; XButton QUIT, SAVE; XWindow qwindow, swindow; X Xstruct safety_offset safety_offsets[4] = { X 0, 0, X WIDTH+PAD_CARD, 0, X 0, HEIGHT+PAD_CARD, X WIDTH+PAD_CARD, HEIGHT+PAD_CARD, X}; X Xchar * Xprune (orig, max) Xchar *orig; X{ X static char buf[512]; X int len; X char c; X X if (XStringWidth (orig, font, 0, 0) < max) X return orig; X strcpy (buf, orig); X len = strlen (orig); X do { X buf[--len] = '\0'; X } while (len > 0 && XStringWidth (buf, font, 0, 0) >= max); X return buf; X} X XMessage (string) Xchar *string; X{ X string = prune (string, MESS_W); X XPixSet (xwindow, MESS_X, MESS_Y, MESS_W, MESS_H, colorMap[GREY_COLOR].pixel); X XText (xwindow, MESS_X, MESS_Y, string, strlen(string), font->id, X colorMap[BLACK_COLOR].pixel, colorMap[GREY_COLOR].pixel); X} X XError (string, arg) Xchar *string; X{ X char buf[512]; X char *o; X X sprintf (buf, string, arg); X o = prune (buf, ERROR_W); X XPixSet (xwindow, ERROR_X, ERROR_Y, ERROR_W, ERROR_H, colorMap[GREY_COLOR].pixel); X XText (xwindow, ERROR_X, ERROR_Y, o, strlen(o), font->id, X colorMap[BLACK_COLOR].pixel, colorMap[GREY_COLOR].pixel); X} X XPrompt (string) Xchar *string; X{ X string = prune (string, PROMPT_W); X XPixSet (xwindow, PROMPT_X, PROMPT_Y, PROMPT_W, PROMPT_H, colorMap[GREY_COLOR].pixel); X XText (xwindow, PROMPT_X, PROMPT_Y, string, strlen(string), font->id, X colorMap[BLACK_COLOR].pixel, colorMap[GREY_COLOR].pixel); X} X Xdebug (pos, string, a0, a1, a2) X{ X} X XComputerStatus (string) X{ X char buffer[512]; X/* X sprintf (buffer, "I %-10.10s", string); X XText (xwindow, COMP_CARD_TX, COMP_CARD_TY, buffer, strlen(buffer), font->id, X colorMap[BLACK_COLOR].pixel, colorMap[GREY_COLOR].pixel); X*/ X} X XComputerCard (type) Xint type; X{ X/* displayCard (type, COMP_CARD_X, COMP_CARD_Y);*/ X} X Xstatic int computer_distance = 0; X XComputerDistance (distance) X{ X displayDistance (COMP_DIST_X, COMP_DIST_Y, distance, DIST_WIDTH, DIST_HEIGHT); X computer_distance = distance; X} X XEraseComputerDistance () X{ X computer_distance = 0; X} X XRedisplayComputerDistance () X{ X displayDistance (COMP_DIST_X, COMP_DIST_Y, computer_distance, DIST_WIDTH, DIST_HEIGHT); X} X XComputerSpeed (type) X{ X displayCard (type, COMP_PLAY_X, COMP_PLAY_Y); X} X XComputerBattle (type) X{ X displayCard (type, COMP_PLAY_X + WIDTH + PAD_CARD, COMP_PLAY_Y); X} X Xstatic int computer_miles_count[5]; X XComputerMiles (type, index, count) X{ X while (computer_miles_count[index] < count) { X displayCard (type, COMP_PLAY_X + (WIDTH + PAD_CARD) * (index + 2), X COMP_PLAY_Y + (MILE_OFFSET * computer_miles_count[index])); X ++computer_miles_count[index]; X } X} X XEraseComputerMiles () X{ X int i; X X for (i = 0; i < 5; i++) X computer_miles_count[i] = 0; X} X XComputerSafety (type, index) X{ X displayCard (type, COMP_SAFE_X + safety_offsets[index].x, X COMP_SAFE_Y + safety_offsets[index].y); X} X XDisplayDiscard (type) X{ X displayCard (type, DISCARD_X, DISCARD_Y); X} X XDisplayDeck (numberLeft) X{ X char buffer[512]; X X sprintf (buffer, "Cards: %3d ", numberLeft); X XText (xwindow, DECK_TX, DECK_TY, buffer, strlen (buffer), font->id, X colorMap[BLACK_COLOR].pixel, colorMap[GREY_COLOR].pixel); X} X Xstatic int human_distance = 0; X XHumanDistance (distance) X{ X displayDistance (HUM_DIST_X, HUM_DIST_Y, distance, DIST_WIDTH, DIST_HEIGHT); X human_distance = distance; X} X XEraseHumanDistance () X{ X human_distance = 0; X} X XRedisplayHumanDistance () X{ X displayDistance (HUM_DIST_X, HUM_DIST_Y, human_distance, DIST_WIDTH, DIST_HEIGHT); X} X XHumanSpeed (type) X{ X displayCard (type, HUM_PLAY_X, HUM_PLAY_Y); X} X XHumanBattle (type) X{ X displayCard (type, HUM_PLAY_X + WIDTH + PAD_CARD, HUM_PLAY_Y); X} X Xstatic int human_miles_count[5]; X XHumanMiles (type, index, count) X{ X while (human_miles_count[index] < count) { X displayCard (type, HUM_PLAY_X + (WIDTH + PAD_CARD) * (index + 2), X HUM_PLAY_Y + (MILE_OFFSET * human_miles_count[index])); X ++human_miles_count[index]; X } X} X XEraseHumanMiles () X{ X int i; X X for (i = 0; i < 5; i++) X human_miles_count[i] = 0; X} X XHumanSafety (type, index) X{ X displayCard (type, HUM_SAFE_X + safety_offsets[index].x, X HUM_SAFE_Y + safety_offsets[index].y); X} X XHumanHand (type, index) Xint type, index; X{ X displayCard (type, HUM_HAND_X + (WIDTH + PAD_CARD) * index, HUM_HAND_Y); X} X XdisplayDistance (x, y, value, width, height) X{ X XPixSet (xwindow, x, y, (value * width) / 1000, height, colorMap[BLUE_COLOR].pixel); X} X XeraseDistance (x, y, value, width, height) X{ X XPixSet (xwindow, x, y, (value * width) / 1000, height, colorMap[GREY_COLOR].pixel); X} X Xchar * XGetpromptedInput (string) Xchar *string; X{ X extern char *co_prompted (); X X return co_prompted (string); X} X Xnewboard() X{ X int i; X char buffer[20]; X int len; X int x, y1, y2, ym1, ym2; X int width; X X XClear (xwindow); X cardEraseAll (); X EraseHumanMiles (); X EraseComputerMiles (); X EraseHumanDistance (); X EraseComputerDistance (); X cardDisplay (&backside, DECK_X, DECK_Y); X redraw_board (); X} X Xnewscore() X{ X register int i; X X InScore (-1, 0, "You"); X InScore (-1, 1, "Computer"); X InScore (0, -1, "Milestones"); X InScore (1, -1, "Safeties"); X InScore (2, -1, "All 4 Safeties"); X InScore (3, -1, "Coup Fourre"); X InScore (4, -1, "Trip Complete"); X InScore (5, -1, "Safe Trip"); X InScore (6, -1, "Delayed Action"); X InScore (7, -1, "Extension"); X InScore (8, -1, "Shut Out"); X InScore (9, -1, "Hand Total"); X InScore (10, -1, "Overall Total"); X InScore (11, -1, "Games"); X} X Xredraw_board () X{ X redraw_region (0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); X} X XexposeBoard (rep) XXExposeEvent *rep; X{ X redraw_region (rep->x, rep->y, rep->width, rep->height); X} X Xredraw_region (xpos, ypos, w, h) X{ X int x1, y1, x2, y2; X int i; X int ym1, ym2, x; X char buffer[20]; X int width; X X XText (xwindow, DISCARD_TX, DISCARD_TY, "Discard Pile", 12, font->id, X colorMap[BLACK_COLOR].pixel, colorMap[GREY_COLOR].pixel); X newscore (); X RedisplayHumanDistance (); X RedisplayComputerDistance (); X x1 = HUM_HAND_X - PAD_CARD/2; X y1 = HUM_HAND_Y - PAD_CARD/2, X x2 = HUM_HAND_X + (WIDTH + PAD_CARD) * 7 - PAD_CARD/2; X y2 = HUM_HAND_Y + (HEIGHT + PAD_CARD) - PAD_CARD/2; X XLine (xwindow, x1, y1, x2, y1, 1, 1, colorMap[BLACK_COLOR].pixel, GXcopy, AllPlanes); X XLine (xwindow, x2, y1, x2, y2, 1, 1, colorMap[BLACK_COLOR].pixel, GXcopy, AllPlanes); X XLine (xwindow, x2, y2, x1, y2, 1, 1, colorMap[BLACK_COLOR].pixel, GXcopy, AllPlanes); X XLine (xwindow, x1, y2, x1, y1, 1, 1, colorMap[BLACK_COLOR].pixel, GXcopy, AllPlanes); X for (i = 0; i <= 1000; i += 100) { X sprintf (buffer, "%d", i); X x = COMP_DIST_TX + (i * DIST_WIDTH) / 1000; X y1 = COMP_DIST_TY; X ym1 = COMP_DIST_MY; X y2 = HUM_DIST_TY; X ym2 = HUM_DIST_MY; X width = XQueryWidth (buffer, font->id); X XText (xwindow, x - width / 2, y1, buffer, strlen(buffer), font->id, X colorMap[BLACK_COLOR].pixel, colorMap[GREY_COLOR].pixel); X XLine (xwindow, x, ym1, x, ym1 + DIST_MARK, 1, 1, colorMap[BLACK_COLOR].pixel, GXcopy, AllPlanes); X XText (xwindow, x - width / 2, y2, buffer, strlen(buffer), font->id, X colorMap[BLACK_COLOR].pixel, colorMap[GREY_COLOR].pixel); X XLine (xwindow, x, ym2, x, ym2 + DIST_MARK, 1, 1, colorMap[BLACK_COLOR].pixel, GXcopy, AllPlanes); X } X cardRedisplay (xpos, ypos, w, h); X} X Xinit_ui () X{ X Color hardware_color, exact_color; X XEvent rep; X Pixmap background; X Pixmap border; X int i; X int do_quit (), do_save (); X int CmanageButton (); X X XOpenDisplay (""); X for (i = 0; i < NUM_COLOR; i++) { X XGetColor (colorMap[i].name, &hardware_color, &exact_color); X colorMap[i].pixel = hardware_color.pixel; X } X fill = XStoreBitmap (WIDTH, HEIGHT, fill_bits); X init_cards (); X co_init (); X background = XMakePixmap (0, colorMap[GREY_COLOR].pixel, colorMap[WHITE_COLOR].pixel); X border = XMakePixmap (0, colorMap[WHITE_COLOR].pixel, colorMap[GREY_COLOR].pixel); X font = XOpenFont ("timrom12"); X xwindow = XCreateWindow (RootWindow, 50, 50, WINDOW_WIDTH, WINDOW_HEIGHT, 1, X WhitePixmap, background); X QUIT = CcreateButton (font, "Quit", 50, colorMap[WHITE_COLOR].pixel, X colorMap[GREY_COLOR].pixel, 1); X SAVE = CcreateButton (font, "Save", 50, colorMap[WHITE_COLOR].pixel, X colorMap[GREY_COLOR].pixel, 1); X qwindow = CmapButton (xwindow, QUIT_X, QUIT_Y, QUIT, do_quit); X swindow = CmapButton (xwindow, SAVE_X, SAVE_Y, SAVE, do_save); X bindEvent (qwindow, ExposeWindow|ButtonPressed|LeaveWindow|ButtonReleased, X CmanageButton); X bindEvent (swindow, ExposeWindow|ButtonPressed|LeaveWindow|ButtonReleased, X CmanageButton); X XMapWindow (xwindow); X X bindEvent (xwindow, ExposeWindow|ExposeRegion, exposeBoard); X} X X Xfinish_ui () X{ X} X Xupdate_ui () X{ X XFlush (); X} X XBeep () X{ X XFeep (0); X} X X/* X * Get a yes or no answer to the given question. Saves are X * also allowed. Return TRUE if the answer was yes, FALSE if no. X */ X Xgetyn(prompt) Xregister char *prompt; X{ X X register char c; X X return co_affirm (prompt); X} X Xstatic char incharacter; Xstatic int gotcharacter; X Xstatic int getmove_done; X Xmouse_event (rep) XXButtonEvent *rep; X{ X int x, y; X X x = rep->x; X y = rep->y; X if (HUM_HAND_Y <= y && y <= HUM_HAND_Y + HEIGHT && X HUM_HAND_X <= x && x <= HUM_HAND_X + (WIDTH + PAD_CARD) * 7) { X switch (rep->detail & 0377) { X case RightButton: X Movetype = M_DISCARD; X break; X case MiddleButton: X Movetype = M_REASONABLE; X break; X case LeftButton: X Movetype = M_PLAY; X break; X } X Card_no = (x - HUM_HAND_X) / (WIDTH + PAD_CARD); X getmove_done = 1; X return; X } X if (DECK_Y <= y && y <= DECK_Y + HEIGHT && X DECK_X <= x && x <= DECK_X + WIDTH) { X Movetype = M_DRAW; X getmove_done = 1; X return; X } X Beep (); X} X Xgetmove() X{ X X getmove_done = 0; X bindEvent (xwindow, ButtonPressed, mouse_event); X while (!getmove_done) { X dispatch (); X } X unbindEvent (xwindow, ButtonPressed); X} X X Xdo_save () X{ X save (); X} X Xdo_quit () X{ X rub(); X} X X# define COMP_STRT 20 X# define CARD_STRT 2 X Xprboard() { X X register PLAY *pp; X register int i, j, k, temp; X X for (k = 0; k < 2; k++) { X pp = &Player[k]; X temp = k * COMP_STRT + CARD_STRT; X for (i = 0; i < NUM_SAFE; i++) X if (pp->safety[i] == S_PLAYED) { X if (k == 0) { X HumanSafety (i + S_CONV, i); X } else { X ComputerSafety (i + S_CONV, i); X } X } X if (k == 0) { X HumanBattle (pp->battle); X HumanSpeed (pp->speed); X } else { X ComputerBattle (pp->battle); X ComputerSpeed (pp->speed); X } X for (i = C_25; i <= C_200; i++) { X register char *name; X register int end; X X name = C_name[i]; X temp = k * 40; X end = pp->nummiles[i]; X if (k == 0) X HumanMiles (i, C_200-i, end); X else X ComputerMiles (i, C_200-i, end); X } X } X prscore(TRUE); X temp = CARD_STRT; X pp = &Player[PLAYER]; X for (i = 0; i < HAND_SZ; i++) { X HumanHand (pp->hand[i], i); X } X DisplayDeck (Topcard - Deck); X DisplayDiscard (Discard); X if (End == 1000) { X static char ext[] = "Extension"; X X/* stand(EXT_Y, EXT_X, ext); */ X } X} X X/* X * Put str at (y,x) in standout mode X */ X Xstand(y, x, str) Xregister int y, x; Xregister char *str; X{ X} X XInScore (line, player, text) Xint line, player; Xchar *text; X{ X XText (xwindow, SCORE_X + player * SCORE_W, SCORE_Y + SCORE_H * (line + 1), X text, strlen (text), font->id, colorMap[BLACK_COLOR].pixel, X colorMap[GREY_COLOR].pixel); X} X Xprscore(for_real) Xregister bool for_real; X{ X X register PLAY *pp; X register int x; X register char *Score_fmt = "%4d "; X char buffer[512]; X X ComputerDistance (Player[1].mileage); X HumanDistance (Player[0].mileage); X X for (pp = Player; pp < &Player[2]; pp++) { X x = (pp - Player) * 6 + 21; X sprintf (buffer, Score_fmt, pp->mileage); X InScore (0, pp - Player, buffer); X sprintf (buffer, Score_fmt, pp->safescore); X InScore (1, pp - Player, buffer); X if (pp->safescore == 400) X InScore (2, pp - Player, " 300 "); X else X InScore (2, pp - Player, " 0 "); X sprintf (buffer, Score_fmt, pp->coupscore); X InScore (3, pp - Player, buffer); X#ifdef EXTRAP X if (for_real) X finalscore(pp); X else X extrapolate(pp); X#else X finalscore(pp); X#endif X sprintf (buffer, Score_fmt, pp->hand_tot); X InScore (9, pp - Player, buffer); X sprintf (buffer, Score_fmt, pp->total); X InScore (10, pp - Player, buffer); X sprintf (buffer, Score_fmt, pp->games); X InScore (11, pp - Player, buffer); X } X} X XFlushInput () X{ X} END_OF_ui.c if test 12859 -ne `wc -c