Mercurial > hg > index.fcgi > lj > lj046
diff src/dssound7.c @ 0:c84446dfb3f5
initial add
author | paulo@localhost |
---|---|
date | Fri, 13 Mar 2009 00:39:12 -0700 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/dssound7.c Fri Mar 13 00:39:12 2009 -0700 1.3 @@ -0,0 +1,429 @@ 1.4 +/*--------------------------------------------------------------------------------- 1.5 + 1.6 + LOCKJAW Tetromino Game: ARM7 sound code 1.7 + 1.8 + based on 1.9 + default ARM7 core 1.10 + 1.11 + Copyright (C) 2007 1.12 + Damian Yerrick (tepples) 1.13 + 1.14 + This software is provided 'as-is', without any express or implied 1.15 + warranty. In no event will the authors be held liable for any 1.16 + damages arising from the use of this software. 1.17 + 1.18 + Permission is granted to anyone to use this software for any 1.19 + purpose, including commercial applications, and to alter it and 1.20 + redistribute it freely, subject to the following restrictions: 1.21 + 1.22 + 1. The origin of this software must not be misrepresented; you 1.23 + must not claim that you wrote the original software. If you use 1.24 + this software in a product, an acknowledgment in the product 1.25 + documentation would be appreciated but is not required. 1.26 + 2. Altered source versions must be plainly marked as such, and 1.27 + must not be misrepresented as being the original software. 1.28 + 3. This notice may not be removed or altered from any source 1.29 + distribution. 1.30 + 1.31 +---------------------------------------------------------------------------------*/ 1.32 +#include <nds.h> 1.33 +#include <sys/types.h> 1.34 + 1.35 +extern const unsigned short midi2psgFreq[120]; 1.36 + 1.37 +#define C(octave) (octave * 12 + 0) 1.38 +#define CS(octave) (octave * 12 + 1) 1.39 +#define D(octave) (octave * 12 + 2) 1.40 +#define DS(octave) (octave * 12 + 3) 1.41 +#define E(octave) (octave * 12 + 4) 1.42 +#define F(octave) (octave * 12 + 5) 1.43 +#define FS(octave) (octave * 12 + 6) 1.44 +#define G(octave) (octave * 12 + 7) 1.45 +#define GS(octave) (octave * 12 + 8) 1.46 +#define A(octave) (octave * 12 + 9) 1.47 +#define AS(octave) (octave * 12 + 10) 1.48 +#define B(octave) (octave * 12 + 11) 1.49 + 1.50 + 1.51 +#define N_MUSIC_CHANNELS 2 1.52 + 1.53 +static unsigned short chNote[N_MUSIC_CHANNELS]; 1.54 +static unsigned char chVol[N_MUSIC_CHANNELS]; 1.55 + 1.56 + 1.57 +static const unsigned char startVol[N_MUSIC_CHANNELS] = {32, 30}; 1.58 +static const unsigned char fade[N_MUSIC_CHANNELS] = {0, 1}; 1.59 +static const unsigned char chDuty[N_MUSIC_CHANNELS] = {0, 3}; 1.60 + 1.61 +static const signed char bassLine[64] = { 1.62 + A(2), 0, A(3), 0, -1, 0, A(2), 0, 1.63 + A(3), 0, -1, 0, 0, 0, 0, 0, 1.64 + 0, 0, 0, 0, 0, 0, 0, 0, 1.65 + C(3), 0, C(4), 0, G(2), 0, G(3), 0, 1.66 + A(2), 0, A(3), 0, -1, 0, A(2), 0, 1.67 + A(3), 0, -1, 0, 0, 0, 0, 0, 1.68 + 0, 0, 0, 0, 0, 0, 0, 0, 1.69 + C(3), 0, C(4), 0, G(2), 0, G(3), 0, 1.70 +}; 1.71 + 1.72 +static const signed char mel1[64] = { 1.73 + E(6), 0, 0, 0, B(5), 0, C(6), 0, 1.74 + D(6), 0, 0, 0, C(6), 0, B(5), 0, 1.75 + A(5), 0, 0, 0, A(5), 0, C(6), 0, 1.76 + E(6), 0, 0, 0, D(6), 0, C(6), 0, 1.77 + B(5), 0, 0, 0, 0, 0, C(6), 0, 1.78 + D(6), 0, 0, 0, E(6), 0, 0, 0, 1.79 + C(6), 0, 0, 0, A(5), 0, 0, 0, 1.80 + A(5) 1.81 +}; 1.82 + 1.83 +static const signed char mel2[64] = { 1.84 + 0, 0, D(6), 0, 0, 0, F(6), 0, 1.85 + A(6), 0, 0, 0, G(6), 0, F(6), 0, 1.86 + E(6), 0, 0, 0, 0, 0, C(6), 0, 1.87 + E(6), 0, 0, 0, D(6), 0, C(6), 0, 1.88 + B(5), 0, 0, 0, B(5), 0, C(6), 0, 1.89 + D(6), 0, 0, 0, E(6), 0, 0, 0, 1.90 + C(6), 0, 0, 0, A(5), 0, 0, 0, 1.91 + A(5) 1.92 +}; 1.93 + 1.94 +static const signed char *const scripts[4][N_MUSIC_CHANNELS] = { 1.95 + { bassLine, mel1 }, 1.96 + { bassLine, mel1 }, 1.97 + { bassLine, mel2 }, 1.98 + { bassLine, mel2 } 1.99 +}; 1.100 + 1.101 +int order = 0; 1.102 +char ticksLeft = 1; 1.103 +char row = 0; 1.104 +char musicPaused = 1; 1.105 + 1.106 +/* 1.107 + * Plays a repeating drum track and bass track. 1.108 + */ 1.109 +void ljMusic(void) { 1.110 + if (musicPaused) { 1.111 + for (int ch = 0; ch < N_MUSIC_CHANNELS; ++ch) { 1.112 + chVol[ch] = 0; 1.113 + } 1.114 + } else if (--ticksLeft <= 0) { 1.115 + ticksLeft += 6; 1.116 + for (int ch = 0; ch < N_MUSIC_CHANNELS; ++ch) { 1.117 + const signed char *script = scripts[order][ch]; 1.118 + int note = script ? script[(int)row] : 0; 1.119 + if (note < 0) { 1.120 + chVol[ch] = 0; 1.121 + } else if (note > 0) { 1.122 + chVol[ch] = startVol[ch]; 1.123 + chNote[ch] = midi2psgFreq[note]; 1.124 + } 1.125 + } 1.126 + ++row; 1.127 + if (row >= 64) { 1.128 + row = 0; 1.129 + ++order; 1.130 + if (order == 4) { 1.131 + order = 0; 1.132 + } 1.133 + } 1.134 + } 1.135 + 1.136 + 1.137 + // Play notes 1.138 + for (int ch = 0; ch < N_MUSIC_CHANNELS; ++ch) { 1.139 + SCHANNEL_CR(8 + ch) = SCHANNEL_ENABLE | SOUND_FORMAT_PSG | SOUND_PAN(64) 1.140 + | (chDuty[ch] << 24) | chVol[ch]; 1.141 + SCHANNEL_TIMER(8 + ch) = chNote[ch]; 1.142 + 1.143 + // update volumes 1.144 + if (chVol[ch] > fade[ch]) { 1.145 + chVol[ch] -= fade[ch]; 1.146 + } else { 1.147 + chVol[ch] = 0; 1.148 + } 1.149 + } 1.150 +} 1.151 + 1.152 +#define FX(note, volume, duty) ((note) | ((volume) << 7) | ((duty) << 14)) 1.153 + 1.154 +static const u16 rotateEffect[] = { 1.155 + 0, 6, 1.156 + FX(A(5), 32, 1), FX(A(5), 8, 1), 1.157 + FX(D(6), 32, 1), FX(D(6), 8, 1), 1.158 + FX(G(6), 32, 1), FX(G(6), 8, 1) 1.159 +}; 1.160 + 1.161 +static const u16 moveEffect[] = { 1.162 + 0, 2, 1.163 + FX(A(6), 32, 1), FX(A(6), 8, 1) 1.164 +}; 1.165 + 1.166 +static const u16 landEffect[] = { 1.167 + 0, 8, 1.168 + FX(C(4), 64, 3), FX(GS(3), 56, 3), 1.169 + FX(F(3), 48, 3), FX(D(3), 40, 3), 1.170 + FX(C(3), 32, 3), FX(B(2), 24, 3), 1.171 + FX(C(3), 16, 3), FX(B(2), 8, 3), 1.172 +}; 1.173 + 1.174 +static const u16 lockEffect[] = { 1.175 + 1, 2, 1.176 + FX(C(8), 16, 1), FX(C(8), 4, 1) 1.177 +}; 1.178 + 1.179 +static const u16 lineEffect[] = { 1.180 + 0, 15, 1.181 + FX(C(6), 64, 2), FX(DS(6), 59, 2), FX(F(6), 54, 2), 1.182 + FX(C(6), 49, 2), FX(D(6), 44, 2), FX(F(6), 39, 2), 1.183 + FX(C(6), 34, 3), FX(DS(6), 29, 3), FX(F(6), 24, 3), 1.184 + FX(C(6), 20, 3), FX(D(6), 16, 3), FX(F(6), 12, 3), 1.185 + FX(C(6), 9, 3), FX(DS(6), 6, 3), FX(F(6), 3, 3) 1.186 +}; 1.187 + 1.188 +static const u16 homerEffect[] = { 1.189 + 0, 25, 1.190 + FX(C(6), 64, 2), FX(DS(6), 59, 2), FX(F(6), 54, 2), 1.191 + FX(C(6), 49, 2), FX(D(6), 44, 2), FX(F(6), 39, 2), 1.192 + FX(C(6), 34, 3), FX(DS(6), 29, 3), FX(F(6), 24, 3), 1.193 + FX(C(6), 20, 3), 1.194 + FX(DS(6), 64, 2), FX(FS(6), 59, 2), FX(GS(6), 54, 2), 1.195 + FX(DS(6), 49, 2), FX(F(6), 44, 2), FX(GS(6), 39, 2), 1.196 + FX(DS(6), 34, 3), FX(FS(6), 29, 3), FX(GS(6), 24, 3), 1.197 + FX(DS(6), 20, 3), FX(F(6), 16, 3), FX(GS(6), 12, 3), 1.198 + FX(DS(6), 9, 3), FX(F(6), 6, 3), FX(GS(6), 3, 3) 1.199 +}; 1.200 + 1.201 +static const u16 streakEffect[] = { 1.202 + 0, 35, 1.203 + FX(C(6), 64, 2), FX(DS(6), 59, 2), FX(F(6), 54, 2), 1.204 + FX(C(6), 49, 2), FX(D(6), 44, 2), FX(F(6), 39, 2), 1.205 + FX(C(6), 34, 3), FX(DS(6), 29, 3), FX(F(6), 24, 3), 1.206 + FX(C(6), 20, 3), 1.207 + FX(DS(6), 64, 2), FX(FS(6), 59, 2), FX(GS(6), 54, 2), 1.208 + FX(DS(6), 49, 2), FX(F(6), 44, 2), FX(GS(6), 39, 2), 1.209 + FX(DS(6), 34, 3), FX(FS(6), 29, 3), FX(GS(6), 24, 3), 1.210 + FX(DS(6), 20, 3), 1.211 + FX(FS(6), 64, 2), FX(A(6), 59, 2), FX(B(6), 54, 2), 1.212 + FX(FS(6), 49, 2), FX(GS(6), 44, 2), FX(B(6), 39, 2), 1.213 + FX(FS(6), 34, 3), FX(A(6), 29, 3), FX(B(6), 24, 3), 1.214 + FX(FS(6), 20, 3), FX(GS(6), 16, 3), FX(B(6), 12, 3), 1.215 + FX(FS(6), 9, 3), FX(GS(6), 6, 3), FX(B(6), 3, 3) 1.216 +}; 1.217 + 1.218 +static const u16 holdEffect[] = { 1.219 + 1, 10, 1.220 + FX(E(5), 20, 0), FX(G(5), 25, 0), 1.221 + FX(B(5), 30, 0), FX(B(5), 30, 0), 1.222 + FX(G(5), 28, 0), FX(E(5), 24, 0), 1.223 + FX(D(5), 20, 0), FX(C(5), 15, 0), 1.224 + FX(C(5), 10, 0), FX(C(5), 5, 0) 1.225 +}; 1.226 + 1.227 + 1.228 +static const u16 irsEffect[] = { 1.229 + 0, 12, 1.230 + FX(CS(7), 40, 3), FX(CS(7), 40, 3), 1.231 + FX(FS(7), 40, 3), FX(FS(7), 40, 3), 1.232 + FX(B(7), 40, 3), FX(B(7), 35, 3), 1.233 + FX(B(7), 30, 3), FX(B(7), 25, 3), 1.234 + FX(B(7), 20, 3), FX(B(7), 15, 3), 1.235 + FX(B(7), 10, 3), FX(B(7), 5, 3), 1.236 +}; 1.237 + 1.238 +static const u16 countEffect[] = { 1.239 + 0, 14, 1.240 + FX(D(5), 64, 0), FX(D(5), 64, 0), 1.241 + FX(CS(5), 64, 0), FX(CS(5), 64, 0), 1.242 + FX(C(5), 64, 1), FX(C(5), 64, 1), 1.243 + FX(B(4), 64, 1), FX(AS(4), 64, 1), 1.244 + FX(A(4), 64, 2), FX(GS(4), 64, 2), 1.245 + FX(GS(4), 64, 3), FX(G(4), 48, 3), 1.246 + FX(G(4), 32, 3), FX(G(4), 16, 3), 1.247 +}; 1.248 + 1.249 +static const u16 winEffect1[] = { 1.250 + 0, 54, 1.251 + FX(C(6), 32, 2), FX(C(6), 48, 1), FX(C(6), 48, 1), FX(C(6), 48, 1), 1.252 + FX(C(6), 32, 2), 0, 0, 0, 0, 1.253 + FX(AS(5), 32, 2), FX(AS(5), 48, 1), FX(AS(5), 48, 1), FX(AS(5), 48, 1), 1.254 + FX(AS(5), 32, 2), 0, 0, 0, 0, 1.255 + FX(C(6), 32, 2), FX(C(6), 48, 1), FX(C(6), 48, 1), FX(C(6), 48, 1), 1.256 + FX(D(6), 32, 2), 0, 0, 0, 0, 1.257 + 1.258 + FX(D(6), 32, 2), FX(D(6), 48, 1), FX(D(6), 48, 1), FX(D(6), 48, 1), 1.259 + FX(D(6), 47, 1), FX(D(6), 46, 1), FX(D(6), 45, 1), FX(D(6), 44, 1), 1.260 + FX(D(6), 43, 1), FX(D(6), 42, 1), FX(D(6), 41, 1), FX(D(6), 40, 1), 1.261 + FX(D(6), 39, 1), FX(D(6), 38, 1), FX(D(6), 37, 1), FX(D(6), 36, 1), 1.262 + FX(D(6), 35, 1), FX(D(6), 34, 1), FX(D(6), 33, 1), FX(D(6), 32, 1), 1.263 + FX(D(6), 31, 1), FX(D(6), 30, 1), FX(D(6), 29, 1), FX(D(6), 28, 1), 1.264 + FX(D(6), 27, 1), FX(D(6), 26, 1), FX(D(6), 25, 1), FX(D(6), 24, 1), 1.265 + FX(D(6), 18, 2), FX(D(6), 12, 2), FX(D(6), 6, 2) 1.266 +}; 1.267 + 1.268 +static const u16 winEffect2[] = { 1.269 + 0, 54, 1.270 + FX(E(6), 32, 2), FX(E(6), 48, 1), FX(E(6), 48, 1), FX(E(6), 48, 1), 1.271 + FX(E(6), 32, 2), 0, 0, 0, 0, 1.272 + FX(D(6), 32, 2), FX(D(6), 48, 1), FX(D(6), 48, 1), FX(D(6), 48, 1), 1.273 + FX(D(6), 32, 2), 0, 0, 0, 0, 1.274 + FX(E(6), 32, 2), FX(E(6), 48, 1), FX(E(6), 48, 1), FX(E(6), 48, 1), 1.275 + FX(E(6), 32, 2), 0, 0, 0, 0, 1.276 + 1.277 + FX(FS(6), 32, 2), FX(FS(6), 48, 1), FX(FS(6), 48, 1), FX(FS(6), 48, 1), 1.278 + FX(FS(6), 47, 1), FX(FS(6), 46, 1), FX(FS(6), 45, 1), FX(FS(6), 44, 1), 1.279 + FX(FS(6), 43, 1), FX(FS(6), 42, 1), FX(FS(6), 41, 1), FX(FS(6), 40, 1), 1.280 + FX(FS(6), 39, 1), FX(FS(6), 38, 1), FX(FS(6), 37, 1), FX(FS(6), 36, 1), 1.281 + FX(FS(6), 35, 1), FX(FS(6), 34, 1), FX(FS(6), 33, 1), FX(FS(6), 32, 1), 1.282 + FX(FS(6), 31, 1), FX(FS(6), 30, 1), FX(FS(6), 29, 1), FX(FS(6), 28, 1), 1.283 + FX(FS(6), 27, 1), FX(FS(6), 26, 1), FX(FS(6), 25, 1), FX(FS(6), 24, 1), 1.284 + FX(FS(6), 18, 2), FX(FS(6), 12, 2), FX(FS(6), 6, 2) 1.285 +}; 1.286 + 1.287 +static const u16 dieEffect1[] = { 1.288 + 0, 60, 1.289 + FX(E(3), 60, 2), FX(E(3), 59, 2), FX(E(3), 58, 2), FX(E(3), 57, 2), 1.290 + FX(E(3), 56, 2), FX(E(3), 55, 2), FX(E(3), 54, 2), FX(E(3), 53, 2), 1.291 + FX(E(3), 52, 2), FX(E(3), 51, 2), FX(E(3), 50, 2), FX(E(3), 49, 2), 1.292 + FX(E(3), 48, 2), FX(E(3), 47, 2), FX(E(3), 46, 2), FX(E(3), 45, 2), 1.293 + FX(E(3), 44, 2), FX(E(3), 43, 2), FX(E(3), 42, 2), FX(E(3), 41, 2), 1.294 + FX(E(3), 40, 2), FX(E(3), 39, 2), FX(E(3), 38, 2), FX(E(3), 37, 2), 1.295 + FX(E(3), 36, 2), FX(E(3), 35, 2), FX(E(3), 34, 2), FX(E(3), 33, 2), 1.296 + FX(E(3), 32, 2), FX(E(3), 31, 2), FX(E(3), 30, 2), FX(E(3), 29, 2), 1.297 + FX(E(3), 28, 2), FX(E(3), 27, 2), FX(E(3), 26, 2), FX(E(3), 25, 2), 1.298 + FX(E(3), 24, 2), FX(E(3), 23, 2), FX(E(3), 22, 2), FX(E(3), 21, 2), 1.299 + FX(E(3), 20, 2), FX(E(3), 19, 2), FX(E(3), 18, 2), FX(E(3), 17, 2), 1.300 + FX(E(3), 16, 2), FX(E(3), 15, 2), FX(E(3), 14, 2), FX(E(3), 13, 2), 1.301 + FX(E(3), 12, 2), FX(E(3), 11, 2), FX(E(3), 10, 2), FX(E(3), 9, 2), 1.302 + FX(E(3), 8, 2), FX(E(3), 7, 2), FX(E(3), 6, 2), FX(E(3), 5, 2), 1.303 + FX(E(3), 4, 2), FX(E(3), 3, 2), FX(E(3), 2, 2), FX(E(3), 1, 2) 1.304 +}; 1.305 + 1.306 +static const u16 dieEffect2[] = { 1.307 + 1, 60, 1.308 + FX(E(4), 60, 2), FX(B(3), 59, 2), FX(E(3), 58, 2), FX(E(3), 57, 2), 1.309 + FX(E(3), 56, 2), FX(E(3), 55, 2), FX(E(3), 54, 2), FX(E(3), 53, 2), 1.310 + FX(E(3), 52, 2), FX(E(3), 51, 2), FX(E(3), 50, 2), FX(E(3), 49, 2), 1.311 + FX(E(3), 48, 2), FX(E(3), 47, 2), FX(E(3), 46, 2), FX(E(3), 45, 2), 1.312 + FX(E(3), 44, 2), FX(E(3), 43, 2), FX(E(3), 42, 2), FX(E(3), 41, 2), 1.313 + FX(E(3), 40, 2), FX(E(3), 39, 2), FX(E(3), 38, 2), FX(E(3), 37, 2), 1.314 + FX(E(3), 36, 2), FX(E(3), 35, 2), FX(E(3), 34, 2), FX(E(3), 33, 2), 1.315 + FX(E(3), 32, 2), FX(E(3), 31, 2), FX(E(3), 30, 2), FX(E(3), 29, 2), 1.316 + FX(E(3), 28, 2), FX(E(3), 27, 2), FX(E(3), 26, 2), FX(E(3), 25, 2), 1.317 + FX(E(3), 24, 2), FX(E(3), 23, 2), FX(E(3), 22, 2), FX(E(3), 21, 2), 1.318 + FX(E(3), 20, 2), FX(E(3), 19, 2), FX(E(3), 18, 2), FX(E(3), 17, 2), 1.319 + FX(E(3), 16, 2), FX(E(3), 15, 2), FX(E(3), 14, 2), FX(E(3), 13, 2), 1.320 + FX(E(3), 12, 2), FX(E(3), 11, 2), FX(E(3), 10, 2), FX(E(3), 9, 2), 1.321 + FX(E(3), 8, 2), FX(E(3), 7, 2), FX(E(3), 6, 2), FX(E(3), 5, 2), 1.322 + FX(E(3), 4, 2), FX(E(3), 3, 2), FX(E(3), 2, 2), FX(E(3), 1, 2) 1.323 +}; 1.324 + 1.325 +static const u16 *effects[32] = { 1.326 + rotateEffect, 1.327 + moveEffect, 1.328 + NULL, // drop: not used 1.329 + landEffect, 1.330 + lockEffect, 1.331 + lineEffect, 1.332 + homerEffect, 1.333 + streakEffect, 1.334 + NULL, // spawn 1.335 + holdEffect, // hold 1.336 + irsEffect, // irs 1.337 + NULL, // 4x4 square 1.338 + NULL, NULL, NULL, NULL, // unused 1.339 + dieEffect1, dieEffect2 1.340 +}; 1.341 + 1.342 + 1.343 + 1.344 +static const u16 *fxPtr[5]; 1.345 +static u8 fxLen[5]; 1.346 +static s8 lastCD; 1.347 + 1.348 + 1.349 + 1.350 +static void startEffect(const u16 *s) { 1.351 + 1.352 + // skip effects that lack an actual effect 1.353 + if (!s) { 1.354 + return; 1.355 + } 1.356 + 1.357 + unsigned int type = s[0]; 1.358 + unsigned int len = s[1]; 1.359 + unsigned int min = 0; 1.360 + unsigned int max = 2; 1.361 + 1.362 + if (type > 0) { 1.363 + min = 3; 1.364 + max = 4; 1.365 + } 1.366 + 1.367 + // prepare to kill the channel with the shortest time remaining 1.368 + unsigned int shortestLen = fxLen[min]; 1.369 + unsigned int shortestCh = min; 1.370 + for (int ch = min + 1; ch <= max; ++ch) { 1.371 + if (fxLen[ch] < shortestLen) { 1.372 + shortestLen = fxLen[ch]; 1.373 + shortestCh = ch; 1.374 + } 1.375 + } 1.376 + 1.377 + // if the channel is suitable, kill it 1.378 + if (shortestLen < len) { 1.379 + fxPtr[shortestCh] = s + 2; 1.380 + fxLen[shortestCh] = len; 1.381 + } 1.382 +} 1.383 + 1.384 +static void pollEffects(void) { 1.385 + for (int ch = 0; ch < 5; ++ch) { 1.386 + unsigned int note = 36; 1.387 + unsigned int vol = 0; 1.388 + unsigned int duty = 0; 1.389 + if (fxLen[ch] > 0) { 1.390 + unsigned int data = *fxPtr[ch]++; 1.391 + duty = (data >> 14) & 0x03; 1.392 + vol = (data >> 7) & 0x7F; 1.393 + note = data & 0x7F; 1.394 + --fxLen[ch]; 1.395 + } 1.396 + SCHANNEL_CR(11 + ch) = SCHANNEL_ENABLE | SOUND_FORMAT_PSG | SOUND_PAN(64) 1.397 + | (duty << 24) | vol; 1.398 + SCHANNEL_TIMER(11 + ch) = midi2psgFreq[note]; 1.399 + } 1.400 +} 1.401 + 1.402 +void ljSoundEffects(unsigned long int sounds, 1.403 + int countdown) { 1.404 + 1.405 + // cancel out overlapping line clear sounds 1.406 + if (sounds & 0x0080) { 1.407 + sounds &= ~0x0060; 1.408 + } else if (sounds & 0x0040) { 1.409 + sounds &= ~0x0020; 1.410 + } 1.411 + 1.412 + for (int y = 0; sounds; ++y, sounds >>= 1) { 1.413 + if (sounds & 1) { 1.414 + startEffect(effects[y]); 1.415 + } 1.416 + } 1.417 + if (countdown < 0) { 1.418 + countdown = 0; 1.419 + } else if (countdown > 6) { 1.420 + countdown = 6; 1.421 + } 1.422 + if (countdown < lastCD) { 1.423 + if (countdown > 0) { 1.424 + startEffect(countEffect); 1.425 + } else { 1.426 + startEffect(winEffect1); 1.427 + startEffect(winEffect2); 1.428 + } 1.429 + } 1.430 + lastCD = countdown; 1.431 + pollEffects(); 1.432 +}