Race around the city collecting the flags while avoiding those that stand in the way of your mission. Make no mistake you will need to be quick to outwit your opponents, they are smart and will try to box you in. I wrote this game to prove that writing a game with scrolling scenery is possible even with the limited 6kB of RAM available. I had to compromise sound effects for features, I wanted multiple opponents, I wanted to be able to drop smoke bombs to trap the opponents but all this required memory so the sound effects had to take a back seat.

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
taylorza
Date:
Sun Feb 01 00:43:25 2015 +0000
Parent:
0:d85c449aca6d
Commit message:
Minor updates

Changed in this revision

Beeper.cpp Show annotated file Show diff for this revision Revisions of this file
Beeper.h Show annotated file Show diff for this revision Revisions of this file
Constants.h Show annotated file Show diff for this revision Revisions of this file
Enemy.h Show annotated file Show diff for this revision Revisions of this file
GameEngine/GameEngine.h Show annotated file Show diff for this revision Revisions of this file
GameEngine/GameObject.cpp Show annotated file Show diff for this revision Revisions of this file
GameEngine/GameObject.h Show annotated file Show diff for this revision Revisions of this file
GameScreen.h Show annotated file Show diff for this revision Revisions of this file
OneBitSound/OneBitSound.cpp Show diff for this revision Revisions of this file
OneBitSound/OneBitSound.h Show diff for this revision Revisions of this file
OneBitSound/SoundBlock.cpp Show diff for this revision Revisions of this file
OneBitSound/SoundBlock.h Show diff for this revision Revisions of this file
OneBitSound/SoundChannel.cpp Show diff for this revision Revisions of this file
OneBitSound/SoundChannel.h Show diff for this revision Revisions of this file
OneBitSound/lookupTables.h Show diff for this revision Revisions of this file
Player.h Show annotated file Show diff for this revision Revisions of this file
RallyCar.h Show annotated file Show diff for this revision Revisions of this file
Smoke.h Show annotated file Show diff for this revision Revisions of this file
SpriteSheet.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r d85c449aca6d -r 1b8125937f28 Beeper.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Beeper.cpp	Sun Feb 01 00:43:25 2015 +0000
@@ -0,0 +1,27 @@
+#include "Beeper.h"
+
+DigitalOut Beeper::_speaker(P0_18);
+
+void Beeper::beep(int freq, int ms)
+{
+    float delay = 1.0f / (float)freq;
+    float duration = (float)ms / 1000.0f;
+    while (duration > 0)
+    {
+        _speaker = !_speaker;        
+        wait(delay);
+        duration -= delay;
+    }
+}
+
+void Beeper::noise(int freq, int ms)
+{
+    float delay = 1.0f / (float)freq;
+    float duration = (float)ms / 1000.0f;
+    while (duration > 0)
+    {
+        _speaker = lfsr_rand() & 0x01;
+        wait(delay);
+        duration -= delay;
+    }
+}
\ No newline at end of file
diff -r d85c449aca6d -r 1b8125937f28 Beeper.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Beeper.h	Sun Feb 01 00:43:25 2015 +0000
@@ -0,0 +1,22 @@
+#include "mbed.h"
+
+#ifndef __BEEPER_H__
+#define __BEEPER_H__
+class Beeper
+{
+public:    
+    static void beep(int freq, int duration);
+    static void noise(int freq, int duration);
+    
+private:
+    static uint16_t lfsr_rand()
+    {
+        static uint16_t lfsr = 0xACE1u;
+        lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xB400u);
+        return lfsr;
+    }
+    
+private:
+    static DigitalOut _speaker;
+};
+#endif //__BEEPER_H__
\ No newline at end of file
diff -r d85c449aca6d -r 1b8125937f28 Constants.h
--- a/Constants.h	Wed Jan 28 03:26:07 2015 +0000
+++ b/Constants.h	Sun Feb 01 00:43:25 2015 +0000
@@ -3,6 +3,7 @@
 #ifndef __CONSTANTS_H__
 #define __CONSTANTS_H__
 
+#define MAX_LIVES       3
 #define MAX_SMOKE       5
 #define MAX_CARS        4
 #define MAX_FLAGS       5
diff -r d85c449aca6d -r 1b8125937f28 Enemy.h
--- a/Enemy.h	Wed Jan 28 03:26:07 2015 +0000
+++ b/Enemy.h	Sun Feb 01 00:43:25 2015 +0000
@@ -35,7 +35,7 @@
         
         _actionCounter = 0;
         
-        _startCount = 90;
+        _startCount = 120;
         _scatterCount = 210;
         _chaseCount = 600;
     }
@@ -43,7 +43,7 @@
     virtual void update()
     {        
         ++_actionCounter;
-           
+        
         Point &position = getPosition();
         
         bool allowLeftRightTurn = position.Y % 8 == 0;
@@ -96,7 +96,12 @@
                         }              
                         
                         Direction direction = hunt(target);  
-                        setDesiredDirection(direction);
+                        if (getDesiredDirection() != direction)
+                        {
+                            setDesiredDirection(direction);
+                            // Slow enemy down when they change direction
+                            return;
+                        }
                     }
                     break;
                 
@@ -111,7 +116,7 @@
                     || (getDesiredDirection() == Up && allowUpDownTurn && canGoUp())
                     || (getDesiredDirection() == Down && allowUpDownTurn && canGoDown()))
                     {
-                         setDirection(getDesiredDirection());                         
+                         setDirection(getDesiredDirection());                              
                     }                
                 }
             
diff -r d85c449aca6d -r 1b8125937f28 GameEngine/GameEngine.h
--- a/GameEngine/GameEngine.h	Wed Jan 28 03:26:07 2015 +0000
+++ b/GameEngine/GameEngine.h	Sun Feb 01 00:43:25 2015 +0000
@@ -6,14 +6,12 @@
 #include "LCD_ST7735.h"
 #include "Color565.h"
 #include "font_IBM.h"
-#include "OneBitSound.h"
 #include "Game.h"
 #include "GameInput.h"
 #include "ImageFrame.h"
 #include "Block.h"
 #include "Sprite.h"
 #include "Fix16.h"
-#include "SoundBlock.h"
 #include "TileViewer.h"
 
 
diff -r d85c449aca6d -r 1b8125937f28 GameEngine/GameObject.cpp
--- a/GameEngine/GameObject.cpp	Wed Jan 28 03:26:07 2015 +0000
+++ b/GameEngine/GameObject.cpp	Sun Feb 01 00:43:25 2015 +0000
@@ -12,7 +12,7 @@
     
 }
 
-void GameObject::setPosition(Point position)
+void GameObject::setPosition(const Point &position)
 {
     _position = position;
 }
diff -r d85c449aca6d -r 1b8125937f28 GameEngine/GameObject.h
--- a/GameEngine/GameObject.h	Wed Jan 28 03:26:07 2015 +0000
+++ b/GameEngine/GameObject.h	Sun Feb 01 00:43:25 2015 +0000
@@ -12,7 +12,7 @@
     GameObject();
 
 public: 
-    void setPosition(Point position);
+    void setPosition(const Point &position);
     void setSpriteId(uint8_t spriteId);
     void setSpeed(uint8_t speed);
     void setCollisionRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h);
diff -r d85c449aca6d -r 1b8125937f28 GameScreen.h
--- a/GameScreen.h	Wed Jan 28 03:26:07 2015 +0000
+++ b/GameScreen.h	Sun Feb 01 00:43:25 2015 +0000
@@ -5,14 +5,13 @@
 #include "Flag.h"
 #include "Enemy.h"
 #include "Player.h"
+#include "Beeper.h"
 
 #ifndef __GAMESCREEN_H__
 #define __GAMESCREEN_H__
 
 class GameScreen;
 
-GameScreen* GameScreenInstance;
-
 class GameScreen : public TileViewer
 {
 public: 
@@ -21,9 +20,10 @@
         _enemy1(Point(64, 464), Point(16, -32), Point(8, 8), _player),
         _enemy2(Point(88, 464), Point(1024, -32), Point(32, 32), _player),
         _enemy3(Point(112, 464), Point(16, 1024), Point(-32, -32), _player),
-        _radarBitmap(48, 64),
+        _radarBitmap(46, 62),
         _radarCanvas(&_radarBitmap),
-        _updateCounter(0)
+        _updateCounter(0),
+        _gameOver(false)
     {
         Game::Surface.setForegroundColor(Color565::White);
         Game::Surface.setBackgroundColor(HUD_BACKGROUND);
@@ -34,8 +34,23 @@
         _cars[1] = &_enemy1;
         _cars[2] = &_enemy2;
         _cars[3] = &_enemy3;
-                
+                        
+        placeFlags();        
+        
+        _player.setPosition(Point(184, 400));
+        _player.setCars(_cars);
+        _player.setFlags(_flags);
         
+        addGameObject(&_enemy1);    
+        addGameObject(&_enemy2);    
+        addGameObject(&_enemy3);    
+        addGameObject(&_player);    
+        
+        track(&_player);               
+    }
+    
+    void placeFlags()
+    {
         for(int i = 0; i < MAX_FLAGS; ++i)
         {
             int x = 0;
@@ -49,64 +64,118 @@
                 if (&block1 == &blocks[0]) break;
             }
             
+            _flags[i].setActive(true);
             _flags[i].setPosition(Point(x * 8, y * 8));
             addGameObject(&_flags[i]);
-        }            
-        
-        _player.setPosition(Point(64, 400));
-        _player.setCars(_cars);
-        _player.setFlags(_flags);
-        
-        addGameObject(&_enemy1);    
-        addGameObject(&_enemy2);    
-        addGameObject(&_enemy3);    
-        addGameObject(&_player);    
-        
-        track(&_player);    
+        }    
     }
-    
+
     virtual void update()
     {        
         if (_player.getLives() > 0)
         {
-            TileViewer::update();  
+            if (_player.getFlagCount() == MAX_FLAGS)
+            {                
+                if(_player.getFuel() > 0)
+                {                    
+                    _player.decreaseFuel();
+                    _player.increaseScore(10);
+                    Beeper::beep(400 + (100 - _player.getFuel()) * 2, 5);                    
+                }
+                else
+                {
+                    placeFlags();
+                    
+                    for (int i = 0; i < MAX_CARS; ++i)
+                    {
+                        _cars[i]->reset();
+                    }
+                }
+            }
+            else
+            {
+                TileViewer::update();  
+            }
         }
         else
         {
-            // Game Over
+            _gameOver = true;            
         }
     }
     
     virtual void draw()
     {
-        TileViewer::draw();  
-        
-        if (_updateCounter++ % 8 == 0)
+        if (!_gameOver)
         {
-            Game::Surface.drawBitmap(108, 16, getRadarBitmap(), 0, 0, 48, 64);
+            TileViewer::draw();                          
+        }
+        else
+        {
+            Game::Surface.setForegroundColor(Color565::Red);
+            Game::Surface.setBackgroundColor(Color565::Black);
+            Game::Surface.drawString(font_ibm, 18, 60, "GAME OVER");
         }
         
-        //char buffer[10];
-        
-        //sprintf(buffer, "%d", _player.getScore());
-        //Game::Surface.drawString(font_ibm, 108, 4, buffer);
-        
-        //sprintf(buffer, "%d", _player.getLives());
-        //Game::Surface.drawString(font_ibm, 108, 100, buffer);
+        // Update HUD
+        if (_updateCounter++ % 8 == 0)
+        {
+            Game::Surface.drawBitmap(109, 17, getRadarBitmap(), 0, 0, 46, 62);                
         
-        // Render fuel
-        uint8_t limit = (uint8_t)(((float)_player.getFuel() / 100) * 48);        
-        //sprintf(buffer, "%d", limit);
-        //Game::Surface.drawString(font_ibm, 108, 100, buffer);
-        
-        uint16_t fuelColor = limit < 15 ? Color565::Red : Color565::Yellow;
-        Game::Surface.fillRect(108, 90, 108, 94, fuelColor, fuelColor);
-        Game::Surface.fillRect(108, 84, 108 + limit, 90, fuelColor);
-        Game::Surface.fillRect(108 + limit + 1, 84, 160, 90, HUD_BACKGROUND);
+            char buffer[10];
+            Game::Surface.setForegroundColor(Color565::Aqua);
+            Game::Surface.setBackgroundColor(HUD_BACKGROUND);                
+            sprintf(buffer, "%d", _player.getScore());
+            Game::Surface.drawString(font_ibm, 108, 4, buffer);
+            
+            // Render lives
+            for (int i = 0; i < _player.getLives(); ++i)
+            {
+                Game::Surface.drawBitmap(108 + i * 8, 100, spriteSheet, 56, 32, 8, 8);
+            }
+            
+            for (int i = _player.getLives(); i < MAX_LIVES; ++i)
+            {
+                Game::Surface.fillRect(108 + i * 8, 100, (108 + i * 8) + 8, 108, HUD_BACKGROUND);
+            }
+            
+            // Render fuel
+            uint8_t limit = (uint8_t)(((float)_player.getFuel() / 100) * 48);        
+                        
+            uint16_t fuelColor = limit < 15 ? Color565::Red : Color565::Yellow;
+            Game::Surface.fillRect(108, 84, 108 + limit, 90, fuelColor);
+            Game::Surface.fillRect(108 + limit + 1, 84, 160, 90, HUD_BACKGROUND);
+            
+            // Fuel ticks
+            Game::Surface.drawLine(108, 92, 114, 92, Color565::Red);
+            Game::Surface.drawLine(108, 92, 108, 94, Color565::Red);
+            Game::Surface.drawLine(114, 92, 114, 94, Color565::Red);
+            
+            
+            Game::Surface.drawLine(115, 92, 156, 92, Color565::Yellow);
+            for (int i = 12; i <= 48; i += 6)
+            {
+                Game::Surface.drawLine(108 + i, 92, 108 + i, 94, Color565::Yellow);
+            }
+        }
     }
     
     inline RallyCar** getCars() { return _cars; } 
     
+    void drawEntity(int16_t x, int16_t y, uint16_t color)
+    {
+        _radarCanvas.setPixel(x - 1, y - 1, color);
+        _radarCanvas.setPixel(x, y - 1, color);
+        _radarCanvas.setPixel(x + 1, y - 1, color);
+        
+        _radarCanvas.setPixel(x - 1, y, color);
+        _radarCanvas.setPixel(x, y, color);
+        _radarCanvas.setPixel(x + 1, y, color);
+        
+        _radarCanvas.setPixel(x - 1, y + 1, color);
+        _radarCanvas.setPixel(x, y + 1, color);
+        _radarCanvas.setPixel(x + 1, y + 1, color);
+    }
+    
     Bitmap2bpp& getRadarBitmap() 
     { 
         _radarCanvas.clear();        
@@ -116,14 +185,14 @@
             Flag &flag = _flags[i];
             if (flag.getActive())
             {
-                _radarCanvas.setPixel(flag.getPosition().X / 8, flag.getPosition().Y / 8, 3);                
+                drawEntity(flag.getPosition().X / 8, flag.getPosition().Y / 8, 3);                
             }
         }
         
-        _radarCanvas.setPixel(_enemy1.getPosition().X / 8, _enemy1.getPosition().Y / 8, 2);
-        _radarCanvas.setPixel(_enemy2.getPosition().X / 8, _enemy2.getPosition().Y / 8, 2);
-        _radarCanvas.setPixel(_enemy3.getPosition().X / 8, _enemy3.getPosition().Y / 8, 2);
-        _radarCanvas.setPixel(_player.getPosition().X / 8, _player.getPosition().Y / 8, 1);        
+        drawEntity(_enemy1.getPosition().X / 8, _enemy1.getPosition().Y / 8, 2);
+        drawEntity(_enemy2.getPosition().X / 8, _enemy2.getPosition().Y / 8, 2);
+        drawEntity(_enemy3.getPosition().X / 8, _enemy3.getPosition().Y / 8, 2);
+        drawEntity(_player.getPosition().X / 8, _player.getPosition().Y / 8, 1);        
 
         return _radarBitmap; 
     }
@@ -141,5 +210,6 @@
     Canvas<Bitmap2bpp>  _radarCanvas;    
     
     uint8_t     _updateCounter;
+    bool        _gameOver;
 };
 #endif //__GAMESCREEN_H__
\ No newline at end of file
diff -r d85c449aca6d -r 1b8125937f28 OneBitSound/OneBitSound.cpp
--- a/OneBitSound/OneBitSound.cpp	Wed Jan 28 03:26:07 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-#include "mbed.h"
-#include "OneBitSound.h"
-
-OneBitSound::OneBitSound(PinName pin) :
-    _soundPin(pin)
-{
-    _lastPinState = _soundPin;
-    _totalElapsed = 0;
-    
-    _ticker.attach_us(this, &OneBitSound::update, 32);
-}
-
-void OneBitSound::play(uint8_t channel, const SoundBlock soundBlocks[], int count)
-{    
-    _channels[channel].play(soundBlocks, count);
-    
-    bool nextState;
-    bool updated = false;
-    uint32_t bit = _soundPin;
-    if (_channels[channel].update(nextState)) { bit = (updated ? bit ^ nextState : nextState); updated = true; }    
-    if (updated) _soundPin = bit;
-}
-
-void OneBitSound::update()
-{    
-    uint32_t bit = 0;
-    bool nextState = false;        
-    bool updated = false;
-    
-    if (_channels[0].update(nextState)) { bit = (updated ? bit ^ nextState : nextState); updated = true; }
-    if (_channels[1].update(nextState)) { bit = (updated ? bit ^ nextState : nextState); updated = true; }
-    if (_channels[2].update(nextState)) { bit = (updated ? bit ^ nextState : nextState); updated = true; }
-    if (_channels[3].update(nextState)) { bit = (updated ? bit ^ nextState : nextState); updated = true; }
-    
-    if (updated) _soundPin = bit;
-}
-
-
diff -r d85c449aca6d -r 1b8125937f28 OneBitSound/OneBitSound.h
--- a/OneBitSound/OneBitSound.h	Wed Jan 28 03:26:07 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-#include "Fix16.h"
-#include "SoundBlock.h"
-#include "SoundChannel.h"
-
-#ifndef __ONEBITSOUND_H__
-#define __ONEBITSOUND_H__
-class OneBitSound
-{
-    public:
-        OneBitSound(PinName pin);
-        
-        void play(uint8_t channel, const SoundBlock soundBlocks[], int count);
-    
-    private:
-        void update();
-        
-    private:
-        DigitalOut      _soundPin;
-        bool            _lastPinState;
-        SoundChannel    _channels[4];
-        int             _totalElapsed;
-        
-        Ticker          _ticker;
-};
-#endif //__ONEBITSOUND_H__
\ No newline at end of file
diff -r d85c449aca6d -r 1b8125937f28 OneBitSound/SoundBlock.cpp
--- a/OneBitSound/SoundBlock.cpp	Wed Jan 28 03:26:07 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-#include "mbed.h"
-#include "Fix16.h"
-#include "SoundBlock.h"
-
-SoundBlock::SoundBlock(ToneType toneType, uint16_t stepCount, uint16_t stepDuration, uint16_t pitch, int16_t pitchSlide, uint8_t duty, int8_t dutySlide)    
-{
-    initialize(toneType, stepCount, stepDuration, pitch, pitchSlide, duty, dutySlide);
-}
-
-SoundBlock::SoundBlock(ToneType toneType, uint16_t stepCount, uint16_t stepDuration)    
-{
-    initialize(toneType, stepCount, stepDuration, 0, 0, 128, 0);
-}
-
-SoundBlock::SoundBlock() {}
-
-void SoundBlock::initialize(ToneType toneType, uint16_t stepCount, uint16_t stepDuration, uint16_t pitch, int16_t pitchSlide, uint8_t duty, int8_t dutySlide)
-{
-    _toneType = toneType;
-    
-    _stepCount = stepCount;
-    _stepDuration = stepDuration;
-    _pitch = fix16_from(pitch);
-    _pitchSlide = fix16_from(pitchSlide);
-    _duty = duty;
-    _dutySlide = dutySlide;
-}
-
diff -r d85c449aca6d -r 1b8125937f28 OneBitSound/SoundBlock.h
--- a/OneBitSound/SoundBlock.h	Wed Jan 28 03:26:07 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-#ifndef __SOUNDBLOCK_H__
-#define __SOUNDBLOCK_H__
-
-#define US_PER_BIT  32
-
-// Fix16 representation of 1000000/32
-#define FREQ_NUMERATOR 0x7a120000
-
-
-// Fix16 representation of 1000000/24
-//#define FREQ_NUMERATOR 0xa2c20000
-
-#define TONE(stepCount, stepDuration, pitch, pitchSlide, duty, dutySlide) SoundBlock(SoundBlock::Tone, stepCount, stepDuration, pitch, pitchSlide, duty, dutySlide)
-#define NOISE(stepCount, stepDuration, pitch, pitchSlide) SoundBlock(SoundBlock::Noise, stepCount, stepDuration, pitch, pitchSlide, 128, 0)
-#define PAUSE(stepCount, stepDuration) SoundBlock(SoundBlock::Pause, stepCount, stepDuration, 0, 0, 0, 0)
-
-#define CREATE_EFFECT(name) \
-static const SoundBlock name[] = \
-{ \
-
-#define END_EFFECT \
-};
-
-#define EFFECT(name) name, sizeof(name)/sizeof(SoundBlock)
-
-class SoundChannel;
-
-class SoundBlock
-{
-    public:
-        enum ToneType {Tone, Noise, Pause};
-        
-    public:
-        SoundBlock(ToneType toneType, uint16_t stepCount, uint16_t stepDuration, uint16_t pitch, int16_t pitchSlide, uint8_t duty, int8_t dutySlide);
-        SoundBlock(ToneType toneType, uint16_t stepCount, uint16_t stepDuration);
-        
-    protected:
-        SoundBlock();
-    
-    private:
-        void initialize(ToneType toneType, uint16_t stepCount, uint16_t stepDuration, uint16_t pitch, int16_t pitchSlide, uint8_t duty, int8_t dutySlide);
-        
-    protected:
-        inline ToneType getToneType() { return _toneType; }
-        inline uint16_t getStepCount() { return _stepCount; }
-        inline uint16_t getStepDuration() { return _stepDuration; }
-        inline fix16_t getPitch(fix16_t offset) { return fix16_div(FREQ_NUMERATOR, _pitch + offset); }
-        inline fix16_t getPitchSlide() {return _pitchSlide; }
-        inline uint8_t getDuty(int8_t offset) { return (uint8_t)(_duty + offset); }
-        inline int8_t getDutySlide() { return _dutySlide; }
-        
-    private:
-        ToneType    _toneType;
-        uint16_t    _stepCount;
-        uint16_t    _stepDuration;
-        fix16_t     _pitch;
-        fix16_t     _pitchSlide;
-        uint8_t     _duty;
-        int8_t      _dutySlide;
-        
-    friend class SoundChannel;
-};
-#endif //__SOUNDBLOCK_H__
-
-
diff -r d85c449aca6d -r 1b8125937f28 OneBitSound/SoundChannel.cpp
--- a/OneBitSound/SoundChannel.cpp	Wed Jan 28 03:26:07 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-#include "mbed.h"
-#include "Fix16.h"
-#include "lookupTables.h"
-#include "SoundBlock.h"
-#include "SoundChannel.h"
-
-SoundChannel::SoundChannel() :
-    _state(4)
-{
-}
-
-void SoundChannel::play(const SoundBlock soundBlocks[], int count)
-{
-    _soundBlocks = soundBlocks;
-    _count = count;    
-    _index = 0;   
-    _state = 0;   
-}
-
-bool SoundChannel::update(bool &pinState)
-{
-    switch(_state)
-    {
-        case 0 :
-            startSoundBlock();
-            break;
-        
-        case 3 : // Stop sound
-            pinState = _pinState = false;
-            _state = 4;
-            return true;
-        
-        case 4 : // No sound
-            return false;
-    }
-
-    if (updateCounters())
-    {
-        switch(_currentSoundBlock.getToneType())
-        {
-            case SoundBlock::Tone  : updateTone(); pinState = _pinState; return true;
-            case SoundBlock::Noise : updateNoise(); pinState = _pinState; return true;
-            case SoundBlock::Pause : return false;
-        }
-    }
-    
-    return false;
-}
-
-void SoundChannel::updateTone()
-{
-    switch(_state)
-    {
-        case 1: // High
-        {
-            _pinState = true;
-            _pitchHighCounter -= fix16_one;
-            if (_pitchHighCounter <= 0)
-            {            
-                _pinState = false;
-                _pitchHighCounter += _basePitchHighCount;
-                _state = 2;
-            }
-        }
-        break;
-            
-        case 2: // Low
-        {
-            _pinState = false;
-            _pitchLowCounter -= fix16_one;
-            if (_pitchLowCounter <= 0)
-            {
-                _pinState = true;
-                _pitchLowCounter += _basePitchLowCount;
-                _state = 1;
-            }
-        }
-        break;
-    }    
-}
-
-void SoundChannel::updateNoise()
-{
-    switch(_state)
-    {
-        case 1: // High/Low        
-        {   
-            _pitchHighCounter -= fix16_one;
-            if (_pitchHighCounter <= 0)
-            {            
-                _pinState = (SoundChannel::lfsr_rand() & 1) == 1;
-                _pitchHighCounter += _basePitchHighCount;                
-            }
-        }
-        break;
-    }    
-}
-
-void SoundChannel::startSoundBlock()
-{
-    _currentSoundBlock = _soundBlocks[_index];
-            
-    _stepCounter = _currentSoundBlock.getStepCount();
-    _stepDurationCounter = _currentSoundBlock.getStepDuration();
-    _pitchOffset = 0;
-    _dutyOffset = 0;
-    
-    updateAudioCounters();
-    _pitchHighCounter = _basePitchHighCount;
-    _pitchLowCounter = _basePitchLowCount;
-    
-    _state = 1;
-}
-
-bool SoundChannel::updateCounters()
-{
-    --_stepDurationCounter;
-    if (_stepDurationCounter == 0)
-    {    
-        --_stepCounter;
-        if (_stepCounter == 0)
-        {                                
-            ++_index;
-            if (_index == _count)
-            {                    
-                _state = 3;
-                return false;
-            }
-            else
-            {
-                _state = 0;
-            }
-        }                        
-        else
-        {  
-            fix16_t pitchSlide = _currentSoundBlock.getPitchSlide();
-            int8_t dutySlide = _currentSoundBlock.getDutySlide();
-            if ( pitchSlide != 0 || dutySlide != 0)
-            {
-                _pitchOffset += pitchSlide;
-                _dutyOffset += dutySlide;
-                updateAudioCounters();
-            }
-        
-            _stepDurationCounter = _currentSoundBlock.getStepDuration();
-        }
-    }
-    return true;
-}
-
-void SoundChannel::updateAudioCounters()
-{
-    fix16_t pitch = _currentSoundBlock.getPitch(_pitchOffset);
-    if (pitch == 0) pitch = fix16_one;
-    
-    if (_currentSoundBlock.getToneType() == SoundBlock::Noise)
-        pitch = fix16_div(pitch, fix16_100);
-        
-    _basePitchHighCount = fix16_mul(pitch, g_dutyLookup[_currentSoundBlock.getDuty(_dutyOffset)]);
-    _basePitchLowCount = pitch - _basePitchHighCount;    
-}
-
-uint16_t SoundChannel::lfsr_rand()
-{
-    static uint16_t lfsr = 0xACE1u;
-    lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xB400u);
-    return lfsr;
-}
diff -r d85c449aca6d -r 1b8125937f28 OneBitSound/SoundChannel.h
--- a/OneBitSound/SoundChannel.h	Wed Jan 28 03:26:07 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-#ifndef __SOUNDCHANNEL_H__
-#define __SOUNDCHANNEL_H__
-class SoundChannel
-{   
-public: 
-    SoundChannel();
-    
-    protected:
-        void play(const SoundBlock soundBlocks[], int count);
-        bool update(bool &pinState);            
-    
-    private:
-        void updateTone();
-        void updateNoise();
-        
-        void startSoundBlock();
-        bool updateCounters();
-        void updateAudioCounters();
-        
-        static uint16_t lfsr_rand();
-        
-    private:
-        int         _state;
-        uint16_t    _stepCounter;
-        uint16_t    _stepDurationCounter;
-        fix16_t     _basePitchHighCount;
-        fix16_t     _basePitchLowCount;
-        fix16_t     _pitchHighCounter;
-        fix16_t     _pitchLowCounter;
-        fix16_t     _pitchOffset;
-        fix16_t     _dutyOffset;
-        
-        const SoundBlock *_soundBlocks;        
-        int         _count;
-        int         _index;  
-        bool        _pinState;
-        
-        SoundBlock  _currentSoundBlock;
-        
-    friend class OneBitSound;           
-};
-#endif //__SOUNDCHANNEL_H__
\ No newline at end of file
diff -r d85c449aca6d -r 1b8125937f28 OneBitSound/lookupTables.h
--- a/OneBitSound/lookupTables.h	Wed Jan 28 03:26:07 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-static const fix16_t g_dutyLookup[] = 
-{
-    0x0,0x100,0x200,0x300,0x400,0x500,0x600,0x700,0x800,0x900,0xa00,0xb00,0xc00,0xd00,0xe00,0xf00,
-    0x1000,0x1100,0x1200,0x1300,0x1400,0x1500,0x1600,0x1700,0x1800,0x1900,0x1a00,0x1b00,0x1c00,0x1d00,0x1e00,0x1f00,
-    0x2000,0x2100,0x2200,0x2300,0x2400,0x2500,0x2600,0x2700,0x2800,0x2900,0x2a00,0x2b00,0x2c00,0x2d00,0x2e00,0x2f00,
-    0x3000,0x3100,0x3200,0x3300,0x3400,0x3500,0x3600,0x3700,0x3800,0x3900,0x3a00,0x3b00,0x3c00,0x3d00,0x3e00,0x3f00,
-    0x4000,0x4100,0x4200,0x4300,0x4400,0x4500,0x4600,0x4700,0x4800,0x4900,0x4a00,0x4b00,0x4c00,0x4d00,0x4e00,0x4f00,
-    0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600,0x5700,0x5800,0x5900,0x5a00,0x5b00,0x5c00,0x5d00,0x5e00,0x5f00,
-    0x6000,0x6100,0x6200,0x6300,0x6400,0x6500,0x6600,0x6700,0x6800,0x6900,0x6a00,0x6b00,0x6c00,0x6d00,0x6e00,0x6f00,
-    0x7000,0x7100,0x7200,0x7300,0x7400,0x7500,0x7600,0x7700,0x7800,0x7900,0x7a00,0x7b00,0x7c00,0x7d00,0x7e00,0x7f00,
-    0x8000,0x8100,0x8200,0x8300,0x8400,0x8500,0x8600,0x8700,0x8800,0x8900,0x8a00,0x8b00,0x8c00,0x8d00,0x8e00,0x8f00,
-    0x9000,0x9100,0x9200,0x9300,0x9400,0x9500,0x9600,0x9700,0x9800,0x9900,0x9a00,0x9b00,0x9c00,0x9d00,0x9e00,0x9f00,
-    0xa000,0xa100,0xa200,0xa300,0xa400,0xa500,0xa600,0xa700,0xa800,0xa900,0xaa00,0xab00,0xac00,0xad00,0xae00,0xaf00,
-    0xb000,0xb100,0xb200,0xb300,0xb400,0xb500,0xb600,0xb700,0xb800,0xb900,0xba00,0xbb00,0xbc00,0xbd00,0xbe00,0xbf00,
-    0xc000,0xc100,0xc200,0xc300,0xc400,0xc500,0xc600,0xc700,0xc800,0xc900,0xca00,0xcb00,0xcc00,0xcd00,0xce00,0xcf00,
-    0xd000,0xd100,0xd200,0xd300,0xd400,0xd500,0xd600,0xd700,0xd800,0xd900,0xda00,0xdb00,0xdc00,0xdd00,0xde00,0xdf00,
-    0xe000,0xe100,0xe200,0xe300,0xe400,0xe500,0xe600,0xe700,0xe800,0xe900,0xea00,0xeb00,0xec00,0xed00,0xee00,0xef00,
-    0xf000,0xf100,0xf200,0xf300,0xf400,0xf500,0xf600,0xf700,0xf800,0xf900,0xfa00,0xfb00,0xfc00,0xfd00,0xfe00,0xff00,
-};
\ No newline at end of file
diff -r d85c449aca6d -r 1b8125937f28 Player.h
--- a/Player.h	Wed Jan 28 03:26:07 2015 +0000
+++ b/Player.h	Sun Feb 01 00:43:25 2015 +0000
@@ -2,6 +2,7 @@
 #include "RallyCar.h"
 #include "Flag.h"
 #include "Smoke.h"
+#include "Beeper.h"
 
 #ifndef __PLAYER_H__
 #define __PLAYER_H__
@@ -12,7 +13,7 @@
     Player(Point startPosition) :
         _startPosition(startPosition),
         _smokeIndex(255),
-        _lives(3),
+        _lives(MAX_LIVES),
         _score(0)
     {            
         reset();
@@ -23,10 +24,17 @@
         setPosition(_startPosition);
         setDirection(Up);
         setDesiredDirection(Up);
-        setState(RallyCar::Driving);
+        setState(RallyCar::Idle);
         setSpriteId(4);
         _fuel = 100;   
         _updateCounter = 0;     
+        
+        if (_flagCount == MAX_FLAGS)
+        {
+            _flagCount = 0;
+        }
+        
+        _stateCounter = 60;
     }
     
     void setCars(RallyCar **cars) { _cars = cars; }
@@ -51,7 +59,14 @@
             _smokeIndex = 0;
         }
         
-        if (getState() == RallyCar::Driving)
+        if (getState() == RallyCar::Idle)
+        {
+            if (--_stateCounter == 0)
+            {
+                setState(RallyCar::Driving);
+            }
+        }
+        else if (getState() == RallyCar::Driving)
         {
             ++_updateCounter;
             if (_updateCounter % FUEL_COUNTER == 0) --_fuel;
@@ -133,18 +148,22 @@
                     flag->setActive(false);
                     getParent()->removeGameObject(flag);
                     _score += 100;                    
+                    ++_flagCount;
+                    Beeper::beep(500, 3);                    
+                    Beeper::beep(2000, 4);                    
+                    Beeper::beep(1000, 2);                    
                 }
             }                        
         }
         else if (getState() == RallyCar::StartCrash)
         {
-            _crashCounter = 30;   
+            _stateCounter = 30;   
             setState(RallyCar::Crashed);         
         }
         else if (getState() == RallyCar::Crashed)
         {
-            setSpriteId(10);            
-            if (--_crashCounter == 0)
+            setSpriteId(10);                        
+            if (--_stateCounter == 0)
             {
                 --_lives;
                 for (int i = 0; i < MAX_CARS; ++i)
@@ -152,6 +171,7 @@
                     _cars[i]->reset();
                 }
             }
+            Beeper::noise(2000, 2);
         }
         
         RallyCar::update();
@@ -160,7 +180,10 @@
     inline uint8_t getLives() { return _lives; }
     inline uint32_t getScore() { return _score; }
     inline uint8_t getFuel() { return _fuel; }
-    
+    inline uint8_t getFlagCount() { return _flagCount; }
+
+    inline void decreaseFuel() { if (_fuel > 0) --_fuel; }
+    inline void increaseScore(int score) { _score += score; }    
 private:    
     void smoke(Direction direction)
     {
@@ -211,6 +234,10 @@
             smoke.setActive(true);            
             _smokeIndex = (_smokeIndex + 1) % MAX_SMOKE;
             _fuel -= 2;
+            
+            Beeper::beep(500, 2);
+            Beeper::beep(1000, 3);
+            Beeper::beep(600, 2);
         }
     }
 
@@ -221,11 +248,12 @@
     RallyCar   **_cars;
     Flag       *_flags; 
     Smoke       _smoke[MAX_SMOKE];
-    uint16_t    _crashCounter;
+    uint16_t    _stateCounter;
         
     uint8_t     _lives;
     uint32_t    _score;
     uint8_t     _fuel;
     uint16_t    _updateCounter;
+    uint8_t     _flagCount;
 };
 #endif //__PLAYER_H__
\ No newline at end of file
diff -r d85c449aca6d -r 1b8125937f28 RallyCar.h
--- a/RallyCar.h	Wed Jan 28 03:26:07 2015 +0000
+++ b/RallyCar.h	Sun Feb 01 00:43:25 2015 +0000
@@ -10,7 +10,7 @@
         _desiredDirection(Up),
         _state(Idle)
     {
-        setCollisionRect(2, 2, 12, 12);
+        setCollisionRect(4, 4, 8, 8);
     }
     
     enum Direction { Up, Left, Down, Right, None };
diff -r d85c449aca6d -r 1b8125937f28 Smoke.h
--- a/Smoke.h	Wed Jan 28 03:26:07 2015 +0000
+++ b/Smoke.h	Sun Feb 01 00:43:25 2015 +0000
@@ -50,7 +50,7 @@
                         }            
                     }
                 }
-                _active = false;
+                _active = false;                
             }
         }                        
     }
diff -r d85c449aca6d -r 1b8125937f28 SpriteSheet.h
--- a/SpriteSheet.h	Wed Jan 28 03:26:07 2015 +0000
+++ b/SpriteSheet.h	Sun Feb 01 00:43:25 2015 +0000
@@ -34,14 +34,14 @@
     0x01, 0x45, 0x54, 0x50, 0x05, 0x54, 0x00, 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x15, 0x50, 
     0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-    0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 
-    0x2a, 0x80, 0x20, 0x02, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 
-    0x0b, 0xe0, 0xb8, 0x0a, 0x00, 0x80, 0x20, 0x08, 0x00, 0x00, 0x20, 0x00, 0xff, 0xff, 0x00, 0x00, 
-    0x02, 0xfa, 0xb8, 0x2e, 0x00, 0xb0, 0x30, 0x0c, 0x00, 0x00, 0x20, 0x00, 0xff, 0xff, 0x00, 0x00, 
-    0x02, 0xeb, 0xae, 0xf8, 0x00, 0xa8, 0xae, 0x38, 0x00, 0x28, 0x20, 0x20, 0xff, 0xff, 0x00, 0x00, 
-    0x02, 0xba, 0xaa, 0xa8, 0x00, 0x3a, 0xaa, 0xa0, 0x00, 0x08, 0x28, 0xa0, 0xff, 0xff, 0x00, 0x00, 
-    0x0a, 0xa9, 0xb6, 0xa0, 0x00, 0x09, 0xb6, 0x80, 0x00, 0x0a, 0xa6, 0x80, 0xff, 0xff, 0x00, 0x00, 
-    0xaa, 0xaa, 0xeb, 0xa0, 0x2a, 0xaa, 0xeb, 0x00, 0x02, 0xab, 0xba, 0x00, 0xff, 0xff, 0x00, 0x00, 
+    0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x33, 0x30, 
+    0x2a, 0x80, 0x20, 0x02, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3f, 0xf0, 
+    0x0b, 0xe0, 0xb8, 0x0a, 0x00, 0x80, 0x20, 0x08, 0x00, 0x00, 0x20, 0x00, 0xff, 0xff, 0x33, 0x30, 
+    0x02, 0xfa, 0xb8, 0x2e, 0x00, 0xb0, 0x30, 0x0c, 0x00, 0x00, 0x20, 0x00, 0xff, 0xff, 0x03, 0x00, 
+    0x02, 0xeb, 0xae, 0xf8, 0x00, 0xa8, 0xae, 0x38, 0x00, 0x28, 0x20, 0x20, 0xff, 0xff, 0x0f, 0xc0, 
+    0x02, 0xba, 0xaa, 0xa8, 0x00, 0x3a, 0xaa, 0xa0, 0x00, 0x08, 0x28, 0xa0, 0xff, 0xff, 0xcf, 0xcc, 
+    0x0a, 0xa9, 0xb6, 0xa0, 0x00, 0x09, 0xb6, 0x80, 0x00, 0x0a, 0xa6, 0x80, 0xff, 0xff, 0xff, 0xfc, 
+    0xaa, 0xaa, 0xeb, 0xa0, 0x2a, 0xaa, 0xeb, 0x00, 0x02, 0xab, 0xba, 0x00, 0xff, 0xff, 0xcf, 0xcc, 
     0x0b, 0xbe, 0x6e, 0xaa, 0x0b, 0xbe, 0x6e, 0x80, 0x00, 0x2e, 0x6e, 0x80, 0x03, 0x00, 0x03, 0x00, 
     0x02, 0xaa, 0x9a, 0xee, 0x00, 0x2a, 0x9a, 0xe8, 0x00, 0x09, 0x9a, 0xa0, 0x03, 0xc0, 0x03, 0xf0, 
     0x02, 0xa6, 0xaa, 0xa8, 0x00, 0x26, 0xaa, 0x00, 0x00, 0x2a, 0xa8, 0x00, 0x03, 0xf0, 0x03, 0xfc, 
@@ -67,4 +67,63 @@
     0x03, 0x0c, 0xfc, 0x30, 0x3f, 0x03, 0xc0, 0x00, 0x0f, 0x03, 0xc3, 0x03, 0x2a, 0x00, 0xa8, 0xa0, 
     0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 
 };
+
+
+const static uint8_t titleGraphics[] = {
+    0x88, 0x00,0x35, 0x00,
+    0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 
+    0x00, 0xf8, 0x38, 0x02, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x08, 0x38, 0x00, 0x00, 0x00, 0x00, 
+    0x03, 0xfc, 0x10, 0x02, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, 
+    0x0f, 0xb8, 0x00, 0x02, 0x00, 0x00, 0x00, 0x38, 0x3e, 0x00, 0x00, 0x30, 0x38, 0x00, 0x00, 0x00, 0x00, 
+    0x0f, 0x38, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c, 0x0e, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 
+    0x08, 0x20, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c, 0x0e, 0x00, 0x80, 0x20, 0x30, 0x00, 0x00, 0x00, 0x00, 
+    0x38, 0x00, 0x10, 0x06, 0x04, 0x0c, 0x00, 0x1c, 0x0c, 0x01, 0xe0, 0x60, 0x70, 0x00, 0x60, 0x00, 0x00, 
+    0x38, 0x00, 0x20, 0x7f, 0xfe, 0x0c, 0x00, 0x1c, 0x38, 0x03, 0xe0, 0xe0, 0x70, 0x20, 0x60, 0x00, 0x00, 
+    0x70, 0x00, 0x70, 0xbf, 0xdc, 0x0c, 0x00, 0x1c, 0x78, 0x06, 0x60, 0xe0, 0x60, 0x60, 0x60, 0x00, 0x00, 
+    0x60, 0x00, 0xe0, 0x3c, 0x1c, 0x1c, 0x00, 0x1b, 0xe0, 0x0e, 0x60, 0xe0, 0xe0, 0xe0, 0xe0, 0x00, 0x00, 
+    0x60, 0x03, 0xa0, 0x7c, 0x0c, 0x18, 0x00, 0x19, 0xe0, 0x0c, 0x61, 0xe0, 0xe0, 0x60, 0xc0, 0x00, 0x00, 
+    0xe0, 0x0e, 0x20, 0xf8, 0x0c, 0x38, 0x00, 0x38, 0xf8, 0x08, 0xe2, 0xe0, 0xe0, 0xe3, 0xc0, 0x00, 0x00, 
+    0xe0, 0x1c, 0x21, 0xd8, 0x0c, 0xf0, 0x00, 0x38, 0x1c, 0x19, 0xe6, 0xe3, 0xe1, 0xc7, 0xc0, 0x00, 0x00, 
+    0xe0, 0x38, 0x2f, 0x98, 0x0f, 0xb0, 0x00, 0x38, 0x0e, 0x1b, 0xb8, 0xea, 0xe2, 0xee, 0x80, 0x00, 0x00, 
+    0x71, 0xf0, 0x3f, 0x18, 0x07, 0x30, 0x00, 0x38, 0x07, 0x9f, 0x30, 0x7c, 0x7e, 0x79, 0x80, 0x00, 0x00, 
+    0x3f, 0x80, 0x1c, 0x1b, 0x00, 0x20, 0x00, 0x38, 0x03, 0xee, 0x00, 0x38, 0x38, 0x03, 0x80, 0x00, 0x00, 
+    0x1c, 0x00, 0x00, 0x1e, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 
+    0x00, 0x00, 0x00, 0x0c, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+    0x00, 0x00, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+    0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+    0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0x00, 0x2a, 0xaa, 0xa8, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0xfe, 0x1f, 0x00, 0xc0, 0x00, 0x00, 
+    0x00, 0x05, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x09, 0x73, 0x98, 0xc1, 0xfe, 0x04, 0x61, 0x2e, 0x67, 0x38, 
+    0x2a, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x09, 0x4a, 0x25, 0x21, 0x86, 0x04, 0x91, 0x04, 0x94, 0x90, 
+    0x15, 0x0c, 0x7f, 0x00, 0x10, 0x00, 0x00, 0x09, 0x4a, 0x21, 0x01, 0x86, 0x04, 0x90, 0x84, 0x94, 0x90, 
+    0xaa, 0xa0, 0xa8, 0x80, 0x08, 0x00, 0x00, 0x0e, 0x73, 0x18, 0xc1, 0x86, 0x04, 0x90, 0x44, 0x97, 0x10, 
+    0x07, 0xc0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x52, 0x04, 0x21, 0x86, 0x04, 0x90, 0x24, 0xf5, 0x10, 
+    0xaa, 0x80, 0x82, 0x00, 0x02, 0x00, 0x00, 0x08, 0x4a, 0x25, 0x21, 0xfe, 0x04, 0x91, 0x24, 0x94, 0x90, 
+    0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4b, 0x98, 0xc1, 0xfe, 0x04, 0x60, 0xc4, 0x94, 0x90, 
+    0xaa, 0xa0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0x4f, 0xd0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0xaa, 0xaa, 0xa0, 0x20, 0x02, 0xaa, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0xc7, 0x10, 0x10, 0x30, 0x15, 0xff, 0x00, 0x08, 0x4c, 0x62, 0x78, 0x19, 0x00, 0x83, 0xc0, 0x20, 0x00, 
+    0xa2, 0xaa, 0x2a, 0xaa, 0xaa, 0xaa, 0xa0, 0x09, 0x52, 0x96, 0x40, 0x25, 0x00, 0x01, 0x00, 0x20, 0x00, 
+    0x00, 0x00, 0x7f, 0xf0, 0x7f, 0xc1, 0xf0, 0x0a, 0x42, 0x92, 0x71, 0xa1, 0xcc, 0x91, 0x34, 0xa4, 0xc0, 
+    0xaa, 0x2a, 0xaa, 0xaa, 0xaa, 0x00, 0xa8, 0x0a, 0x44, 0x92, 0x08, 0x21, 0x2a, 0xa1, 0x55, 0x2a, 0xa0, 
+    0x14, 0x01, 0xff, 0x7c, 0x1f, 0x80, 0x5c, 0x09, 0x48, 0x92, 0x48, 0x25, 0x28, 0x91, 0x52, 0x2a, 0x80, 
+    0xa2, 0x2a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x08, 0x5e, 0x67, 0x30, 0x19, 0x28, 0xa1, 0x32, 0x24, 0x80, 
+    0x04, 0x01, 0x7f, 0xff, 0xe7, 0xf9, 0x50, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 
+    0x08, 0x2a, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0x00, 0x00, 0x1f, 0xf0, 0x7d, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0x00, 0xaa, 0xaa, 0xa2, 0x2a, 0xaa, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0x00, 0x00, 0x55, 0x40, 0x34, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0x00, 0x00, 0x2a, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0x00, 0x00, 0x00, 0x45, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0x00, 0x00, 0x00, 0x22, 0x8a, 0x82, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0x00, 0x00, 0x00, 0x01, 0x05, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0x00, 0x00, 0x00, 0x00, 0x8a, 0xaa, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0x00, 0x00, 0x00, 0x04, 0x1f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0x00, 0x00, 0x00, 0x00, 0x2a, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+};
+
 #endif //__SPRITESHEET_H__
\ No newline at end of file
diff -r d85c449aca6d -r 1b8125937f28 main.cpp
--- a/main.cpp	Wed Jan 28 03:26:07 2015 +0000
+++ b/main.cpp	Sun Feb 01 00:43:25 2015 +0000
@@ -4,8 +4,9 @@
 #include "GameEngine.h"
 #include "Assets.h"
 #include "GameScreen.h"
+#include "Beeper.h"
 
-const uint16_t palette[] = 
+static const uint16_t palette[] = 
 {
     Color565::Black,
     Color565::Blue,
@@ -13,42 +14,57 @@
     0xfe20
 };
 
+void showIntro();
+
 GameScreen gameScreen;
 
-char buffer[10];
-Timer timer;
-
-CREATE_EFFECT(Sound_Intro)
-    TONE(1, 10, 329, 0, 128, 0),    
-END_EFFECT
-
-//static OneBitSound g_sound(P0_18);
+//char buffer[10];
+//Timer timer;
 
 main()
 {    
-    GameScreenInstance = &gameScreen;
-    
     Game::Surface.setPalette((uint16_t*)palette);
-    Game::Surface.clearScreen(HUD_BACKGROUND);
+    Game::Surface.clearScreen(0);    
     Game::Surface.setOrientation(LCD_ST7735::Rotate270, false);
     
-//    g_sound.play(0, EFFECT(Sound_Intro));
-            
-    timer.start();
-    int lastTime = timer.read_us();    
-    int updateCounter = 0;    
+    showIntro();
+    
+    Game::Surface.clearScreen(HUD_BACKGROUND);
+    
+  //  timer.start();
+//    int lastTime = timer.read_us();
+    
+//    int updateCounter = 0;    
     while(true)
-    {          
+    {   
         gameScreen.update();        
         gameScreen.draw();
-        
+/*
         int time = timer.read_us();
-        int duration = time - lastTime;
+        int elapsedTime = time - lastTime;
         lastTime = time;
         
-        sprintf(buffer, "%d", duration);
+        sprintf(buffer, "%d", elapsedTime);
         Game::Surface.drawString(font_ibm, 104, 120, buffer);
         
         ++updateCounter;
+*/        
     }     
-}
\ No newline at end of file
+}
+
+void showIntro()
+{
+    // Title
+    Game::Surface.drawBitmap(22, 0, titleGraphics, 0, 0, 115, 22, Color565::Aqua, Color565::Black);
+    
+    // Image
+    Game::Surface.drawBitmap(51, 50, titleGraphics, 0, 24, 57, 29, Color565::Blue, Color565::Black);
+    
+    // Press [] to start
+    Game::Surface.drawBitmap(43, 102, titleGraphics, 60, 24, 73, 8, Color565::White, Color565::Black);
+    
+    // (c)2015
+    Game::Surface.drawBitmap(44, 120, titleGraphics, 60, 34, 71, 8, Color565::White, Color565::Black);
+    
+    while (!GameInput::isSquarePressed());
+}