rev |
line source |
paulo@0
|
1 /* Header file for the engine of LOCKJAW, an implementation of the Soviet Mind Game
|
paulo@0
|
2
|
paulo@0
|
3 Copyright (C) 2006 Damian Yerrick <tepples+lj@spamcop.net>
|
paulo@0
|
4
|
paulo@0
|
5 This work is free software; you can redistribute it and/or modify
|
paulo@0
|
6 it under the terms of the GNU General Public License as published by
|
paulo@0
|
7 the Free Software Foundation; either version 2 of the License, or
|
paulo@0
|
8 (at your option) any later version.
|
paulo@0
|
9
|
paulo@0
|
10 This program is distributed in the hope that it will be useful,
|
paulo@0
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
paulo@0
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
paulo@0
|
13 GNU General Public License for more details.
|
paulo@0
|
14
|
paulo@0
|
15 You should have received a copy of the GNU General Public License
|
paulo@0
|
16 along with this program; if not, write to the Free Software
|
paulo@0
|
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
paulo@0
|
18
|
paulo@0
|
19 Original game concept and design by Alexey Pajitnov.
|
paulo@0
|
20 The Software is not sponsored or endorsed by Alexey Pajitnov, Elorg,
|
paulo@0
|
21 or The Tetris Company LLC.
|
paulo@0
|
22
|
paulo@0
|
23 */
|
paulo@0
|
24
|
paulo@0
|
25 #ifndef LJ_H
|
paulo@0
|
26 #define LJ_H
|
paulo@0
|
27
|
paulo@0
|
28 #include <stdlib.h>
|
paulo@0
|
29 #include "ljtypes.h"
|
paulo@0
|
30
|
paulo@0
|
31 enum {
|
paulo@0
|
32 CONNECT_U = 0x01,
|
paulo@0
|
33 CONNECT_R = 0x02,
|
paulo@0
|
34 CONNECT_D = 0x04,
|
paulo@0
|
35 CONNECT_L = 0x08,
|
paulo@0
|
36 CONNECT_UD = CONNECT_U | CONNECT_D,
|
paulo@0
|
37 CONNECT_UL = CONNECT_U | CONNECT_L,
|
paulo@0
|
38 CONNECT_DL = CONNECT_D | CONNECT_L,
|
paulo@0
|
39 CONNECT_UR = CONNECT_U | CONNECT_R,
|
paulo@0
|
40 CONNECT_DR = CONNECT_D | CONNECT_R,
|
paulo@0
|
41 CONNECT_LR = CONNECT_L | CONNECT_R,
|
paulo@0
|
42 CONNECT_UDL = CONNECT_UD | CONNECT_L,
|
paulo@0
|
43 CONNECT_UDR = CONNECT_UD | CONNECT_R,
|
paulo@0
|
44 CONNECT_ULR = CONNECT_UL | CONNECT_R,
|
paulo@0
|
45 CONNECT_DLR = CONNECT_DL | CONNECT_R,
|
paulo@0
|
46 CONNECT_UDLR = CONNECT_UD | CONNECT_LR,
|
paulo@0
|
47 CONNECT_MASK = CONNECT_UDLR,
|
paulo@0
|
48 COLOR_MASK = 0xF0
|
paulo@0
|
49 };
|
paulo@0
|
50
|
paulo@0
|
51 typedef unsigned char LJBlock;
|
paulo@0
|
52
|
paulo@0
|
53 typedef enum LJState {
|
paulo@0
|
54 LJS_INACTIVE,
|
paulo@0
|
55 LJS_NEW_PIECE, /* delay is ARE */
|
paulo@0
|
56 LJS_FALLING, /* delay is fall delay; NOT IMPLEMENTED */
|
paulo@0
|
57 LJS_LANDED, /* delay is lock delay */
|
paulo@0
|
58 LJS_LINES, /* delay is line delay */
|
paulo@0
|
59 LJS_LINES_FALLING, /* delay is fall delay per line; NOT IMPLEMENTED */
|
paulo@0
|
60 LJS_GAMEOVER, /* game over animation */
|
paulo@0
|
61 LJS_EXPLODE /* used for bombliss extension */
|
paulo@0
|
62 } LJState;
|
paulo@0
|
63
|
paulo@0
|
64 // for other
|
paulo@0
|
65 enum {
|
paulo@0
|
66 LJI_HOLD = 0x01,
|
paulo@0
|
67 LJI_LOCK = 0x02
|
paulo@0
|
68 };
|
paulo@0
|
69
|
paulo@0
|
70 // for dirty bits
|
paulo@0
|
71 enum {
|
paulo@0
|
72 LJ_DIRTY_NEXT = 0x01000000,
|
paulo@0
|
73 LJ_DIRTY_SCORE = 0x02000000
|
paulo@0
|
74 };
|
paulo@0
|
75
|
paulo@0
|
76 // for gimmick (game mode)
|
paulo@0
|
77 enum {
|
paulo@0
|
78 LJGM_ATYPE, // marathon
|
paulo@0
|
79 LJGM_BTYPE, // 40 lines
|
paulo@0
|
80 LJGM_ULTRA, // 180 seconds
|
paulo@0
|
81 LJGM_DRILL, // clear bottom line
|
paulo@0
|
82 LJGM_ITEMS, // no rotation + no next + fast drop + garbage + banana
|
paulo@0
|
83 LJGM_BABY, // 300 keypresses
|
paulo@0
|
84 LJGM_N_GIMMICKS
|
paulo@0
|
85 };
|
paulo@0
|
86
|
paulo@0
|
87 enum {
|
paulo@0
|
88 LJP_I = 0,
|
paulo@0
|
89 LJP_J,
|
paulo@0
|
90 LJP_L,
|
paulo@0
|
91 LJP_O,
|
paulo@0
|
92 LJP_S,
|
paulo@0
|
93 LJP_T,
|
paulo@0
|
94 LJP_Z,
|
paulo@0
|
95 LJP_I2,
|
paulo@0
|
96 LJP_I3,
|
paulo@0
|
97 LJP_L3,
|
paulo@0
|
98 LJP_GARBAGE = 7,
|
paulo@0
|
99 LJP_MASK = 0x0F
|
paulo@0
|
100 };
|
paulo@0
|
101
|
paulo@0
|
102 enum {
|
paulo@0
|
103 LJSND_ROTATE = 0x0001,
|
paulo@0
|
104 LJSND_SHIFT = 0x0002,
|
paulo@0
|
105 LJSND_DROP = 0x0004,
|
paulo@0
|
106 LJSND_LAND = 0x0008,
|
paulo@0
|
107 LJSND_LOCK = 0x0010,
|
paulo@0
|
108 LJSND_LINE = 0x0020, // a line was scored
|
paulo@0
|
109 LJSND_SETB2B = 0x0040, // this line is b2b worthy (tetris or t-spin)
|
paulo@0
|
110 LJSND_B2B = 0x0080, // this line AND last line were b2b worthy
|
paulo@0
|
111 LJSND_SPAWN = 0x0100, // next piece was moved up
|
paulo@0
|
112 LJSND_HOLD = 0x0200, // hold piece was activated
|
paulo@0
|
113 LJSND_IRS = 0x0400, // initial rotation: spawn last frame and rotation this frame
|
paulo@0
|
114 LJSND_SQUARE = 0x0800, // formed 4x4 square
|
paulo@0
|
115 LJSND_COUNTDOWN = 0x4000, // countdown value changed
|
paulo@0
|
116 LJSND_SECTIONUP = 0x8000, // section increased
|
paulo@0
|
117 };
|
paulo@0
|
118
|
paulo@0
|
119 enum {
|
paulo@0
|
120 LJRAND_PURE,
|
paulo@0
|
121 LJRAND_BAG,
|
paulo@0
|
122 LJRAND_BAGPLUS1,
|
paulo@0
|
123 LJRAND_2BAG,
|
paulo@0
|
124 LJRAND_HIST_INF,
|
paulo@0
|
125 LJRAND_HIST_6,
|
paulo@0
|
126 LJRAND_N_RANDS
|
paulo@0
|
127 };
|
paulo@0
|
128
|
paulo@0
|
129 enum {
|
paulo@0
|
130 LJRAND_4BLK,
|
paulo@0
|
131 LJRAND_JLOSTZ,
|
paulo@0
|
132 LJRAND_SZ,
|
paulo@0
|
133 LJRAND_I,
|
paulo@0
|
134 LJRAND_234BLK,
|
paulo@0
|
135 LJRAND_T,
|
paulo@0
|
136 LJRAND_N_PIECE_SETS
|
paulo@0
|
137 };
|
paulo@0
|
138
|
paulo@0
|
139 enum {
|
paulo@0
|
140 LJTS_OFF = 0,
|
paulo@0
|
141 LJTS_TNT,
|
paulo@0
|
142 LJTS_TDS,
|
paulo@0
|
143 LJTS_TDS_NO_KICK,
|
paulo@0
|
144 LJTS_N_ALGOS
|
paulo@0
|
145 };
|
paulo@0
|
146
|
paulo@0
|
147 enum {
|
paulo@0
|
148 LJSPD_ZERO = 0,
|
paulo@0
|
149 LJSPD_RHYTHMZERO,
|
paulo@0
|
150 LJSPD_EXP,
|
paulo@0
|
151 LJSPD_RHYTHM,
|
paulo@0
|
152 LJSPD_TGM,
|
paulo@0
|
153 LJSPD_DEATH,
|
paulo@0
|
154 LJSPD_DEATH300,
|
paulo@0
|
155 LJSPD_NES,
|
paulo@0
|
156 LJSPD_GB,
|
paulo@0
|
157 LJSPD_GBHEART,
|
paulo@0
|
158 LJSPD_N_CURVES
|
paulo@0
|
159 };
|
paulo@0
|
160
|
paulo@0
|
161 enum {
|
paulo@0
|
162 LJLOCK_NOW = 0,
|
paulo@0
|
163 LJLOCK_SPAWN,
|
paulo@0
|
164 LJLOCK_STEP,
|
paulo@0
|
165 LJLOCK_MOVE,
|
paulo@0
|
166 LJLOCK_N_STYLES
|
paulo@0
|
167 };
|
paulo@0
|
168
|
paulo@0
|
169 enum {
|
paulo@0
|
170 LJGRAV_NAIVE = 0,
|
paulo@0
|
171 LJGRAV_STICKY,
|
paulo@0
|
172 LJGRAV_STICKY_BY_COLOR,
|
paulo@0
|
173 LJGRAV_CASCADE,
|
paulo@0
|
174 LJGRAV_N_ALGOS
|
paulo@0
|
175 };
|
paulo@0
|
176
|
paulo@0
|
177 enum {
|
paulo@0
|
178 LJSCORE_LJ,
|
paulo@0
|
179 LJSCORE_TNT64,
|
paulo@0
|
180 LJSCORE_HOTLINE,
|
paulo@0
|
181 LJSCORE_TDS,
|
paulo@0
|
182 LJSCORE_NES,
|
paulo@0
|
183 LJSCORE_LJ_NERF,
|
paulo@0
|
184 LJSCORE_N_STYLES,
|
paulo@0
|
185 LJSCORE_WORLDS,
|
paulo@0
|
186 LJSCORE_TGM1,
|
paulo@0
|
187 LJSCORE_IPOD
|
paulo@0
|
188 };
|
paulo@0
|
189
|
paulo@0
|
190 enum {
|
paulo@0
|
191 LJDROP_NOSCORE,
|
paulo@0
|
192 LJDROP_NES,
|
paulo@0
|
193 LJDROP_1CELL,
|
paulo@0
|
194 LJDROP_1S_2H,
|
paulo@0
|
195 LJDROP_N_STYLES
|
paulo@0
|
196 };
|
paulo@0
|
197
|
paulo@0
|
198 enum {
|
paulo@0
|
199 LJGARBAGE_NONE,
|
paulo@0
|
200 LJGARBAGE_1,
|
paulo@0
|
201 LJGARBAGE_2,
|
paulo@0
|
202 LJGARBAGE_3,
|
paulo@0
|
203 LJGARBAGE_4,
|
paulo@0
|
204 LJGARBAGE_HRDERBY,
|
paulo@0
|
205 LJGARBAGE_DRILL,
|
paulo@0
|
206 LJGARBAGE_ZIGZAG,
|
paulo@0
|
207
|
paulo@0
|
208 LJGARBAGE_N_STYLES
|
paulo@0
|
209 };
|
paulo@0
|
210
|
paulo@0
|
211 enum {
|
paulo@0
|
212 LJHOLD_NONE,
|
paulo@0
|
213 LJHOLD_EMPTY,
|
paulo@0
|
214 LJHOLD_TNT,
|
paulo@0
|
215 LJHOLD_TO_NEXT,
|
paulo@0
|
216 LJHOLD_N_STYLES
|
paulo@0
|
217 };
|
paulo@0
|
218
|
paulo@0
|
219 enum {
|
paulo@0
|
220 LJGLUING_NONE,
|
paulo@0
|
221 LJGLUING_SQUARE,
|
paulo@0
|
222 LJGLUING_STICKY,
|
paulo@0
|
223 LJGLUING_STICKY_BY_COLOR,
|
paulo@0
|
224 LJGLUING_N_STYLES
|
paulo@0
|
225 };
|
paulo@0
|
226
|
paulo@0
|
227 // Guideline says 10 wide, but we want to support tetrinet mode
|
paulo@0
|
228 #define LJ_PF_WID ((size_t)12)
|
paulo@0
|
229 #define LJ_SPAWN_X ((LJ_PF_WID - 3) / 2)
|
paulo@0
|
230 #define LJ_PF_HT ((size_t)24)
|
paulo@0
|
231 #define LJ_PF_VIS_HT ((size_t)20)
|
paulo@0
|
232 #define LJ_NEXT_PIECES 8
|
paulo@0
|
233 #define LJ_MAX_LINES_PER_PIECE 8
|
paulo@0
|
234
|
paulo@0
|
235 typedef struct LJBlkSpec
|
paulo@0
|
236 {
|
paulo@0
|
237 signed char x, y, conn, reserved;
|
paulo@0
|
238 } LJBlkSpec;
|
paulo@0
|
239
|
paulo@0
|
240 typedef struct LJInput {
|
paulo@0
|
241 signed char rotation, movement;
|
paulo@0
|
242 unsigned char gravity; /* 5.3 format */
|
paulo@0
|
243 unsigned char other;
|
paulo@0
|
244 } LJInput;
|
paulo@0
|
245
|
paulo@0
|
246 typedef struct LJSpeedSetting {
|
paulo@0
|
247 LJFixed gravity;
|
paulo@0
|
248 unsigned char entryDelay, dasDelay, lockDelay, lineDelay;
|
paulo@0
|
249 } LJSpeedSetting;
|
paulo@0
|
250
|
paulo@0
|
251 typedef struct SpeedStateBase {
|
paulo@0
|
252 unsigned char curve, section;
|
paulo@0
|
253 unsigned char pad[2];
|
paulo@0
|
254 signed int level;
|
paulo@0
|
255 } SpeedStateBase;
|
paulo@0
|
256
|
paulo@0
|
257 #define MAX_BAG_LEN 10
|
paulo@0
|
258 #define MAX_OMINO 4
|
paulo@0
|
259
|
paulo@0
|
260 typedef struct LJField
|
paulo@0
|
261 {
|
paulo@0
|
262 /* Game state */
|
paulo@0
|
263 LJBlock b[LJ_PF_HT][LJ_PF_WID];
|
paulo@0
|
264 LJBlock c[LJ_PF_HT][LJ_PF_WID];
|
paulo@0
|
265 LJBits clearedLines;
|
paulo@0
|
266 LJBits sounds;
|
paulo@0
|
267 LJBits tempRows;
|
paulo@0
|
268 unsigned char curPiece[1 + LJ_NEXT_PIECES];
|
paulo@0
|
269 signed char permuPiece[2 * MAX_BAG_LEN], permuPhase;
|
paulo@0
|
270 unsigned short nLineClears[LJ_MAX_LINES_PER_PIECE]; // [n-1] = # of n-line clears
|
paulo@0
|
271 LJFixed y;
|
paulo@0
|
272 LJState state;
|
paulo@0
|
273 signed char stateTime;
|
paulo@0
|
274 unsigned char theta;
|
paulo@0
|
275 signed char x;
|
paulo@0
|
276 signed char hardDropY;
|
paulo@0
|
277 char alreadyHeld;
|
paulo@0
|
278 char isSpin;
|
paulo@0
|
279 char nLinesThisPiece;
|
paulo@0
|
280 char canRotate;
|
paulo@0
|
281 unsigned char upwardKicks;
|
paulo@0
|
282
|
paulo@0
|
283 /* Persist from piece to piece */
|
paulo@0
|
284 int score, lines;
|
paulo@0
|
285 unsigned int gameTime; // number of frames
|
paulo@0
|
286 unsigned int activeTime; // number of frames
|
paulo@0
|
287 signed short holdPiece;
|
paulo@0
|
288 char chain;
|
paulo@0
|
289 signed char garbage;
|
paulo@0
|
290 unsigned char dropDist;
|
paulo@0
|
291 unsigned char garbageX;
|
paulo@0
|
292 unsigned short nPieces, outGarbage;
|
paulo@0
|
293 unsigned short monosquares, multisquares;
|
paulo@0
|
294
|
paulo@0
|
295 /* Determined by gimmick */
|
paulo@0
|
296 signed char gimmick;
|
paulo@0
|
297 signed int bpmCounter;
|
paulo@0
|
298 unsigned int speedupCounter;
|
paulo@0
|
299 unsigned int goalCount;
|
paulo@0
|
300 unsigned int seed;
|
paulo@0
|
301 unsigned char goalType;
|
paulo@0
|
302
|
paulo@0
|
303 LJSpeedSetting speed;
|
paulo@0
|
304 SpeedStateBase speedState;
|
paulo@0
|
305
|
paulo@0
|
306 unsigned char lockReset; // lockdown reset rule type
|
paulo@0
|
307 unsigned char areStyle;
|
paulo@0
|
308 unsigned char setLockDelay; // Overridden lock delay (255 = never)
|
paulo@0
|
309 unsigned char setLineDelay; // Overridden line delay
|
paulo@0
|
310 unsigned char garbageStyle;
|
paulo@0
|
311 unsigned char ceiling;
|
paulo@0
|
312 unsigned char enterAbove;
|
paulo@0
|
313 unsigned char leftWall, rightWall;
|
paulo@0
|
314 unsigned char pieceSet;
|
paulo@0
|
315 unsigned char randomizer;
|
paulo@0
|
316 unsigned char rotationSystem;
|
paulo@0
|
317 unsigned char garbageRandomness; // 64: change garbageX in 1/4 of rows; 255: change all
|
paulo@0
|
318 unsigned char tSpinAlgo; // 0: off, 1: TNT, 2: TDS
|
paulo@0
|
319 unsigned char clearGravity;
|
paulo@0
|
320 unsigned char gluing; // 0: off; 1: square
|
paulo@0
|
321 unsigned char scoreStyle;
|
paulo@0
|
322 unsigned char dropScoreStyle;
|
paulo@0
|
323 unsigned char maxUpwardKicks;
|
paulo@0
|
324 unsigned char holdStyle;
|
paulo@0
|
325 unsigned char bottomBlocks;
|
paulo@0
|
326 unsigned char reloaded; // 0: played through; 1: reloaded from saved state
|
paulo@0
|
327 } LJField;
|
paulo@0
|
328
|
paulo@0
|
329 /**
|
paulo@0
|
330 * Names of the supported rotation systems (wktables.c).
|
paulo@0
|
331 */
|
paulo@0
|
332 enum {
|
paulo@0
|
333 LJROT_SRS,
|
paulo@0
|
334 LJROT_SEGA,
|
paulo@0
|
335 LJROT_ARIKA,
|
paulo@0
|
336 LJROT_ATARI,
|
paulo@0
|
337 LJROT_NES,
|
paulo@0
|
338 LJROT_GB,
|
paulo@0
|
339 LJROT_TOD,
|
paulo@0
|
340 LJROT_TDX,
|
paulo@0
|
341 N_ROTATION_SYSTEMS
|
paulo@0
|
342 };
|
paulo@0
|
343
|
paulo@0
|
344 #define N_PIECE_SHAPES 10
|
paulo@0
|
345 #define KICK_TABLE_LEN 5
|
paulo@0
|
346 extern const char pieceColors[N_PIECE_SHAPES];
|
paulo@0
|
347 typedef unsigned char WallKickTable[4][KICK_TABLE_LEN];
|
paulo@0
|
348 typedef struct LJRotSystem {
|
paulo@0
|
349 /**
|
paulo@0
|
350 * Color scheme for this rotation system (0: SRS; 1: Sega)
|
paulo@0
|
351 * Use colorset 0 (SRS) if all free-space kicks are WK(0, 0).
|
paulo@0
|
352 * Otherwise, your rotation system has what Eddie Rogers has called
|
paulo@0
|
353 * a topknot, and you should use Sega colors.
|
paulo@0
|
354 */
|
paulo@0
|
355 unsigned char colorScheme;
|
paulo@0
|
356 unsigned char reserved1[3];
|
paulo@0
|
357 unsigned char entryOffset[N_PIECE_SHAPES];
|
paulo@0
|
358 unsigned char entryTheta[N_PIECE_SHAPES];
|
paulo@0
|
359 /* These control which kick table is used for each piece.
|
paulo@0
|
360 * If negative, no kick table is present.
|
paulo@0
|
361 */
|
paulo@0
|
362 signed char kicksL[N_PIECE_SHAPES];
|
paulo@0
|
363 signed char kicksR[N_PIECE_SHAPES];
|
paulo@0
|
364 WallKickTable kickTables[];
|
paulo@0
|
365 } LJRotSystem;
|
paulo@0
|
366
|
paulo@0
|
367 extern const LJRotSystem *const rotSystems[N_ROTATION_SYSTEMS];
|
paulo@0
|
368
|
paulo@0
|
369 #ifdef LJ_INTERNAL
|
paulo@0
|
370 // Used for defining wall kick tables:
|
paulo@0
|
371 // WK(x, y) builds a 1-byte record with 2 coordinates, at 4 bits
|
paulo@0
|
372 // per coordinate.
|
paulo@0
|
373 // WKX() and WKY() retrieve the X or Y coordinate from this record.
|
paulo@0
|
374 // The ((stuff ^ 8) - 8) is sign extension magick
|
paulo@0
|
375 #define WK(x, y) (((x) & 0x0F) | ((y) & 0x0F) << 4)
|
paulo@0
|
376 #define WKX(wk) ((((wk) & 0x0F) ^ 8) - 8)
|
paulo@0
|
377 #define WKY(wk) WKX((wk) >> 4)
|
paulo@0
|
378 // If ARIKA_IF_NOT_CENTER is specified, check the free space
|
paulo@0
|
379 // rotation for blocks in columns other than 1, and stop if
|
paulo@0
|
380 // none of them are filled. This obsoletes the old SKIP_IF.
|
paulo@0
|
381 #define SKIP_IF 0x80
|
paulo@0
|
382 #define SKIP_IF3 0x82
|
paulo@0
|
383
|
paulo@0
|
384 #define ARIKA_IF_NOT_CENTER 0x83
|
paulo@0
|
385 #define WK_END 0x8F
|
paulo@0
|
386 #if 0
|
paulo@0
|
387 extern const WallKickTable *const wkTablesL[N_ROTATION_SYSTEMS][N_PIECE_SHAPES];
|
paulo@0
|
388 extern const WallKickTable *const wkTablesR[N_ROTATION_SYSTEMS][N_PIECE_SHAPES];
|
paulo@0
|
389 #endif
|
paulo@0
|
390 #endif
|
paulo@0
|
391
|
paulo@0
|
392 /**
|
paulo@0
|
393 * Expands a tetromino to the blocks that make it up.
|
paulo@0
|
394 * @param out an array of length 4
|
paulo@0
|
395 * @param p the field into which the tetromino will be spawned
|
paulo@0
|
396 * (used for default spawn orientation)
|
paulo@0
|
397 * @param piece a piece number
|
paulo@0
|
398 * @param xBase x coordinate of base position of the tetromino
|
paulo@0
|
399 * @param yBase y coordinate of base position of the tetromino
|
paulo@0
|
400 * @param theta the orientation of the tetromino
|
paulo@0
|
401 * (0-3: use this; 4: use default spawn rotation)
|
paulo@0
|
402 */
|
paulo@0
|
403 void expandPieceToBlocks(LJBlkSpec out[],
|
paulo@0
|
404 const LJField *p,
|
paulo@0
|
405 int piece, int xBase, int yBase, int theta);
|
paulo@0
|
406
|
paulo@0
|
407 /**
|
paulo@0
|
408 * Tests whether a particular block is occupied.
|
paulo@0
|
409 * @param p the playfield
|
paulo@0
|
410 * @param x the column
|
paulo@0
|
411 * @param y the row (0 = bottom)
|
paulo@0
|
412 * @return zero iff the space is open
|
paulo@0
|
413 */
|
paulo@0
|
414 int isOccupied(const LJField *p, int x, int y);
|
paulo@0
|
415
|
paulo@0
|
416 /**
|
paulo@0
|
417 * Tests whether a particular tetromino would overlap one or more
|
paulo@0
|
418 * blocks, a side wall, or the floor
|
paulo@0
|
419 * @param p the playfield
|
paulo@0
|
420 * @param x the column of the left side of the piece's bounding 4x4
|
paulo@0
|
421 * @param y the row of the bottom of the piece's bounding 4x4 (0 = bottom)
|
paulo@0
|
422 * @return zero iff the space is open
|
paulo@0
|
423 */
|
paulo@0
|
424 int isCollision(const LJField *p, int x, int y, int theta);
|
paulo@0
|
425
|
paulo@0
|
426 /**
|
paulo@0
|
427 * Blanks a playfield and prepares it for a new game.
|
paulo@0
|
428 * @param p the playfield
|
paulo@0
|
429 */
|
paulo@0
|
430 void newGame(LJField *p);
|
paulo@0
|
431
|
paulo@0
|
432 /**
|
paulo@0
|
433 * Runs one frame of S.M.G.
|
paulo@0
|
434 * @param p the playfield
|
paulo@0
|
435 * @param in the player's input
|
paulo@0
|
436 * @return the rows that were modified
|
paulo@0
|
437 */
|
paulo@0
|
438 LJBits frame(LJField *p, const LJInput *in);
|
paulo@0
|
439
|
paulo@0
|
440 /**
|
paulo@0
|
441 * Applies gimmicks to a new game.
|
paulo@0
|
442 * @param p the playfield
|
paulo@0
|
443 * @param in the player's input
|
paulo@0
|
444 */
|
paulo@0
|
445 void initGimmicks(LJField *p);
|
paulo@0
|
446
|
paulo@0
|
447 /**
|
paulo@0
|
448 * Runs gimmicks for one frame of S.M.G.
|
paulo@0
|
449 * @param p the playfield
|
paulo@0
|
450 * @param c the control settings
|
paulo@0
|
451 * @return the rows that were modified
|
paulo@0
|
452 */
|
paulo@0
|
453 struct LJControl;
|
paulo@0
|
454 LJBits gimmicks(LJField *p, struct LJControl *c);
|
paulo@0
|
455
|
paulo@0
|
456 /**
|
paulo@0
|
457 * Sets up the randomizer.
|
paulo@0
|
458 * @return the number of this piece
|
paulo@0
|
459 */
|
paulo@0
|
460 void initRandomize(LJField *p);
|
paulo@0
|
461
|
paulo@0
|
462 /**
|
paulo@0
|
463 * Chooses a pseudo-random piece.
|
paulo@0
|
464 * @param the field on which the piece will be generated
|
paulo@0
|
465 * @return the number of this piece
|
paulo@0
|
466 * (0=i, 1=j, 2=l, 3=o, 4=s, 5=t, 6=z)
|
paulo@0
|
467 */
|
paulo@0
|
468 unsigned int randomize(LJField *p);
|
paulo@0
|
469
|
paulo@0
|
470 /**
|
paulo@0
|
471 * Counts the number of 1 bits in a bitfield.
|
paulo@0
|
472 * @param p the bitfield
|
paulo@0
|
473 * @return the number of bits in p with a value of 1.
|
paulo@0
|
474 */
|
paulo@0
|
475 unsigned int countOnes(LJBits b);
|
paulo@0
|
476
|
paulo@0
|
477 /**
|
paulo@0
|
478 * Shuffles the columns of blocks in the playfield.
|
paulo@0
|
479 * @param p the playfield
|
paulo@0
|
480 */
|
paulo@0
|
481 void shuffleColumns(LJField *p);
|
paulo@0
|
482
|
paulo@0
|
483 /**
|
paulo@0
|
484 * Random number generator. Use this for all random events
|
paulo@0
|
485 * that affect the game state.
|
paulo@0
|
486 * @param field
|
paulo@0
|
487 * @return uniformly distributed number in 0 to 0x7FFF
|
paulo@0
|
488 */
|
paulo@0
|
489 unsigned int ljRand(LJField *p);
|
paulo@0
|
490
|
paulo@0
|
491 /**
|
paulo@0
|
492 * List of lines used for hotline scoring.
|
paulo@0
|
493 * A line clear completed at row hotlineRows[i] is worth 100*(i + 1).
|
paulo@0
|
494 */
|
paulo@0
|
495 extern const char hotlineRows[LJ_PF_HT];
|
paulo@0
|
496
|
paulo@0
|
497 /**
|
paulo@0
|
498 * Counts the number of trailing zero bits on an integer.
|
paulo@0
|
499 * For instance, 00000000 00000000 00000001 11111000
|
paulo@0
|
500 * has 3 trailing zeroes.
|
paulo@0
|
501 */
|
paulo@0
|
502 unsigned int bfffo(LJBits rowBits);
|
paulo@0
|
503
|
paulo@0
|
504 void setupZigzagField(LJField *p, size_t height);
|
paulo@0
|
505 unsigned int calcZigzagGrade(const LJField *p);
|
paulo@0
|
506
|
paulo@0
|
507 #endif
|