X-Git-Url: http://git.shiar.net/netris.git/blobdiff_plain/ec797c133bd83404f6167fb46c098c236333d168..21add7c13bc1df386e45aad2939ee5ff2a152c2b:/curses.c diff --git a/curses.c b/curses.c index 047efa4..f28a6a3 100644 --- a/curses.c +++ b/curses.c @@ -1,6 +1,6 @@ /* * Netris -- A free networked version of T*tris - * Copyright (C) 1994,1995,1996 Mark H. Weaver + * Copyright (C) 1994-1996,1999 Mark H. Weaver * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: curses.c,v 1.32 1996/02/09 08:47:25 mhw Exp $ + * $Id: curses.c,v 1.33 1999/05/16 06:56:25 mhw Exp $ */ #include "netris.h" @@ -26,7 +26,27 @@ #include #include -static void PlotBlock1(int scr, int y, int x, BlockType type); +#ifdef NCURSES_VERSION +# define HAVE_NCURSES +#endif + +#ifdef HAVE_NCURSES +static struct { + BlockType type; + short color; +} myColorTable[] = { + { BT_white, COLOR_WHITE }, + { BT_blue, COLOR_BLUE }, + { BT_magenta, COLOR_MAGENTA }, + { BT_cyan, COLOR_CYAN }, + { BT_yellow, COLOR_YELLOW }, + { BT_green, COLOR_GREEN }, + { BT_red, COLOR_RED }, + { BT_none, 0 } +}; +#endif + +ExtFunc void PlotBlock1(int scr, int y, int x, BlockType type); static MyEventType KeyGenFunc(EventGenRec *gen, MyEvent *event); static EventGenRec keyGen = @@ -34,6 +54,7 @@ static EventGenRec keyGen = static int boardYPos[MAX_SCREENS], boardXPos[MAX_SCREENS]; static int statusYPos, statusXPos; +static int haveColor; static char *term_vi; /* String to make cursor invisible */ static char *term_ve; /* String to make cursor visible */ @@ -45,11 +66,34 @@ ExtFunc void InitScreens(void) GetTermcapInfo(); /* - * Do this atomically. Otherwise a badly timed Ctrl-C during - * initialization will leave your terminal in a bad state. + * Block signals while initializing curses. Otherwise a badly timed + * Ctrl-C during initialization might leave the terminal in a bad state. */ BlockSignals(&oldMask, SIGINT, 0); initscr(); + +#ifdef CURSES_HACK + { + extern char *CS; + + CS = 0; + } +#endif + +#ifdef HAVE_NCURSES + haveColor = Game.color && has_colors(); + if (haveColor) { + int i = 0; + + start_color(); + for (i = 0; myColorTable[i].type != BT_none; ++i) + init_pair(myColorTable[i].type, COLOR_BLACK, + myColorTable[i].color); + } +#else + haveColor = 0; +#endif + AtExit(CleanupScreens); RestoreSignals(NULL, &oldMask); @@ -58,21 +102,27 @@ ExtFunc void InitScreens(void) OutputTermStr(term_vi, 0); AddEventGen(&keyGen); - move(0, 0); - addstr("Netris "); + move(0, 1); + addstr("NETRIS "); addstr(version_string); - addstr(" (C) 1994,1995,1996 Mark H. Weaver " - "\"netris -h\" for more info"); + { + int rows, cols; + + getmaxyx(stdscr, rows, cols); + move(0, cols - 48); + addstr("(C)1994-1996,1999 Mark H. Weaver, (C)2002 Shiar"); +// addstr(" \"netris -h\" for more info"); + } statusYPos = 22; statusXPos = 0; -} +} //InitScreens ExtFunc void CleanupScreens(void) { RemoveEventGen(&keyGen); endwin(); OutputTermStr(term_ve, 1); -} +} //CleanupScreens ExtFunc void GetTermcapInfo(void) { @@ -128,175 +178,218 @@ ExtFunc void GetTermcapInfo(void) } if (!term_vi || !term_ve) term_vi = term_ve = NULL; -} +} //GetTermcapInfo ExtFunc void OutputTermStr(char *str, int flush) { if (str) { fputs(str, stdout); - if (flush) - fflush(stdout); + if (flush) fflush(stdout); } -} +} //OutputTermStr -ExtFunc void InitScreen(int scr) -{ - int y, x; +ExtFunc void DrawField(int scr) +{ //drow field for player scr + { + int y, x; + + getmaxyx(stdscr, y, x); + if (x < boardXPos[scr] + 2 * Players[scr].boardWidth + 1) { + Players[scr].spy = 0; + return; + } + + for (y = Players[scr].boardVisible - 1; y >= 0; --y) { + mvaddch(boardYPos[scr] - y, boardXPos[scr] - 1, + Game.ascii ? '|' : ACS_VLINE); //left + mvaddch(boardYPos[scr] - y, + boardXPos[scr] + 2 * Players[scr].boardWidth, + Game.ascii ? '|' : ACS_VLINE); //right + } + move(2, boardXPos[scr] - 1); //top + addch(Game.ascii ? '+' : ACS_ULCORNER); + for (x = Players[scr].boardWidth * 2 - 1; x >= 0; --x) + addch(Game.ascii ? '-' : ACS_HLINE); + addch(Game.ascii ? '+' : ACS_URCORNER); + move(boardYPos[scr] + 1, boardXPos[scr] - 1); //bottom + addch(Game.ascii ? '+' : ACS_LLCORNER); + for (x = Players[scr].boardWidth * 2 - 1; x >= 0; --x) + addch(Game.ascii ? '-' : ACS_HLINE); + addch(Game.ascii ? '+' : ACS_LRCORNER); + } //draw field grid - if (scr == 0) - boardXPos[scr] = 1; - else - boardXPos[scr] = boardXPos[scr - 1] + - 2 * boardWidth[scr - 1] + 3; - boardYPos[scr] = 22; - if (statusXPos < boardXPos[scr] + 2 * boardWidth[scr] + 3) - statusXPos = boardXPos[scr] + 2 * boardWidth[scr] + 3; - for (y = boardVisible[scr] - 1; y >= 0; --y) { - move(boardYPos[scr] - y, boardXPos[scr] - 1); - addch('|'); - move(boardYPos[scr] - y, boardXPos[scr] + 2 * boardWidth[scr]); - addch('|'); - } - for (y = boardVisible[scr]; y >= -1; y -= boardVisible[scr] + 1) { - move(boardYPos[scr] - y, boardXPos[scr] - 1); - addch('+'); - for (x = boardWidth[scr] - 1; x >= 0; --x) - addstr("--"); - addch('+'); + { + char userstr[300]; + + if (Players[scr].host && Players[scr].host[0]) + sprintf(userstr, "%s <%s>", Players[scr].name, Players[scr].host); + else sprintf(userstr, "%s", Players[scr].name); + userstr[20 - 7*((Players[scr].flags & SCF_usingRobot) != 0) + - 5*((Players[scr].flags & SCF_fairRobot) != 0)] = 0; + mvaddstr(1, boardXPos[scr], userstr); + + if (Players[scr].flags & SCF_usingRobot) { + addstr((Players[scr].flags & SCF_fairRobot) + ? "(fair robot)" : "(robot)"); + } + } //display playername/host + + ShowPause(scr); +} //DrawScreen + +ExtFunc void InitFields() +{ //place fields for all players + int scr, prevscr; + + statusXPos = 2 * Players[me].boardWidth + 3; + boardXPos[me] = 1; + boardYPos[me] = 22; + prevscr = me; + for (scr = 1; scr <= totalPlayers + 1; scr++) if (scr != me) { + boardXPos[scr] = + boardXPos[prevscr] + 2 * Players[prevscr].boardWidth + 3; + if (prevscr == me) + boardXPos[scr] += 24; //scorebar + boardYPos[scr] = 22; + prevscr = scr; } -} +} //InitScreen ExtFunc void CleanupScreen(int scr) { } -static void PlotBlock1(int scr, int y, int x, BlockType type) +ExtFunc void PlotBlock1(int scr, int y, int x, BlockType type) { - move(boardYPos[scr] - y, boardXPos[scr] + 2 * x); - switch (type) { - case BT_none: - addstr(" "); - break; - case -BT_piece1: - if (standoutEnable) - standout(); - addstr("$$"); - if (standoutEnable) - standend(); - break; - case BT_piece1: - if (standoutEnable) + int colorIndex = abs(type); + + move(y, x); + + if (type == BT_none) + addstr(" "); + else + { + if (Game.standout) + { +#ifdef HAVE_NCURSES + if (haveColor) + attrset(COLOR_PAIR(colorIndex)); + else +#endif standout(); - addstr("[]"); - if (standoutEnable) - standend(); - break; - default: - assert(0); + } + + addstr(type ? "[]" : "$$"); + standend(); } -} +} //PlotBlock1 ExtFunc void PlotBlock(int scr, int y, int x, BlockType type) { - if (y >= 0 && y < boardVisible[scr] && x >= 0 && x < boardWidth[scr]) - PlotBlock1(scr, y, x, type); -} + if (y >= 0 && y < Players[scr].boardVisible && + x >= 0 && x < Players[scr].boardWidth) + PlotBlock1(scr, boardYPos[scr] - y, boardXPos[scr] + 2 * x, type); +} //PlotBlock ExtFunc void PlotUnderline(int scr, int x, int flag) { - move(boardYPos[scr] + 1, boardXPos[scr] + 2 * x); + move(boardYPos[scr] + 1, boardXPos[scr] + 2 * x); + if (Game.ascii) addstr(flag ? "==" : "--"); -} - -ExtFunc void ShowDisplayInfo(void) -{ - move(statusYPos - 9, statusXPos); - printw("Seed: %d", initSeed); - clrtoeol(); - move(statusYPos - 8, statusXPos); - printw("Speed: %dms", speed / 1000); - clrtoeol(); - if (robotEnable) { - move(statusYPos - 6, statusXPos); - if (fairRobot) - addstr("Controlled by a fair robot"); - else - addstr("Controlled by a robot"); - clrtoeol(); + else { + addch(flag ? ACS_BTEE : ACS_HLINE); + addch(flag ? ACS_BTEE : ACS_HLINE); + } +} //PlotUnderline + +ExtFunc void ShowScore(int scr, struct _Score score) +{ //show score stuff + float timer; + + move(6, statusXPos); addstr("Next: "); + move(7, statusXPos + 7); addstr(" "); + ShapeIterate(Players[scr].nextShape, scr, + ShapeToNetNum(Players[scr].nextShape) == 15 ? 13 : 14, + statusXPos / 2 + 5, 1, GlanceFunc, NULL); + move(statusYPos - 21 + 1, statusXPos); + printw("Score:%6d level: %2d", score.score, score.level); + move(statusYPos - 20 + 1, statusXPos); + timer = CurTimeval() / 1e6; + printw("Lines:%6d", score.lines); + if (timer > 4) { + printw(" ppm:%5.1f", score.drops * 60 / timer); + move(statusYPos - 18, statusXPos); + if (score.lines > 0) + printw("yield: %3d%%", 100 * score.adds / score.lines); + else addstr(" "); + printw(" apm:%5.1f", score.adds * 60 / timer); } - if (opponentFlags & SCF_usingRobot) { - move(statusYPos - 5, statusXPos); - if (opponentFlags & SCF_fairRobot) - addstr("The opponent is a fair robot"); - else - addstr("The opponent is a robot"); - clrtoeol(); - } -} - -ExtFunc void UpdateOpponentDisplay(void) -{ - move(1, 0); - printw("Playing %s@%s", opponentName, opponentHost); - clrtoeol(); -} +} //ShowScore + +ExtFunc void FieldMessage(int playa, char *message) +{ //put a message over playa's field + if (!Players[playa].spy) return; + if (message) { + char s[MAX_BOARD_WIDTH+1]; + memset(s, ' ', MAX_BOARD_WIDTH); + memcpy(&s[Players[playa].boardWidth - strlen(message) / 2], + message, strlen(message)); + s[Players[playa].boardWidth * 2] = 0; + if (Game.standout) standout(); + mvprintw(boardYPos[playa] - Players[playa].boardVisible / 2, + boardXPos[playa], "%s", s); + standend(); + } //display + else { + int x, y; + y = Players[playa].boardVisible / 2; + for (x = 0; x <= Players[playa].boardWidth; x++) + PlotBlock(playa, y, x, GetBlock(playa, y, x)); + } //restore field +} //FieldMessage + +ExtFunc void ShowPause(int playa) +{ //put paused over player's field + if (Players[playa].flags & SCF_paused) + FieldMessage(playa, "P A U S E D"); + else FieldMessage(playa, NULL); +} //ShowPause -ExtFunc void ShowPause(int pausedByMe, int pausedByThem) -{ - move(statusYPos - 3, statusXPos); - if (pausedByThem) - addstr("Game paused by opponent"); - else - clrtoeol(); - move(statusYPos - 2, statusXPos); - if (pausedByMe) - addstr("Game paused by you"); - else - clrtoeol(); -} ExtFunc void Message(char *s) { static int line = 0; - move(statusYPos - 20 + line, statusXPos); +// move(statusYPos - 20 + line, statusXPos); + move(statusYPos + 2 + line, 1); addstr(s); /* XXX Should truncate long lines */ clrtoeol(); line = (line + 1) % 10; - move(statusYPos - 20 + line, statusXPos); +// move(statusYPos - 20 + line, statusXPos); + move(statusYPos + 2 + line, 1); clrtoeol(); -} +} //Message -ExtFunc void RefreshScreen(void) -{ - static char timeStr[2][32]; - time_t theTime; - - time(&theTime); - strftime(timeStr[0], 30, "%I:%M %p", localtime(&theTime)); - /* Just in case the local curses library sucks */ - if (strcmp(timeStr[0], timeStr[1])) - { - move(statusYPos, statusXPos); - addstr(timeStr[0]); - strcpy(timeStr[1], timeStr[0]); - } - move(boardYPos[0] + 1, boardXPos[0] + 2 * boardWidth[0] + 1); - refresh(); -} +ExtFunc void ShowTime(void) +{ //display timer + move(statusYPos, statusXPos); + printw("Timer: %.0f ", CurTimeval() / 1e6); + move(boardYPos[0] + 1, boardXPos[0] + 2 * Players[0].boardWidth + 1); +// refresh(); +} //ShowTime ExtFunc void ScheduleFullRedraw(void) { touchwin(stdscr); -} +} //ScheduleFullRedraw static MyEventType KeyGenFunc(EventGenRec *gen, MyEvent *event) -{ +{ //read keypresses if (MyRead(gen->fd, &event->u.key, 1)) return E_key; else return E_none; -} +} //KeyGenFunc /* * vi: ts=4 ai