After decimating the enemy forces that have attacked your ship, you are charged with taking out as many of the remaining enemy fighters as possible. 3d space fighter game was initially written while I was testing some 3d routines I was implementing for a flight simulator, but my daughter started playing it and seemed to enjoy it so I added a few sound effects, explosions etc. and so this little game was born.

Dependencies:   mbed

Committer:
taylorza
Date:
Sun Jan 04 03:05:13 2015 +0000
Revision:
1:9ff7384171ec
Child:
4:b857db213f10
Version 1.0 of Game

Who changed what in which revision?

UserRevisionLine numberNew contents of line
taylorza 1:9ff7384171ec 1 #include "mbed.h"
taylorza 1:9ff7384171ec 2 #include "Fix16.h"
taylorza 1:9ff7384171ec 3 #include "lookupTables.h"
taylorza 1:9ff7384171ec 4 #include "SoundBlock.h"
taylorza 1:9ff7384171ec 5 #include "SoundChannel.h"
taylorza 1:9ff7384171ec 6
taylorza 1:9ff7384171ec 7 SoundChannel::SoundChannel() :
taylorza 1:9ff7384171ec 8 _state(4)
taylorza 1:9ff7384171ec 9 {
taylorza 1:9ff7384171ec 10 }
taylorza 1:9ff7384171ec 11
taylorza 1:9ff7384171ec 12 void SoundChannel::play(const SoundBlock soundBlocks[], int count)
taylorza 1:9ff7384171ec 13 {
taylorza 1:9ff7384171ec 14 _soundBlocks = soundBlocks;
taylorza 1:9ff7384171ec 15 _count = count;
taylorza 1:9ff7384171ec 16 _index = 0;
taylorza 1:9ff7384171ec 17 _state = 0;
taylorza 1:9ff7384171ec 18 }
taylorza 1:9ff7384171ec 19
taylorza 1:9ff7384171ec 20 bool SoundChannel::update(bool &pinState)
taylorza 1:9ff7384171ec 21 {
taylorza 1:9ff7384171ec 22 switch(_state)
taylorza 1:9ff7384171ec 23 {
taylorza 1:9ff7384171ec 24 case 0 :
taylorza 1:9ff7384171ec 25 startSoundBlock();
taylorza 1:9ff7384171ec 26 break;
taylorza 1:9ff7384171ec 27
taylorza 1:9ff7384171ec 28 case 3 : // Stop sound
taylorza 1:9ff7384171ec 29 pinState = _pinState = false;
taylorza 1:9ff7384171ec 30 _state = 4;
taylorza 1:9ff7384171ec 31 return true;
taylorza 1:9ff7384171ec 32
taylorza 1:9ff7384171ec 33 case 4 : // No sound
taylorza 1:9ff7384171ec 34 return false;
taylorza 1:9ff7384171ec 35 }
taylorza 1:9ff7384171ec 36
taylorza 1:9ff7384171ec 37 if (updateCounters())
taylorza 1:9ff7384171ec 38 {
taylorza 1:9ff7384171ec 39 switch(_currentSoundBlock.getToneType())
taylorza 1:9ff7384171ec 40 {
taylorza 1:9ff7384171ec 41 case SoundBlock::Tone : updateTone(); pinState = _pinState; return true;
taylorza 1:9ff7384171ec 42 case SoundBlock::Noise : updateNoise(); pinState = _pinState; return true;
taylorza 1:9ff7384171ec 43 case SoundBlock::Pause : return false;
taylorza 1:9ff7384171ec 44 }
taylorza 1:9ff7384171ec 45 }
taylorza 1:9ff7384171ec 46
taylorza 1:9ff7384171ec 47 return false;
taylorza 1:9ff7384171ec 48 }
taylorza 1:9ff7384171ec 49
taylorza 1:9ff7384171ec 50 void SoundChannel::updateTone()
taylorza 1:9ff7384171ec 51 {
taylorza 1:9ff7384171ec 52 switch(_state)
taylorza 1:9ff7384171ec 53 {
taylorza 1:9ff7384171ec 54 case 1: // High
taylorza 1:9ff7384171ec 55 {
taylorza 1:9ff7384171ec 56 _pinState = true;
taylorza 1:9ff7384171ec 57 _pitchHighCounter -= fix16_one;
taylorza 1:9ff7384171ec 58 if (_pitchHighCounter <= 0)
taylorza 1:9ff7384171ec 59 {
taylorza 1:9ff7384171ec 60 _pinState = false;
taylorza 1:9ff7384171ec 61 _pitchHighCounter += _basePitchHighCount;
taylorza 1:9ff7384171ec 62 _state = 2;
taylorza 1:9ff7384171ec 63 }
taylorza 1:9ff7384171ec 64 }
taylorza 1:9ff7384171ec 65 break;
taylorza 1:9ff7384171ec 66
taylorza 1:9ff7384171ec 67 case 2: // Low
taylorza 1:9ff7384171ec 68 {
taylorza 1:9ff7384171ec 69 _pinState = false;
taylorza 1:9ff7384171ec 70 _pitchLowCounter -= fix16_one;
taylorza 1:9ff7384171ec 71 if (_pitchLowCounter <= 0)
taylorza 1:9ff7384171ec 72 {
taylorza 1:9ff7384171ec 73 _pinState = true;
taylorza 1:9ff7384171ec 74 _pitchLowCounter += _basePitchLowCount;
taylorza 1:9ff7384171ec 75 _state = 1;
taylorza 1:9ff7384171ec 76 }
taylorza 1:9ff7384171ec 77 }
taylorza 1:9ff7384171ec 78 break;
taylorza 1:9ff7384171ec 79 }
taylorza 1:9ff7384171ec 80 }
taylorza 1:9ff7384171ec 81
taylorza 1:9ff7384171ec 82 void SoundChannel::updateNoise()
taylorza 1:9ff7384171ec 83 {
taylorza 1:9ff7384171ec 84 switch(_state)
taylorza 1:9ff7384171ec 85 {
taylorza 1:9ff7384171ec 86 case 1: // High/Low
taylorza 1:9ff7384171ec 87 {
taylorza 1:9ff7384171ec 88 _pitchHighCounter -= fix16_one;
taylorza 1:9ff7384171ec 89 if (_pitchHighCounter <= 0)
taylorza 1:9ff7384171ec 90 {
taylorza 1:9ff7384171ec 91 _pinState = (SoundChannel::lfsr_rand() & 1) == 1;
taylorza 1:9ff7384171ec 92 _pitchHighCounter += _basePitchHighCount;
taylorza 1:9ff7384171ec 93 }
taylorza 1:9ff7384171ec 94 }
taylorza 1:9ff7384171ec 95 break;
taylorza 1:9ff7384171ec 96 }
taylorza 1:9ff7384171ec 97 }
taylorza 1:9ff7384171ec 98
taylorza 1:9ff7384171ec 99 void SoundChannel::startSoundBlock()
taylorza 1:9ff7384171ec 100 {
taylorza 1:9ff7384171ec 101 _currentSoundBlock = _soundBlocks[_index];
taylorza 1:9ff7384171ec 102
taylorza 1:9ff7384171ec 103 _stepCounter = _currentSoundBlock.getStepCount();
taylorza 1:9ff7384171ec 104 _stepDurationCounter = _currentSoundBlock.getStepDuration();
taylorza 1:9ff7384171ec 105 _pitchOffset = 0;
taylorza 1:9ff7384171ec 106 _dutyOffset = 0;
taylorza 1:9ff7384171ec 107
taylorza 1:9ff7384171ec 108 updateAudioCounters();
taylorza 1:9ff7384171ec 109 _pitchHighCounter = _basePitchHighCount;
taylorza 1:9ff7384171ec 110 _pitchLowCounter = _basePitchLowCount;
taylorza 1:9ff7384171ec 111
taylorza 1:9ff7384171ec 112 _state = 1;
taylorza 1:9ff7384171ec 113 }
taylorza 1:9ff7384171ec 114
taylorza 1:9ff7384171ec 115 bool SoundChannel::updateCounters()
taylorza 1:9ff7384171ec 116 {
taylorza 1:9ff7384171ec 117 --_stepDurationCounter;
taylorza 1:9ff7384171ec 118 if (_stepDurationCounter == 0)
taylorza 1:9ff7384171ec 119 {
taylorza 1:9ff7384171ec 120 --_stepCounter;
taylorza 1:9ff7384171ec 121 if (_stepCounter == 0)
taylorza 1:9ff7384171ec 122 {
taylorza 1:9ff7384171ec 123 ++_index;
taylorza 1:9ff7384171ec 124 if (_index == _count)
taylorza 1:9ff7384171ec 125 {
taylorza 1:9ff7384171ec 126 _state = 3;
taylorza 1:9ff7384171ec 127 return false;
taylorza 1:9ff7384171ec 128 }
taylorza 1:9ff7384171ec 129 else
taylorza 1:9ff7384171ec 130 {
taylorza 1:9ff7384171ec 131 _state = 0;
taylorza 1:9ff7384171ec 132 }
taylorza 1:9ff7384171ec 133 }
taylorza 1:9ff7384171ec 134 else
taylorza 1:9ff7384171ec 135 {
taylorza 1:9ff7384171ec 136 fix16_t pitchSlide = _currentSoundBlock.getPitchSlide();
taylorza 1:9ff7384171ec 137 int8_t dutySlide = _currentSoundBlock.getDutySlide();
taylorza 1:9ff7384171ec 138 if ( pitchSlide != 0 || dutySlide != 0)
taylorza 1:9ff7384171ec 139 {
taylorza 1:9ff7384171ec 140 _pitchOffset += pitchSlide;
taylorza 1:9ff7384171ec 141 _dutyOffset += dutySlide;
taylorza 1:9ff7384171ec 142 updateAudioCounters();
taylorza 1:9ff7384171ec 143 }
taylorza 1:9ff7384171ec 144
taylorza 1:9ff7384171ec 145 _stepDurationCounter = _currentSoundBlock.getStepDuration();
taylorza 1:9ff7384171ec 146 }
taylorza 1:9ff7384171ec 147 }
taylorza 1:9ff7384171ec 148 return true;
taylorza 1:9ff7384171ec 149 }
taylorza 1:9ff7384171ec 150
taylorza 1:9ff7384171ec 151 void SoundChannel::updateAudioCounters()
taylorza 1:9ff7384171ec 152 {
taylorza 1:9ff7384171ec 153 fix16_t pitch = _currentSoundBlock.getPitch(_pitchOffset);
taylorza 1:9ff7384171ec 154 if (pitch == 0) pitch = fix16_one;
taylorza 1:9ff7384171ec 155
taylorza 1:9ff7384171ec 156 if (_currentSoundBlock.getToneType() == SoundBlock::Noise)
taylorza 1:9ff7384171ec 157 pitch = fix16_div(pitch, fix16_100);
taylorza 1:9ff7384171ec 158
taylorza 1:9ff7384171ec 159 _basePitchHighCount = fix16_mul(pitch, g_dutyLookup[_currentSoundBlock.getDuty(_dutyOffset)]);
taylorza 1:9ff7384171ec 160 _basePitchLowCount = pitch - _basePitchHighCount;
taylorza 1:9ff7384171ec 161 }
taylorza 1:9ff7384171ec 162
taylorza 1:9ff7384171ec 163 uint16_t SoundChannel::lfsr_rand()
taylorza 1:9ff7384171ec 164 {
taylorza 1:9ff7384171ec 165 static uint16_t lfsr = 0xACE1u;
taylorza 1:9ff7384171ec 166 lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xB400u);
taylorza 1:9ff7384171ec 167 return lfsr;
taylorza 1:9ff7384171ec 168 }