paulo@0: /*--------------------------------------------------------------------------------- paulo@0: paulo@0: LOCKJAW Tetromino Game: ARM7 sound code paulo@0: paulo@0: based on paulo@0: default ARM7 core paulo@0: paulo@0: Copyright (C) 2007 paulo@0: Damian Yerrick (tepples) paulo@0: paulo@0: This software is provided 'as-is', without any express or implied paulo@0: warranty. In no event will the authors be held liable for any paulo@0: damages arising from the use of this software. paulo@0: paulo@0: Permission is granted to anyone to use this software for any paulo@0: purpose, including commercial applications, and to alter it and paulo@0: redistribute it freely, subject to the following restrictions: paulo@0: paulo@0: 1. The origin of this software must not be misrepresented; you paulo@0: must not claim that you wrote the original software. If you use paulo@0: this software in a product, an acknowledgment in the product paulo@0: documentation would be appreciated but is not required. paulo@0: 2. Altered source versions must be plainly marked as such, and paulo@0: must not be misrepresented as being the original software. paulo@0: 3. This notice may not be removed or altered from any source paulo@0: distribution. paulo@0: paulo@0: ---------------------------------------------------------------------------------*/ paulo@0: #include paulo@0: #include paulo@0: paulo@0: extern const unsigned short midi2psgFreq[120]; paulo@0: paulo@0: #define C(octave) (octave * 12 + 0) paulo@0: #define CS(octave) (octave * 12 + 1) paulo@0: #define D(octave) (octave * 12 + 2) paulo@0: #define DS(octave) (octave * 12 + 3) paulo@0: #define E(octave) (octave * 12 + 4) paulo@0: #define F(octave) (octave * 12 + 5) paulo@0: #define FS(octave) (octave * 12 + 6) paulo@0: #define G(octave) (octave * 12 + 7) paulo@0: #define GS(octave) (octave * 12 + 8) paulo@0: #define A(octave) (octave * 12 + 9) paulo@0: #define AS(octave) (octave * 12 + 10) paulo@0: #define B(octave) (octave * 12 + 11) paulo@0: paulo@0: paulo@0: #define N_MUSIC_CHANNELS 2 paulo@0: paulo@0: static unsigned short chNote[N_MUSIC_CHANNELS]; paulo@0: static unsigned char chVol[N_MUSIC_CHANNELS]; paulo@0: paulo@0: paulo@0: static const unsigned char startVol[N_MUSIC_CHANNELS] = {32, 30}; paulo@0: static const unsigned char fade[N_MUSIC_CHANNELS] = {0, 1}; paulo@0: static const unsigned char chDuty[N_MUSIC_CHANNELS] = {0, 3}; paulo@0: paulo@0: static const signed char bassLine[64] = { paulo@0: A(2), 0, A(3), 0, -1, 0, A(2), 0, paulo@0: A(3), 0, -1, 0, 0, 0, 0, 0, paulo@0: 0, 0, 0, 0, 0, 0, 0, 0, paulo@0: C(3), 0, C(4), 0, G(2), 0, G(3), 0, paulo@0: A(2), 0, A(3), 0, -1, 0, A(2), 0, paulo@0: A(3), 0, -1, 0, 0, 0, 0, 0, paulo@0: 0, 0, 0, 0, 0, 0, 0, 0, paulo@0: C(3), 0, C(4), 0, G(2), 0, G(3), 0, paulo@0: }; paulo@0: paulo@0: static const signed char mel1[64] = { paulo@0: E(6), 0, 0, 0, B(5), 0, C(6), 0, paulo@0: D(6), 0, 0, 0, C(6), 0, B(5), 0, paulo@0: A(5), 0, 0, 0, A(5), 0, C(6), 0, paulo@0: E(6), 0, 0, 0, D(6), 0, C(6), 0, paulo@0: B(5), 0, 0, 0, 0, 0, C(6), 0, paulo@0: D(6), 0, 0, 0, E(6), 0, 0, 0, paulo@0: C(6), 0, 0, 0, A(5), 0, 0, 0, paulo@0: A(5) paulo@0: }; paulo@0: paulo@0: static const signed char mel2[64] = { paulo@0: 0, 0, D(6), 0, 0, 0, F(6), 0, paulo@0: A(6), 0, 0, 0, G(6), 0, F(6), 0, paulo@0: E(6), 0, 0, 0, 0, 0, C(6), 0, paulo@0: E(6), 0, 0, 0, D(6), 0, C(6), 0, paulo@0: B(5), 0, 0, 0, B(5), 0, C(6), 0, paulo@0: D(6), 0, 0, 0, E(6), 0, 0, 0, paulo@0: C(6), 0, 0, 0, A(5), 0, 0, 0, paulo@0: A(5) paulo@0: }; paulo@0: paulo@0: static const signed char *const scripts[4][N_MUSIC_CHANNELS] = { paulo@0: { bassLine, mel1 }, paulo@0: { bassLine, mel1 }, paulo@0: { bassLine, mel2 }, paulo@0: { bassLine, mel2 } paulo@0: }; paulo@0: paulo@0: int order = 0; paulo@0: char ticksLeft = 1; paulo@0: char row = 0; paulo@0: char musicPaused = 1; paulo@0: paulo@0: /* paulo@0: * Plays a repeating drum track and bass track. paulo@0: */ paulo@0: void ljMusic(void) { paulo@0: if (musicPaused) { paulo@0: for (int ch = 0; ch < N_MUSIC_CHANNELS; ++ch) { paulo@0: chVol[ch] = 0; paulo@0: } paulo@0: } else if (--ticksLeft <= 0) { paulo@0: ticksLeft += 6; paulo@0: for (int ch = 0; ch < N_MUSIC_CHANNELS; ++ch) { paulo@0: const signed char *script = scripts[order][ch]; paulo@0: int note = script ? script[(int)row] : 0; paulo@0: if (note < 0) { paulo@0: chVol[ch] = 0; paulo@0: } else if (note > 0) { paulo@0: chVol[ch] = startVol[ch]; paulo@0: chNote[ch] = midi2psgFreq[note]; paulo@0: } paulo@0: } paulo@0: ++row; paulo@0: if (row >= 64) { paulo@0: row = 0; paulo@0: ++order; paulo@0: if (order == 4) { paulo@0: order = 0; paulo@0: } paulo@0: } paulo@0: } paulo@0: paulo@0: paulo@0: // Play notes paulo@0: for (int ch = 0; ch < N_MUSIC_CHANNELS; ++ch) { paulo@0: SCHANNEL_CR(8 + ch) = SCHANNEL_ENABLE | SOUND_FORMAT_PSG | SOUND_PAN(64) paulo@0: | (chDuty[ch] << 24) | chVol[ch]; paulo@0: SCHANNEL_TIMER(8 + ch) = chNote[ch]; paulo@0: paulo@0: // update volumes paulo@0: if (chVol[ch] > fade[ch]) { paulo@0: chVol[ch] -= fade[ch]; paulo@0: } else { paulo@0: chVol[ch] = 0; paulo@0: } paulo@0: } paulo@0: } paulo@0: paulo@0: #define FX(note, volume, duty) ((note) | ((volume) << 7) | ((duty) << 14)) paulo@0: paulo@0: static const u16 rotateEffect[] = { paulo@0: 0, 6, paulo@0: FX(A(5), 32, 1), FX(A(5), 8, 1), paulo@0: FX(D(6), 32, 1), FX(D(6), 8, 1), paulo@0: FX(G(6), 32, 1), FX(G(6), 8, 1) paulo@0: }; paulo@0: paulo@0: static const u16 moveEffect[] = { paulo@0: 0, 2, paulo@0: FX(A(6), 32, 1), FX(A(6), 8, 1) paulo@0: }; paulo@0: paulo@0: static const u16 landEffect[] = { paulo@0: 0, 8, paulo@0: FX(C(4), 64, 3), FX(GS(3), 56, 3), paulo@0: FX(F(3), 48, 3), FX(D(3), 40, 3), paulo@0: FX(C(3), 32, 3), FX(B(2), 24, 3), paulo@0: FX(C(3), 16, 3), FX(B(2), 8, 3), paulo@0: }; paulo@0: paulo@0: static const u16 lockEffect[] = { paulo@0: 1, 2, paulo@0: FX(C(8), 16, 1), FX(C(8), 4, 1) paulo@0: }; paulo@0: paulo@0: static const u16 lineEffect[] = { paulo@0: 0, 15, paulo@0: FX(C(6), 64, 2), FX(DS(6), 59, 2), FX(F(6), 54, 2), paulo@0: FX(C(6), 49, 2), FX(D(6), 44, 2), FX(F(6), 39, 2), paulo@0: FX(C(6), 34, 3), FX(DS(6), 29, 3), FX(F(6), 24, 3), paulo@0: FX(C(6), 20, 3), FX(D(6), 16, 3), FX(F(6), 12, 3), paulo@0: FX(C(6), 9, 3), FX(DS(6), 6, 3), FX(F(6), 3, 3) paulo@0: }; paulo@0: paulo@0: static const u16 homerEffect[] = { paulo@0: 0, 25, paulo@0: FX(C(6), 64, 2), FX(DS(6), 59, 2), FX(F(6), 54, 2), paulo@0: FX(C(6), 49, 2), FX(D(6), 44, 2), FX(F(6), 39, 2), paulo@0: FX(C(6), 34, 3), FX(DS(6), 29, 3), FX(F(6), 24, 3), paulo@0: FX(C(6), 20, 3), paulo@0: FX(DS(6), 64, 2), FX(FS(6), 59, 2), FX(GS(6), 54, 2), paulo@0: FX(DS(6), 49, 2), FX(F(6), 44, 2), FX(GS(6), 39, 2), paulo@0: FX(DS(6), 34, 3), FX(FS(6), 29, 3), FX(GS(6), 24, 3), paulo@0: FX(DS(6), 20, 3), FX(F(6), 16, 3), FX(GS(6), 12, 3), paulo@0: FX(DS(6), 9, 3), FX(F(6), 6, 3), FX(GS(6), 3, 3) paulo@0: }; paulo@0: paulo@0: static const u16 streakEffect[] = { paulo@0: 0, 35, paulo@0: FX(C(6), 64, 2), FX(DS(6), 59, 2), FX(F(6), 54, 2), paulo@0: FX(C(6), 49, 2), FX(D(6), 44, 2), FX(F(6), 39, 2), paulo@0: FX(C(6), 34, 3), FX(DS(6), 29, 3), FX(F(6), 24, 3), paulo@0: FX(C(6), 20, 3), paulo@0: FX(DS(6), 64, 2), FX(FS(6), 59, 2), FX(GS(6), 54, 2), paulo@0: FX(DS(6), 49, 2), FX(F(6), 44, 2), FX(GS(6), 39, 2), paulo@0: FX(DS(6), 34, 3), FX(FS(6), 29, 3), FX(GS(6), 24, 3), paulo@0: FX(DS(6), 20, 3), paulo@0: FX(FS(6), 64, 2), FX(A(6), 59, 2), FX(B(6), 54, 2), paulo@0: FX(FS(6), 49, 2), FX(GS(6), 44, 2), FX(B(6), 39, 2), paulo@0: FX(FS(6), 34, 3), FX(A(6), 29, 3), FX(B(6), 24, 3), paulo@0: FX(FS(6), 20, 3), FX(GS(6), 16, 3), FX(B(6), 12, 3), paulo@0: FX(FS(6), 9, 3), FX(GS(6), 6, 3), FX(B(6), 3, 3) paulo@0: }; paulo@0: paulo@0: static const u16 holdEffect[] = { paulo@0: 1, 10, paulo@0: FX(E(5), 20, 0), FX(G(5), 25, 0), paulo@0: FX(B(5), 30, 0), FX(B(5), 30, 0), paulo@0: FX(G(5), 28, 0), FX(E(5), 24, 0), paulo@0: FX(D(5), 20, 0), FX(C(5), 15, 0), paulo@0: FX(C(5), 10, 0), FX(C(5), 5, 0) paulo@0: }; paulo@0: paulo@0: paulo@0: static const u16 irsEffect[] = { paulo@0: 0, 12, paulo@0: FX(CS(7), 40, 3), FX(CS(7), 40, 3), paulo@0: FX(FS(7), 40, 3), FX(FS(7), 40, 3), paulo@0: FX(B(7), 40, 3), FX(B(7), 35, 3), paulo@0: FX(B(7), 30, 3), FX(B(7), 25, 3), paulo@0: FX(B(7), 20, 3), FX(B(7), 15, 3), paulo@0: FX(B(7), 10, 3), FX(B(7), 5, 3), paulo@0: }; paulo@0: paulo@0: static const u16 countEffect[] = { paulo@0: 0, 14, paulo@0: FX(D(5), 64, 0), FX(D(5), 64, 0), paulo@0: FX(CS(5), 64, 0), FX(CS(5), 64, 0), paulo@0: FX(C(5), 64, 1), FX(C(5), 64, 1), paulo@0: FX(B(4), 64, 1), FX(AS(4), 64, 1), paulo@0: FX(A(4), 64, 2), FX(GS(4), 64, 2), paulo@0: FX(GS(4), 64, 3), FX(G(4), 48, 3), paulo@0: FX(G(4), 32, 3), FX(G(4), 16, 3), paulo@0: }; paulo@0: paulo@0: static const u16 winEffect1[] = { paulo@0: 0, 54, paulo@0: FX(C(6), 32, 2), FX(C(6), 48, 1), FX(C(6), 48, 1), FX(C(6), 48, 1), paulo@0: FX(C(6), 32, 2), 0, 0, 0, 0, paulo@0: FX(AS(5), 32, 2), FX(AS(5), 48, 1), FX(AS(5), 48, 1), FX(AS(5), 48, 1), paulo@0: FX(AS(5), 32, 2), 0, 0, 0, 0, paulo@0: FX(C(6), 32, 2), FX(C(6), 48, 1), FX(C(6), 48, 1), FX(C(6), 48, 1), paulo@0: FX(D(6), 32, 2), 0, 0, 0, 0, paulo@0: paulo@0: FX(D(6), 32, 2), FX(D(6), 48, 1), FX(D(6), 48, 1), FX(D(6), 48, 1), paulo@0: FX(D(6), 47, 1), FX(D(6), 46, 1), FX(D(6), 45, 1), FX(D(6), 44, 1), paulo@0: FX(D(6), 43, 1), FX(D(6), 42, 1), FX(D(6), 41, 1), FX(D(6), 40, 1), paulo@0: FX(D(6), 39, 1), FX(D(6), 38, 1), FX(D(6), 37, 1), FX(D(6), 36, 1), paulo@0: FX(D(6), 35, 1), FX(D(6), 34, 1), FX(D(6), 33, 1), FX(D(6), 32, 1), paulo@0: FX(D(6), 31, 1), FX(D(6), 30, 1), FX(D(6), 29, 1), FX(D(6), 28, 1), paulo@0: FX(D(6), 27, 1), FX(D(6), 26, 1), FX(D(6), 25, 1), FX(D(6), 24, 1), paulo@0: FX(D(6), 18, 2), FX(D(6), 12, 2), FX(D(6), 6, 2) paulo@0: }; paulo@0: paulo@0: static const u16 winEffect2[] = { paulo@0: 0, 54, paulo@0: FX(E(6), 32, 2), FX(E(6), 48, 1), FX(E(6), 48, 1), FX(E(6), 48, 1), paulo@0: FX(E(6), 32, 2), 0, 0, 0, 0, paulo@0: FX(D(6), 32, 2), FX(D(6), 48, 1), FX(D(6), 48, 1), FX(D(6), 48, 1), paulo@0: FX(D(6), 32, 2), 0, 0, 0, 0, paulo@0: FX(E(6), 32, 2), FX(E(6), 48, 1), FX(E(6), 48, 1), FX(E(6), 48, 1), paulo@0: FX(E(6), 32, 2), 0, 0, 0, 0, paulo@0: paulo@0: FX(FS(6), 32, 2), FX(FS(6), 48, 1), FX(FS(6), 48, 1), FX(FS(6), 48, 1), paulo@0: FX(FS(6), 47, 1), FX(FS(6), 46, 1), FX(FS(6), 45, 1), FX(FS(6), 44, 1), paulo@0: FX(FS(6), 43, 1), FX(FS(6), 42, 1), FX(FS(6), 41, 1), FX(FS(6), 40, 1), paulo@0: FX(FS(6), 39, 1), FX(FS(6), 38, 1), FX(FS(6), 37, 1), FX(FS(6), 36, 1), paulo@0: FX(FS(6), 35, 1), FX(FS(6), 34, 1), FX(FS(6), 33, 1), FX(FS(6), 32, 1), paulo@0: FX(FS(6), 31, 1), FX(FS(6), 30, 1), FX(FS(6), 29, 1), FX(FS(6), 28, 1), paulo@0: FX(FS(6), 27, 1), FX(FS(6), 26, 1), FX(FS(6), 25, 1), FX(FS(6), 24, 1), paulo@0: FX(FS(6), 18, 2), FX(FS(6), 12, 2), FX(FS(6), 6, 2) paulo@0: }; paulo@0: paulo@0: static const u16 dieEffect1[] = { paulo@0: 0, 60, paulo@0: FX(E(3), 60, 2), FX(E(3), 59, 2), FX(E(3), 58, 2), FX(E(3), 57, 2), paulo@0: FX(E(3), 56, 2), FX(E(3), 55, 2), FX(E(3), 54, 2), FX(E(3), 53, 2), paulo@0: FX(E(3), 52, 2), FX(E(3), 51, 2), FX(E(3), 50, 2), FX(E(3), 49, 2), paulo@0: FX(E(3), 48, 2), FX(E(3), 47, 2), FX(E(3), 46, 2), FX(E(3), 45, 2), paulo@0: FX(E(3), 44, 2), FX(E(3), 43, 2), FX(E(3), 42, 2), FX(E(3), 41, 2), paulo@0: FX(E(3), 40, 2), FX(E(3), 39, 2), FX(E(3), 38, 2), FX(E(3), 37, 2), paulo@0: FX(E(3), 36, 2), FX(E(3), 35, 2), FX(E(3), 34, 2), FX(E(3), 33, 2), paulo@0: FX(E(3), 32, 2), FX(E(3), 31, 2), FX(E(3), 30, 2), FX(E(3), 29, 2), paulo@0: FX(E(3), 28, 2), FX(E(3), 27, 2), FX(E(3), 26, 2), FX(E(3), 25, 2), paulo@0: FX(E(3), 24, 2), FX(E(3), 23, 2), FX(E(3), 22, 2), FX(E(3), 21, 2), paulo@0: FX(E(3), 20, 2), FX(E(3), 19, 2), FX(E(3), 18, 2), FX(E(3), 17, 2), paulo@0: FX(E(3), 16, 2), FX(E(3), 15, 2), FX(E(3), 14, 2), FX(E(3), 13, 2), paulo@0: FX(E(3), 12, 2), FX(E(3), 11, 2), FX(E(3), 10, 2), FX(E(3), 9, 2), paulo@0: FX(E(3), 8, 2), FX(E(3), 7, 2), FX(E(3), 6, 2), FX(E(3), 5, 2), paulo@0: FX(E(3), 4, 2), FX(E(3), 3, 2), FX(E(3), 2, 2), FX(E(3), 1, 2) paulo@0: }; paulo@0: paulo@0: static const u16 dieEffect2[] = { paulo@0: 1, 60, paulo@0: FX(E(4), 60, 2), FX(B(3), 59, 2), FX(E(3), 58, 2), FX(E(3), 57, 2), paulo@0: FX(E(3), 56, 2), FX(E(3), 55, 2), FX(E(3), 54, 2), FX(E(3), 53, 2), paulo@0: FX(E(3), 52, 2), FX(E(3), 51, 2), FX(E(3), 50, 2), FX(E(3), 49, 2), paulo@0: FX(E(3), 48, 2), FX(E(3), 47, 2), FX(E(3), 46, 2), FX(E(3), 45, 2), paulo@0: FX(E(3), 44, 2), FX(E(3), 43, 2), FX(E(3), 42, 2), FX(E(3), 41, 2), paulo@0: FX(E(3), 40, 2), FX(E(3), 39, 2), FX(E(3), 38, 2), FX(E(3), 37, 2), paulo@0: FX(E(3), 36, 2), FX(E(3), 35, 2), FX(E(3), 34, 2), FX(E(3), 33, 2), paulo@0: FX(E(3), 32, 2), FX(E(3), 31, 2), FX(E(3), 30, 2), FX(E(3), 29, 2), paulo@0: FX(E(3), 28, 2), FX(E(3), 27, 2), FX(E(3), 26, 2), FX(E(3), 25, 2), paulo@0: FX(E(3), 24, 2), FX(E(3), 23, 2), FX(E(3), 22, 2), FX(E(3), 21, 2), paulo@0: FX(E(3), 20, 2), FX(E(3), 19, 2), FX(E(3), 18, 2), FX(E(3), 17, 2), paulo@0: FX(E(3), 16, 2), FX(E(3), 15, 2), FX(E(3), 14, 2), FX(E(3), 13, 2), paulo@0: FX(E(3), 12, 2), FX(E(3), 11, 2), FX(E(3), 10, 2), FX(E(3), 9, 2), paulo@0: FX(E(3), 8, 2), FX(E(3), 7, 2), FX(E(3), 6, 2), FX(E(3), 5, 2), paulo@0: FX(E(3), 4, 2), FX(E(3), 3, 2), FX(E(3), 2, 2), FX(E(3), 1, 2) paulo@0: }; paulo@0: paulo@0: static const u16 *effects[32] = { paulo@0: rotateEffect, paulo@0: moveEffect, paulo@0: NULL, // drop: not used paulo@0: landEffect, paulo@0: lockEffect, paulo@0: lineEffect, paulo@0: homerEffect, paulo@0: streakEffect, paulo@0: NULL, // spawn paulo@0: holdEffect, // hold paulo@0: irsEffect, // irs paulo@0: NULL, // 4x4 square paulo@0: NULL, NULL, NULL, NULL, // unused paulo@0: dieEffect1, dieEffect2 paulo@0: }; paulo@0: paulo@0: paulo@0: paulo@0: static const u16 *fxPtr[5]; paulo@0: static u8 fxLen[5]; paulo@0: static s8 lastCD; paulo@0: paulo@0: paulo@0: paulo@0: static void startEffect(const u16 *s) { paulo@0: paulo@0: // skip effects that lack an actual effect paulo@0: if (!s) { paulo@0: return; paulo@0: } paulo@0: paulo@0: unsigned int type = s[0]; paulo@0: unsigned int len = s[1]; paulo@0: unsigned int min = 0; paulo@0: unsigned int max = 2; paulo@0: paulo@0: if (type > 0) { paulo@0: min = 3; paulo@0: max = 4; paulo@0: } paulo@0: paulo@0: // prepare to kill the channel with the shortest time remaining paulo@0: unsigned int shortestLen = fxLen[min]; paulo@0: unsigned int shortestCh = min; paulo@0: for (int ch = min + 1; ch <= max; ++ch) { paulo@0: if (fxLen[ch] < shortestLen) { paulo@0: shortestLen = fxLen[ch]; paulo@0: shortestCh = ch; paulo@0: } paulo@0: } paulo@0: paulo@0: // if the channel is suitable, kill it paulo@0: if (shortestLen < len) { paulo@0: fxPtr[shortestCh] = s + 2; paulo@0: fxLen[shortestCh] = len; paulo@0: } paulo@0: } paulo@0: paulo@0: static void pollEffects(void) { paulo@0: for (int ch = 0; ch < 5; ++ch) { paulo@0: unsigned int note = 36; paulo@0: unsigned int vol = 0; paulo@0: unsigned int duty = 0; paulo@0: if (fxLen[ch] > 0) { paulo@0: unsigned int data = *fxPtr[ch]++; paulo@0: duty = (data >> 14) & 0x03; paulo@0: vol = (data >> 7) & 0x7F; paulo@0: note = data & 0x7F; paulo@0: --fxLen[ch]; paulo@0: } paulo@0: SCHANNEL_CR(11 + ch) = SCHANNEL_ENABLE | SOUND_FORMAT_PSG | SOUND_PAN(64) paulo@0: | (duty << 24) | vol; paulo@0: SCHANNEL_TIMER(11 + ch) = midi2psgFreq[note]; paulo@0: } paulo@0: } paulo@0: paulo@0: void ljSoundEffects(unsigned long int sounds, paulo@0: int countdown) { paulo@0: paulo@0: // cancel out overlapping line clear sounds paulo@0: if (sounds & 0x0080) { paulo@0: sounds &= ~0x0060; paulo@0: } else if (sounds & 0x0040) { paulo@0: sounds &= ~0x0020; paulo@0: } paulo@0: paulo@0: for (int y = 0; sounds; ++y, sounds >>= 1) { paulo@0: if (sounds & 1) { paulo@0: startEffect(effects[y]); paulo@0: } paulo@0: } paulo@0: if (countdown < 0) { paulo@0: countdown = 0; paulo@0: } else if (countdown > 6) { paulo@0: countdown = 6; paulo@0: } paulo@0: if (countdown < lastCD) { paulo@0: if (countdown > 0) { paulo@0: startEffect(countEffect); paulo@0: } else { paulo@0: startEffect(winEffect1); paulo@0: startEffect(winEffect2); paulo@0: } paulo@0: } paulo@0: lastCD = countdown; paulo@0: pollEffects(); paulo@0: }