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.
33 #include "Controller.h"
34 #include "ComboTabulator.h"
35 #include "ComboManager.h"
36 #include "CountDownManager.h"
39 int Swapper::x
, Swapper::y
;
42 int Swapper::swap_alarm
;
43 int Swapper::move_pause_alarm
;
44 bool Swapper::button_down_swap
;
45 int Swapper::button_down_move
;
46 Block
*Swapper::left_block
, *Swapper::right_block
;
47 int Swapper::queued_move
;
48 bool Swapper::queued_swap
;
49 float Swapper::swap_factor
;
52 void Swapper::gameStart ( )
54 x
= GC_INITIAL_SWAPPER_LOCATION_X
;
55 y
= GC_INITIAL_SWAPPER_LOCATION_Y
;
62 button_down_swap
= false;
71 void Swapper::timeStep ( )
73 * If we're swapping, check to see if we're done. Check the keyboard for any
74 * commands which we must react to.
77 if (!Controller::moveCommand())
79 if (!Controller::swapCommand())
80 button_down_swap
= false;
82 if (state
& SS_MOVE_PAUSE
)
83 // if it's time, unset the move pause state
84 if (move_pause_alarm
== Game::time_step
)
85 state
&= ~SS_MOVE_PAUSE
;
87 // otherwise, listen to queue a swap
88 else if (!button_down_swap
&& Controller::swapCommand()) {
89 if (queued_move
) queued_move
= 0;
91 button_down_swap
= true;
93 // otherwise, listen to queue a move
94 } else if (Controller::moveCommand()
95 && button_down_move
!= Controller::moveCommand() && !queued_swap
)
96 queued_move
= button_down_move
= Controller::moveCommand();
98 if (state
& SS_SWAPPING
)
99 if (swap_alarm
== Game::time_step
) {
101 // unset the swap state
102 state
&= ~SS_SWAPPING
;
107 Grid::remove(x
, y
, left_block
);
109 Grid::remove(x
+ 1, y
, right_block
);
112 // otherwise the assert bites us
113 if (!(swap
& SA_LEFT
))
114 Grid::changeState(x
, y
, null
, GR_EMPTY
);
115 if (!(swap
& SA_RIGHT
))
116 Grid::changeState(x
+ 1, y
, null
, GR_EMPTY
);
120 left_block
->finishSwapping(x
+ 1);
122 right_block
->finishSwapping(x
);
124 // register blocks for elimination checking
126 // if two blocks moved, we need a combo tabulator to link potential
128 ComboTabulator
*combo
= (swap
== (SA_LEFT
| SA_RIGHT
)
129 ? &ComboManager::newComboTabulator() : null
);
132 Grid::requestEliminationCheck(*left_block
, combo
);
134 Grid::requestEliminationCheck(*right_block
, combo
);
136 // listen to queue a move
137 if (!button_down_move
&& Controller::moveCommand())
138 queued_move
= button_down_move
= Controller::moveCommand();
140 // no commands when we're swapping
144 swap_factor
= (Game::time_step
- Swapper::swap_alarm
)
145 * (1.0f
/ (float) GC_SWAP_DELAY
);
147 if (state
& SS_SWAPPING
) {
148 // listen to queue a move
149 if (!button_down_move
&& Controller::moveCommand())
150 queued_move
= button_down_move
= Controller::moveCommand();
152 // no commands when we're swapping
156 // if we're not in a move pause or swap
157 if (!(state
& (SS_MOVE_PAUSE
| SS_SWAPPING
)) && (queued_move
158 || (Controller::moveCommand()
159 && button_down_move
!= Controller::moveCommand()))) {
160 switch (queued_move
? queued_move
: Controller::moveCommand()) {
162 if (!X::reverseControls()) {
165 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_LEFT
| SS_MOVE_PAUSE
);
166 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
167 button_down_move
= CC_LEFT
;
170 if (x
< GC_PLAY_WIDTH
- 2) {
172 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_RIGHT
| SS_MOVE_PAUSE
);
173 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
174 button_down_move
= CC_LEFT
;
179 if (!X::reverseControls()) {
180 if (x
< GC_PLAY_WIDTH
- 2) {
182 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_RIGHT
| SS_MOVE_PAUSE
);
183 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
184 button_down_move
= CC_RIGHT
;
189 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_LEFT
| SS_MOVE_PAUSE
);
190 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
191 button_down_move
= CC_RIGHT
;
196 if (!X::reverseControls()) {
197 if (y
< GC_SAFE_HEIGHT
- 1) {
199 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_UP
| SS_MOVE_PAUSE
);
200 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
201 button_down_move
= CC_UP
;
206 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_DOWN
| SS_MOVE_PAUSE
);
207 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
208 button_down_move
= CC_UP
;
213 if (!X::reverseControls()) {
216 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_DOWN
| SS_MOVE_PAUSE
);
217 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
218 button_down_move
= CC_DOWN
;
221 if (y
< GC_SAFE_HEIGHT
- 1) {
223 state
= (state
& ~SS_MOVE_MASK
) | (SS_MOVE_UP
| SS_MOVE_PAUSE
);
224 move_pause_alarm
= Game::time_step
+ GC_MOVE_DELAY
;
225 button_down_move
= CC_DOWN
;
233 if (!(state
& (SS_MOVE_PAUSE
| SS_SWAPPING
)) && (queued_swap
234 || (Controller::swapCommand() && !button_down_swap
))
235 && CountDownManager::start_pause_alarm
== 0) {
237 button_down_swap
= true;
241 if (Grid::stateAt(x
, y
) & GR_BLOCK
) {
242 left_block
= &Grid::blockAt(x
, y
);
244 } else if (!(Grid::stateAt(x
, y
) & GR_EMPTY
)
245 || Grid::stateAt(x
, y
- 1) & GR_FALLING
246 || Grid::stateAt(x
, y
+ 1) & GR_HANGING
)
247 swap
|= SA_DISALLOWED
;
249 if (Grid::stateAt(x
+ 1, y
) & GR_BLOCK
) {
250 right_block
= &Grid::blockAt(x
+ 1, y
);
252 } else if (!(Grid::stateAt(x
+ 1, y
) & GR_EMPTY
)
253 || Grid::stateAt(x
+ 1, y
- 1) & GR_FALLING
254 || Grid::stateAt(x
+ 1, y
+ 1) & GR_HANGING
)
255 swap
|= SA_DISALLOWED
;
257 // if swap is allowed
258 if (!(swap
& SA_DISALLOWED
) && swap
!= 0) {
261 state
|= SS_SWAPPING
;
264 swap_alarm
= Game::time_step
+ GC_SWAP_DELAY
;
266 // start the swapping
268 left_block
->startSwapping(SA_RIGHT
);
270 Grid::changeState(x
, y
, null
, GR_IMMUTABLE
);
273 right_block
->startSwapping(SA_LEFT
);
275 Grid::changeState(x
+ 1, y
, null
, GR_IMMUTABLE
);
277 // initialize the swap factor