Fixes for datatype size on amd64.
[crack-attack.git] / src / BlockManager.h
blobb51a8ffeb406aedf8424261ff2193d57462dd264
1 /*
2 * BlockManager.h
3 * Daniel Nelson - 8/24/0
5 * Copyright (C) 2000 Daniel Nelson
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * Daniel Nelson - aluminumangel.org
22 * 174 W. 18th Ave.
23 * Columbus, OH 43210
26 #ifndef BLOCKMANAGER_H
27 #define BLOCKMANAGER_H
29 #include <cassert>
31 #include "Game.h"
32 #include "Block.h"
33 #include "Random.h"
34 #include "MetaState.h"
35 #include "X.h"
37 class ComboTabulator;
39 /* static */ class BlockManager {
40 public:
41 static void gameStart ( );
42 static void newAwakingBlock ( int x, int y, int pop_delay, int awake_delay,
43 ComboTabulator *combo, int pop_color );
45 static inline void newCreepRow ( )
47 if (!(MetaState::mode & CM_X))
48 if (Random::chanceIn(GC_NO_SPECIAL_BLOCK_CHANCE_IN))
49 special_block_location = -1;
50 else
51 special_block_location = Random::number(GC_PLAY_WIDTH);
52 else
53 if (Random::chanceIn(GC_X_NO_SPECIAL_BLOCK_CHANCE_IN))
54 special_block_location = -1;
55 else
56 special_block_location = Random::number(GC_PLAY_WIDTH);
58 for (int x = GC_PLAY_WIDTH; x--; )
59 newCreepBlock(x);
62 static inline void newBlock ( int x, int y, int flavor )
64 if (block_count == GC_BLOCK_STORE_SIZE) return;
66 int id = findFreeId();
67 allocateId(id);
68 Block &block = blockStore[id];
70 block.initializeStatic(x, y, flavor);
73 static inline void newBlock ( int x, int y, int flavor, int pop_delay,
74 int awake_delay, ComboTabulator *combo, int pop_color )
76 if (block_count == GC_BLOCK_STORE_SIZE) return;
78 int id = findFreeId();
79 allocateId(id);
80 Block &block = blockStore[id];
82 block.initializeAwaking(x, y, flavor, pop_delay, awake_delay, combo,
83 pop_color);
86 static inline void deleteBlock ( Block *block )
88 freeId(block->id);
91 static inline void shiftUp ( )
93 int c = block_count;
94 for (int n = 0; c; n++)
95 if (storeMap[n]) {
96 c--;
97 blockStore[n].y++;
101 static inline int generatePopDirection ( )
103 if (next_pop_direction & (1 << 3))
104 return next_pop_direction = (1 << 0);
105 else
106 return next_pop_direction <<= 1;
109 static inline int generatePopDirection ( int n )
111 int npd;
112 if (next_pop_direction & (1 << 3))
113 npd = next_pop_direction = (1 << 0);
114 else
115 npd = next_pop_direction <<= 1;
116 while (--n)
117 if (next_pop_direction & (1 << 3))
118 next_pop_direction = (1 << 0);
119 else
120 next_pop_direction <<= 1;
121 return npd;
124 static inline bool flavorMatch ( Block &block_1, Block &block_2 )
126 if (!X::wildActive())
127 return mapFlavorToBaseFlavor(block_1.flavor)
128 == mapFlavorToBaseFlavor(block_2.flavor);
129 else if (block_1.flavor != BF_WILD && block_2.flavor != BF_WILD)
130 return mapFlavorToBaseFlavor(block_1.flavor)
131 == mapFlavorToBaseFlavor(block_2.flavor);
132 else {
133 int f1;
134 if (block_1.flavor == BF_WILD)
135 f1 = X::wildFlavor(block_1);
136 else
137 f1 = mapFlavorToBaseFlavor(block_1.flavor);
138 if (block_2.flavor == BF_WILD)
139 return f1 == X::wildFlavor(block_2);
140 else
141 return f1 == mapFlavorToBaseFlavor(block_2.flavor);
145 static inline bool isNormalFlavor ( int flavor )
147 return flavor <= BF_NUMBER_NORMAL;
150 static inline bool isBaseFlavor ( int flavor )
152 return flavor <= BF_GRAY;
155 static inline bool isColorlessFlavor ( int flavor )
157 return flavor >= BF_GRAY && flavor <= BF_FINAL_GRAY_SPECIAL;
160 static inline bool isSpecialFlavor ( int flavor )
162 return flavor > BF_GRAY;
165 static inline bool isSpecialColorFlavor ( int flavor )
167 return flavor >= BF_SPECIAL_COLOR_1;
170 static inline int mapFlavorToBaseFlavor ( int flavor )
172 if (isBaseFlavor(flavor))
173 return flavor;
174 if (isSpecialColorFlavor(flavor))
175 return mapSpecialColorFlavorToColor(flavor);
176 return BF_GRAY;
179 // The following handle block flavor codes. Each special block flavor has
180 // a code which is distinct from it's flavor number. This code is used to
181 // dereference special flavor arrays.
183 static inline bool isColorlessCode ( int code )
185 return code <= mapSpecialFlavorToCode(BF_FINAL_GRAY_SPECIAL);
188 static inline int mapSpecialFlavorToCode ( int flavor )
190 return flavor - (BF_GRAY + 1);
193 static inline int mapSpecialColorFlavorToColor ( int flavor )
195 return flavor - BF_SPECIAL_COLOR_1;
198 static int block_count;
199 static Block blockStore[GC_BLOCK_STORE_SIZE];
200 static bool storeMap[GC_BLOCK_STORE_SIZE];
202 static int last_row_c[GC_PLAY_WIDTH], second_to_last_row_c[GC_PLAY_WIDTH];
204 private:
205 static void newCreepBlock ( int x );
207 static inline int findFreeId ( )
209 int n;
210 for (n = 0; storeMap[n]; n++);
211 return n;
214 static inline void allocateId ( int id )
216 assert(!storeMap[id]);
217 storeMap[id] = true;
218 block_count++;
221 static inline void freeId ( int id )
223 assert(storeMap[id]);
224 storeMap[id] = false;
225 block_count--;
228 static int next_pop_direction;
230 static int last_flavor_a, second_to_last_flavor_a;
231 static int last_flavor_c, second_to_last_flavor_c;
232 static int last_row_a[GC_PLAY_WIDTH], second_to_last_row_a[GC_PLAY_WIDTH];
233 static int special_block_location;
236 #endif