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: shapes.c,v 1.16 1999/05/16 06:56:31 mhw Exp $
25 #define ShapeName(name, dir) \
26 shape_ ## name ## _ ## dir
28 #define PreDecl(name, dir) \
29 static Shape ShapeName(name, dir)
31 #define StdShape(name, cmdName, mirror, type, realDir, dir, nextDir, prevDir) \
32 static Shape ShapeName(name, dir) = { \
33 &ShapeName(name, nextDir), &ShapeName(name, prevDir), \
34 0, 0, mirror, D_ ## realDir, type, cmds_ ## cmdName \
37 #define FourWayDecl(name, cmdName, mirror, type) \
38 PreDecl(name, down); \
40 StdShape(name, cmdName, mirror, type, left, left, up, down); \
41 PreDecl(name, right); \
42 StdShape(name, cmdName, mirror, type, up, up, right, left); \
43 StdShape(name, cmdName, mirror, type, right, right, down, up); \
44 StdShape(name, cmdName, mirror, type, down, down, left, right)
46 #define TwoWayDecl(name, cmdName, mirror, type) \
47 PreDecl(name, vert); \
48 StdShape(name, cmdName, mirror, type, right, horiz, vert, vert); \
49 StdShape(name, cmdName, mirror, type, down, vert, horiz, horiz)
51 static Cmd cmds_long[] = { C_back, C_plot, C_forw, C_plot, C_forw, C_plot,
52 C_forw, C_plot, C_end };
53 TwoWayDecl(long, long, 0, BT_blue);
55 static Cmd cmds_square[] = { C_plot, C_forw, C_left, C_plot, C_forw, C_left,
56 C_plot, C_forw, C_left, C_plot, C_end };
57 static Shape shape_square = { &shape_square, &shape_square, 0, 0, D_up, 0,
58 BT_magenta, cmds_square };
60 static Cmd cmds_l[] = { C_right, C_back, C_plot, C_forw, C_plot, C_forw,
61 C_plot, C_left, C_forw, C_plot, C_end };
62 FourWayDecl(l, l, 0, BT_cyan);
63 FourWayDecl(l1, l, 1, BT_yellow);
65 static Cmd cmds_t[] = { C_plot, C_forw, C_plot, C_back, C_right, C_forw,
66 C_plot, C_back, C_back, C_plot, C_end };
67 FourWayDecl(t, t, 0, BT_white);
69 static Cmd cmds_s[] = { C_back, C_plot, C_forw, C_plot, C_left, C_forw,
70 C_plot, C_right, C_forw, C_plot, C_end };
71 TwoWayDecl(s, s, 0, BT_green);
72 TwoWayDecl(s1, s, 1, BT_red);
74 ShapeOption stdOptions[] = {
75 {1, &shape_long_horiz},
84 Shape *netMapping[] = {
106 ExtFunc void MoveInDir(Dir dir, int dist, int *y, int *x)
109 case D_down: *y -= dist; break;
110 case D_right: *x += dist; break;
111 case D_up: *y += dist; break;
112 case D_left: *x -= dist; break;
118 ExtFunc Dir RotateDir(Dir dir, int delta)
120 return 3 & (dir + delta);
123 ExtFunc int ShapeIterate(Shape *s, int scr, int y, int x, int falling,
124 ExtFunc ShapeDrawFunc func, void *data)
126 int i, mirror, result;
133 type = falling ? -s->type : s->type;
134 mirror = s->mirrored ? -1 : 1;
135 for (i = 0; s->cmds[i] != C_end; ++i)
136 switch (s->cmds[i]) {
138 MoveInDir(dir, 1, &y, &x);
141 MoveInDir(dir, -1, &y, &x);
144 dir = RotateDir(dir, mirror);
147 dir = RotateDir(dir, -mirror);
150 if ((result = func(scr, y, x, type, data)))
159 ExtFunc Shape *ChooseOption(ShapeOption *options)
162 float total = 0, val;
164 for (i = 0; options[i].shape; ++i)
165 total += options[i].weight;
166 val = Random(0, 32767) / 32768.0 * total;
167 for (i = 0; options[i].shape; ++i) {
168 val -= options[i].weight;
170 return options[i].shape;
172 return options[0].shape;
175 ExtFunc short ShapeToNetNum(Shape *shape)
179 for (num = 0; netMapping[num]; ++num)
180 if (netMapping[num] == shape)
186 ExtFunc Shape *NetNumToShape(short num)
188 assert(num >= 0 && num < sizeof(netMapping) / sizeof(netMapping[0]) - 1);
189 return netMapping[num];