3 * Daniel Nelson - 8/22/0
5 * Copyright (C) 2000 Daniel Nelson
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
25 * The thingy you swap blocks with.
34 #include "Controller.h"
35 #include "ComboTabulator.h"
36 #include "ComboManager.h"
37 #include "CountDownManager.h"
40 int Swapper::x
, Swapper::y
;
43 int Swapper::swap_alarm
;
44 int Swapper::move_pause_alarm
;
45 bool Swapper::button_down_swap
;
46 int Swapper::button_down_move
;
47 Block
*Swapper::left_block
, *Swapper::right_block
;
48 int Swapper::queued_move
;
49 bool Swapper::queued_swap
;
50 float Swapper::swap_factor
;
53 void Swapper::gameStart ( )
55 x
= GC_INITIAL_SWAPPER_LOCATION_X
;
56 y
= GC_INITIAL_SWAPPER_LOCATION_Y
;
63 button_down_swap
= false;
72 void Swapper::timeStep ( )
74 * If we're swapping, check to see if we're done. Check the keyboard for any
75 * commands which we must react to.
78 if (!Controller::moveCommand())
80 if (!Controller::swapCommand())
81 button_down_swap
= false;
83 if (state
& SS_MOVE_PAUSE
)
84 // if it's time, unset the move pause state
85 if (move_pause_alarm
== Game::time_step
)
86 state
&= ~SS_MOVE_PAUSE
;
88 // otherwise, listen to queue a swap
89 else if (!button_down_swap
&& Controller::swapCommand()) {
90 if (queued_move
) queued_move
= 0;
92 button_down_swap
= true;
94 // otherwise, listen to queue a move
95 } else if (Controller::moveCommand()
96 && button_down_move
!= Controller::moveCommand() && !queued_swap
)
97 queued_move
= button_down_move
= Controller::moveCommand();
99 if (state
& SS_SWAPPING
)
100 if (swap_alarm
== Game::time_step
) {
102 // unset the swap state
103 state
&= ~SS_SWAPPING
;
108 Grid::remove(x
, y
, left_block
);
110 Grid::remove(x
+ 1, y
, right_block
);
113 // otherwise the assert bites us
114 if (!(swap
& SA_LEFT
))
115 Grid::changeState(x
, y
, null
, GR_EMPTY
);
116 if (!(swap
& SA_RIGHT
))
117 Grid::changeState(x
+ 1, y
, null
, GR_EMPTY
);
121 left_block
->finishSwapping(x
+ 1);
123 right_block
->finishSwapping(x
);
125 // register blocks for elimination checking
127 // if two blocks moved, we need a combo tabulator to link potential
129 ComboTabulator
*combo
= (swap
== (SA_LEFT
| SA_RIGHT
)
130 ? &ComboManager::newComboTabulator() : null
);
133 Grid::requestEliminationCheck(*left_block
, combo
);
135 Grid::requestEliminationCheck(*right_block
, combo
);
137 // listen to queue a move
138 if (!button_down_move
&& Controller::moveCommand())
139 queued_move
= button_down_move
= Controller::moveCommand();
141 // no commands when we're swapping
145 swap_factor
= (Game::time_step
- Swapper::swap_alarm
)
146 * (1.0f
/ (float) GC_SWAP_DELAY
);
148 if (state
& SS_SWAPPING
) {
149 // listen to queue a move
150 if (!button_down_move
&& Controller::moveCommand())
151 queued_move
= button_down_move
= Controller::moveCommand();
153 // no commands when we're swapping
157 // if we're not in a move pause or swap
158 if (!(state
& (SS_MOVE_PAUSE
| SS_SWAPPING
)) && (queued_move
159 || (Controller::moveCommand()
160 && button_down_move
!= Controller::moveCommand()))) {
161 switch (queued_move
? queued_move
: Controller::moveCommand()) {
163 if (!X::reverseControls()) {
166 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_LEFT
| SS_MOVE_PAUSE
);
167 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
168 button_down_move
= CC_LEFT
;
171 if (x
< GC_PLAY_WIDTH
- 2) {
173 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_RIGHT
| SS_MOVE_PAUSE
);
174 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
175 button_down_move
= CC_LEFT
;
180 if (!X::reverseControls()) {
181 if (x
< GC_PLAY_WIDTH
- 2) {
183 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_RIGHT
| SS_MOVE_PAUSE
);
184 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
185 button_down_move
= CC_RIGHT
;
190 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_LEFT
| SS_MOVE_PAUSE
);
191 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
192 button_down_move
= CC_RIGHT
;
197 if (!X::reverseControls()) {
198 if (y
< GC_SAFE_HEIGHT
- 1) {
200 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_UP
| SS_MOVE_PAUSE
);
201 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
202 button_down_move
= CC_UP
;
207 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_DOWN
| SS_MOVE_PAUSE
);
208 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
209 button_down_move
= CC_UP
;
214 if (!X::reverseControls()) {
217 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_DOWN
| SS_MOVE_PAUSE
);
218 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
219 button_down_move
= CC_DOWN
;
222 if (y
< GC_SAFE_HEIGHT
- 1) {
224 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_UP
| SS_MOVE_PAUSE
);
225 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
226 button_down_move
= CC_DOWN
;
234 if (!(state
& (SS_MOVE_PAUSE
| SS_SWAPPING
)) && (queued_swap
235 || (Controller::swapCommand() && !button_down_swap
))
236 && CountDownManager::start_pause_alarm
== 0) {
238 button_down_swap
= true;
242 if (Grid::stateAt(x
, y
) & GR_BLOCK
) {
243 left_block
= &Grid::blockAt(x
, y
);
245 } else if (!(Grid::stateAt(x
, y
) & GR_EMPTY
)
246 || Grid::stateAt(x
, y
- 1) & GR_FALLING
247 || Grid::stateAt(x
, y
+ 1) & GR_HANGING
)
248 swap
|= SA_DISALLOWED
;
250 if (Grid::stateAt(x
+ 1, y
) & GR_BLOCK
) {
251 right_block
= &Grid::blockAt(x
+ 1, y
);
253 } else if (!(Grid::stateAt(x
+ 1, y
) & GR_EMPTY
)
254 || Grid::stateAt(x
+ 1, y
- 1) & GR_FALLING
255 || Grid::stateAt(x
+ 1, y
+ 1) & GR_HANGING
)
256 swap
|= SA_DISALLOWED
;
258 // if swap is allowed
259 if (!(swap
& SA_DISALLOWED
) && swap
!= 0) {
262 state
|= SS_SWAPPING
;
265 swap_alarm
= Game::time_step
+ GC_SWAP_DELAY
;
267 // start the swapping
269 left_block
->startSwapping(SA_RIGHT
);
271 Grid::changeState(x
, y
, null
, GR_IMMUTABLE
);
274 right_block
->startSwapping(SA_LEFT
);
276 Grid::changeState(x
+ 1, y
, null
, GR_IMMUTABLE
);
278 // initialize the swap factor