Invaders game for the Gameduino

Dependencies:   Gameduino mbed

Committer:
TheChrisyd
Date:
Sat Sep 29 13:01:42 2012 +0000
Revision:
1:f44175dd69fd
Parent:
0:8a7c58553b44
Child:
2:20a89dc286d5
saved progress

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TheChrisyd 1:f44175dd69fd 1 //#include <SPI.h>
TheChrisyd 1:f44175dd69fd 2
TheChrisyd 1:f44175dd69fd 3 #include "utils.h"
TheChrisyd 1:f44175dd69fd 4 SPI spiutils(ARD_MOSI, ARD_MISO, ARD_SCK); // mosi, miso, sclk
TheChrisyd 1:f44175dd69fd 5 Serial pcu(USBTX, USBRX);
TheChrisyd 1:f44175dd69fd 6 /*---------------------------------------------
TheChrisyd 1:f44175dd69fd 7 Coprocessor controller
TheChrisyd 1:f44175dd69fd 8 ---------------------------------------------*/
TheChrisyd 1:f44175dd69fd 9 enum {
TheChrisyd 1:f44175dd69fd 10 COPPERCTRL = COMM,
TheChrisyd 1:f44175dd69fd 11 COPPERLISTSTART = COPPERCTRL,
TheChrisyd 1:f44175dd69fd 12 SAMPLEREADPOS = COPPERCTRL+2,
TheChrisyd 1:f44175dd69fd 13 SAMPLEREADPAGE = COPPERCTRL+4,
TheChrisyd 1:f44175dd69fd 14 COPPERLISTPTR = COPPERCTRL+6,
TheChrisyd 1:f44175dd69fd 15 YLINEECHO = COPPERCTRL+8,
TheChrisyd 1:f44175dd69fd 16 DUMMYCOPPERLIST = COPPERCTRL+10
TheChrisyd 1:f44175dd69fd 17 };
TheChrisyd 1:f44175dd69fd 18
TheChrisyd 1:f44175dd69fd 19 // Available commands
TheChrisyd 1:f44175dd69fd 20 enum copper_commands {
TheChrisyd 1:f44175dd69fd 21 cp_halt='@',
TheChrisyd 1:f44175dd69fd 22 cp_wait,
TheChrisyd 1:f44175dd69fd 23 cp_write8,
TheChrisyd 1:f44175dd69fd 24 cp_write16,
TheChrisyd 1:f44175dd69fd 25 cp_copy
TheChrisyd 1:f44175dd69fd 26 };
TheChrisyd 1:f44175dd69fd 27
TheChrisyd 1:f44175dd69fd 28 #include "j1.h"
TheChrisyd 1:f44175dd69fd 29 void crash()
TheChrisyd 1:f44175dd69fd 30 {
TheChrisyd 1:f44175dd69fd 31 unsigned int p;
TheChrisyd 1:f44175dd69fd 32 while (1) {
TheChrisyd 1:f44175dd69fd 33 GD.wr(0,p++);
TheChrisyd 1:f44175dd69fd 34 }
TheChrisyd 1:f44175dd69fd 35 }
TheChrisyd 1:f44175dd69fd 36 static unsigned int samplePage_, listStart_;
TheChrisyd 1:f44175dd69fd 37 void Coprocessor::reset(unsigned int spg)
TheChrisyd 1:f44175dd69fd 38 {
TheChrisyd 1:f44175dd69fd 39 samplePage_ = spg;
TheChrisyd 1:f44175dd69fd 40 GD.wr(J1_RESET, 1); // Halt the coprocessor
TheChrisyd 1:f44175dd69fd 41 GD.copy(J1_CODE, copper_code, sizeof(copper_code));
TheChrisyd 1:f44175dd69fd 42 for (unsigned int i=J1_CODE; i<J1_CODE+256; i+=2) {
TheChrisyd 1:f44175dd69fd 43 unsigned int w = GD.rd16(i);
TheChrisyd 1:f44175dd69fd 44 if (w == 0xbf00) { GD.wr16(i,spg+0x8000); }
TheChrisyd 1:f44175dd69fd 45 else if (w == COMM+0x8000) { listStart_ = i; }
TheChrisyd 1:f44175dd69fd 46 }
TheChrisyd 1:f44175dd69fd 47 CopperlistBuilder d; // Set up a fake copperlist
TheChrisyd 1:f44175dd69fd 48 GD.wr(DUMMYCOPPERLIST,cp_halt);
TheChrisyd 1:f44175dd69fd 49 GD.wr16(listStart_,DUMMYCOPPERLIST+0x8000);
TheChrisyd 1:f44175dd69fd 50 GD.wr16(SAMPLEREADPAGE,samplePage_);
TheChrisyd 1:f44175dd69fd 51 SoundController::reset();
TheChrisyd 1:f44175dd69fd 52 GD.wr(J1_RESET, 0); // Go!
TheChrisyd 1:f44175dd69fd 53 delay(10);
TheChrisyd 1:f44175dd69fd 54 SoundController::update();
TheChrisyd 1:f44175dd69fd 55 }
TheChrisyd 1:f44175dd69fd 56
TheChrisyd 1:f44175dd69fd 57 void Coprocessor::setCopperlist(unsigned int addr)
TheChrisyd 1:f44175dd69fd 58 {
TheChrisyd 1:f44175dd69fd 59 GD.wr(J1_RESET, 1); // Halt the coprocessor
TheChrisyd 1:f44175dd69fd 60 GD.wr16(listStart_,addr+0x8000);
TheChrisyd 1:f44175dd69fd 61 GD.wr(J1_RESET, 0); // Go!
TheChrisyd 1:f44175dd69fd 62 }
TheChrisyd 1:f44175dd69fd 63
TheChrisyd 1:f44175dd69fd 64 int Coprocessor::yline()
TheChrisyd 1:f44175dd69fd 65 {
TheChrisyd 1:f44175dd69fd 66 return GD.rd16(YLINEECHO);
TheChrisyd 1:f44175dd69fd 67 }
TheChrisyd 1:f44175dd69fd 68 unsigned int Coprocessor::samplePage()
TheChrisyd 1:f44175dd69fd 69 {
TheChrisyd 1:f44175dd69fd 70 return samplePage_;
TheChrisyd 1:f44175dd69fd 71 }
TheChrisyd 1:f44175dd69fd 72 byte Coprocessor::sampleReadPos()
TheChrisyd 1:f44175dd69fd 73 {
TheChrisyd 1:f44175dd69fd 74 return GD.rd(SAMPLEREADPOS);
TheChrisyd 1:f44175dd69fd 75 }
TheChrisyd 1:f44175dd69fd 76
TheChrisyd 1:f44175dd69fd 77 // CopperlistBuilder
TheChrisyd 1:f44175dd69fd 78 void CopperlistBuilder::put(byte b)
TheChrisyd 1:f44175dd69fd 79 {
TheChrisyd 1:f44175dd69fd 80 GD.wr(out++,b);
TheChrisyd 1:f44175dd69fd 81 }
TheChrisyd 1:f44175dd69fd 82 void CopperlistBuilder::put16(unsigned int v)
TheChrisyd 1:f44175dd69fd 83 {
TheChrisyd 1:f44175dd69fd 84 put(lowByte(v));
TheChrisyd 1:f44175dd69fd 85 put(highByte(v));
TheChrisyd 1:f44175dd69fd 86 }
TheChrisyd 1:f44175dd69fd 87
TheChrisyd 1:f44175dd69fd 88 void CopperlistBuilder::begin(unsigned int dest)
TheChrisyd 1:f44175dd69fd 89 {
TheChrisyd 1:f44175dd69fd 90 out = start = dest;
TheChrisyd 1:f44175dd69fd 91 #if 0
TheChrisyd 1:f44175dd69fd 92 // Debugging...
TheChrisyd 1:f44175dd69fd 93 write(0,65);
TheChrisyd 1:f44175dd69fd 94 write(1,66);
TheChrisyd 1:f44175dd69fd 95 write(2,67);
TheChrisyd 1:f44175dd69fd 96 write(3,68);
TheChrisyd 1:f44175dd69fd 97 write(4,69);
TheChrisyd 1:f44175dd69fd 98 copy(0,64,4);
TheChrisyd 1:f44175dd69fd 99 copy(64,128,3);
TheChrisyd 1:f44175dd69fd 100 copy(128,131,5);
TheChrisyd 1:f44175dd69fd 101 #endif
TheChrisyd 1:f44175dd69fd 102 }
TheChrisyd 1:f44175dd69fd 103 void CopperlistBuilder::wait(int line)
TheChrisyd 1:f44175dd69fd 104 {
TheChrisyd 1:f44175dd69fd 105 if (line > 0) {
TheChrisyd 1:f44175dd69fd 106 put(cp_wait);
TheChrisyd 1:f44175dd69fd 107 put16(line);
TheChrisyd 1:f44175dd69fd 108 }
TheChrisyd 1:f44175dd69fd 109 }
TheChrisyd 1:f44175dd69fd 110 void CopperlistBuilder::write(unsigned int addr, byte val)
TheChrisyd 1:f44175dd69fd 111 {
TheChrisyd 1:f44175dd69fd 112 put(cp_write8);
TheChrisyd 1:f44175dd69fd 113 put(val);
TheChrisyd 1:f44175dd69fd 114 put16(addr);
TheChrisyd 1:f44175dd69fd 115 }
TheChrisyd 1:f44175dd69fd 116 void CopperlistBuilder::write16(unsigned int addr, unsigned int val)
TheChrisyd 1:f44175dd69fd 117 {
TheChrisyd 1:f44175dd69fd 118 put(cp_write16);
TheChrisyd 1:f44175dd69fd 119 put16(val);
TheChrisyd 1:f44175dd69fd 120 put16(addr);
TheChrisyd 1:f44175dd69fd 121 }
TheChrisyd 1:f44175dd69fd 122 void CopperlistBuilder::copy(unsigned int src, unsigned int dst, unsigned int numBytes)
TheChrisyd 1:f44175dd69fd 123 {
TheChrisyd 1:f44175dd69fd 124 if (numBytes > 0) {
TheChrisyd 1:f44175dd69fd 125 put(cp_copy);
TheChrisyd 1:f44175dd69fd 126 put16(src);
TheChrisyd 1:f44175dd69fd 127 put16(dst);
TheChrisyd 1:f44175dd69fd 128 put16(numBytes);
TheChrisyd 1:f44175dd69fd 129 }
TheChrisyd 1:f44175dd69fd 130 }
TheChrisyd 1:f44175dd69fd 131 void CopperlistBuilder::end(bool executeNow)
TheChrisyd 1:f44175dd69fd 132 {
TheChrisyd 1:f44175dd69fd 133 put(cp_halt); // Nice end to the list
TheChrisyd 1:f44175dd69fd 134 if (executeNow) {
TheChrisyd 1:f44175dd69fd 135 Coprocessor::setCopperlist(start);
TheChrisyd 1:f44175dd69fd 136 }
TheChrisyd 1:f44175dd69fd 137 }
TheChrisyd 1:f44175dd69fd 138
TheChrisyd 1:f44175dd69fd 139 unsigned int CopperlistBuilder::position()
TheChrisyd 1:f44175dd69fd 140 {
TheChrisyd 1:f44175dd69fd 141 return out;
TheChrisyd 1:f44175dd69fd 142 }
TheChrisyd 1:f44175dd69fd 143
TheChrisyd 1:f44175dd69fd 144 /*---------------------------------------------
TheChrisyd 1:f44175dd69fd 145 Sound
TheChrisyd 1:f44175dd69fd 146 ---------------------------------------------*/
TheChrisyd 1:f44175dd69fd 147 // The amount of space to leave in the buffer
TheChrisyd 1:f44175dd69fd 148 #define BUFFERGAP 8
TheChrisyd 1:f44175dd69fd 149
TheChrisyd 1:f44175dd69fd 150 /*---------------------------------------------
TheChrisyd 1:f44175dd69fd 151 Sample playback
TheChrisyd 1:f44175dd69fd 152 ---------------------------------------------*/
TheChrisyd 1:f44175dd69fd 153 static byte sampleWritePos;
TheChrisyd 1:f44175dd69fd 154 static prog_char *sampleStart0, *samplePos0, *sampleEnd0;
TheChrisyd 1:f44175dd69fd 155 static prog_char *sampleStart1, *samplePos1, *sampleEnd1;
TheChrisyd 1:f44175dd69fd 156 static prog_char *sampleStart2, *samplePos2, *sampleEnd2;
TheChrisyd 1:f44175dd69fd 157 static prog_char *sampleStart3, *samplePos3, *sampleEnd3;
TheChrisyd 1:f44175dd69fd 158 static bool repeatSample0, repeatSample1, repeatSample2, repeatSample3;
TheChrisyd 1:f44175dd69fd 159
TheChrisyd 1:f44175dd69fd 160 static void writeSamples(byte num)
TheChrisyd 1:f44175dd69fd 161 {
TheChrisyd 1:f44175dd69fd 162 if (num > 0) {
TheChrisyd 1:f44175dd69fd 163 GD.__wstart(Coprocessor::samplePage()+sampleWritePos);
TheChrisyd 1:f44175dd69fd 164 prog_char *s0=samplePos0, *se0=sampleEnd0;
TheChrisyd 1:f44175dd69fd 165 prog_char *s1=samplePos1, *se1=sampleEnd1;
TheChrisyd 1:f44175dd69fd 166 prog_char *s2=samplePos2, *se2=sampleEnd2;
TheChrisyd 1:f44175dd69fd 167 prog_char *s3=samplePos3, *se3=sampleEnd3;
TheChrisyd 1:f44175dd69fd 168 for (byte i=0; i<num; ++i) {
TheChrisyd 1:f44175dd69fd 169 int val = 0;
TheChrisyd 1:f44175dd69fd 170 if (s0) {
TheChrisyd 1:f44175dd69fd 171 val += (char)pgm_read_byte(s0++);
TheChrisyd 1:f44175dd69fd 172 if (s0 == se0) {
TheChrisyd 1:f44175dd69fd 173 s0 = (repeatSample0)? sampleStart0: 0;
TheChrisyd 1:f44175dd69fd 174 }
TheChrisyd 1:f44175dd69fd 175 }
TheChrisyd 1:f44175dd69fd 176 if (s1) {
TheChrisyd 1:f44175dd69fd 177 val += (char)pgm_read_byte(s1++);
TheChrisyd 1:f44175dd69fd 178 if (s1 == se1) {
TheChrisyd 1:f44175dd69fd 179 s1 = (repeatSample1)? sampleStart1: 0;
TheChrisyd 1:f44175dd69fd 180 }
TheChrisyd 1:f44175dd69fd 181 }
TheChrisyd 1:f44175dd69fd 182 if (s2) {
TheChrisyd 1:f44175dd69fd 183 val += (char)pgm_read_byte(s2++);
TheChrisyd 1:f44175dd69fd 184 if (s2 == se2) {
TheChrisyd 1:f44175dd69fd 185 s2 = (repeatSample2)? sampleStart2: 0;
TheChrisyd 1:f44175dd69fd 186 }
TheChrisyd 1:f44175dd69fd 187 }
TheChrisyd 1:f44175dd69fd 188 if (s3) {
TheChrisyd 1:f44175dd69fd 189 val += (char)pgm_read_byte(s3++);
TheChrisyd 1:f44175dd69fd 190 if (s3 == se3) {
TheChrisyd 1:f44175dd69fd 191 s3 = (repeatSample3)? sampleStart3: 0;
TheChrisyd 1:f44175dd69fd 192 }
TheChrisyd 1:f44175dd69fd 193 }
TheChrisyd 1:f44175dd69fd 194 spiutils.write(val>>2);
TheChrisyd 1:f44175dd69fd 195 }
TheChrisyd 1:f44175dd69fd 196 GD.__end();
TheChrisyd 1:f44175dd69fd 197 samplePos0 = s0;
TheChrisyd 1:f44175dd69fd 198 samplePos1 = s1;
TheChrisyd 1:f44175dd69fd 199 samplePos2 = s2;
TheChrisyd 1:f44175dd69fd 200 samplePos3 = s3;
TheChrisyd 1:f44175dd69fd 201 sampleWritePos += num;
TheChrisyd 1:f44175dd69fd 202 }
TheChrisyd 1:f44175dd69fd 203 }
TheChrisyd 1:f44175dd69fd 204
TheChrisyd 1:f44175dd69fd 205 void SoundController::playSample(prog_char *s, int n, byte ch)
TheChrisyd 1:f44175dd69fd 206 {
TheChrisyd 1:f44175dd69fd 207 bool repeat = (n < 0);
TheChrisyd 1:f44175dd69fd 208 if (repeat) {
TheChrisyd 1:f44175dd69fd 209 n = -n;
TheChrisyd 1:f44175dd69fd 210 }
TheChrisyd 1:f44175dd69fd 211 switch (ch) {
TheChrisyd 1:f44175dd69fd 212 case 0: sampleStart0 = s;
TheChrisyd 1:f44175dd69fd 213 samplePos0 = s;
TheChrisyd 1:f44175dd69fd 214 sampleEnd0 = s+n;
TheChrisyd 1:f44175dd69fd 215 repeatSample0 = repeat;
TheChrisyd 1:f44175dd69fd 216 break;
TheChrisyd 1:f44175dd69fd 217 case 1: sampleStart1 = s;
TheChrisyd 1:f44175dd69fd 218 samplePos1 = s;
TheChrisyd 1:f44175dd69fd 219 sampleEnd1 = s+n;
TheChrisyd 1:f44175dd69fd 220 repeatSample1 = repeat;
TheChrisyd 1:f44175dd69fd 221 break;
TheChrisyd 1:f44175dd69fd 222 case 2: sampleStart2 = s;
TheChrisyd 1:f44175dd69fd 223 samplePos2 = s;
TheChrisyd 1:f44175dd69fd 224 sampleEnd2 = s+n;
TheChrisyd 1:f44175dd69fd 225 repeatSample2 = repeat;
TheChrisyd 1:f44175dd69fd 226 break;
TheChrisyd 1:f44175dd69fd 227 case 3: sampleStart3 = s;
TheChrisyd 1:f44175dd69fd 228 samplePos3 = s;
TheChrisyd 1:f44175dd69fd 229 sampleEnd3 = s+n;
TheChrisyd 1:f44175dd69fd 230 repeatSample3 = repeat;
TheChrisyd 1:f44175dd69fd 231 break;
TheChrisyd 1:f44175dd69fd 232 }
TheChrisyd 1:f44175dd69fd 233 }
TheChrisyd 1:f44175dd69fd 234
TheChrisyd 1:f44175dd69fd 235 #if SYNTHSOUNDS
TheChrisyd 1:f44175dd69fd 236 /*---------------------------------------------
TheChrisyd 1:f44175dd69fd 237 Synthesized sounds
TheChrisyd 1:f44175dd69fd 238 ---------------------------------------------*/
TheChrisyd 1:f44175dd69fd 239 static SoundPlayer *soundPlayerList=0;
TheChrisyd 1:f44175dd69fd 240 ADSR::ADSR(byte a, byte d, byte s, byte r) : attack(a), decay(d), sustain(s), release(r)
TheChrisyd 1:f44175dd69fd 241 {
TheChrisyd 1:f44175dd69fd 242 }
TheChrisyd 1:f44175dd69fd 243 byte ADSR::evaluate(unsigned int t, unsigned int r)
TheChrisyd 1:f44175dd69fd 244 {
TheChrisyd 1:f44175dd69fd 245 if (t > r) {
TheChrisyd 1:f44175dd69fd 246 // In release phase...
TheChrisyd 1:f44175dd69fd 247 t -= r;
TheChrisyd 1:f44175dd69fd 248 if (t > release) {
TheChrisyd 1:f44175dd69fd 249 return 0;
TheChrisyd 1:f44175dd69fd 250 }
TheChrisyd 1:f44175dd69fd 251 t = sustain*(release-t);
TheChrisyd 1:f44175dd69fd 252 return t/release;
TheChrisyd 1:f44175dd69fd 253 }
TheChrisyd 1:f44175dd69fd 254 else if (t >= (attack+decay)) {
TheChrisyd 1:f44175dd69fd 255 // In sustain phase
TheChrisyd 1:f44175dd69fd 256 return sustain;
TheChrisyd 1:f44175dd69fd 257 }
TheChrisyd 1:f44175dd69fd 258 else if (t > attack) {
TheChrisyd 1:f44175dd69fd 259 // In decay phase
TheChrisyd 1:f44175dd69fd 260 t -= attack;
TheChrisyd 1:f44175dd69fd 261 t = (255-sustain)*t;
TheChrisyd 1:f44175dd69fd 262 return 255-(t/decay);
TheChrisyd 1:f44175dd69fd 263 }
TheChrisyd 1:f44175dd69fd 264 else if (t > 0) {
TheChrisyd 1:f44175dd69fd 265 // In attack phase
TheChrisyd 1:f44175dd69fd 266 return (t*255)/attack;
TheChrisyd 1:f44175dd69fd 267 }
TheChrisyd 1:f44175dd69fd 268 return 0;
TheChrisyd 1:f44175dd69fd 269 }
TheChrisyd 1:f44175dd69fd 270
TheChrisyd 1:f44175dd69fd 271 SoundPlayer::SoundPlayer()
TheChrisyd 1:f44175dd69fd 272 {
TheChrisyd 1:f44175dd69fd 273 volume = 255;
TheChrisyd 1:f44175dd69fd 274 active = false;
TheChrisyd 1:f44175dd69fd 275 isLinked = false;
TheChrisyd 1:f44175dd69fd 276 }
TheChrisyd 1:f44175dd69fd 277 SoundPlayer& SoundPlayer::setVolume(byte v)
TheChrisyd 1:f44175dd69fd 278 {
TheChrisyd 1:f44175dd69fd 279 volume = v;
TheChrisyd 1:f44175dd69fd 280 return *this;
TheChrisyd 1:f44175dd69fd 281 }
TheChrisyd 1:f44175dd69fd 282 SoundPlayer& SoundPlayer::setSound(const Sound& s)
TheChrisyd 1:f44175dd69fd 283 {
TheChrisyd 1:f44175dd69fd 284 sound = s;
TheChrisyd 1:f44175dd69fd 285 return *this;
TheChrisyd 1:f44175dd69fd 286 }
TheChrisyd 1:f44175dd69fd 287 void SoundPlayer::play(unsigned int p, unsigned int d)
TheChrisyd 1:f44175dd69fd 288 {
TheChrisyd 1:f44175dd69fd 289 if (!isLinked) {
TheChrisyd 1:f44175dd69fd 290 // Add me to the list of sounds to be updated
TheChrisyd 1:f44175dd69fd 291 isLinked = true;
TheChrisyd 1:f44175dd69fd 292 link = soundPlayerList;
TheChrisyd 1:f44175dd69fd 293 soundPlayerList = this;
TheChrisyd 1:f44175dd69fd 294 }
TheChrisyd 1:f44175dd69fd 295 ticks = 0;
TheChrisyd 1:f44175dd69fd 296 pitch = p;
TheChrisyd 1:f44175dd69fd 297 duration = d;
TheChrisyd 1:f44175dd69fd 298 releasing = false;
TheChrisyd 1:f44175dd69fd 299 active = true;
TheChrisyd 1:f44175dd69fd 300 }
TheChrisyd 1:f44175dd69fd 301 void SoundPlayer::release()
TheChrisyd 1:f44175dd69fd 302 {
TheChrisyd 1:f44175dd69fd 303 releasing = true;
TheChrisyd 1:f44175dd69fd 304 duration = ticks;
TheChrisyd 1:f44175dd69fd 305 }
TheChrisyd 1:f44175dd69fd 306 void SoundPlayer::update()
TheChrisyd 1:f44175dd69fd 307 {
TheChrisyd 1:f44175dd69fd 308 if (active) {
TheChrisyd 1:f44175dd69fd 309 if (releasing) {
TheChrisyd 1:f44175dd69fd 310 if (++ticks > (duration+sound.adsr.release)) {
TheChrisyd 1:f44175dd69fd 311 stop();
TheChrisyd 1:f44175dd69fd 312 }
TheChrisyd 1:f44175dd69fd 313 }
TheChrisyd 1:f44175dd69fd 314 else {
TheChrisyd 1:f44175dd69fd 315 if (ticks!=infinite) {
TheChrisyd 1:f44175dd69fd 316 ++ticks;
TheChrisyd 1:f44175dd69fd 317 }
TheChrisyd 1:f44175dd69fd 318 if ((ticks==duration) and (duration!=infinite)) {
TheChrisyd 1:f44175dd69fd 319 release();
TheChrisyd 1:f44175dd69fd 320 }
TheChrisyd 1:f44175dd69fd 321 }
TheChrisyd 1:f44175dd69fd 322 if (active) {
TheChrisyd 1:f44175dd69fd 323 GD.__wstart(VOICES);
TheChrisyd 1:f44175dd69fd 324 spimain.write(lowByte(pitch));
TheChrisyd 1:f44175dd69fd 325 spimain.write(highByte(pitch));
TheChrisyd 1:f44175dd69fd 326 unsigned int b = sound.adsr.evaluate(ticks,duration);
TheChrisyd 1:f44175dd69fd 327 b = highByte(b*volume);
TheChrisyd 1:f44175dd69fd 328 //spimain.write(b);
TheChrisyd 1:f44175dd69fd 329 //spimain.write(b);
TheChrisyd 1:f44175dd69fd 330 GD.__end();
TheChrisyd 1:f44175dd69fd 331 }
TheChrisyd 1:f44175dd69fd 332 }
TheChrisyd 1:f44175dd69fd 333 }
TheChrisyd 1:f44175dd69fd 334 void SoundPlayer::stop()
TheChrisyd 1:f44175dd69fd 335 {
TheChrisyd 1:f44175dd69fd 336 if (active) {
TheChrisyd 1:f44175dd69fd 337 active = false;
TheChrisyd 1:f44175dd69fd 338 GD.__wstart(VOICES+2);
TheChrisyd 1:f44175dd69fd 339 spimain.write(0);
TheChrisyd 1:f44175dd69fd 340 spimain.write(0);
TheChrisyd 1:f44175dd69fd 341 GD.__end();
TheChrisyd 1:f44175dd69fd 342 }
TheChrisyd 1:f44175dd69fd 343 }
TheChrisyd 1:f44175dd69fd 344 #endif
TheChrisyd 1:f44175dd69fd 345 /*---------------------------------------------
TheChrisyd 1:f44175dd69fd 346 SoundController object
TheChrisyd 1:f44175dd69fd 347 ---------------------------------------------*/
TheChrisyd 1:f44175dd69fd 348 void SoundController::reset()
TheChrisyd 1:f44175dd69fd 349 {
TheChrisyd 1:f44175dd69fd 350 samplePos0 = 0;
TheChrisyd 1:f44175dd69fd 351 samplePos1 = 0;
TheChrisyd 1:f44175dd69fd 352 samplePos2 = 0;
TheChrisyd 1:f44175dd69fd 353 samplePos3 = 0;
TheChrisyd 1:f44175dd69fd 354 GD.__wstart(Coprocessor::samplePage());
TheChrisyd 1:f44175dd69fd 355 for (int i=0; i<256; ++i) {
TheChrisyd 1:f44175dd69fd 356 spiutils.write(0);
TheChrisyd 1:f44175dd69fd 357 }
TheChrisyd 1:f44175dd69fd 358 GD.__end();
TheChrisyd 1:f44175dd69fd 359 #if SYNTHSOUNDS
TheChrisyd 1:f44175dd69fd 360 SoundPlayer *p = soundPlayerList;
TheChrisyd 1:f44175dd69fd 361 while (p) {
TheChrisyd 1:f44175dd69fd 362 p->stop();
TheChrisyd 1:f44175dd69fd 363 p->isLinked = false;
TheChrisyd 1:f44175dd69fd 364 p = p->link;
TheChrisyd 1:f44175dd69fd 365 }
TheChrisyd 1:f44175dd69fd 366 #endif
TheChrisyd 1:f44175dd69fd 367 }
TheChrisyd 1:f44175dd69fd 368
TheChrisyd 1:f44175dd69fd 369 void SoundController::update()
TheChrisyd 1:f44175dd69fd 370 {
TheChrisyd 1:f44175dd69fd 371 #if SYNTHSOUNDS
TheChrisyd 1:f44175dd69fd 372 { // Synthesized sounds
TheChrisyd 1:f44175dd69fd 373 byte b = '0';
TheChrisyd 1:f44175dd69fd 374 SoundPlayer *p = soundPlayerList;
TheChrisyd 1:f44175dd69fd 375 while (p) {
TheChrisyd 1:f44175dd69fd 376 ++b;
TheChrisyd 1:f44175dd69fd 377 p->update();
TheChrisyd 1:f44175dd69fd 378 p = p->link;
TheChrisyd 1:f44175dd69fd 379 }
TheChrisyd 1:f44175dd69fd 380 GD.wr(0,b);
TheChrisyd 1:f44175dd69fd 381 }
TheChrisyd 1:f44175dd69fd 382 #endif
TheChrisyd 1:f44175dd69fd 383 { // Sampled sounds
TheChrisyd 1:f44175dd69fd 384 unsigned int rp = Coprocessor::sampleReadPos();
TheChrisyd 1:f44175dd69fd 385 unsigned int wp = sampleWritePos;
TheChrisyd 1:f44175dd69fd 386 unsigned int emptySpace = (rp-wp)&255;
TheChrisyd 1:f44175dd69fd 387 if (emptySpace > BUFFERGAP) {
TheChrisyd 1:f44175dd69fd 388 emptySpace -= BUFFERGAP;
TheChrisyd 1:f44175dd69fd 389 if ((wp+emptySpace) > 256) {
TheChrisyd 1:f44175dd69fd 390 // Write would overflow the buffer - need to split it into two
TheChrisyd 1:f44175dd69fd 391 unsigned int b = 256-wp;
TheChrisyd 1:f44175dd69fd 392 writeSamples(b);
TheChrisyd 1:f44175dd69fd 393 writeSamples(emptySpace-b);
TheChrisyd 1:f44175dd69fd 394 }
TheChrisyd 1:f44175dd69fd 395 else {
TheChrisyd 1:f44175dd69fd 396 // Can write a single block
TheChrisyd 1:f44175dd69fd 397 writeSamples(emptySpace);
TheChrisyd 1:f44175dd69fd 398 }
TheChrisyd 1:f44175dd69fd 399 }
TheChrisyd 1:f44175dd69fd 400 }
TheChrisyd 1:f44175dd69fd 401 }
TheChrisyd 1:f44175dd69fd 402
TheChrisyd 1:f44175dd69fd 403
TheChrisyd 1:f44175dd69fd 404 /*------------------------------------------------------------
TheChrisyd 1:f44175dd69fd 405 Useful little functions
TheChrisyd 1:f44175dd69fd 406 ------------------------------------------------------------*/
TheChrisyd 1:f44175dd69fd 407 void showNumber(int n, byte x, byte y)
TheChrisyd 1:f44175dd69fd 408 {
TheChrisyd 1:f44175dd69fd 409 char temp[8];
TheChrisyd 1:f44175dd69fd 410 boolean neg = (n<0);
TheChrisyd 1:f44175dd69fd 411 if (neg) {
TheChrisyd 1:f44175dd69fd 412 n = -n;
TheChrisyd 1:f44175dd69fd 413 }
TheChrisyd 1:f44175dd69fd 414 char *o = temp;
TheChrisyd 1:f44175dd69fd 415 int m = 10000;
TheChrisyd 1:f44175dd69fd 416 while (m != 0) {
TheChrisyd 1:f44175dd69fd 417 int d = n/m;
TheChrisyd 1:f44175dd69fd 418 *o++ = d+'0';
TheChrisyd 1:f44175dd69fd 419 n -= d*m;
TheChrisyd 1:f44175dd69fd 420 m /= 10;
TheChrisyd 1:f44175dd69fd 421 }
TheChrisyd 1:f44175dd69fd 422 *o-- = 0;
TheChrisyd 1:f44175dd69fd 423 // Remove leading zeros
TheChrisyd 1:f44175dd69fd 424 char *s = temp;
TheChrisyd 1:f44175dd69fd 425 while ((s<o) and (*s=='0')) {
TheChrisyd 1:f44175dd69fd 426 *s++ = ' ';
TheChrisyd 1:f44175dd69fd 427 }
TheChrisyd 1:f44175dd69fd 428 if (neg) {
TheChrisyd 1:f44175dd69fd 429 *--s = '-';
TheChrisyd 1:f44175dd69fd 430 }
TheChrisyd 1:f44175dd69fd 431 GD.__wstart((64*y)+x);
TheChrisyd 1:f44175dd69fd 432 while (*s) {
TheChrisyd 1:f44175dd69fd 433 spiutils.write(*s++);
TheChrisyd 1:f44175dd69fd 434 }
TheChrisyd 1:f44175dd69fd 435 GD.__end();
TheChrisyd 1:f44175dd69fd 436 }
TheChrisyd 1:f44175dd69fd 437
TheChrisyd 1:f44175dd69fd 438 static void hexDigit(byte b)
TheChrisyd 1:f44175dd69fd 439 {
TheChrisyd 1:f44175dd69fd 440 b = (b&0x0f)+'0';
TheChrisyd 1:f44175dd69fd 441 if (b > '9') {
TheChrisyd 1:f44175dd69fd 442 b += 'a'-('9'+1);
TheChrisyd 1:f44175dd69fd 443 }
TheChrisyd 1:f44175dd69fd 444 spiutils.write(b);
TheChrisyd 1:f44175dd69fd 445 }
TheChrisyd 1:f44175dd69fd 446 static void hexPair(byte b)
TheChrisyd 1:f44175dd69fd 447 {
TheChrisyd 1:f44175dd69fd 448 hexDigit(b>>4);
TheChrisyd 1:f44175dd69fd 449 hexDigit(b);
TheChrisyd 1:f44175dd69fd 450 }
TheChrisyd 1:f44175dd69fd 451 void showHexNumber(unsigned int n, byte x, byte y)
TheChrisyd 1:f44175dd69fd 452 {
TheChrisyd 1:f44175dd69fd 453 GD.__wstart((64*y)+x);
TheChrisyd 1:f44175dd69fd 454 hexPair(highByte(n));
TheChrisyd 1:f44175dd69fd 455 hexPair(lowByte(n));
TheChrisyd 1:f44175dd69fd 456 GD.__end();
TheChrisyd 1:f44175dd69fd 457 }
TheChrisyd 1:f44175dd69fd 458 void writeColor(int c)
TheChrisyd 1:f44175dd69fd 459 {
TheChrisyd 1:f44175dd69fd 460 // Colors are five bits - encode in base 32
TheChrisyd 1:f44175dd69fd 461 c = (c&31)+'0';
TheChrisyd 1:f44175dd69fd 462 if (c > '9') {
TheChrisyd 1:f44175dd69fd 463 c += 'A'-('9'+1);
TheChrisyd 1:f44175dd69fd 464 }
TheChrisyd 1:f44175dd69fd 465 pcu.printf("%d", c);
TheChrisyd 1:f44175dd69fd 466 }
TheChrisyd 1:f44175dd69fd 467 void sendScreenshot()
TheChrisyd 1:f44175dd69fd 468 {
TheChrisyd 1:f44175dd69fd 469 pcu.baud(115200);
TheChrisyd 1:f44175dd69fd 470 for (int i=0; i<300; ++i) {
TheChrisyd 1:f44175dd69fd 471 // Ask for the line...
TheChrisyd 1:f44175dd69fd 472 GD.wr16(SCREENSHOT_Y, 0x8000|i);
TheChrisyd 1:f44175dd69fd 473 // Wait for it to appear
TheChrisyd 1:f44175dd69fd 474 while ((GD.rd(SCREENSHOT_Y+1)&0x80)==0) {
TheChrisyd 1:f44175dd69fd 475 delay(1);
TheChrisyd 1:f44175dd69fd 476 }
TheChrisyd 1:f44175dd69fd 477 // Send the line of pixels to the serial port
TheChrisyd 1:f44175dd69fd 478 for (int x=0; x<400; ++x) {
TheChrisyd 1:f44175dd69fd 479 uint16_t pixel = GD.rd16(SCREENSHOT+(x*2));
TheChrisyd 1:f44175dd69fd 480 writeColor(pixel>>10); // Red
TheChrisyd 1:f44175dd69fd 481 writeColor(pixel>>5); // Green
TheChrisyd 1:f44175dd69fd 482 writeColor(pixel); // Blue
TheChrisyd 1:f44175dd69fd 483 }
TheChrisyd 1:f44175dd69fd 484 pcu.printf("\n");
TheChrisyd 1:f44175dd69fd 485 }
TheChrisyd 1:f44175dd69fd 486 // Restore sanity
TheChrisyd 1:f44175dd69fd 487 GD.wr16(SCREENSHOT_Y, 0);
TheChrisyd 1:f44175dd69fd 488 }