Version of Robotron arcade game using LPC1768, a Gameduino shield, a serial EEPROM (for high scores), two microswitch joysticks and two buttons plus a box to put it in. 20 levels of mayhem.

Dependencies:   25LCxxx_SPI CommonTypes Gameduino mbed

Revision:
9:fa7e7b37b632
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SoundManager.cpp	Sun Jun 09 14:28:53 2013 +0000
@@ -0,0 +1,129 @@
+/*
+ * SOURCE FILE : SoundManager.cpp
+ *
+ * Responsible for playing simple sounds.
+ *
+ */
+
+#include "SoundManager.h"
+#include "Notes.h"
+
+// An instance of the SoundManager class.
+SoundManager SoundManager::Instance;
+
+/***************/
+/* CONSTRUCTOR */
+/***************/
+SoundManager::SoundManager() :
+    gd( (Gameduino*)NULL )
+{
+}
+
+/*****************************/
+/* UPDATE A SINGLE TUNE SLOT */
+/*****************************/
+// Do NOT call with a record containing zero in TuneAddress (a free slot).
+void SoundManager::UpdateTuneSection( UInt8 voiceNum, TuneRecord *rec ) {
+  if( rec->Countdown > 0 ) {
+    rec->Countdown--;
+  }
+  else {
+    // Countdown has reached zero. Load next section of tune.
+    UInt8 noteNum = *(rec->TuneAddress++);
+    if( noteNum == 0 ) {
+      // End of tune. Silence voice and set tune address to NULL to
+      // indicate slot is free.
+      gd->voice( voiceNum, Gameduino::SineWave, 0, 0, 0 );
+      rec->TuneAddress = (UInt8*)NULL;
+    }
+    else {
+      // Convert note number to frequency.
+      UInt16 frequency = Notes::NoteFrequencies[ noteNum ];
+      // Read amplitude for next tune section and add biases.
+      UInt8 amp = *(rec->TuneAddress++);
+      // Start playing section.
+      gd->voice( voiceNum, rec->TuneWaveform, frequency, amp + rec->LeftAmpBias, amp + rec->RightAmpBias );
+      // Set countdown according to length of this section.
+      rec->Countdown = *(rec->TuneAddress++);
+    }
+  }
+}
+
+/************************/
+/* TRY AND PLAY A SOUND */
+/************************/
+// Pass address of tune in program memory in tuneAddress.
+// Pass bias to apply to left speaker amplitude in leftAmpBias.
+// Pass bias to apply to right speaker amplitude in leftAmpBias.
+// Returns true if sound was started, false if no sound slots free.
+bool SoundManager::PlaySound( const UInt8 *tuneAddress, UInt8 leftAmpBias, UInt8 rightAmpBias ) {
+  // Find a tune record that is free.
+  UInt8 i = 0;
+  TuneRecord *rec = tuneRecords;
+  while( ( i < VoiceCount ) && ( rec->TuneAddress != (UInt8*)NULL ) ) {
+    i++;
+    rec++;
+  }
+  if( i < VoiceCount ) {
+    // Found a free tune record. Initialise it.
+    rec->TuneWaveform = (Gameduino::WaveForm)*tuneAddress;
+    rec->TuneAddress = tuneAddress + 1;
+    rec->LeftAmpBias = leftAmpBias;
+    rec->RightAmpBias = rightAmpBias;
+    rec->Countdown = 0;
+    // Start playing first part of sound.
+    UpdateTuneSection( FirstVoice + i, rec );
+    return true;
+  }
+  else {
+    // No free counter found.
+    return false;
+  }
+}
+
+/****************************/
+/* UPDATE PLAYING OF SOUNDS */
+/****************************/
+// Should be called at regular intervals.
+void SoundManager::Update( void ) {
+  TuneRecord *ptr = tuneRecords;
+  // Repeat for all tune records.
+  for( UInt8 i = 0; i < VoiceCount; ++i ) {
+    // Skip over any unused records (with TuneAddress of zero).
+    if( ptr->TuneAddress != (UInt8*)NULL ) {
+      UpdateTuneSection( FirstVoice + i, ptr );
+    }
+    ptr++;
+  }
+}
+
+/**********************************/
+/* COUNT NUMBER OF SOUNDS PLAYING */
+/**********************************/
+// Returns number of sounds playing.
+UInt8 SoundManager::CountSoundsPlaying( void ) {
+  UInt8 count = 0;
+  TuneRecord *ptr = tuneRecords;
+  // Repeat for all tune records.
+  for( UInt8 i = 0; i < VoiceCount; ++i ) {
+    // If TuneAddress is not zero then increment count.
+    if( ptr->TuneAddress != (UInt8*)NULL ) {
+      count++;
+    }
+    ptr++;
+  }
+  return count;
+}
+
+/******************************/
+/* SILENCE ALL SOUNDS PLAYING */
+/******************************/
+void SoundManager::SilenceAll( void ) {
+  TuneRecord *ptr = tuneRecords;
+  for( UInt8 i = 0; i < VoiceCount; ++i ) {
+    gd->voice( FirstVoice + i, Gameduino::SineWave, 0, 0, 0 );
+    ptr->TuneAddress = (UInt8*)NULL;
+    ptr++;
+  }
+}
+