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) \
32 static Shape ShapeName(name, dir) = { &ShapeName(name, nextDir), \
33 0, 0, mirror, D_ ## realDir, type, cmds_ ## cmdName }
35 #define FourWayDecl(name, cmdName, mirror, type) \
36 PreDecl(name, down); \
37 StdShape(name, cmdName, mirror, type, left, left, down); \
38 StdShape(name, cmdName, mirror, type, up, up, left); \
39 StdShape(name, cmdName, mirror, type, right, right, up); \
40 StdShape(name, cmdName, mirror, type, down, down, right)
42 #define TwoWayDecl(name, cmdName, mirror, type) \
43 PreDecl(name, vert); \
44 StdShape(name, cmdName, mirror, type, right, horiz, vert); \
45 StdShape(name, cmdName, mirror, type, down, vert, horiz)
47 static Cmd cmds_long[] = { C_back, C_plot, C_forw, C_plot, C_forw, C_plot,
48 C_forw, C_plot, C_end };
49 TwoWayDecl(long, long, 0, BT_blue);
51 static Cmd cmds_square[] = { C_plot, C_forw, C_left, C_plot, C_forw, C_left,
52 C_plot, C_forw, C_left, C_plot, C_end };
53 static Shape shape_square = { &shape_square, 0, 0, D_up, 0, BT_magenta,
56 static Cmd cmds_l[] = { C_right, C_back, C_plot, C_forw, C_plot, C_forw,
57 C_plot, C_left, C_forw, C_plot, C_end };
58 FourWayDecl(l, l, 0, BT_cyan);
59 FourWayDecl(l1, l, 1, BT_yellow);
61 static Cmd cmds_t[] = { C_plot, C_forw, C_plot, C_back, C_right, C_forw,
62 C_plot, C_back, C_back, C_plot, C_end };
63 FourWayDecl(t, t, 0, BT_white);
65 static Cmd cmds_s[] = { C_back, C_plot, C_forw, C_plot, C_left, C_forw,
66 C_plot, C_right, C_forw, C_plot, C_end };
67 TwoWayDecl(s, s, 0, BT_green);
68 TwoWayDecl(s1, s, 1, BT_red);
70 ShapeOption stdOptions[] = {
71 {1, &shape_long_horiz},
80 Shape *netMapping[] = {
102 ExtFunc void MoveInDir(Dir dir, int dist, int *y, int *x)
105 case D_down: *y -= dist; break;
106 case D_right: *x += dist; break;
107 case D_up: *y += dist; break;
108 case D_left: *x -= dist; break;
114 ExtFunc Dir RotateDir(Dir dir, int delta)
116 return 3 & (dir + delta);
119 ExtFunc int ShapeIterate(Shape *s, int scr, int y, int x, int falling,
120 ExtFunc ShapeDrawFunc func, void *data)
122 int i, mirror, result;
129 type = falling ? -s->type : s->type;
130 mirror = s->mirrored ? -1 : 1;
131 for (i = 0; s->cmds[i] != C_end; ++i)
132 switch (s->cmds[i]) {
134 MoveInDir(dir, 1, &y, &x);
137 MoveInDir(dir, -1, &y, &x);
140 dir = RotateDir(dir, mirror);
143 dir = RotateDir(dir, -mirror);
146 if ((result = func(scr, y, x, type, data)))
155 ExtFunc Shape *ChooseOption(ShapeOption *options)
158 float total = 0, val;
160 for (i = 0; options[i].shape; ++i)
161 total += options[i].weight;
162 val = Random(0, 32767) / 32768.0 * total;
163 for (i = 0; options[i].shape; ++i) {
164 val -= options[i].weight;
166 return options[i].shape;
168 return options[0].shape;
171 ExtFunc short ShapeToNetNum(Shape *shape)
175 for (num = 0; netMapping[num]; ++num)
176 if (netMapping[num] == shape)
182 ExtFunc Shape *NetNumToShape(short num)
184 assert(num >= 0 && num < sizeof(netMapping) / sizeof(netMapping[0]) - 1);
185 return netMapping[num];