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 Feb 08 01:38:18 2015 +0000
Revision:
4:b857db213f10
Parent:
1:9ff7384171ec
Removed duty lookup table

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