Initial import of the project.
[crack-attack.git] / src / LevelLights.h
blobac3913c66a2a76f0bef839802baf8409c8bd9fbc
1 /*
2 * LevelLights.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 LEVELLIGHTS_H
27 #define LEVELLIGHTS_H
29 using namespace std;
31 #include "Game.h"
32 #include "Displayer.h"
33 #include "Communicator.h"
35 #define LL_NUMBER_LEVEL_LIGHTS (GC_SAFE_HEIGHT - 1)
37 // two light sets
38 #define LL_LOCAL_LIGHTS (0)
39 #define LL_OPPONENT_LIGHTS (1)
41 // light states
42 #define LS_RED (1 << 0)
43 #define LS_BLUE (1 << 1)
44 #define LS_FADE_TO_RED (1 << 2)
45 #define LS_FADE_TO_BLUE (1 << 3)
46 #define LS_IMPACT_FLASH (1 << 4)
48 // communication buffer states
49 #define LC_BLUE (1 << 0)
50 #define LC_IMPACT (1 << 1)
51 #define LC_DEATH_FLASH_MASK (1 << (2 * LL_NUMBER_LEVEL_LIGHTS))
53 class LevelLight {
54 public:
55 int state;
56 int fade_alarm;
57 int flash_alarm;
60 /* static */ class LevelLights {
61 public:
62 static void initialize ( );
63 static void gameStart ( );
64 static void timeStep ( );
66 static inline void levelRaise ( int top_effective_row )
68 top_effective_row--;
69 if (top_effective_row >= LL_NUMBER_LEVEL_LIGHTS)
70 top_effective_row = LL_NUMBER_LEVEL_LIGHTS - 1;
72 while (top_effective_row >= 0) {
73 LevelLight &light = lights[LL_LOCAL_LIGHTS][top_effective_row];
74 if (light.state & (LS_RED | LS_FADE_TO_RED)) break;
75 setRed(light);
76 top_effective_row--;
80 static inline void levelLower ( int top_effective_row )
82 while (top_effective_row < LL_NUMBER_LEVEL_LIGHTS) {
83 LevelLight &light = lights[LL_LOCAL_LIGHTS][top_effective_row];
84 if (light.state & (LS_BLUE | LS_FADE_TO_BLUE)) break;
85 setBlue(light);
86 top_effective_row++;
90 static inline void notifyImpact ( int y, int height )
92 if (y - 1 + height > LL_NUMBER_LEVEL_LIGHTS) {
93 height = LL_NUMBER_LEVEL_LIGHTS - y + 1;
94 if (height < 1) return;
97 while (height--) {
98 LevelLight &light = lights[LL_LOCAL_LIGHTS][y - 1 + height];
99 Communicator::setLevelLightSendBit(LC_IMPACT << (2 * (y - 1 + height)));
100 setFlashing(light);
104 static inline void notifySafeHeightViolation ( )
106 if (death_flash_alarm[LL_LOCAL_LIGHTS] == -1)
107 death_flash_alarm[LL_LOCAL_LIGHTS] = DC_LEVEL_LIGHT_DEATH_FLASH_TIME;
110 static inline void readySendBuffer ( )
112 for (int n = LL_NUMBER_LEVEL_LIGHTS; n--; )
113 if (lights[LL_LOCAL_LIGHTS][n].state & (LS_BLUE | LS_FADE_TO_BLUE))
114 Communicator::setLevelLightSendBit(LC_BLUE << (2 * n));
116 if (death_flash_alarm[LL_LOCAL_LIGHTS] != -1)
117 Communicator::setLevelLightSendBit(LC_DEATH_FLASH_MASK);
120 static inline void handleRecvBuffer ( )
122 if (Communicator::checkLevelLightRecvBit(LC_DEATH_FLASH_MASK)
123 && death_flash_alarm[LL_OPPONENT_LIGHTS] == -1)
124 death_flash_alarm[LL_OPPONENT_LIGHTS] = DC_LEVEL_LIGHT_DEATH_FLASH_TIME;
126 for (int n = LL_NUMBER_LEVEL_LIGHTS; n--; ) {
127 if (lights[LL_OPPONENT_LIGHTS][n].state & (LS_RED | LS_FADE_TO_RED)) {
128 if (Communicator::checkLevelLightRecvBit(LC_BLUE << (2 * n)))
129 setBlue(lights[LL_OPPONENT_LIGHTS][n]);
130 } else {
131 if (!Communicator::checkLevelLightRecvBit(LC_BLUE << (2 * n)))
132 setRed(lights[LL_OPPONENT_LIGHTS][n]);
135 if (Communicator::checkLevelLightRecvBit(LC_IMPACT << (2 * n)))
136 setFlashing(lights[LL_OPPONENT_LIGHTS][n]);
140 // level light n corresponds to row n + 1 in the grid
141 static LevelLight lights[2][LL_NUMBER_LEVEL_LIGHTS];
143 static int death_flash_alarm[2];
145 private:
146 static inline void setBlue ( LevelLight &light )
148 if (light.state & LS_FADE_TO_RED)
149 light.fade_alarm = DC_LEVEL_LIGHT_FADE_TIME - light.fade_alarm;
150 else
151 light.fade_alarm = DC_LEVEL_LIGHT_FADE_TIME;
152 light.state &= ~(LS_RED | LS_FADE_TO_RED);
153 light.state |= LS_FADE_TO_BLUE;
156 static inline void setRed ( LevelLight &light )
158 if (light.state & LS_FADE_TO_BLUE)
159 light.fade_alarm = DC_LEVEL_LIGHT_FADE_TIME - light.fade_alarm;
160 else
161 light.fade_alarm = DC_LEVEL_LIGHT_FADE_TIME;
162 light.state &= ~(LS_BLUE | LS_FADE_TO_BLUE);
163 light.state |= LS_FADE_TO_RED;
166 static inline void setFlashing ( LevelLight &light )
168 if (light.state & LS_IMPACT_FLASH) {
169 // if past flash inflection point, sync flash start
170 if (light.flash_alarm < (int) (DC_LEVEL_LIGHT_FLASH_INFLECTION
171 * DC_LEVEL_LIGHT_IMPACT_FLASH_TIME))
172 light.flash_alarm = (int) (DC_LEVEL_LIGHT_FLASH_INFLECTION
173 * DC_LEVEL_LIGHT_IMPACT_FLASH_TIME)
174 + (int) (((1.0f - DC_LEVEL_LIGHT_FLASH_INFLECTION)
175 * DC_LEVEL_LIGHT_IMPACT_FLASH_TIME) * (1.0f
176 - light.flash_alarm * (1.0f / (DC_LEVEL_LIGHT_FLASH_INFLECTION
177 * DC_LEVEL_LIGHT_IMPACT_FLASH_TIME))));
179 } else {
180 light.state |= LS_IMPACT_FLASH;
181 light.flash_alarm = DC_LEVEL_LIGHT_IMPACT_FLASH_TIME;
186 #endif