2 * Netris -- A free networked version of T*tris
3 * Copyright (C) 1994-1996,1999 Mark H. Weaver <mhw@netris.org>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 * $Id: board.c,v 1.15 1999/05/16 06:56:24 mhw Exp $
31 static BlockType board[MAX_SCREENS][MAX_BOARD_HEIGHT][MAX_BOARD_WIDTH];
32 static BlockType oldBoard[MAX_SCREENS][MAX_BOARD_HEIGHT][MAX_BOARD_WIDTH];
33 static unsigned int changed[MAX_SCREENS][MAX_BOARD_HEIGHT];
34 static int falling[MAX_SCREENS][MAX_BOARD_WIDTH];
35 static int oldFalling[MAX_SCREENS][MAX_BOARD_WIDTH];
37 ExtFunc void InitBoard(int scr)
41 for(s = 0 ; s < MAX_SCREENS ; s++)
42 for(h = 0 ; h < MAX_BOARD_HEIGHT ; h++)
43 for(w = 0 ; w < MAX_BOARD_WIDTH ; w++) {
45 oldBoard[s][h][w] = 0;
52 boardHeight[scr] = MAX_BOARD_HEIGHT;
53 boardVisible[scr] = 20;
58 ExtFunc void CleanupBoard(int scr)
63 ExtFunc BlockType GetBlock(int scr, int y, int x)
65 if (y < 0 || x < 0 || x >= boardWidth[scr])
67 else if (y >= boardHeight[scr])
70 return abs(board[scr][y][x]);
73 ExtFunc void SetBlock(int scr, int y, int x, BlockType type)
75 if (y >= 0 && y < boardHeight[scr] && x >= 0 && x < boardWidth[scr]) {
76 if (y < boardVisible[scr])
77 falling[scr][x] += (type < 0) - (board[scr][y][x] < 0);
78 board[scr][y][x] = type;
79 changed[scr][y] |= 1 << x;
83 ExtFunc int RefreshBoard(int scr)
89 for (y = boardVisible[scr] - 1; y >= 0; --y)
90 if ((c = changed[scr][y])) {
92 RobotCmd(0, "RowUpdate %d %d", scr, y);
93 for (x = 0; x < boardWidth[scr]; ++x) {
97 RobotCmd(0, " %d", b);
103 for (x = 0; c; (c >>= 1), (++x))
104 if ((c & 1) && B_OLD(board[scr][y][x])!=oldBoard[scr][y][x]) {
105 PlotBlock(scr, y, x, B_OLD(board[scr][y][x]));
106 oldBoard[scr][y][x] = B_OLD(board[scr][y][x]);
111 for (x = 0; x < boardWidth[scr]; ++x)
112 if (oldFalling[scr][x] != !!falling[scr][x]) {
113 oldFalling[scr][x] = !!falling[scr][x];
114 PlotUnderline(scr, x, oldFalling[scr][x]);
120 ExtFunc int PlotFunc(int scr, int y, int x, BlockType type, void *data)
122 SetBlock(scr, y, x, type);
126 ExtFunc int EraseFunc(int scr, int y, int x, BlockType type, void *data)
128 SetBlock(scr, y, x, BT_none);
132 ExtFunc int CollisionFunc(int scr, int y, int x, BlockType type, void *data)
134 return GetBlock(scr, y, x) != BT_none;
137 ExtFunc int VisibleFunc(int scr, int y, int x, BlockType type, void *data)
139 return (y >= 0 && y < boardVisible[scr] && x >= 0 && x < boardWidth[scr]);
142 ExtFunc void PlotShape(Shape *shape, int scr, int y, int x, int falling)
144 ShapeIterate(shape, scr, y, x, falling, PlotFunc, NULL);
147 ExtFunc void EraseShape(Shape *shape, int scr, int y, int x)
149 ShapeIterate(shape, scr, y, x, 0, EraseFunc, NULL);
152 ExtFunc int ShapeFits(Shape *shape, int scr, int y, int x)
154 return !ShapeIterate(shape, scr, y, x, 0, CollisionFunc, NULL);
157 ExtFunc int ShapeVisible(Shape *shape, int scr, int y, int x)
159 return ShapeIterate(shape, scr, y, x, 0, VisibleFunc, NULL);
162 ExtFunc int MovePiece(int scr, int deltaY, int deltaX)
166 EraseShape(curShape[scr], scr, curY[scr], curX[scr]);
167 result = ShapeFits(curShape[scr], scr, curY[scr] + deltaY,
173 PlotShape(curShape[scr], scr, curY[scr], curX[scr], 1);
177 ExtFunc int RotatePiece(int scr)
181 EraseShape(curShape[scr], scr, curY[scr], curX[scr]);
182 result = ShapeFits(curShape[scr]->rotateTo, scr, curY[scr], curX[scr]);
184 curShape[scr] = curShape[scr]->rotateTo;
185 PlotShape(curShape[scr], scr, curY[scr], curX[scr], 1);
189 ExtFunc int DropPiece(int scr)
193 EraseShape(curShape[scr], scr, curY[scr], curX[scr]);
194 while (ShapeFits(curShape[scr], scr, curY[scr] - 1, curX[scr])) {
198 PlotShape(curShape[scr], scr, curY[scr], curX[scr], 1);
202 ExtFunc int LineIsFull(int scr, int y)
206 for (x = 0; x < boardWidth[scr]; ++x)
207 if (GetBlock(scr, y, x) == BT_none)
212 ExtFunc void CopyLine(int scr, int from, int to)
217 for (x = 0; x < boardWidth[scr]; ++x)
218 SetBlock(scr, to, x, GetBlock(scr, from, x));
221 ExtFunc int ClearFullLines(int scr)
226 while (to < boardHeight[scr]) {
227 while (LineIsFull(scr, from))
229 CopyLine(scr, from++, to++);
234 ExtFunc void FreezePiece(int scr)
239 for (y = 0; y < boardHeight[scr]; ++y)
240 for (x = 0; x < boardWidth[scr]; ++x)
241 if ((type = board[scr][y][x]) < 0)
242 SetBlock(scr, y, x, -type);
245 ExtFunc void InsertJunk(int scr, int count, int column)
249 for (y = boardHeight[scr] - count - 1; y >= 0; --y)
250 CopyLine(scr, y, y + count);
251 for (y = 0; y < count; ++y)
252 for (x = 0; x < boardWidth[scr]; ++x)
253 SetBlock(scr, y, x, (x == column) ? BT_none : BT_white);