unofficial version 0.7.1: ui improvements
[netris.git] / board.c
diff --git a/board.c b/board.c
index 97f1124fe318bda0ffdd10b5b304472900005b7a..55983b477de3513218ebab9b019e0db1e029956f 100644 (file)
--- a/board.c
+++ b/board.c
@@ -1,6 +1,6 @@
 /*
- * Netris -- A free networked version of Tetris
- * Copyright (C) 1994,1995  Mark Weaver <Mark_Weaver@brown.edu>
+ * Netris -- A free networked version of T*tris
+ * Copyright (C) 1994-1996,1999  Mark H. Weaver <mhw@netris.org>
  * 
  * 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: board.c,v 1.13 1995/07/11 08:53:20 mhw Exp $
+ * $Id: board.c,v 1.15 1999/05/16 06:56:24 mhw Exp $
  */
 
 #include "netris.h"
@@ -33,58 +33,58 @@ static BlockType oldBoard[MAX_SCREENS][MAX_BOARD_HEIGHT][MAX_BOARD_WIDTH];
 static unsigned int changed[MAX_SCREENS][MAX_BOARD_HEIGHT];
 static int falling[MAX_SCREENS][MAX_BOARD_WIDTH];
 static int oldFalling[MAX_SCREENS][MAX_BOARD_WIDTH];
+static int shadowy;
 
-ExtFunc void InitBoard(int scr)
-{
-       boardHeight[scr] = MAX_BOARD_HEIGHT;
-       boardVisible[scr] = 20;
-       boardWidth[scr] = 10;
-       InitScreen(scr);
-}
 
-ExtFunc void CleanupBoard(int scr)
+ExtFunc void ClearField(int scr)
 {
-       CleanupScreen(scr);
-}
+       int y, x;
+
+       for (y = Players[scr].boardHeight - 1; y >= 0; --y)
+               for (x = 0; x < Players[scr].boardWidth; ++x) {
+                       oldBoard[scr][y][x] = board[scr][y][x] = BT_none;
+               }
+} //ClearField
 
 ExtFunc BlockType GetBlock(int scr, int y, int x)
 {
-       if (y < 0 || x < 0 || x >= boardWidth[scr])
+       if (y < 0 || x < 0 || x >= Players[scr].boardWidth)
                return BT_wall;
-       else if (y >= boardHeight[scr])
+       else if (y >= Players[scr].boardHeight)
                return BT_none;
        else
                return abs(board[scr][y][x]);
-}
+} //GetBlock
 
 ExtFunc void SetBlock(int scr, int y, int x, BlockType type)
 {
-       if (y >= 0 && y < boardHeight[scr] && x >= 0 && x < boardWidth[scr]) {
-               if (y < boardVisible[scr])
+       if (y >= 0 && y < Players[scr].boardHeight &&
+               x >= 0 && x < Players[scr].boardWidth) {
+               if (y < Players[scr].boardVisible)
                        falling[scr][x] += (type < 0) - (board[scr][y][x] < 0);
                board[scr][y][x] = type;
                changed[scr][y] |= 1 << x;
        }
-}
+} //SetBlock
 
 ExtFunc int RefreshBoard(int scr)
-{
+{ //draw changes to screen
        int y, x, any = 0;
        unsigned int c;
        BlockType b;
 
-       for (y = boardVisible[scr] - 1; y >= 0; --y)
+       for (y = Players[scr].boardVisible - 1; y >= 0; --y)
                if ((c = changed[scr][y])) {
                        if (robotEnable) {
                                RobotCmd(0, "RowUpdate %d %d", scr, y);
-                               for (x = 0; x < boardWidth[scr]; ++x) {
+                               for (x = 0; x < Players[scr].boardWidth; ++x) {
                                        b = board[scr][y][x];
                                        if (fairRobot)
                                                b = abs(b);
                                        RobotCmd(0, " %d", b);
                                }
                                RobotCmd(0, "\n");
-                       }
+                       } //robot
                        changed[scr][y] = 0;
                        any = 1;
                        for (x = 0; c; (c >>= 1), (++x))
@@ -92,106 +92,132 @@ ExtFunc int RefreshBoard(int scr)
                                        PlotBlock(scr, y, x, B_OLD(board[scr][y][x]));
                                        oldBoard[scr][y][x] = B_OLD(board[scr][y][x]);
                                }
-               }
-       if (robotEnable)
-               RobotTimeStamp();
-       for (x = 0; x < boardWidth[scr]; ++x)
+               } //changed row
+       if (robotEnable) RobotTimeStamp();
+       for (x = 0; x < Players[scr].boardWidth; ++x)
                if (oldFalling[scr][x] != !!falling[scr][x]) {
                        oldFalling[scr][x] = !!falling[scr][x];
                        PlotUnderline(scr, x, oldFalling[scr][x]);
                        any = 1;
                }
        return any;
-}
+} //RefreshBoard
+
+ExtFunc int GlanceFunc(int scr, int y, int x, BlockType type, void *data)
+{
+       PlotBlock1(scr, 20 - y, x * 2, type);
+       return 0;
+} //GlanceFunc
+
+ExtFunc int ShadowFunc(int scr, int y, int x, BlockType type, void *data)
+{ //draw shadow
+       SetBlock(scr, y, x, BT_shadow);
+       return 0;
+} //ShadowFunc
 
 ExtFunc int PlotFunc(int scr, int y, int x, BlockType type, void *data)
 {
        SetBlock(scr, y, x, type);
        return 0;
 }
+ExtFunc void PlotShape(Shape *shape, int scr, int y, int x, int falling, int shadow)
+{ //put shape on field
+       if (shadow && scr == me) {
+               for (shadowy = y - 1; shadowy >= 0; shadowy--)
+                       if (!ShapeFits(shape, scr, shadowy, x))
+                               break;
+               ShapeIterate(shape, scr, shadowy + 1, x, falling, ShadowFunc, NULL);
+       } //draw shadow
+       ShapeIterate(shape, scr, y, x, falling, PlotFunc, NULL);
+} //PlotShape
 
 ExtFunc int EraseFunc(int scr, int y, int x, BlockType type, void *data)
 {
        SetBlock(scr, y, x, BT_none);
        return 0;
 }
+ExtFunc void EraseShape(Shape *shape, int scr, int y, int x, int shadow)
+{ //remove block from field
+       ShapeIterate(shape, scr, y, x, 0, EraseFunc, NULL);
+       if (shadow && scr == me) //draw shadow
+               ShapeIterate(shape, scr, shadowy + 1, x, 0, EraseFunc, NULL);
+} //EraseShape
 
 ExtFunc int CollisionFunc(int scr, int y, int x, BlockType type, void *data)
 {
-       return GetBlock(scr, y, x) != BT_none;
+       return GetBlock(scr, y, x) > BT_none;
 }
+ExtFunc int ShapeFits(Shape *shape, int scr, int y, int x)
+{ //check if there's nothing in the way
+       return !ShapeIterate(shape, scr, y, x, 0, CollisionFunc, NULL);
+} //ShapeFits
 
 ExtFunc int VisibleFunc(int scr, int y, int x, BlockType type, void *data)
 {
-       return (y >= 0 && y < boardVisible[scr] && x >= 0 && x < boardWidth[scr]);
-}
-
-ExtFunc void PlotShape(Shape *shape, int scr, int y, int x, int falling)
-{
-       ShapeIterate(shape, scr, y, x, falling, PlotFunc, NULL);
+       return (y >= 0 && y < Players[scr].boardVisible &&
+                       x >= 0 && x < Players[scr].boardWidth);
 }
-
-ExtFunc void EraseShape(Shape *shape, int scr, int y, int x)
-{
-       ShapeIterate(shape, scr, y, x, 0, EraseFunc, NULL);
-}
-
-ExtFunc int ShapeFits(Shape *shape, int scr, int y, int x)
-{
-       return !ShapeIterate(shape, scr, y, x, 0, CollisionFunc, NULL);
-}
-
 ExtFunc int ShapeVisible(Shape *shape, int scr, int y, int x)
 {
        return ShapeIterate(shape, scr, y, x, 0, VisibleFunc, NULL);
-}
+} //ShapeVisible
 
 ExtFunc int MovePiece(int scr, int deltaY, int deltaX)
 {
        int result;
 
-       EraseShape(curShape[scr], scr, curY[scr], curX[scr]);
-       result = ShapeFits(curShape[scr], scr, curY[scr] + deltaY,
-                               curX[scr] + deltaX);
+       EraseShape(Players[scr].curShape, scr,
+               Players[scr].curY, Players[scr].curX, 1);
+       result = ShapeFits(Players[scr].curShape, scr, Players[scr].curY + deltaY,
+                               Players[scr].curX + deltaX);
        if (result) {
-               curY[scr] += deltaY;
-               curX[scr] += deltaX;
+               Players[scr].curY += deltaY;
+               Players[scr].curX += deltaX;
        }
-       PlotShape(curShape[scr], scr, curY[scr], curX[scr], 1);
+       PlotShape(Players[scr].curShape, scr, Players[scr].curY, Players[scr].curX,
+               1, 1);
        return result;
-}
+} //MovePiece
 
-ExtFunc int RotatePiece(int scr)
+ExtFunc int RotatePiece(int scr, int dir)
 {
        int result;
 
-       EraseShape(curShape[scr], scr, curY[scr], curX[scr]);
-       result = ShapeFits(curShape[scr]->rotateTo, scr, curY[scr], curX[scr]);
+       EraseShape(Players[scr].curShape, scr, Players[scr].curY,
+               Players[scr].curX, 1);
+       result = ShapeFits(dir ? Players[scr].curShape->rotateTo
+                                                  : Players[scr].curShape->rotateFrom,
+               scr, Players[scr].curY, Players[scr].curX);
        if (result)
-               curShape[scr] = curShape[scr]->rotateTo;
-       PlotShape(curShape[scr], scr, curY[scr], curX[scr], 1);
+               Players[scr].curShape = dir ? Players[scr].curShape->rotateTo
+                                                                       : Players[scr].curShape->rotateFrom;
+       PlotShape(Players[scr].curShape, scr,
+                       Players[scr].curY, Players[scr].curX, 1, 1);
        return result;
-}
+} //RotatePiece
 
 ExtFunc int DropPiece(int scr)
 {
        int count = 0;
 
-       EraseShape(curShape[scr], scr, curY[scr], curX[scr]);
-       while (ShapeFits(curShape[scr], scr, curY[scr] - 1, curX[scr])) {
-               --curY[scr];
+       EraseShape(Players[scr].curShape, scr,
+               Players[scr].curY, Players[scr].curX, 1);
+       while (ShapeFits(Players[scr].curShape, scr,
+                       Players[scr].curY - 1, Players[scr].curX)) {
+               --Players[scr].curY;
                ++count;
        }
-       PlotShape(curShape[scr], scr, curY[scr], curX[scr], 1);
+       PlotShape(Players[scr].curShape, scr,
+               Players[scr].curY, Players[scr].curX, 1, 0);
        return count;
-}
+} //DropPiece
 
 ExtFunc int LineIsFull(int scr, int y)
 {
        int x;
 
-       for (x = 0; x < boardWidth[scr]; ++x)
-               if (GetBlock(scr, y, x) == BT_none)
+       for (x = 0; x < Players[scr].boardWidth; ++x)
+               if (GetBlock(scr, y, x) <= BT_none)
                        return 0;
        return 1;
 }
@@ -201,7 +227,7 @@ ExtFunc void CopyLine(int scr, int from, int to)
        int x;
 
        if (from != to)
-               for (x = 0; x < boardWidth[scr]; ++x)
+               for (x = 0; x < Players[scr].boardWidth; ++x)
                        SetBlock(scr, to, x, GetBlock(scr, from, x));
 }
 
@@ -210,7 +236,7 @@ ExtFunc int ClearFullLines(int scr)
        int from, to;
 
        from = to = 0;
-       while (to < boardHeight[scr]) {
+       while (to < Players[scr].boardHeight) {
                while (LineIsFull(scr, from))
                        ++from;
                CopyLine(scr, from++, to++);
@@ -223,8 +249,8 @@ ExtFunc void FreezePiece(int scr)
        int y, x;
        BlockType type;
 
-       for (y = 0; y < boardHeight[scr]; ++y)
-               for (x = 0; x < boardWidth[scr]; ++x)
+       for (y = 0; y < Players[scr].boardHeight; ++y)
+               for (x = 0; x < Players[scr].boardWidth; ++x)
                        if ((type = board[scr][y][x]) < 0)
                                SetBlock(scr, y, x, -type);
 }
@@ -233,11 +259,23 @@ ExtFunc void InsertJunk(int scr, int count, int column)
 {
        int y, x;
 
-       for (y = boardHeight[scr] - count - 1; y >= 0; --y)
+       EraseShape(Players[scr].curShape, scr,
+               Players[scr].curY, Players[scr].curX, 1);
+       for (y = Players[scr].boardHeight - count - 1; y >= 0; --y)
                CopyLine(scr, y, y + count);
        for (y = 0; y < count; ++y)
-               for (x = 0; x < boardWidth[scr]; ++x)
-                       SetBlock(scr, y, x, (x == column) ? BT_none : BT_piece1);
-       curY[scr] += count;
-}
+               for (x = 0; x < Players[scr].boardWidth; ++x)
+                       SetBlock(scr, y, x, (x == column) ? BT_none : BT_white);
+       Players[scr].curY += count; //move piece up..
+       for (y = 0; y < count; ++y)
+               if (ShapeFits(Players[scr].curShape, scr, Players[scr].curY - 1, Players[scr].curX))
+                       Players[scr].curY--; //..and down again as far as possible
+               else break;
+       PlotShape(Players[scr].curShape, scr, Players[scr].curY, Players[scr].curX,
+               1, 1);
+} //InoertJunk
 
+/*
+ * vi: ts=4 ai
+ * vim: noai si
+ */