From 0078e2aeaa20855cf2e822fe954a8b3f703cfcee Mon Sep 17 00:00:00 2001
From: Rtch90 <ritchie.cunningham@protonmail.com>
Date: Fri, 13 Jan 2012 23:34:03 +0000
Subject: [PATCH] [Fix] .gitignore decided not to add recursively add
 /Unuk/srs/libUnuk ...

---
 src/libUnuk/Engine/AStar.cpp           |  92 +++++++++
 src/libUnuk/Engine/AStar.h             |  30 +++
 src/libUnuk/Engine/AStarBase.h         |  26 +++
 src/libUnuk/Engine/Character.cpp       | 204 +++++++++++++++++++
 src/libUnuk/Engine/Character.h         | 117 +++++++++++
 src/libUnuk/Engine/Collision.cpp       |  27 +++
 src/libUnuk/Engine/Collision.h         |   6 +
 src/libUnuk/Engine/MemClass.h          |  32 +++
 src/libUnuk/Engine/MemManager.cpp      | 206 +++++++++++++++++++
 src/libUnuk/Engine/MemManager.h        |  88 ++++++++
 src/libUnuk/Engine/NPC.cpp             |  59 ++++++
 src/libUnuk/Engine/NPC.h               |  26 +++
 src/libUnuk/Engine/ParticleEmitter.cpp |  80 ++++++++
 src/libUnuk/Engine/ParticleEmitter.h   |  52 +++++
 src/libUnuk/Engine/WorldManager.cpp    |  54 +++++
 src/libUnuk/Engine/WorldManager.h      |  20 ++
 src/libUnuk/Map/Map.cpp                | 251 +++++++++++++++++++++++
 src/libUnuk/Map/Map.h                  |  64 ++++++
 src/libUnuk/Map/MapElement.cpp         |  39 ++++
 src/libUnuk/Map/MapElement.h           |  36 ++++
 src/libUnuk/Map/MapEntities.cpp        |  16 ++
 src/libUnuk/Map/MapEntities.h          |  19 ++
 src/libUnuk/Map/MapTile.h              |  66 ++++++
 src/libUnuk/Sprite/ApplySurface.cpp    |  23 +++
 src/libUnuk/Sprite/ApplySurface.h      |  16 ++
 src/libUnuk/Sprite/ImageLoader.cpp     |  37 ++++
 src/libUnuk/Sprite/ImageLoader.h       |   8 +
 src/libUnuk/Sprite/Texture.cpp         |  53 +++++
 src/libUnuk/Sprite/Texture.h           |  33 +++
 src/libUnuk/Sprite/TextureManager.cpp  |  55 +++++
 src/libUnuk/Sprite/TextureManager.h    |  39 ++++
 src/libUnuk/System/Debug.cpp           | 101 ++++++++++
 src/libUnuk/System/Debug.h             |  20 ++
 src/libUnuk/System/FPS.cpp             |  41 ++++
 src/libUnuk/System/FPS.h               |  25 +++
 src/libUnuk/System/Input.cpp           |  82 ++++++++
 src/libUnuk/System/Input.h             |  43 ++++
 src/libUnuk/System/Rect.cpp            |  66 ++++++
 src/libUnuk/System/Rect.h              |  35 ++++
 src/libUnuk/System/Timer.cpp           |  54 +++++
 src/libUnuk/System/Timer.h             |  31 +++
 src/libUnuk/Ui/Button.cpp              | 120 +++++++++++
 src/libUnuk/Ui/Button.h                |  62 ++++++
 src/libUnuk/Ui/ButtonGroup.cpp         | 101 ++++++++++
 src/libUnuk/Ui/ButtonGroup.h           |  33 +++
 src/libUnuk/Ui/ButtonToggle.cpp        |  35 ++++
 src/libUnuk/Ui/ButtonToggle.h          |  36 ++++
 src/libUnuk/Ui/Font.cpp                |  11 +
 src/libUnuk/Ui/Font.h                  |   8 +
 src/libUnuk/Ui/IngameMenu.cpp          |  99 +++++++++
 src/libUnuk/Ui/IngameMenu.h            |  32 +++
 src/libUnuk/Ui/MainMenu.cpp            | 171 ++++++++++++++++
 src/libUnuk/Ui/MainMenu.h              |  37 ++++
 src/libUnuk/Ui/Text.cpp                | 269 +++++++++++++++++++++++++
 src/libUnuk/Ui/Text.h                  |  62 ++++++
 55 files changed, 3448 insertions(+)
 create mode 100644 src/libUnuk/Engine/AStar.cpp
 create mode 100644 src/libUnuk/Engine/AStar.h
 create mode 100644 src/libUnuk/Engine/AStarBase.h
 create mode 100644 src/libUnuk/Engine/Character.cpp
 create mode 100644 src/libUnuk/Engine/Character.h
 create mode 100644 src/libUnuk/Engine/Collision.cpp
 create mode 100644 src/libUnuk/Engine/Collision.h
 create mode 100644 src/libUnuk/Engine/MemClass.h
 create mode 100644 src/libUnuk/Engine/MemManager.cpp
 create mode 100644 src/libUnuk/Engine/MemManager.h
 create mode 100644 src/libUnuk/Engine/NPC.cpp
 create mode 100644 src/libUnuk/Engine/NPC.h
 create mode 100644 src/libUnuk/Engine/ParticleEmitter.cpp
 create mode 100644 src/libUnuk/Engine/ParticleEmitter.h
 create mode 100644 src/libUnuk/Engine/WorldManager.cpp
 create mode 100644 src/libUnuk/Engine/WorldManager.h
 create mode 100644 src/libUnuk/Map/Map.cpp
 create mode 100644 src/libUnuk/Map/Map.h
 create mode 100644 src/libUnuk/Map/MapElement.cpp
 create mode 100644 src/libUnuk/Map/MapElement.h
 create mode 100644 src/libUnuk/Map/MapEntities.cpp
 create mode 100644 src/libUnuk/Map/MapEntities.h
 create mode 100644 src/libUnuk/Map/MapTile.h
 create mode 100644 src/libUnuk/Sprite/ApplySurface.cpp
 create mode 100644 src/libUnuk/Sprite/ApplySurface.h
 create mode 100644 src/libUnuk/Sprite/ImageLoader.cpp
 create mode 100644 src/libUnuk/Sprite/ImageLoader.h
 create mode 100644 src/libUnuk/Sprite/Texture.cpp
 create mode 100644 src/libUnuk/Sprite/Texture.h
 create mode 100644 src/libUnuk/Sprite/TextureManager.cpp
 create mode 100644 src/libUnuk/Sprite/TextureManager.h
 create mode 100644 src/libUnuk/System/Debug.cpp
 create mode 100644 src/libUnuk/System/Debug.h
 create mode 100644 src/libUnuk/System/FPS.cpp
 create mode 100644 src/libUnuk/System/FPS.h
 create mode 100644 src/libUnuk/System/Input.cpp
 create mode 100644 src/libUnuk/System/Input.h
 create mode 100644 src/libUnuk/System/Rect.cpp
 create mode 100644 src/libUnuk/System/Rect.h
 create mode 100644 src/libUnuk/System/Timer.cpp
 create mode 100644 src/libUnuk/System/Timer.h
 create mode 100644 src/libUnuk/Ui/Button.cpp
 create mode 100644 src/libUnuk/Ui/Button.h
 create mode 100644 src/libUnuk/Ui/ButtonGroup.cpp
 create mode 100644 src/libUnuk/Ui/ButtonGroup.h
 create mode 100644 src/libUnuk/Ui/ButtonToggle.cpp
 create mode 100644 src/libUnuk/Ui/ButtonToggle.h
 create mode 100644 src/libUnuk/Ui/Font.cpp
 create mode 100644 src/libUnuk/Ui/Font.h
 create mode 100644 src/libUnuk/Ui/IngameMenu.cpp
 create mode 100644 src/libUnuk/Ui/IngameMenu.h
 create mode 100644 src/libUnuk/Ui/MainMenu.cpp
 create mode 100644 src/libUnuk/Ui/MainMenu.h
 create mode 100644 src/libUnuk/Ui/Text.cpp
 create mode 100644 src/libUnuk/Ui/Text.h

diff --git a/src/libUnuk/Engine/AStar.cpp b/src/libUnuk/Engine/AStar.cpp
new file mode 100644
index 0000000..a04f9e3
--- /dev/null
+++ b/src/libUnuk/Engine/AStar.cpp
@@ -0,0 +1,92 @@
+#include "AStar.h"
+
+AStar::AStar(void) {
+  while(_openList.size() > 0) {
+    _openList.pop();
+  }
+  _closedList.clear();
+  _solution.clear();
+}
+
+AStar::~AStar(void) {
+  AStarBase* best = 0;
+  while(_openList.size() > 0) {
+    best = _openList.top();
+    _openList.pop();
+    delete best;
+  }
+  _closedList.clear();
+}
+
+/*
+ * Solved the situation given by the initial state with AStar,
+ * and returns a vector of AStarBase that solves the problem.
+ */
+std::vector<AStarBase*> AStar::Solve(AStarBase* initState) {
+  AStarBase* best = 0;
+  while(_openList.size() > 0) {
+    best = _openList.top();
+    _openList.pop();
+    delete best;
+  }
+  _closedList.clear();
+
+  _openList.push(initState);
+  return GetSolutionSequence(Search());
+}
+
+// Search for the best path.
+AStarBase* AStar::Search(void) {
+  AStarBase* best = 0;
+  long key = 0;
+  std::vector<AStarBase*> child;
+
+  while(_openList.size() > 0) {
+    while(_closedList.find(key) != _closedList.end()) {
+      // Take the best state, and check if it is on the closed list.
+      if(_openList.size() > 0) {
+        best = _openList.top();
+        _openList.pop();
+      } else 
+        return 0;
+
+      key = best->CalculateKey();
+    }
+    
+    // Put best on the closed list.
+    _closedList[key] = best;
+
+    // Check if best is our goal.
+    if(best->isGoal())
+      return best;
+
+    // Generate the children.
+    child = best->GenerateChildren();
+    for(unsigned int i = 0; i < child.size(); i++) {
+      _openList.push(child[i]);
+    }
+  }
+  return 0;
+}
+
+// Generate a solution sequence for a given state.
+std::vector<AStarBase*> AStar::GetSolutionSequence(AStarBase* node) {
+  _solution.clear();
+  AStarBase* state = node;
+
+  while(state != 0) {
+    _closedList.erase(state->_key);
+    _solution.insert(_solution.begin(), state);
+    state = state->_parent;
+  }
+
+  // Delete the states which are not part of the solution.
+  while(_closedList.size() > 0) {
+    state = _closedList.begin()->second;
+    _closedList.erase(state->_key);
+    delete state;
+  }
+
+  return _solution;
+}
+
diff --git a/src/libUnuk/Engine/AStar.h b/src/libUnuk/Engine/AStar.h
new file mode 100644
index 0000000..4e9e7d3
--- /dev/null
+++ b/src/libUnuk/Engine/AStar.h
@@ -0,0 +1,30 @@
+#pragma once
+#include <vector>
+#include <map>
+#include <queue>
+
+#include "AStarBase.h"
+
+class AStar {
+public:
+  AStar(void);
+  ~AStar(void);
+
+  std::vector<AStarBase*> Solve(AStarBase* initState);
+
+private:
+  // Comparison structure.
+  struct Cmp : public std::binary_function<AStarBase*, AStarBase*, bool> {
+     bool operator()(AStarBase* a1, AStarBase* a2) const {
+       return (a1->_totalEstimatedCost >= a2->_totalEstimatedCost);
+     }
+   };
+
+  std::priority_queue<AStarBase*, std::vector<AStarBase*>, Cmp > _openList;
+  std::map<const long, AStarBase*> _closedList;
+
+  AStarBase* Search(void);
+
+  std::vector<AStarBase*> GetSolutionSequence(AStarBase* node);
+  std::vector<AStarBase*> _solution;
+};
diff --git a/src/libUnuk/Engine/AStarBase.h b/src/libUnuk/Engine/AStarBase.h
new file mode 100644
index 0000000..67f5c3c
--- /dev/null
+++ b/src/libUnuk/Engine/AStarBase.h
@@ -0,0 +1,26 @@
+#pragma once
+#include <vector>
+
+class AStarBase {
+public:
+  AStarBase(void) { };
+  virtual ~AStarBase(void) { };
+
+  // Generate a unique key.
+  virtual long CalculateKey(void) = 0;
+
+  // Aproximate the heuristic cost to the goal.
+  virtual double Estimate(void) = 0;
+
+  // Have we reached the goal?
+  virtual bool isGoal(void) = 0;
+
+  virtual std::vector<AStarBase*> GenerateChildren(void) = 0;
+
+  AStarBase* _parent;
+
+  double _pastCost;
+  double _totalEstimatedCost;
+
+  long _key;
+};
diff --git a/src/libUnuk/Engine/Character.cpp b/src/libUnuk/Engine/Character.cpp
new file mode 100644
index 0000000..07271fe
--- /dev/null
+++ b/src/libUnuk/Engine/Character.cpp
@@ -0,0 +1,204 @@
+#include "Character.h"
+
+// Pixels * 60 / sec
+const float Character::CHARACTER_SPEED = 3.5f;
+
+static list<Character*>collisionList;
+static list<Character*>::iterator collisionIter;
+
+Character::Character(Map* mapArg) {
+  map = mapArg;
+  attacking = false;
+  directionFacing = FACING_DOWN;
+  _animationStage  = ANIM_NO_FOOT;
+  _animationTimer.Start();
+  _leftFoot = false;
+  _health = 100;
+
+  xVel = 0.0f;
+  yVel = 0.0f;
+  
+  _texture = NULL;
+  
+  collisionList.push_front(this);
+}
+
+Character::~Character(void) {
+  SDL_FreeSurface(_texture);
+  for(collisionIter = collisionList.begin(); collisionIter != collisionList.end(); collisionIter++) {
+    if((*collisionIter) == this) {
+      collisionList.erase(collisionIter);
+      break;
+    }
+  }
+}
+
+void Character::LoadSprites(string filename, int wArg, int hArg) {
+  if(_texture != NULL)
+    SDL_FreeSurface(_texture);
+
+  _texture = LoadImageAlpha(filename.c_str());
+
+  w = (float)wArg;
+  h = (float)hArg;
+
+  for(int m_direction = 0; m_direction < 4; m_direction++) {
+    for(int m_action = 0; m_action < 4; m_action++) {
+      _sprites[m_direction][m_action].x = (Sint16)(w * m_action);
+      _sprites[m_direction][m_action].y = (Sint16)(h * m_direction);
+      _sprites[m_direction][m_action].w = (Sint16)w;
+      _sprites[m_direction][m_action].h = (Sint16)h;
+    }
+  }
+}
+
+void Character::AddSpeachBubble(string text) {
+  _speachBubble.push_back(text);
+
+  _speachBubbleText.SetLineWidth(200);
+  _speachBubbleText.SetTextBlended(text, small, 0, 0, 0, true);
+
+  if(_speachBubbleTimer.IsStarted() == false)
+    _speachBubbleTimer.Start();
+}
+
+void Character::Render(void) {
+  // Draw some fancy speach bubbles. It is a bit of a mess, I am playing.
+  if(_speachBubble.size() != 0) {
+    if(_speachBubbleTimer.GetTicks() < SPEACH_BUBBLE_DISPLAY_LENGTH) {
+      roundedBoxRGBA(screen, (Sint16)((x + w / 2) - 100 - camera.x),
+                     (Sint16)(y - 100 - camera.y),
+                     (Sint16)((x + w / 2) + 100 - camera.x),
+                     (Sint16)(y - 35 - camera.y),
+                     5, 255, 255, 255, 255);
+
+      filledTrigonRGBA(screen, (Sint16)((x + w / 2) - 100 - camera.x),
+                       (Sint16)(y - 100 - camera.y),
+                       (Sint16)((x + w / 2) - 10 - camera.x),
+                       (Sint16)(y - 40 - camera.y),
+                       (Sint16)((x + w / 2) + 10 - camera.x),
+                       (Sint16)(y - 40 - camera.y),
+                       255, 255, 255, 255);
+
+      _speachBubbleText.Render((int)((x + w / 2) - 90), (int)y - 90);
+    }
+  }
+
+  if(attacking && attackTimer.GetTicks() < ATTACKING_DISPLAY_LEN) {
+    ApplySurface((int)x, (int)y, _texture, screen, &_sprites[directionFacing][ANIM_ATTACK]);
+    return;
+  }
+  else if(attacking)
+    attacking = false;
+  
+  if(xVel == 0.0f && yVel == 0.0f)
+    ApplySurface((int)x, (int)y, _texture, screen, &_sprites[directionFacing][ANIM_NO_FOOT]);
+  else {
+    if(_animationTimer.GetTicks() > ANIMATION_SPEED) {
+      if(_animationStage == ANIM_NO_FOOT) {
+        if(_leftFoot == true)
+          _animationStage = ANIM_RIGHT_FOOT;
+        else
+          _animationStage = ANIM_LEFT_FOOT;
+      }
+      else if(_animationStage == ANIM_LEFT_FOOT) {
+        _animationStage = ANIM_NO_FOOT;
+        _leftFoot = true;
+      }
+      else if(_animationStage == ANIM_RIGHT_FOOT) {
+        _animationStage = ANIM_NO_FOOT;
+        _leftFoot = false;
+      }
+      _animationTimer.Start();
+    }
+    ApplySurface((int)x, (int)y, _texture, screen, &_sprites[directionFacing][_animationStage]);
+  }
+}
+
+void Character::Update(void) {
+  Move();
+
+  if(_speachBubble.size() != 0) {
+    if(_speachBubbleTimer.GetTicks() > SPEACH_BUBBLE_DISPLAY_LENGTH) {
+      _speachBubble.pop_front();
+
+      if(_speachBubble.size() != 0) {
+        _speachBubbleTimer.Start();
+      }
+    } else {
+      if(_speachBubble.front() != _speachBubbleText.GetText()) {
+        _speachBubbleText.SetTextBlended(_speachBubble.front(), small, 0, 0, 0);
+      }
+    }
+  }
+}
+
+void Character::Move(void) {
+  x += xVel;
+  tileX = (int)(((x + (w / 2)) / TILE_WIDTH));
+  tileY = (int)(((y + (h / 2)) / TILE_HEIGHT));
+
+  // Check collisions.
+  if((x < 0) || (x + w) > levelWidth || (x + w) > SCREEN_WIDTH)     x -= xVel;
+  if(CheckTileCollisions())                                         x -= xVel;
+  if(CheckEntityCollisions())                                       x -= xVel;
+  if(CheckCharacterCollisions())                                    x -= xVel;
+
+  y += yVel;
+  tileX = (int)(((x + (w / 2)) / TILE_WIDTH));
+  tileY = (int)(((y + (h / 2)) / TILE_HEIGHT));
+
+  if((y < 0) || (y + h) > levelHeight || (y + h) > SCREEN_HEIGHT)    y -= yVel;
+  if(CheckTileCollisions())                                          y -= yVel;
+  if(CheckEntityCollisions())                                        y -= yVel;
+  if(CheckCharacterCollisions())                                     y -= yVel;
+}
+
+/*
+ * Bounds checking only included in map.GetTileSolidity() and
+ * map.GetEntitySolidity(). Remember to add bounds checking
+ * if any other map method is used in a similar manner.
+ */
+bool Character::CheckTileCollisions(void) {
+  for(int i = -1; i < 2; i++) {
+    for(int j = -1; j < 2; j++) {
+      if(map->GetTileSolidity(tileX + i, tileY + j))
+        if(CheckCollisionXY((int)x, (int)y, (int)w, (int)h, map->GetTileX(tileX + i, tileY + j),
+                            map->GetTileY(tileX + i, tileY + j), TILE_WIDTH, TILE_HEIGHT))
+          return true;
+    }
+  }
+  return false;
+}
+
+bool Character::CheckEntityCollisions(void) {
+  for(int i = -1; i < 2; i++) {
+    for(int j = -1; j < 2; j++) {
+      if(map->GetEntitySolidity(tileX + i, tileY + j)) {
+        if(CheckCollisionXY((int)x, (int)y, (int)w, (int)h, map->GetEntityX(tileX + i, tileY + j),
+                            map->GetEntityY(tileX + i, tileY + j),
+                            map->GetEntityWidth(tileX + i, tileY + j),
+                            map->GetEntityHeight(tileX + i, tileY + j)))
+          return true;
+      }
+    }
+  }
+  return false;
+}
+
+bool Character::CheckCharacterCollisions(void) {
+  for(collisionIter = collisionList.begin();
+      collisionIter != collisionList.end();
+      collisionIter++) {
+    if((*collisionIter) != this) {
+      if(CheckCollisionXY((int)x, (int)y, (int)w, (int)h,
+                          (int)(*collisionIter)->GetX(),
+                          (int)(*collisionIter)->GetY(),
+                          (int)(*collisionIter)->GetWidth(),
+                          (int)(*collisionIter)->GetHeight())) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
diff --git a/src/libUnuk/Engine/Character.h b/src/libUnuk/Engine/Character.h
new file mode 100644
index 0000000..10c5e70
--- /dev/null
+++ b/src/libUnuk/Engine/Character.h
@@ -0,0 +1,117 @@
+#pragma once
+#include <SDL/SDL.h>
+#include <SDL/SDL_gfxPrimitives.h>
+#include <list>
+
+#include "../../Unuk/Globals.h"
+#include "../../Unuk/Constants.h"
+#include "../Engine/MemClass.h"
+#include "../Sprite/ApplySurface.h"
+#include "../Sprite/ImageLoader.h"
+#include "../Engine/Collision.h"
+#include "../Map/Map.h"
+#include "../System/Timer.h"
+#include "../Ui/Text.h"
+#include "../System/Debug.h"
+using namespace std;
+
+class Map;
+
+class Character {
+public:
+  Character(Map* mapArg);
+  ~Character(void);
+
+  void LoadSprites(string filename, int wArg, int hArg);
+  
+  float GetX(void)                   	{ return x; }
+  float GetY(void)                  	{ return y; }
+  float GetWidth(void)               	{ return w; }
+  float GetHeight(void)             	{ return h; }
+  
+  void SetXY(float xArg, float yArg)	{ x = xArg, y = yArg; }
+  void SetXVelocity(float arg)        { xVel = arg; }
+  void SetYVelocity(float arg)      	{ yVel = arg; }
+
+  void SetHealth(int health)          { _health = health; }
+  int GetHealth(void)                 { return _health; }
+  
+  void AddSpeachBubble(string text);
+
+  void Render(void);
+  void Update(void);
+
+  inline void* operator new(size_t size) {
+    return gMemManager.Allocate(size);
+  }
+
+  inline void operator delete(void* object) {
+    gMemManager.Free(object);
+  }
+
+  inline void* operator new [](size_t size) {
+    return gMemManager.Allocate(size);
+  }
+
+  inline void operator delete [](void* object) {
+    gMemManager.Free(object);
+  }
+  
+protected:
+  void Move(void);
+  
+  bool CheckTileCollisions(void);
+  bool CheckEntityCollisions(void);
+  bool CheckCharacterCollisions(void);
+  
+  float x;
+  float y;
+  float w;
+  float h;
+  
+  float xVel;
+  float yVel;
+  
+  int tileX;
+  int tileY;
+  
+  Timer attackTimer;
+  bool attacking;
+
+  int _health;
+  
+  Map* map;
+  
+  static const float CHARACTER_SPEED;
+  
+  int directionFacing;
+  static const int FACING_UP     = 0;
+  static const int FACING_RIGHT  = 1;
+  static const int FACING_DOWN   = 2;
+  static const int FACING_LEFT   = 3;
+  
+  static const int ANIM_LEFT_FOOT    = 0;
+  static const int ANIM_NO_FOOT      = 1;
+  static const int ANIM_RIGHT_FOOT   = 2;
+  static const int ANIM_ATTACK       = 3;
+
+private:
+  static const int ANIMATION_SPEED         = 200;
+  static const int ATTACKING_DISPLAY_LEN   = 150;
+
+  static const int SPEACH_BUBBLE_DISPLAY_LENGTH = 6000;
+  
+  SDL_Surface* _texture;
+  
+  // [direction][action]
+  SDL_Rect _sprites[4][4];
+  
+  Timer _animationTimer;
+  int _animationStage;
+  bool _leftFoot;
+
+  list<string> _speachBubble;
+  list<string>::iterator _speachBubbleIter;
+  Timer _speachBubbleTimer;
+  Text _speachBubbleText;
+};
diff --git a/src/libUnuk/Engine/Collision.cpp b/src/libUnuk/Engine/Collision.cpp
new file mode 100644
index 0000000..8ca25be
--- /dev/null
+++ b/src/libUnuk/Engine/Collision.cpp
@@ -0,0 +1,27 @@
+#include "Collision.h"
+
+bool CheckCollisionRect(SDL_Rect a, SDL_Rect b) {
+  if(a.y + a.h <= b.y)
+    return false;
+  if(a.y >= b.y + b.h)
+    return false;
+  if(a.x + a.w <= b.x)
+    return false;
+  if(a.x >= b.x + b.w)
+    return false;
+
+  return true;
+}
+
+bool CheckCollisionXY(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) {
+  if(y1 + h1 <= y2)
+    return false;
+  if(y1 >= y2 + h2)
+    return false;
+  if(x1 + w1 <= x2)
+    return false;
+  if(x1 >= x2 + w2)
+    return false;
+
+  return true;
+}
diff --git a/src/libUnuk/Engine/Collision.h b/src/libUnuk/Engine/Collision.h
new file mode 100644
index 0000000..b477fd1
--- /dev/null
+++ b/src/libUnuk/Engine/Collision.h
@@ -0,0 +1,6 @@
+#pragma once
+#define _COLLISION_H_
+#include <SDL/SDL.h>
+
+bool CheckCollisionRect(SDL_Rect a, SDL_Rect b);
+bool CheckCollisionXY(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2);
diff --git a/src/libUnuk/Engine/MemClass.h b/src/libUnuk/Engine/MemClass.h
new file mode 100644
index 0000000..6e0ea71
--- /dev/null
+++ b/src/libUnuk/Engine/MemClass.h
@@ -0,0 +1,32 @@
+#pragma once
+#include "MemManager.h"
+
+extern MemManager gMemManager;
+
+class MemClass {
+public:
+  MemClass(void) : r(0), c(0) {}
+  MemClass(double a, double b): r(a), c(b) {}
+
+  inline void* operator new(size_t size) {
+    return gMemManager.Allocate(size);
+  }
+
+  inline void operator delete(void* object) {
+    gMemManager.Free(object);
+  }
+
+  inline void* operator new [](size_t size) {
+    return gMemManager.Allocate(size);
+  }
+
+  inline void operator delete [](void* object) {
+    gMemManager.Free(object);
+  }
+
+private:
+  // Real part.
+  double r;
+  // Complex part.
+  double c;
+};
diff --git a/src/libUnuk/Engine/MemManager.cpp b/src/libUnuk/Engine/MemManager.cpp
new file mode 100644
index 0000000..afb317e
--- /dev/null
+++ b/src/libUnuk/Engine/MemManager.cpp
@@ -0,0 +1,206 @@
+#include "MemClass.h"
+#include "MemManager.h"
+
+MemManager gMemManager;
+
+void BitMapEntry::SetBit(int position, bool flag) {
+  blocksAvailable += flag ? 1 : -1;
+  int elementNo = position / INT_SIZE;
+  int bitNo = position % INT_SIZE;
+  if(flag)
+    bitMap[elementNo] = bitMap[elementNo] | (1 << bitNo);
+  else
+    bitMap[elementNo] = bitMap[elementNo] & ~(1 << bitNo);
+}
+
+void BitMapEntry::SetMultipleBits(int position, bool flag, int count) {
+  blocksAvailable += flag ? count : -count;
+  int elementNo = position / INT_SIZE;
+  int bitNo = position % INT_SIZE;
+
+  int bitSize = (count <= INT_SIZE - bitNo) ? count : INT_SIZE - bitNo;
+  SetRangeOfInt(&bitMap[elementNo], bitNo + bitSize - 1, bitNo, flag);
+  count -= bitSize;
+  if(!count) return;
+
+  int i = ++elementNo;
+  while(count >= 0) {
+    if(count <= INT_SIZE) {
+      SetRangeOfInt(&bitMap[i], count - 1, 0, flag);
+      return;
+    } else
+      bitMap[i] = flag ? unsigned (-1) : 0;
+    count -= 32;
+    i++;
+  }
+}
+
+void BitMapEntry::SetRangeOfInt(int* element, int msb, int lsb, bool flag) {
+  if(flag) {
+    int mask = (unsigned(-1) << lsb) & (unsigned(-1) >> INT_SIZE - msb - 1);
+    *element |= mask;
+  } else {
+    int mask = (unsigned(-1) << lsb) & (unsigned(-1) >> INT_SIZE - msb - 1);
+    *element &= ~mask;
+  }
+}
+
+MemClass* BitMapEntry::FirstFreeBlock(size_t size) {
+  for(int i = 0; i < BIT_MAP_ELEMENTS; i++) {
+    if(bitMap[i] == 0)
+      // There aint any bits free.
+      continue;
+
+    // Yield the first bit position. This is a 1
+    // in an int from the right.
+    int result = bitMap[i] & -(bitMap[i]);
+    void* address = 0;
+    int basePos = (INT_SIZE * i);
+
+    switch(result) {
+      // Make the corresponfing bit 0 so block is no longer free.
+    case 0x00000001: return ComplexObjectAddress(basePos + 0);
+    case 0x00000002: return ComplexObjectAddress(basePos + 1);
+    case 0x00000004: return ComplexObjectAddress(basePos + 2);
+    case 0x00000008: return ComplexObjectAddress(basePos + 3);
+    case 0x00000010: return ComplexObjectAddress(basePos + 4);
+    case 0x00000020: return ComplexObjectAddress(basePos + 5);
+    case 0x00000040: return ComplexObjectAddress(basePos + 6);
+    case 0x00000080: return ComplexObjectAddress(basePos + 7);
+    case 0x00000100: return ComplexObjectAddress(basePos + 8);
+    case 0x00000200: return ComplexObjectAddress(basePos + 9);
+    case 0x00000400: return ComplexObjectAddress(basePos + 10);
+    case 0x00000800: return ComplexObjectAddress(basePos + 11);
+    case 0x00001000: return ComplexObjectAddress(basePos + 12);
+    case 0x00002000: return ComplexObjectAddress(basePos + 13);
+    case 0x00004000: return ComplexObjectAddress(basePos + 14);
+    case 0x00008000: return ComplexObjectAddress(basePos + 15);
+    case 0x00010000: return ComplexObjectAddress(basePos + 16);
+    case 0x00020000: return ComplexObjectAddress(basePos + 17);
+    case 0x00040000: return ComplexObjectAddress(basePos + 18);
+    case 0x00080000: return ComplexObjectAddress(basePos + 19);
+    case 0x00100000: return ComplexObjectAddress(basePos + 20);
+    case 0x00200000: return ComplexObjectAddress(basePos + 21);
+    case 0x00400000: return ComplexObjectAddress(basePos + 22);
+    case 0x00800000: return ComplexObjectAddress(basePos + 23);
+    case 0x01000000: return ComplexObjectAddress(basePos + 24);
+    case 0x02000000: return ComplexObjectAddress(basePos + 25);
+    case 0x04000000: return ComplexObjectAddress(basePos + 26);
+    case 0x08000000: return ComplexObjectAddress(basePos + 27);
+    case 0x10000000: return ComplexObjectAddress(basePos + 28);
+    case 0x20000000: return ComplexObjectAddress(basePos + 29);
+    case 0x40000000: return ComplexObjectAddress(basePos + 30);
+    case 0x80000000: return ComplexObjectAddress(basePos + 31);
+    default: break;
+    }
+  }
+  return 0;
+}
+
+MemClass* BitMapEntry::ComplexObjectAddress(int pos) {
+  SetBit(pos, false);
+  return &((static_cast<MemClass*>(Head()) + (pos / INT_SIZE)) [INT_SIZE - (pos % INT_SIZE + 1)]);
+}
+
+void* BitMapEntry::Head(void) {
+  return gMemManager.GetMemoryPoolList()[index];
+}
+
+void* MemManager::Allocate(size_t size) {
+  // None array.
+  if(size == sizeof(MemClass)) {
+    set<BitMapEntry*>::iterator freeMapI = _freeMapEntries.begin();
+    if(freeMapI != _freeMapEntries.end()) {
+      BitMapEntry* mapEntry = *freeMapI;
+      return mapEntry->FirstFreeBlock(size);
+    } else {
+      AllocateChunkAndInitBitMap();
+      _freeMapEntries.insert(&(_bitMapEntryList[_bitMapEntryList.size() - 1]));
+      return _bitMapEntryList[_bitMapEntryList.size() - 1].FirstFreeBlock(size);
+    }
+  } else {
+    // Array.
+    if(_arrayMemoryList.empty()) {
+      return AllocateArrayMemory(size);
+    } else {
+      map<void*, ArrayMemoryInfo>::iterator infoI    = _arrayMemoryList.begin();
+      map<void*, ArrayMemoryInfo>::iterator infoEndI = _arrayMemoryList.end();
+
+      while(infoI != infoEndI) {
+        ArrayMemoryInfo info = (*infoI).second;
+        if(info.StartPosition != 0)
+          // Only search the memory blocks where allocation
+          // is done from first byte.
+          continue;
+        else {
+          BitMapEntry* entry = &_bitMapEntryList[info.memPoolListIndex];
+          if(entry->blocksAvailable < (size / sizeof(MemClass)))
+            return AllocateArrayMemory(size);
+          else {
+            info.StartPosition = BIT_MAP_SIZE - entry->blocksAvailable;
+            info.Size = size / sizeof(MemClass);
+            MemClass* baseAddress = static_cast<MemClass*>(_memoryPoolList[info.memPoolListIndex]) + info.StartPosition;
+
+            _arrayMemoryList[baseAddress] = info;
+            SetMultipleBlockBits(&info, false);
+
+            return baseAddress;
+          }
+        }
+      }
+    }
+  }
+  return 0;
+}
+
+void* MemManager::AllocateArrayMemory(size_t size) {
+  void* chunkAddress = AllocateChunkAndInitBitMap();
+  ArrayMemoryInfo info;
+  info.memPoolListIndex = _memoryPoolList.size() - 1;
+  info.StartPosition = 0;
+  info.Size = size / sizeof(MemClass);
+  _arrayMemoryList[chunkAddress] = info;
+  SetMultipleBlockBits(&info, false);
+  return chunkAddress;
+}
+
+void* MemManager::AllocateChunkAndInitBitMap(void) {
+  BitMapEntry mapEntry;
+  MemClass* memoryBeginAddress = reinterpret_cast<MemClass*>(new char[sizeof(MemClass) * BIT_MAP_SIZE]);
+  _memoryPoolList.push_back(memoryBeginAddress);
+  mapEntry.index = _memoryPoolList.size() - 1;
+  _bitMapEntryList.push_back(mapEntry);
+  return memoryBeginAddress;
+}
+
+void MemManager::Free(void* object) {
+  if(_arrayMemoryList.find(object) == _arrayMemoryList.end())
+    // Simple block deletion.
+    SetBlockBit(object, true);
+  else {
+    // Memory block deletion.
+    ArrayMemoryInfo *info = &_arrayMemoryList[object];
+    SetMultipleBlockBits(info, true);
+  }
+}
+
+void MemManager::SetBlockBit(void* object, bool flag) {
+  int i = _bitMapEntryList.size() - 1;
+  for(; i >= 0; i--) {
+    BitMapEntry* bitMap = &_bitMapEntryList[i];
+    if((bitMap->Head() <= object) && (&(static_cast<MemClass*>(bitMap->Head()))[BIT_MAP_SIZE - 1] >= object)) {
+      int position = static_cast<MemClass*>(object)- static_cast<MemClass*>(bitMap->Head());
+      bitMap->SetBit(position, flag);
+      flag ? bitMap->blocksAvailable++ : bitMap->blocksAvailable--;
+    }
+  }
+}
+
+void MemManager::SetMultipleBlockBits(ArrayMemoryInfo* info, bool flag) {
+  BitMapEntry* mapEntry = &_bitMapEntryList[info->memPoolListIndex];
+  mapEntry->SetMultipleBits(info->StartPosition, flag, info->Size);
+}
+
+vector<void*>& MemManager::GetMemoryPoolList(void) {
+  return _memoryPoolList;
+}
diff --git a/src/libUnuk/Engine/MemManager.h b/src/libUnuk/Engine/MemManager.h
new file mode 100644
index 0000000..3ceee14
--- /dev/null
+++ b/src/libUnuk/Engine/MemManager.h
@@ -0,0 +1,88 @@
+#pragma once
+#include <iostream>
+#include <vector>
+#include <string>
+#include <string.h>
+#include <vector>
+#include <set>
+#include <map>
+#include <bitset>
+using namespace std;
+
+const int BIT_MAP_SIZE   = 1024;
+const int INT_SIZE      = sizeof(int) * 8;
+const int BIT_MAP_ELEMENTS = BIT_MAP_SIZE / INT_SIZE;
+
+/*
+ * Memory Allocation Pattern.
+ * 11111111 11111111 11111111
+ * 11111110 11111111 11111111
+ * 11111100 11111111 11111111
+ *
+ * If all bits for the first section becomes zero go to next section.
+ *
+ * 00000000 11111111 11111111
+ * 00000000 11111110 11111111
+ * 00000000 11111100 11111111
+ * 00000000 11111000 11111111
+ *
+ * The lookup inside the map becomes 0(1) for the first available free block.
+ */
+
+class MemClass;
+
+typedef struct BitMapEntry {
+  int index;
+  int blocksAvailable;
+  int bitMap[BIT_MAP_SIZE];
+
+public:
+  BitMapEntry():blocksAvailable(BIT_MAP_SIZE) {
+    // All blocks are free to begin with and bit value 1
+    // in the map denotes available blocks.
+    memset(bitMap, 0xff, BIT_MAP_SIZE / sizeof(char));
+  }
+
+  void SetBit(int position, bool flag);
+  void SetMultipleBits(int position, bool flag, int count);
+  void SetRangeOfInt(int* element, int msb, int lsb, bool flag);
+  MemClass* FirstFreeBlock(size_t size);
+  MemClass* ComplexObjectAddress(int pos);
+  void* Head(void);
+} BitMapEntry;
+
+typedef struct ArrayInfo {
+  int memPoolListIndex;
+  int StartPosition;
+  int Size;
+} ArrayMemoryInfo;
+
+class IMemManager {
+public:
+  virtual void* Allocate(size_t size) = 0;
+  virtual void  Free(void* object)    = 0;
+};
+
+class MemManager : public IMemManager {
+public:
+  MemManager(void)  {}
+  ~MemManager(void) {}
+
+  void* Allocate(size_t size);
+  void  Free(void* object);
+  vector<void*>& GetMemoryPoolList(void);
+
+private:
+  void* AllocateArrayMemory(size_t size);
+  void* AllocateChunkAndInitBitMap(void);
+  void SetBlockBit(void* object, bool flag);
+  void SetMultipleBlockBits(ArrayMemoryInfo* info, bool flag);
+
+  // The following lists will maintain one to one correspondace
+  // and should be the same size.
+  vector<void*> _memoryPoolList;
+  vector<BitMapEntry> _bitMapEntryList;
+
+  set<BitMapEntry*> _freeMapEntries;
+  map<void*, ArrayMemoryInfo> _arrayMemoryList;
+};
diff --git a/src/libUnuk/Engine/NPC.cpp b/src/libUnuk/Engine/NPC.cpp
new file mode 100644
index 0000000..37fa4d7
--- /dev/null
+++ b/src/libUnuk/Engine/NPC.cpp
@@ -0,0 +1,59 @@
+#include "NPC.h"
+
+NPC::NPC(Map* mapArg) : Character(mapArg) {
+  _moveTimer.Start();
+  
+  _moveChangeFrequency = 14000;
+  _moveDurationMax	= 3000;
+  _moveDurationMin	= 1000;
+}
+
+NPC::~NPC(void) {
+
+}
+
+void NPC::Update(void) {
+  // Store the NPC's health.
+  // int health = GetHealth(); // not referenced
+
+  Move();
+
+  if(xVel > 0) directionFacing          = FACING_RIGHT;
+  else if(xVel < 0) directionFacing     = FACING_LEFT;
+  else if(yVel > 0) directionFacing     = FACING_DOWN;
+  else if(yVel < 0) directionFacing     = FACING_UP;
+}
+
+void NPC::Move(void) {
+  if(_moving && _moveTimer.GetTicks() > _moveDurationMax) {
+    xVel = 0.0f;
+    yVel = 0.0f;
+    _moving = false;
+  }
+  
+  if(_moving && _moveTimer.GetTicks() >= _moveDurationCurrent) {
+    xVel = 0.0f;
+    yVel = 0.0f;
+    _moving = false;
+  }
+  
+  if(_moveTimer.GetTicks() > _moveChangeFrequency) {
+    _moveTimer.Start();
+    _moveDurationCurrent = _moveDurationMin + (rand() % (_moveDurationMax - _moveDurationMin));
+    if(rand() % 2) {
+      yVel = 0.0f;
+      if(rand() % 2)
+        xVel = CHARACTER_SPEED;
+      else
+        xVel = -CHARACTER_SPEED;
+    } else {
+      xVel = 0.0f;
+      if(rand() % 2)
+        yVel = CHARACTER_SPEED;
+      else
+        yVel = -CHARACTER_SPEED;
+    }
+    _moving = true;
+  }
+  Character::Move();
+}
diff --git a/src/libUnuk/Engine/NPC.h b/src/libUnuk/Engine/NPC.h
new file mode 100644
index 0000000..5774690
--- /dev/null
+++ b/src/libUnuk/Engine/NPC.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "Character.h"
+#include "AStar.h"
+
+class NPC : public Character {
+public:
+  NPC(Map* mapArg);
+  ~NPC(void);
+  
+  void Update(void);
+
+protected:
+  void Move(void);
+  
+private:
+  int _moveChangeFrequency;
+  
+  int _moveDurationCurrent;
+  int _moveDurationMin;
+  int _moveDurationMax;
+  
+  bool _moving;
+  
+  Timer _moveTimer;
+};
diff --git a/src/libUnuk/Engine/ParticleEmitter.cpp b/src/libUnuk/Engine/ParticleEmitter.cpp
new file mode 100644
index 0000000..b029fab
--- /dev/null
+++ b/src/libUnuk/Engine/ParticleEmitter.cpp
@@ -0,0 +1,80 @@
+#include "ParticleEmitter.h"
+
+ParticleEmitter::ParticleEmitter(void) {
+
+}
+
+ParticleEmitter::~ParticleEmitter(void) {
+
+}
+
+void ParticleEmitter::SetXY(int xArg, int yArg) {
+  x = xArg;
+  y = yArg;
+}
+
+void ParticleEmitter::ForceXY(int xArg, int yArg) {
+  for(int i = 0; i < _particleCount; i++) {
+    m_particle[i].x = (float)xArg;
+    m_particle[i].y = (float)yArg;
+  }
+}
+
+void ParticleEmitter::SetParticleCount(int countArg) {
+  _particleCount = countArg;
+  m_particle.resize(_particleCount);
+
+  for(int i = 0; i < _particleCount; i++) {
+    m_particle[i].startTime = SDL_GetTicks();
+  }
+}
+
+void ParticleEmitter::SetParticleSpeed(float speedArg) {
+  _particleSpeed = speedArg;
+}
+
+void ParticleEmitter::SetParticleType(string typeArg) {
+  if(!_particleTexture) {
+    SDL_FreeSurface(_particleTexture);
+  }
+
+  string textureFilename = "../Data/Media/Images/Particles/" + typeArg + ".png";
+  _particleTexture = LoadImageAlpha(textureFilename.c_str());
+}
+
+void ParticleEmitter::SetParticleLifetime(int lifetimeArg) {
+  _particleLifetime = lifetimeArg;
+
+  for(int i = 0; i < _particleCount; i++) {
+    m_particle[i].lifetime = rand() % _particleLifetime + _particleLifetime / 4;
+  }
+}
+
+void ParticleEmitter::Render(void) {
+  for(int i = 0; i < _particleCount; i++) {
+    ApplySurface((int)m_particle[i].x, (int)m_particle[i].y, _particleTexture, screen);
+  }
+}
+
+void ParticleEmitter::Update(void) {
+  for(int i = 0; i < _particleCount; i++) {
+    if((int)SDL_GetTicks() - m_particle[i].startTime > m_particle[i].lifetime) {
+      // Reset the x and y coords.
+      m_particle[i].x = (float)x;
+      m_particle[i].y = (float)y;
+
+      m_particle[i].xVel = (float)(rand() % 360);
+      m_particle[i].yVel = (float)(rand() % 360);
+
+      if(rand() % 2)
+        m_particle[i].xVel = m_particle[i].xVel * -1.0f;
+      if(rand() % 2)
+        m_particle[i].yVel = m_particle[i].yVel * -1.0f;
+
+      m_particle[i].startTime = SDL_GetTicks();
+    } else {
+      m_particle[i].x += m_particle[i].xVel * _particleSpeed;
+      m_particle[i].y += m_particle[i].yVel * _particleSpeed;
+    }
+  }
+}
diff --git a/src/libUnuk/Engine/ParticleEmitter.h b/src/libUnuk/Engine/ParticleEmitter.h
new file mode 100644
index 0000000..a554338
--- /dev/null
+++ b/src/libUnuk/Engine/ParticleEmitter.h
@@ -0,0 +1,52 @@
+#pragma once
+#include <SDL/SDL.h>
+#include <vector>
+#include <string>
+#include <sstream>
+
+#include "../../Unuk/Globals.h"
+#include "../Sprite/ImageLoader.h"
+#include "../Sprite/ApplySurface.h"
+using namespace std;
+
+struct Particle {
+  float x;
+  float y;
+
+  float xVel;
+  float yVel;
+
+  int lifetime;
+  int startTime;
+};
+
+class ParticleEmitter {
+public:
+  ParticleEmitter(void);
+  ~ParticleEmitter(void);
+
+  // distribute particles from the new x and y.
+  void SetXY(int xArg, int yArg);
+  // Move all the existing particles to the new x and y.
+  void ForceXY(int xArg, int yArg);
+
+  void SetParticleCount(int countArg);
+  void SetParticleLifetime(int lifetimeArg);
+  void SetParticleSpeed(float speedArg);
+  void SetParticleType(string typeArg);
+
+  void Render(void);
+  void Update(void);
+
+private:
+  vector<Particle> m_particle;
+
+  int x;
+  int y;
+
+  int     _particleCount;
+  int     _particleLifetime;
+  float   _particleSpeed;
+
+  SDL_Surface* _particleTexture;
+};
diff --git a/src/libUnuk/Engine/WorldManager.cpp b/src/libUnuk/Engine/WorldManager.cpp
new file mode 100644
index 0000000..af23a6b
--- /dev/null
+++ b/src/libUnuk/Engine/WorldManager.cpp
@@ -0,0 +1,54 @@
+#include "WorldManager.h"
+#include "NPC.h"
+
+WorldManager::WorldManager(void) {
+}
+
+WorldManager::~WorldManager(void) {
+  for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
+    NPC* npc = (*i);
+    delete npc;
+  }
+}
+
+void WorldManager::Update(void) {
+  for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
+    NPC* npc = (*i);
+    npc->Update();
+  }
+}
+
+void WorldManager::Render(void) {
+  for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
+    NPC* npc = (*i);
+    npc->Render();
+  }
+}
+
+void WorldManager::AddNPC(NPC* npc) {
+  _npcs.push_back(npc);
+}
+
+void WorldManager::RemoveNPC(int index) {
+  int npcsIndex = 0;
+  for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
+    NPC* npc = (*i);
+    if(npcsIndex == index) {
+      _npcs.erase(i);
+      delete npc;
+    }
+    npcsIndex++;
+  }
+}
+
+NPC* WorldManager::GetNPC(int index) {
+  int npcsIndex = 0;
+  for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
+    NPC* npc = (*i);
+    if(npcsIndex == index) {
+      return npc;
+    }
+    npcsIndex++;
+  }
+  return NULL;
+}
diff --git a/src/libUnuk/Engine/WorldManager.h b/src/libUnuk/Engine/WorldManager.h
new file mode 100644
index 0000000..466571c
--- /dev/null
+++ b/src/libUnuk/Engine/WorldManager.h
@@ -0,0 +1,20 @@
+#pragma once
+#include <list>
+
+class NPC;
+
+class WorldManager {
+public:
+  WorldManager(void);
+  ~WorldManager(void);
+
+  void Update(void);
+  void Render(void);
+
+  void AddNPC(NPC* npc);
+  void RemoveNPC(int index);
+  NPC* GetNPC(int index);
+
+private:
+  std::list<NPC*> _npcs;
+};
diff --git a/src/libUnuk/Map/Map.cpp b/src/libUnuk/Map/Map.cpp
new file mode 100644
index 0000000..d3952c8
--- /dev/null
+++ b/src/libUnuk/Map/Map.cpp
@@ -0,0 +1,251 @@
+#include "Map.h"
+#include "../Engine/NPC.h"
+
+Map::Map(void) {
+
+}
+
+Map::~Map(void) {
+
+}
+
+void Map::Load(const string filename) {
+  Unload();
+  _currentMap = filename;
+  string fullMapPath = "../Data/Media/Maps/" + filename;
+  TiXmlDocument mapFile(fullMapPath.c_str());
+
+  assert(mapFile.LoadFile() == true);
+
+  // Getting dirty with some XML. This seems like a nicer
+  // approach to loading maps, rather than parsing tet files.
+  TiXmlElement* rootElem = NULL;
+  TiXmlElement* lineElem = NULL;
+  TiXmlElement* tileElem = NULL;
+  TiXmlElement* dataElem = NULL;
+
+  x = -1;
+  y = -1;
+
+  // <map> - Let's start parsing the map.
+  rootElem = mapFile.FirstChildElement("map");
+  assert(rootElem != NULL);
+  if(rootElem) {
+    // <line> - We want to tile one line at a time. line represents
+    // the row we are tiling.
+    lineElem = rootElem->FirstChildElement("line");
+    assert(lineElem != NULL);
+    while(lineElem) {
+      y++;
+      x = -1;
+
+      // <tile> - Then we will select the tile. and increment x to keep tiling that row.
+      tileElem = lineElem->FirstChildElement("tile");
+      assert(tileElem != NULL);
+      while(tileElem) {
+        x++;
+        _tile[x][y].SetTileXY(x * TILE_WIDTH, y * TILE_HEIGHT);
+
+        // <tileTexture> - Apply a teture to the tile.
+        dataElem = tileElem->FirstChildElement("tileTexture");
+        assert(dataElem != NULL);
+        stringstream tilePath;
+        tilePath << "../Data/Media/Images/Tiles/" << dataElem->GetText() << ".png";
+        _tile[x][y].SetTileTexture(_tileTextures.Add(tilePath.str()));
+        // <tileTexture> - Finished applying the texture, move to the next sibling.
+
+        // <solidTile> - Check to see if the tile is solid or not.
+        dataElem = dataElem->NextSiblingElement("solidTile");
+        assert(dataElem != NULL);
+        string tileSolidity = dataElem->GetText();
+        assert(tileSolidity == "false" || tileSolidity == "true");
+        if(tileSolidity == "false")
+          _tile[x][y].SetTileSolidity(false);
+        else
+          _tile[x][y].SetTileSolidity(true);
+        // </solidTile>
+
+        // <entityTexture>
+        dataElem = dataElem->NextSiblingElement("entityTexture");
+        assert(dataElem != NULL);
+        string entityName = dataElem->GetText();
+        if(entityName != "null") {
+          stringstream entityPath;
+          entityPath << "../Data/Media/Images/Entities/" << entityName << ".png";
+          _tile[x][y].SetEntityTexture(_entityTextures.AddAlpha(entityPath.str()));
+
+          _tile[x][y].SetEntityXY(_tile[x][y].GetTileX() + TILE_WIDTH  / 2 - _tile[x][y].GetEntityWidth()  / 2,
+                                   _tile[x][y].GetTileY() + TILE_HEIGHT / 2 - _tile[x][y].GetEntityHeight() / 2);
+        }
+        // </entityTexture>
+
+        // <SolidEntity>
+        dataElem = dataElem->NextSiblingElement("solidEntity");
+        assert(dataElem != NULL);
+        string entitySolidity = dataElem->GetText();
+        assert(entitySolidity == "false" || entitySolidity == "true");
+        if(entitySolidity == "false")
+          _tile[x][y].SetEntitySolidity(false);
+        else
+          _tile[x][y].SetEntitySolidity(true);
+        // </solidEntity>
+
+        // <zlevel>
+        dataElem = dataElem->NextSiblingElement("zLevel");
+        assert(dataElem != NULL);
+        _tile[x][y].SetZLevel(atoi(dataElem->GetText()));
+        // </zlevel>
+
+        // <mapTransition>
+        dataElem = dataElem->NextSiblingElement("mapTransition");
+        assert(dataElem != NULL);
+        _tile[x][y].SetMapTransitionName(dataElem->GetText());
+        // </mapTransition>
+
+        // <mapTransX>
+        dataElem = dataElem->NextSiblingElement("mapTransX");
+        assert(dataElem != NULL);
+        // int mapTransX = atoi(dataElem->GetText()); // not referenced
+        // </mapTransX>
+
+        // <mapTransY>
+        dataElem = dataElem->NextSiblingElement("mapTransY");
+        assert(dataElem != NULL);
+       // int mapTransY = atoi(dataElem->GetText()); // not referenced
+        // </mapTransY>
+
+        tileElem = tileElem->NextSiblingElement("tile");
+      }
+      //</tile>
+
+      lineElem = lineElem->NextSiblingElement("line");
+    }
+    // </line>
+  }
+  // </map>
+  levelWidth  = x * TILE_WIDTH;
+  levelHeight = y * TILE_HEIGHT;
+
+  //character->Load(filename);
+
+  NPC* npc = new NPC(this);
+
+  npc->SetXY(300, 300);
+  npc->LoadSprites("../Data/Media/Images/Characters/template.png", 40,45);
+  _world.AddNPC(npc);
+
+  npc = new NPC(this);
+  npc->SetXY(150, 350);
+  npc->LoadSprites("../Data/Media/Images/Characters/template.png", 40,45);
+  _world.AddNPC(npc);
+
+  npc = new NPC(this);
+  npc->SetXY(100, 250);
+  npc->LoadSprites("../Data/Media/Images/Characters/template.png", 40,45);
+  _world.AddNPC(npc);
+}
+
+void Map::Update(void) {
+  _world.Update();
+  // Update the map so we can render when camera moves.
+}
+
+void Map::Render(void) {
+  int xOrig = (camera.x / TILE_WIDTH) - 1;
+  int yOrig = (camera.y / TILE_HEIGHT) - 1;
+
+  if (xOrig < 0) xOrig = 0;
+  if (yOrig < 0) yOrig = 0;
+
+  int xEnd = xOrig + (SCREEN_WIDTH  / TILE_WIDTH) + 3;
+  int yEnd = yOrig + (SCREEN_HEIGHT / TILE_HEIGHT) + 3;
+
+  /* the fuck is this Allanis? --konom
+  if(xEnd < x)
+    xEnd++;
+  else
+    xEnd = x;
+
+  if(yEnd < y)
+    yEnd++;
+  else
+    yEnd = y;
+  */
+
+  if (xEnd > x) xEnd = x;
+  if (yEnd > y) yEnd = y;
+  if (xEnd < 0) xEnd = 0;
+  if (yEnd < 0) yEnd = 0;
+
+  if (xOrig > xEnd) xOrig = xEnd - 1;
+  if (yOrig > yEnd) yOrig = yEnd - 1;
+
+  for(int i = xOrig; i < xEnd; i++) {
+    for(int j = yOrig; j < yEnd; j++) {
+      _tile[i][j].Render();
+    }
+  }
+
+  _world.Render();
+}
+
+void Map::Unload(void) {
+  _tileTextures.Unload();
+  _entityTextures.Unload();
+}
+
+string Map::GetCurrentMap(void) {
+  return _currentMap;
+}
+
+bool Map::GetTileSolidity(int xArg, int yArg) {
+  return _tile[xArg + 1][yArg + 1].GetTileSolidity();
+}
+
+int Map::GetTileX(int xArg, int yArg) {
+  return _tile[xArg + 1][yArg + 1].GetTileX();
+}
+
+int Map::GetTileY(int xArg, int yArg) {
+  return _tile[xArg + 1][yArg + 1].GetTileY();
+}
+
+bool Map::GetEntitySolidity(int xArg, int yArg) {
+  if(xArg > x || yArg > y || yArg < 0 || yArg < 0) {
+    return false;
+  }
+
+  return _tile[xArg + 1][yArg + 1].GetEntitySolitity();
+}
+
+int Map::GetEntityX(int xArg, int yArg) {
+  return _tile[xArg + 1][yArg + 1].GetEntityX();
+}
+
+int Map::GetEntityY(int xArg, int yArg) {
+  return _tile[xArg + 1][yArg + 1].GetEntityY();
+}
+
+int Map::GetEntityWidth(int xArg, int yArg) {
+  return _tile[xArg + 1][yArg + 1].GetEntityWidth();
+}
+
+int Map::GetEntityHeight(int xArg, int yArg) {
+  return _tile[xArg + 1][yArg + 1].GetEntityHeight();
+}
+
+int Map::GetTileZLevel(int xArg, int yArg) {
+  return _tile[xArg + 1][yArg + 1].GetZLevel();
+}
+
+string Map::GetMapTransitionName(int xArg, int yArg) {
+  return _tile[xArg + 1][yArg + 1].GetMapTransitionName();
+}
+
+int Map::GetMapTransitionX(int xArg, int yArg) {
+  return _tile[xArg + 1][yArg + 1].GetMapTransitionX();
+}
+
+int Map::GetMapTransitionY(int xArg, int yArg) {
+  return _tile[xArg + 1][yArg + 1].GetMapTransitionY();
+}
diff --git a/src/libUnuk/Map/Map.h b/src/libUnuk/Map/Map.h
new file mode 100644
index 0000000..0d6a5cc
--- /dev/null
+++ b/src/libUnuk/Map/Map.h
@@ -0,0 +1,64 @@
+#pragma once
+#include <SDL/SDL.h>
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <fstream>
+#include <assert.h>
+#include <tinyxml.h>
+
+#include "../../Unuk/Globals.h"
+#include "../../Unuk/Constants.h"
+#include "../Sprite/ImageLoader.h"
+#include "../Sprite/ApplySurface.h"
+#include "../Map/MapTile.h"
+#include "../System/Debug.h"
+#include "../Engine/WorldManager.h"
+using namespace std;
+
+//class CharacterManager;
+
+class Map {
+public:
+  Map(void);
+  ~Map(void);
+
+  void Load(const string filename);
+  void Update(void);
+  void Render(void);
+
+  bool GetTileSolidity(int xArg, int yArg);
+  int  GetTileX(int xArg, int yArg);
+  int  GetTileY(int xArg, int yArg);
+
+  bool GetEntitySolidity(int xArg, int yArg);
+  int  GetEntityX(int xArg, int yArg);
+  int  GetEntityY(int xArg, int yArg);
+  int  GetEntityWidth(int xArg, int yArg);
+  int  GetEntityHeight(int xArg, int yArg);
+
+  int  GetTileZLevel(int xArg, int yArg);
+
+  string GetMapTransitionName(int xArg, int yArg);
+  int    GetMapTransitionX(int xArg, int yArg);
+  int    GetMapTransitionY(int xArg, int yArg);
+
+  string GetCurrentMap(void);
+
+  WorldManager& GetWorld(void) { return _world; }
+
+private:
+  void Unload(void);
+
+  string _currentMap;
+  int x;
+  int y;
+
+  static const int TILE_ARRAY_SIZE = 150;
+  MapTile _tile[TILE_ARRAY_SIZE][TILE_ARRAY_SIZE];
+
+  TextureManager _tileTextures;
+  TextureManager _entityTextures;
+
+  WorldManager _world;
+};
diff --git a/src/libUnuk/Map/MapElement.cpp b/src/libUnuk/Map/MapElement.cpp
new file mode 100644
index 0000000..102327a
--- /dev/null
+++ b/src/libUnuk/Map/MapElement.cpp
@@ -0,0 +1,39 @@
+#include "MapElement.h"
+
+MapElement::MapElement(void) {
+
+}
+
+MapElement::~MapElement(void) {
+
+}
+
+void MapElement::SetTexture(SDL_Surface* arg) {
+  _texture = arg;
+}
+
+void MapElement::Render(void) {
+  ApplySurface(x, y, _texture, screen);
+}
+
+void MapElement::Update(void) {
+
+}
+
+void MapElement::SetSolidity(bool arg) {
+  _solid = arg;
+}
+
+bool MapElement::GetSolidity(void) {
+  return _solid;
+}
+
+void MapElement::SetXY(int xArg, int yArg) {
+  x = xArg,
+  y = yArg;
+}
+
+int MapElement::GetX(void)        { return x; }
+int MapElement::GetY(void)        { return y; }
+int MapElement::GetWidth(void)    { return _texture->w; }
+int MapElement::GetHeight(void)   { return _texture->h; }
diff --git a/src/libUnuk/Map/MapElement.h b/src/libUnuk/Map/MapElement.h
new file mode 100644
index 0000000..4d681cf
--- /dev/null
+++ b/src/libUnuk/Map/MapElement.h
@@ -0,0 +1,36 @@
+#pragma once
+#include <SDL/SDL.h>
+#include <string>
+
+#include "../../Unuk/Globals.h"
+#include "../Sprite/ApplySurface.h"
+#include "../Sprite/TextureManager.h"
+
+class MapElement {
+public:
+  MapElement(void);
+  ~MapElement(void);
+
+  static void SetTextureManager(TextureManager* arg);
+
+  virtual void SetTexture(SDL_Surface* arg);
+  virtual void Render(void);
+  virtual void Update(void);
+
+  void SetSolidity(bool arg);
+  bool GetSolidity(void);
+
+  void SetXY(int xArg, int yArg);
+  int GetX(void);
+  int GetY(void);
+  int GetWidth(void);
+  int GetHeight(void);
+
+protected:
+  SDL_Surface* _texture;
+
+  bool _solid;
+
+  int x;
+  int y;
+};
diff --git a/src/libUnuk/Map/MapEntities.cpp b/src/libUnuk/Map/MapEntities.cpp
new file mode 100644
index 0000000..a662269
--- /dev/null
+++ b/src/libUnuk/Map/MapEntities.cpp
@@ -0,0 +1,16 @@
+#include "MapEntities.h"
+
+MapEntityGeneric::MapEntityGeneric(void) {
+  _texture = NULL;
+
+}
+
+MapEntityGeneric::~MapEntityGeneric(void) {
+
+}
+
+void MapEntityGeneric::Render(void) {
+  if(_texture != NULL) {
+    MapElement::Render();
+  }
+}
diff --git a/src/libUnuk/Map/MapEntities.h b/src/libUnuk/Map/MapEntities.h
new file mode 100644
index 0000000..530eb62
--- /dev/null
+++ b/src/libUnuk/Map/MapEntities.h
@@ -0,0 +1,19 @@
+#pragma once
+/*
+ * Version of MapElement, that will check whether the SDL_Surface it
+ * owns is NULL or not and draws.
+ *
+ */
+
+#include "MapElement.h"
+
+class MapEntityGeneric : public MapElement {
+public:
+  MapEntityGeneric(void);
+  ~MapEntityGeneric(void);
+
+  void Render(void);
+
+private:
+
+};
diff --git a/src/libUnuk/Map/MapTile.h b/src/libUnuk/Map/MapTile.h
new file mode 100644
index 0000000..e32ed8d
--- /dev/null
+++ b/src/libUnuk/Map/MapTile.h
@@ -0,0 +1,66 @@
+#pragma once
+#include <list>
+#include <string>
+#include <SDL/SDL.h>
+
+#include "../../Unuk/Constants.h"
+#include "../Sprite/ApplySurface.h"
+#include "../Map/MapElement.h"
+#include "../Map/MapEntities.h"
+using namespace std;
+
+class MapTile {
+public:
+  MapTile(void)                                     {  }
+  ~MapTile(void)                                    {  }
+
+  void Render(void)                                 { _tile.Render(), _entity.Render(); }
+
+  // Tile Mutators.
+  SDL_Surface* SetTileTexture(SDL_Surface* arg)	 	  { _tile.SetTexture(arg); return NULL; }
+  void SetTileSolidity(bool arg)                    { _tile.SetSolidity(arg); }
+  bool GetTileSolidity(void)                        { return _tile.GetSolidity(); }
+  // Well, it kinda helps if I lay the
+  // tiles rather than just get the
+  // return value right??
+  void SetTileXY(int xArg, int yArg)                { _tile.SetXY(xArg, yArg); }
+  int GetTileX(void)                                { return _tile.GetX(); }
+  int GetTileY(void)                                { return _tile.GetY(); }
+
+  // Entity Mutators.
+  void SetEntityTexture(SDL_Surface* arg)           { _entity.SetTexture(arg); }
+  void SetEntityXY(int xArg, int yArg)              { _entity.SetXY(xArg, yArg); }
+  void SetEntitySolidity(bool arg)                  { _entity.SetSolidity(arg); }
+  bool GetEntitySolitity(void)                      { return _entity.GetSolidity(); }
+
+  // Entity Mutators.
+  int GetEntityX(void)                              { return _entity.GetX(); }
+  int GetEntityY(void)                              { return _entity.GetY(); }
+  int GetEntityWidth(void)                          { return _entity.GetWidth(); }
+  int GetEntityHeight(void)                         { return _entity.GetHeight(); }
+
+  // ZLevel Mutators.
+  void SetZLevel(int arg)                           { _zLevel = arg; }
+  int GetZLevel(void)                               { return _zLevel; }
+
+  // Map Transition Mutators.
+  void SetMapTransitionName(string arg)             { _mapTransitionName = arg; }
+  string GetMapTransitionName(void)                 { return _mapTransitionName; }
+
+  void SetMapTransitionXY(int xArg, int yArg)       { _mapTransitionX = xArg, _mapTransitionY = yArg; }
+  int GetMapTransitionX(void)                       { return _mapTransitionX; }
+  int GetMapTransitionY(void)                       { return _mapTransitionY; }
+
+private:
+  MapElement _tile;
+  MapEntityGeneric _entity;
+
+  // -1 is a 'special' tile, the next tile that the player walks
+  // on is the players new zlevel.
+  int _zLevel;
+
+  // If not 'null', switch map when the player walks on this tile.
+  string _mapTransitionName;
+  int _mapTransitionX;
+  int _mapTransitionY;
+};
diff --git a/src/libUnuk/Sprite/ApplySurface.cpp b/src/libUnuk/Sprite/ApplySurface.cpp
new file mode 100644
index 0000000..b6b88c8
--- /dev/null
+++ b/src/libUnuk/Sprite/ApplySurface.cpp
@@ -0,0 +1,23 @@
+#include "ApplySurface.h"
+
+void ApplySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip) {
+  assert(source != NULL);
+
+  SDL_Rect offset;
+
+  offset.x = (Sint16)(x - camera.x);
+  offset.y = (Sint16)(y - camera.y);
+
+  SDL_BlitSurface(source, clip, destination, &offset);
+}
+
+void ApplySurfaceLiteral(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip) {
+  assert(source != NULL);
+
+  SDL_Rect offset;
+
+  offset.x = (Sint16)x;
+  offset.y = (Sint16)y;
+
+  SDL_BlitSurface(source, clip, destination, &offset);
+}
diff --git a/src/libUnuk/Sprite/ApplySurface.h b/src/libUnuk/Sprite/ApplySurface.h
new file mode 100644
index 0000000..bc3f000
--- /dev/null
+++ b/src/libUnuk/Sprite/ApplySurface.h
@@ -0,0 +1,16 @@
+#pragma once
+#include <SDL/SDL.h>
+#include <assert.h>
+#include "../System/Debug.h"
+#include "../../Unuk/Globals.h"
+
+/*            Use for objects.
+ * Blit a surface to another surface. An
+ * optioanl clip argument can be given. The surface
+ * will be applied to the destination, taking into
+ * account the position of the camera.
+ */
+void ApplySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL);
+
+// This one won't take the camera into account, so we could use it for GUI stuff.
+void ApplySurfaceLiteral(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL);
diff --git a/src/libUnuk/Sprite/ImageLoader.cpp b/src/libUnuk/Sprite/ImageLoader.cpp
new file mode 100644
index 0000000..68b3397
--- /dev/null
+++ b/src/libUnuk/Sprite/ImageLoader.cpp
@@ -0,0 +1,37 @@
+#include "ImageLoader.h"
+
+SDL_Surface* LoadImage(const char* filename) {
+  SDL_Surface* loadedImage    = NULL;
+  SDL_Surface* optimizedImage = NULL;
+
+  // Initialize loadedImage with the file.
+  loadedImage = IMG_Load(filename);
+  if(loadedImage != NULL) {
+    // Then copy the image to a surface for us to blit later.
+    optimizedImage = SDL_DisplayFormat(loadedImage);
+    SDL_FreeSurface(loadedImage);
+    return optimizedImage;
+  } else {
+    // Tell us what file is missing and do some stupid error texture thing.
+    Debug::logger->message("ImageLoader: %s cannot be found!");
+    return errorTexture;
+  }
+}
+
+SDL_Surface* LoadImageAlpha(const char* filename) {
+  SDL_Surface* loadedImage    = NULL;
+  SDL_Surface* optimizedImage = NULL;
+
+  // Initialize loadedImage with the file.
+  loadedImage = IMG_Load(filename);
+  if(loadedImage != NULL) {
+    // Then copy the image to a surface and give us an alpha channel.
+    optimizedImage = SDL_DisplayFormatAlpha(loadedImage);
+    SDL_FreeSurface(loadedImage);
+    return optimizedImage;
+  } else {
+    // Tell us what file is missing and do some stupid error texture thing.
+    Debug::logger->message("ImageLoader: %s cannot be found!");
+    return errorTexture;
+  }
+}
diff --git a/src/libUnuk/Sprite/ImageLoader.h b/src/libUnuk/Sprite/ImageLoader.h
new file mode 100644
index 0000000..111b7ff
--- /dev/null
+++ b/src/libUnuk/Sprite/ImageLoader.h
@@ -0,0 +1,8 @@
+#pragma once
+#include <SDL/SDL.h>
+#include <SDL/SDL_image.h>
+#include "../../Unuk/Globals.h"
+#include "../System/Debug.h"
+
+SDL_Surface* LoadImage(const char* filename);
+SDL_Surface* LoadImageAlpha(const char* filename);
diff --git a/src/libUnuk/Sprite/Texture.cpp b/src/libUnuk/Sprite/Texture.cpp
new file mode 100644
index 0000000..5a0a11c
--- /dev/null
+++ b/src/libUnuk/Sprite/Texture.cpp
@@ -0,0 +1,53 @@
+#include "Texture.h"
+
+Texture::Texture(void) {
+  _texture = NULL;
+}
+
+Texture::~Texture(void) {
+  assert(_texture != NULL);
+  SDL_FreeSurface(_texture);
+}
+
+void Texture::SetXY(int xArg, int yArg) {
+  x = xArg;
+  y = yArg;
+}
+
+void Texture::Render(void) {
+  ApplySurface(x, y, _texture, screen);
+}
+
+void Texture::Render(int xArg, int yArg) {
+  ApplySurface(xArg, yArg, _texture, screen);
+}
+
+void Texture::RenderLiteral(void) {
+  ApplySurfaceLiteral(x, y, _texture, screen);
+}
+
+void Texture::RenderLiteral(int xArg, int yArg) {
+  ApplySurfaceLiteral(xArg, yArg,_texture, screen);
+}
+
+void Texture::Load(const char* filename) {
+  if(_texture != NULL) {
+    // Free the texture.
+    SDL_FreeSurface(_texture);
+  }
+  // Load the texture.
+  _texture = LoadImage(filename);
+}
+
+void Texture::LoadAlpha(const char* filename) {
+  if(_texture != NULL) {
+    // Free the texture.
+    SDL_FreeSurface(_texture);
+  }
+  // Load the texture with an alpha channel.
+  _texture = LoadImageAlpha(filename);
+}
+
+void Texture::SetAlpha(int alphaArg) {
+  SDL_SetAlpha(_texture, SDL_SRCALPHA, (Uint8)alphaArg);
+}
diff --git a/src/libUnuk/Sprite/Texture.h b/src/libUnuk/Sprite/Texture.h
new file mode 100644
index 0000000..bfecf93
--- /dev/null
+++ b/src/libUnuk/Sprite/Texture.h
@@ -0,0 +1,33 @@
+#pragma once
+#include "../../Unuk/Globals.h"
+#include "ImageLoader.h"
+#include "ApplySurface.h"
+
+class Texture {
+public:
+  Texture(void);
+  ~Texture(void);
+
+  int GetWidth(void)    { return _texture->w; }
+  int GetHeight(void)   { return _texture->h; }
+  int GetX(void)        { return x; }
+  int GetY(void)        { return y; }
+
+  void SetXY(int xArg, int yArg);
+
+  void Render(void);
+  void Render(int xArg, int yArg);
+
+  void RenderLiteral(void);
+  void RenderLiteral(int xArg, int yArg);
+
+  void Load(const char* filename);
+  void LoadAlpha(const char* filename);
+  void SetAlpha(int alphaArg);
+
+protected:
+  int x, y;
+
+private:
+  SDL_Surface* _texture;
+};
diff --git a/src/libUnuk/Sprite/TextureManager.cpp b/src/libUnuk/Sprite/TextureManager.cpp
new file mode 100644
index 0000000..8089c1d
--- /dev/null
+++ b/src/libUnuk/Sprite/TextureManager.cpp
@@ -0,0 +1,55 @@
+#include "TextureManager.h"
+
+TextureManager::TextureManager(void) {
+  _allocated = 0;
+}
+
+TextureManager::~TextureManager(void) {
+  Unload();
+}
+
+void TextureManager::Unload(void) {
+  for(int i = 0; i < _allocated; i++) {
+    SDL_FreeSurface(_textures[i].texture);
+    _textures[i].name.clear();
+  }
+  _allocated = 0;
+}
+
+SDL_Surface* TextureManager::Add(string filename) {
+  assert(_allocated < TEXTURE_ARR_SIZE - 1);
+
+  // Has the texture been loaded already?
+  for(int i = 0; i < _allocated; i++) {
+    if(_textures[i].name == filename) {
+      return _textures[i].texture;
+    }
+  }
+  // If not, then load it.
+  _textures[_allocated].name = filename;
+  _textures[_allocated].texture = LoadImage(filename.c_str());
+
+  _allocated++;
+
+  return _textures[_allocated - 1].texture;
+}
+
+SDL_Surface* TextureManager::AddAlpha(string filename) {
+  assert(_allocated < TEXTURE_ARR_SIZE - 1);
+
+  // Has the texture been loaded already?
+  for(int i = 0; i < _allocated; i++) {
+    if(_textures[i].name == filename) {
+      return _textures[i].texture;
+    }
+  }
+
+  // If not, then load it.
+
+  _textures[_allocated].name = filename;
+  _textures[_allocated].texture = LoadImageAlpha(filename.c_str());
+
+  _allocated++;
+
+  return _textures[_allocated -1].texture;
+}
diff --git a/src/libUnuk/Sprite/TextureManager.h b/src/libUnuk/Sprite/TextureManager.h
new file mode 100644
index 0000000..a12a96c
--- /dev/null
+++ b/src/libUnuk/Sprite/TextureManager.h
@@ -0,0 +1,39 @@
+#pragma once
+
+/*
+ * The Texture Manager will keep a small "Database"
+ * of the name of the texture that is loaded and the
+ * actual texture so we can query it with the filename
+ * and it will return the teture if it is already in memory
+ * or load the tture if it is not.
+ */
+
+#include <SDL/SDL.h>
+#include <string>
+#include <assert.h>
+#include "ImageLoader.h"
+using namespace std;
+
+class TextureManager {
+public:
+  TextureManager(void);
+  ~TextureManager(void);
+
+  void Unload(void);
+
+  SDL_Surface* Add(string filename);
+  SDL_Surface* AddAlpha(string filename);
+
+private:
+  // The textureNode will hold the name and the texture.
+  struct textureNode {
+    SDL_Surface* texture;
+    string name;
+  };
+
+  // We should not need more than a hundred..
+  static const int TEXTURE_ARR_SIZE = 100;
+  textureNode _textures[TEXTURE_ARR_SIZE];
+
+  int _allocated;
+};
diff --git a/src/libUnuk/System/Debug.cpp b/src/libUnuk/System/Debug.cpp
new file mode 100644
index 0000000..db6a8b6
--- /dev/null
+++ b/src/libUnuk/System/Debug.cpp
@@ -0,0 +1,101 @@
+#include <iostream>
+#include <fstream>
+#include <cstdarg>
+#include <ctime>
+#include "Debug.h"
+#include "string"
+
+
+using namespace std;
+
+// ===================================================================
+// The Debug log allows us to display ever piece of data that
+// populates our class components, anything that is loaded, serialized,
+// de-serialized etc will be printed out to a text file.
+// (Running our program in a terminal, this debug log will print to it.)
+// ===================================================================
+
+Debug *Debug::logger = NULL;
+
+Debug::Debug(bool logToFile) {
+  time_t timestamp;
+  if(logToFile) {
+    _logFile.open("../Bin/Debug.log", ios::out);
+    if(!logToFile) {
+      // We can not open our log.
+      cerr << "Warning: Can not open Debug.log to write, continueing without logging\n";
+    } else {
+      // Log File is open, let us give it a nice time stamp.
+      timestamp = time(NULL);
+      _logFile << "Log Started: " << ctime(&timestamp) << endl;
+    }
+  }
+}
+
+Debug::~Debug(void) {
+  time_t timestamp;
+  
+  // We only need to close the log if it is open.
+  if(_logFile) {
+    // Give it a closing timestamp.
+    timestamp = time(NULL);
+    _logFile << endl << "Log Closed: " << ctime(&timestamp) << endl;
+    
+    // Close the log file.
+    _logFile.close();
+  }
+}
+
+void Debug::message(std::string msg) {
+  if(_logFile) {
+    _logFile << msg << endl;
+  }
+  cerr << msg << endl << endl;
+}
+
+void Debug::message(const char *msg, ...) {
+  va_list vargList; // This is to handlle the variable arguments
+
+  char outBuf[1024];
+  unsigned short outLen;
+
+  // This takes the arguments and puts them into the character array.
+  va_start(vargList, msg);
+
+#if defined WIN32
+  outLen = (unsigned short)_vsnprintf(outBuf, sizeof(outBuf), msg, vargList);
+#else
+  outLen = vsnprintf(outBuf, sizeof(outBuf), msg, vargList);
+#endif
+
+  va_end(vargList);
+
+  if(outLen >= sizeof(outBuf)) {
+    outLen = sizeof(outBuf);
+  }
+  
+  if(_logFile) {
+    _logFile << outBuf << endl;
+  }
+  
+  cerr << outBuf << endl;
+}
+
+bool Debug::openLog(bool logToFile) {
+  // Make sure the logger has not already been initialized.
+  if(logger != NULL) {
+    logger->message("Warning: Multiple calls to openLog().");
+    return false;
+  }
+  logger = new Debug(logToFile);
+  return true;
+}
+
+void Debug::closeLog(void) {
+  if(logger == NULL) {
+    cerr << "Warning: Call to closeLog() with NULL logger pointer." << endl;
+    return;
+  }
+  delete logger;
+  logger = NULL;
+}
diff --git a/src/libUnuk/System/Debug.h b/src/libUnuk/System/Debug.h
new file mode 100644
index 0000000..96e93f0
--- /dev/null
+++ b/src/libUnuk/System/Debug.h
@@ -0,0 +1,20 @@
+#pragma once
+#include <fstream>
+#include "string"
+
+class Debug {
+public:
+  Debug(bool logToFile);
+  ~Debug(void);
+
+  // Log an error message.
+  void message(std::string msg);
+  void message(const char *msg, ...);
+  static bool openLog(bool logToFile);
+  static void closeLog(void);
+  
+  static Debug *logger;
+
+private: 
+  std::ofstream _logFile;
+};
diff --git a/src/libUnuk/System/FPS.cpp b/src/libUnuk/System/FPS.cpp
new file mode 100644
index 0000000..b8608c3
--- /dev/null
+++ b/src/libUnuk/System/FPS.cpp
@@ -0,0 +1,41 @@
+#include "FPS.h"
+
+FPS::FPS(int maxFPSArg) {
+  _maxFPS = maxFPSArg;
+
+  _fps = 0;
+  _frame = 0;
+
+  _frameTimer.Start();
+  _fpsCalc.Start();
+}
+
+FPS::~FPS(void) {
+
+}
+
+void FPS::LimitFPS(void) {
+  // Calculate the FPS.
+  if(_fpsCalc.GetTicks() > 1000) {
+
+    _fps = _frame / (_fpsCalc.GetTicks() / 1000);
+
+    _fpsCalc.Start();
+    _frame = 0;
+  }
+
+  // Put a limitation on the FPS.
+  if(1000 / _maxFPS  > _frameTimer.GetTicks()) {
+    // SDL_Delay does not accept a float so for higher framerate
+    // limits there's an innacuracy. This is as much as 3fps
+    // at a limit of 60fps.
+    SDL_Delay((1000 / _maxFPS) - _frameTimer.GetTicks());
+  }
+
+  _frameTimer.Start();
+  _frame++;
+}
+
+void FPS::SetMaxFPS(int maxFPSArg) {
+  _maxFPS = maxFPSArg;
+}
diff --git a/src/libUnuk/System/FPS.h b/src/libUnuk/System/FPS.h
new file mode 100644
index 0000000..5a24263
--- /dev/null
+++ b/src/libUnuk/System/FPS.h
@@ -0,0 +1,25 @@
+#pragma once
+#include "../../Unuk/Globals.h"
+#include "Timer.h"
+
+
+class FPS {
+public:
+  FPS(int maxFPSArg);
+  ~FPS(void);
+
+  void LimitFPS(void);
+
+  void SetMaxFPS(int maxFPSArg);
+  int GetMaxFPS(void)       { return _maxFPS; }
+
+  int GetCurrentFPS(void)   { return _fps; }
+
+private:
+  int _fps;
+  int _frame;
+  int _maxFPS;
+
+  Timer _frameTimer;
+  Timer _fpsCalc;
+};
diff --git a/src/libUnuk/System/Input.cpp b/src/libUnuk/System/Input.cpp
new file mode 100644
index 0000000..a99b5d3
--- /dev/null
+++ b/src/libUnuk/System/Input.cpp
@@ -0,0 +1,82 @@
+#include <string.h>
+#include "Input.h"
+
+static mouse_t mouse;
+static keyboard_t keyboard;
+
+bool _curr_key(int index) {
+  return(keyboard.keys[index] != 0);
+}
+
+bool _old_key(int index) {
+  return(keyboard.oldKeys[index] != 0);
+}
+
+bool _curr_mouse(int button) {
+  return((mouse.buttons * SDL_BUTTON(button)) != 0);
+}
+
+bool _old_mouse(int button) {
+  return((mouse.oldButtons & SDL_BUTTON(button)) != 0);
+}
+
+bool CreateInput(void) {
+  memset(&keyboard, 0, sizeof(keyboard_t));
+  memset(&mouse, 0, sizeof(mouse_t));
+  SDL_PumpEvents();
+  SDL_PumpEvents();
+  unsigned char* tempKeys      = SDL_GetKeyState(&keyboard.keycount);
+  keyboard.keys                = (unsigned char*)malloc(sizeof(char) * keyboard.keycount);
+  keyboard.oldKeys             = (unsigned char*)malloc(sizeof(char) * keyboard.keycount);
+
+  memcpy(keyboard.keys, tempKeys, sizeof(char) * keyboard.keycount);
+  mouse.buttons = SDL_GetMouseState(&mouse.dx, &mouse.dy);
+  return true;
+}
+
+void UpdateInput(void) {
+  SDL_PumpEvents();
+  keyboard.lastChar     = -1;
+  mouse.oldx            = mouse.dx;
+  mouse.oldy            = mouse.dy;
+  mouse.oldButtons      = SDL_GetMouseState(&mouse.dx, &mouse.dy);
+
+  memcpy(keyboard.oldKeys, keyboard.keys, sizeof(char) * keyboard.keycount);
+
+  unsigned char *tmp = SDL_GetKeyState(&keyboard.keycount);
+  memcpy(keyboard.keys, tmp, sizeof(char) * keyboard.keycount);
+
+  keyboard.mods = SDL_GetModState();
+
+  SDL_Event event;
+  while(SDL_PollEvent(&event)) {
+    if(event.type == SDL_KEYDOWN) {
+      keyboard.lastChar = event.key.keysym.sym;
+    }
+  }
+}
+
+char GetKey(void) {
+  if(keyboard.lastChar != -1)
+    return (char)keyboard.lastChar;
+  return 0;
+}
+
+unsigned int GetX(void)           { return mouse.dx; }
+unsigned int GetY(void)           { return mouse.dy; }
+unsigned int GetOldX(void)        { return mouse.oldx; }
+unsigned int GetOldY(void)        { return mouse.oldy; }
+unsigned int GetMods(void)        { return  keyboard.mods; }
+bool KeyDown(int index)           { return(_curr_key(index)   && !_old_key(index)); }
+bool KeyStillDown(int index)      { return(_curr_key(index)   && _old_key(index)); }
+bool KeyUp(int index)             { return(!_curr_key(index) && _old_key(index)); }
+bool KeyStillUp(int index)        { return(!_curr_key(index) && !_old_key(index)); }
+bool MouseDown(int button)        { return(_curr_mouse(button) && !_old_mouse(button)); }
+bool MouseStillDown(int button)   { return(_curr_mouse(button) && _old_mouse(button)); }
+bool MouseUp(int button)          { return(!_curr_mouse(button) && _old_mouse(button)); }
+bool MouseStillUp(int button)     { return(!_curr_mouse(button) && !_old_mouse(button)); }
+
+void DestroyInput(void) {
+  free(keyboard.keys);
+  free(keyboard.oldKeys);
+}
diff --git a/src/libUnuk/System/Input.h b/src/libUnuk/System/Input.h
new file mode 100644
index 0000000..988dfee
--- /dev/null
+++ b/src/libUnuk/System/Input.h
@@ -0,0 +1,43 @@
+#pragma once
+#include <SDL/SDL.h>
+
+typedef struct mouse_s {
+  int dx, dy;
+  int oldx, oldy;
+  unsigned int buttons;
+  unsigned int oldButtons;
+} mouse_t;
+
+typedef struct keyboard_s {
+  unsigned char *keys;
+  unsigned char *oldKeys;
+  int keycount;
+  int lastChar;
+  unsigned int mods;
+} keyboard_t;
+
+typedef struct input_s {
+  mouse_t mouse;
+  keyboard_t keyboard;
+} input_t;
+
+  bool CreateInput(void);
+  void UpdateInput(void);
+
+  char GetKey(void);
+
+  unsigned int GetX(void);
+  unsigned int GetY(void);
+  unsigned int GetOldX(void);
+  unsigned int GetOldY(void);
+  unsigned int GetMods(void);
+  bool KeyDown(int index);
+  bool KeyStillDown(int index);
+  bool KeyUp(int index);
+  bool KeyStillUp(int index);
+  bool MouseDown(int button);
+  bool MouseStillDown(int button);
+  bool MouseUp(int button);
+  bool MouseStillUp(int button);
+
+  void DestroyInput(void);
diff --git a/src/libUnuk/System/Rect.cpp b/src/libUnuk/System/Rect.cpp
new file mode 100644
index 0000000..d2b1d53
--- /dev/null
+++ b/src/libUnuk/System/Rect.cpp
@@ -0,0 +1,66 @@
+#include "Rect.h"
+
+Rect::Rect(void) {
+}
+
+Rect::~Rect(void) {
+}
+
+void Rect::SetXY(int xArg, int yArg) {
+  rect.x = (Sint16)xArg;
+  rect.y = (Sint16)yArg;
+}
+
+void Rect::SetWidthHeight(int wArg, int hArg) {
+  rect.w = (Uint16)wArg;
+  rect.h = (Uint16)hArg;
+}
+
+void Rect::SetRGB(Uint8 rArg, Uint8 gArg, Uint8 bArg) {
+  r = rArg;
+  g = gArg;
+  b = bArg;
+}
+
+void Rect::SetRGB(SDL_Color colour) {
+  r = colour.r;
+  g = colour.g;
+  b = colour.b;
+}
+
+void Rect::Draw(void) {
+  SDL_Rect offset;
+
+  offset.x = rect.x - camera.x;
+  offset.y = rect.y - camera.y;
+  offset.w = rect.w;
+  offset.h = rect.h;
+
+  SDL_FillRect(screen, &offset, SDL_MapRGB(screen->format, r, g, b));
+}
+
+void Rect::Draw(int xArg, int yArg) {
+  SDL_Rect offset;
+
+  offset.x = (Sint16)(xArg - camera.x);
+  offset.y = (Sint16)(yArg - camera.y);
+  offset.w = (Sint16)rect.w;
+  offset.h = (Sint16)rect.h;
+
+  SDL_FillRect(screen, &offset, SDL_MapRGB(screen->format, r, g, b));
+}
+
+void Rect::DrawLiteral(void) {
+  SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, r, g, b));
+}
+
+void Rect::DrawLiteral(int xArg, int yArg) {
+  SDL_Rect offset;
+
+  offset.x = (Sint16)xArg;
+  offset.y = (Sint16)yArg;
+  offset.w = rect.w;
+  offset.h = rect.h;
+
+  SDL_FillRect(screen, &offset, SDL_MapRGB(screen->format, r, g, b));
+}
diff --git a/src/libUnuk/System/Rect.h b/src/libUnuk/System/Rect.h
new file mode 100644
index 0000000..645f3d7
--- /dev/null
+++ b/src/libUnuk/System/Rect.h
@@ -0,0 +1,35 @@
+#pragma once
+#include <SDL/SDL.h>
+#include "../../Unuk/Globals.h"
+#include "../Sprite/ApplySurface.h"
+using namespace std;
+
+class Rect {
+public:
+  Rect(void);
+  ~Rect(void);
+
+  int GetWidth(void)  { return rect.w; }
+  int GetHeight(void) { return rect.h; }
+  int GetX(void)      { return rect.x; }
+  int GetY(void)      { return rect.y; }
+
+  void SetXY(int xArg, int yArg);
+  void SetWidthHeight(int wArg, int hArg);
+
+  void SetRGB(Uint8 rArg, Uint8 gArg, Uint8 bArg);
+  void SetRGB(SDL_Color);
+
+  void Draw(void);
+  void Draw(int xArg, int yArg);
+  void DrawLiteral(void);
+  void DrawLiteral(int xArg, int yArg);
+
+protected:
+  Uint8 r;
+  Uint8 g;
+  Uint8 b;
+
+private:
+  SDL_Rect rect;
+};
diff --git a/src/libUnuk/System/Timer.cpp b/src/libUnuk/System/Timer.cpp
new file mode 100644
index 0000000..6b4f383
--- /dev/null
+++ b/src/libUnuk/System/Timer.cpp
@@ -0,0 +1,54 @@
+#include "Timer.h"
+
+Timer::Timer(void) {
+  _startTicks  = 0;
+  _pausedTicks = 0;
+  _paused  = false;
+  _started = false;
+}
+
+Timer::~Timer(void) {
+}
+
+void Timer::Start(void) {
+  _paused  = false;
+  _started = true;
+  _startTicks = SDL_GetTicks();
+}
+
+void Timer::Stop(void) {
+  _paused  = false;
+  _started = true;
+}
+
+void Timer::Pause(void) {
+  assert(_paused == false);
+  _paused = true;
+
+  _pausedTicks = SDL_GetTicks() - _startTicks;
+}
+
+void Timer::Unpause(void) {
+  assert(_paused == true);
+  _paused = false;
+
+  _startTicks = SDL_GetTicks() - _pausedTicks;
+
+  _pausedTicks = 0;
+}
+
+int Timer::GetTicks(void) {
+  if(_paused == true)
+    return _pausedTicks;
+  else if(_started == true)
+    return SDL_GetTicks() - _startTicks;
+  else
+    return 0;
+}
+
+string Timer::GetTicksStr(void) {
+  stringstream str;
+  str << GetTicks() << "ms";
+
+  return str.str();
+}
diff --git a/src/libUnuk/System/Timer.h b/src/libUnuk/System/Timer.h
new file mode 100644
index 0000000..d0d51b1
--- /dev/null
+++ b/src/libUnuk/System/Timer.h
@@ -0,0 +1,31 @@
+#pragma once
+#include <SDL/SDL.h>
+#include <string>
+#include <assert.h>
+#include <sstream>
+using namespace std;
+
+class Timer {
+public:
+  Timer(void);
+  ~Timer(void);
+
+  void Pause(void);
+  void Unpause(void);
+  void Start(void);
+  void Stop(void);
+
+  bool IsPaused(void)  { return _paused; }
+  bool IsStarted(void) { return _started; }
+
+  int GetTicks(void);
+
+  string GetTicksStr(void);
+
+private:
+  bool _paused;
+  bool _started;
+
+  int  _startTicks;
+  int  _pausedTicks;
+};
diff --git a/src/libUnuk/Ui/Button.cpp b/src/libUnuk/Ui/Button.cpp
new file mode 100644
index 0000000..2c0bc20
--- /dev/null
+++ b/src/libUnuk/Ui/Button.cpp
@@ -0,0 +1,120 @@
+#include "Button.h"
+
+Button::Button(void) {
+  _highlighted = false;
+  _mouseOver = false;
+}
+
+Button::~Button(void) {
+}
+
+void Button::SetOutRGB(Uint8 r, Uint8 g, Uint8 b) {
+  _button.SetRGB(r, g, b);
+  _mouseOutColour.r = r;
+  _mouseOutColour.g = g;
+  _mouseOutColour.b = b;
+}
+
+void Button::SetOutRGB(SDL_Color colour) {
+  _button.SetRGB(colour);
+  _mouseOutColour = colour;
+}
+
+void Button::SetOverRGB(Uint8 r, Uint8 g, Uint8 b) {
+  _mouseOverColour.r = r;
+  _mouseOverColour.g = g;
+  _mouseOverColour.b = b;
+}
+
+void Button::SetOverRGB(SDL_Color colour) {
+  _mouseOverColour = colour;
+}
+
+void Button::SetHighlightRGB(Uint8 r, Uint8 g, Uint8 b) {
+  _highlightColour.r = r;
+  _highlightColour.g = g;
+  _highlightColour.b = b;
+}
+
+void Button::SetHighlightRGB(SDL_Color colour) {
+  _highlightColour = colour;
+}
+
+void Button::SetXY(int xArg, int yArg) {
+  x = xArg;
+  y = yArg;
+  _button.SetXY(x, y);
+
+  _text.SetXY(x + 10, y + 10);
+}
+
+void Button::SetTextRGB(Uint8 r, Uint8 g, Uint8 b) {
+  _textColour.r = r;
+  _textColour.g = g;
+  _textColour.b = b;
+
+  _text.SetTextBlended(_text.GetText(), small, _textColour);
+}
+
+void Button::SetTextRGB(SDL_Color colour) {
+  _textColour = colour;
+  _text.SetTextBlended(_text.GetText(), small, colour);
+}
+
+void Button::SetText(string textArg) {
+  _text.SetTextBlended(textArg, small, _textColour);
+
+  w = _text.GetWidth();
+  h = _text.GetHeight();
+  _button.SetWidthHeight(w + 20, h + 15);
+}
+
+bool Button::CheckMouseOver(void) {
+  if(event.motion.x > _button.GetX() && event.motion.x < _button.GetX() + _button.GetWidth()) {
+    if(event.motion.y > _button.GetY() && event.motion.y < _button.GetY() + _button.GetHeight()) {
+      if(!_highlighted) {
+        _button.SetRGB(_mouseOverColour.r, _mouseOverColour.g, _mouseOverColour.b);
+      }
+      return true;
+    }
+  }
+  if(!_highlighted) {
+    _button.SetRGB(_mouseOutColour);
+  }
+  return false;
+}
+
+void Button::SetHighlighted(bool highlighted) { 
+  if(_highlighted != highlighted) {
+    if(highlighted) {
+      _button.SetRGB(_highlightColour);
+    } else {
+      if(!_mouseOver) {
+        _button.SetRGB(_mouseOverColour);
+      } else {
+        _button.SetRGB(_textColour);
+      }
+    }
+  }
+  _highlighted = highlighted;
+}
+
+void Button::Render(void) {
+  _button.Draw();
+  _text.Render();
+}
+
+void Button::Render(int xArg, int yArg) {
+  _button.Draw(xArg, yArg);
+  _text.Render(xArg, yArg);
+}
+
+void Button::RenderLiteral(void) {
+  _button.DrawLiteral();
+  _text.RenderLiteral();
+}
+
+void Button::RenderLiteral(int xArg, int yArg) {
+  _button.DrawLiteral(xArg, yArg);
+  _text.RenderLiteral(xArg, yArg);
+}
diff --git a/src/libUnuk/Ui/Button.h b/src/libUnuk/Ui/Button.h
new file mode 100644
index 0000000..56ba241
--- /dev/null
+++ b/src/libUnuk/Ui/Button.h
@@ -0,0 +1,62 @@
+#pragma once
+#include <SDL/SDL.h>
+#include <SDL/SDL_ttf.h>
+
+#include "../../Unuk/Globals.h"
+#include "../System/Input.h"
+#include "../Ui/Text.h"
+#include "../System/Rect.h"
+
+class Button {
+public:
+  Button(void);
+  ~Button(void);
+
+  void SetOutRGB(Uint8 r, Uint8 g, Uint8 b);
+  void SetOutRGB(SDL_Color);
+  void SetOverRGB(Uint8 r, Uint8 g, Uint8 b);
+  void SetOverRGB(SDL_Color);
+
+  void SetTextRGB(Uint8 r, Uint8 g, Uint8 b);
+  void SetTextRGB(SDL_Color);
+  void SetText(string textArg);
+
+  void SetHighlightRGB(Uint8 r, Uint8 g, Uint8 b);
+  void SetHighlightRGB(SDL_Color);
+
+  void SetHighlighted(bool highlighted);
+
+  void SetXY(int xArg, int yArg);
+
+  int GetX(void)        const     { return x; }
+  int GetY(void)        const     { return y; }
+  int GetWidth(void)    const     { return w; }
+  int GetHeight(void)   const     { return h; }
+
+  bool GetHighlighted(void) { return _highlighted; }
+
+  bool CheckMouseOver(void);
+
+  void Render(void);
+  void Render(int xArg, int yArg);
+  void RenderLiteral(void);
+  void RenderLiteral(int xArg, int yArg);
+
+private:
+  SDL_Color _mouseOutColour;
+  SDL_Color _mouseOverColour;
+  SDL_Color _textColour;
+  SDL_Color _highlightColour;
+
+  int x;
+  int y;
+  int w;
+  int h;
+
+  Rect _button;
+  Text _text;
+
+  bool _highlighted;
+
+  bool _mouseOver;
+};
diff --git a/src/libUnuk/Ui/ButtonGroup.cpp b/src/libUnuk/Ui/ButtonGroup.cpp
new file mode 100644
index 0000000..4bdfd02
--- /dev/null
+++ b/src/libUnuk/Ui/ButtonGroup.cpp
@@ -0,0 +1,101 @@
+#include "ButtonGroup.h"
+
+ButtonGroup::ButtonGroup(void) {
+  _selectedButton = -1;
+}
+
+ButtonGroup::~ButtonGroup(void) {
+  for(std::list<Button*>::iterator i = _buttons.begin(); i != _buttons.end(); ++i) {
+    Button* btn = (*i);
+    delete btn;
+  }
+}
+
+void ButtonGroup::CheckMouseOverDummy(void) {
+  for(std::list<Button*>::iterator i = _buttons.begin(); i != _buttons.end(); ++i) {
+    (*i)->CheckMouseOver();
+  }
+}
+
+int ButtonGroup::CheckMouseOver(void) {
+  int buttonIndex = 0;
+  for(std::list<Button*>::iterator i = _buttons.begin(); i != _buttons.end(); ++i) {
+    if((*i)->CheckMouseOver()) {
+      return buttonIndex;
+    }
+    buttonIndex++;
+  }
+  return -1;
+}
+
+void ButtonGroup::RenderLiteral(void) {
+  for(std::list<Button*>::iterator i = _buttons.begin(); i != _buttons.end(); ++i) {
+    (*i)->RenderLiteral();
+  }
+}
+
+void ButtonGroup::AddButton(Button* button) {
+  _buttons.push_back(button);
+}
+
+void ButtonGroup::RemoveButton(int index) {
+  int buttonsIndex = 0;
+  for(std::list<Button*>::iterator i = _buttons.begin(); i != _buttons.end(); ++i) {
+    if(buttonsIndex == index) {
+      _buttons.erase(i);
+      break;
+    }
+    buttonsIndex++;
+  }
+}
+
+void ButtonGroup::SelectNext(void) {
+  if(_selectedButton == -1) {
+    HighlightNewSelection(0);
+  } else {
+    HighlightNewSelection(_selectedButton + 1);
+  }
+}
+
+void ButtonGroup::SelectPrevious(void) {
+  if(_selectedButton == -1) {
+    HighlightNewSelection(0);
+  } else {
+    HighlightNewSelection(_selectedButton - 1);
+  }
+}
+
+void ButtonGroup::SetSelectedButton(int button) {
+  HighlightNewSelection(button);
+}
+
+void ButtonGroup::HighlightNewSelection(int newButton) {
+  if(_selectedButton != -1) {
+    // Turn off highlight for currently highlighted button
+    GetButton(_selectedButton)->SetHighlighted(false);
+  }
+
+  _selectedButton = newButton;
+
+  // If < 0 then up was pressed when first index was selected
+  // If >= _buttons.size() then down was pressed when last index was selected
+  if(_selectedButton < 0) {
+    _selectedButton = _buttons.size() - 1;
+  } else if(_selectedButton >= (int)_buttons.size()) {
+    _selectedButton = 0;
+  }
+
+  // Highlight new selection
+  GetButton(_selectedButton)->SetHighlighted(true);
+}
+
+Button* ButtonGroup::GetButton(int index) {
+  int buttonsIndex = 0;
+  for(std::list<Button*>::iterator i = _buttons.begin(); i != _buttons.end(); ++i) {
+    if(buttonsIndex == index) {
+      return (*i);
+    }
+    buttonsIndex++;
+  }
+  return NULL;
+}
diff --git a/src/libUnuk/Ui/ButtonGroup.h b/src/libUnuk/Ui/ButtonGroup.h
new file mode 100644
index 0000000..05a4a76
--- /dev/null
+++ b/src/libUnuk/Ui/ButtonGroup.h
@@ -0,0 +1,33 @@
+#pragma once
+#include <list>
+
+#include "../Ui/Button.h"
+#include "../Engine/MemClass.h"
+
+class ButtonGroup {
+public:
+  ButtonGroup(void);
+  ~ButtonGroup(void);
+
+  void  CheckMouseOverDummy(void);
+  int   CheckMouseOver(void);
+
+  void RenderLiteral(void);
+
+  void AddButton(Button* button);
+  void RemoveButton(int index);
+
+  void SelectNext(void);
+  void SelectPrevious(void);
+
+  int   GetSelectedButton(void)         { return _selectedButton; }
+  void  SetSelectedButton(int button);
+
+  Button* GetButton(int index);
+
+private:
+  void HighlightNewSelection(int newButton);
+
+  std::list<Button*> _buttons;
+  int _selectedButton;
+};
diff --git a/src/libUnuk/Ui/ButtonToggle.cpp b/src/libUnuk/Ui/ButtonToggle.cpp
new file mode 100644
index 0000000..3451aca
--- /dev/null
+++ b/src/libUnuk/Ui/ButtonToggle.cpp
@@ -0,0 +1,35 @@
+#include "ButtonToggle.h"
+
+ButtonToggle::ButtonToggle(void) {
+
+}
+
+ButtonToggle::~ButtonToggle(void) {
+
+}
+
+void ButtonToggle::SetOverRGB(Uint8 r, Uint8 g, Uint8 b) {
+  Button::SetOverRGB(r, g, b);
+}
+
+void ButtonToggle::SetOverRGB(SDL_Color colour) {
+  Button::SetOverRGB(colour);
+}
+
+void ButtonToggle::SetOffRGB(Uint8 r, Uint8 g, Uint8 b) {
+  ButtonToggle::SetOutRGB(r, g, b);
+}
+
+void ButtonToggle::SetOffRGB(SDL_Color colour) {
+  Button::SetOutRGB(colour);
+}
+
+void ButtonToggle::SetOnRGB(Uint8 r, Uint8 g, Uint8 b) {
+  _onColour.r = r;
+  _onColour.g = g;
+  _onColour.b = b;
+}
+
+void ButtonToggle::SetOnRGB(SDL_Color colour) {
+  _onColour = colour;
+}
diff --git a/src/libUnuk/Ui/ButtonToggle.h b/src/libUnuk/Ui/ButtonToggle.h
new file mode 100644
index 0000000..83c5362
--- /dev/null
+++ b/src/libUnuk/Ui/ButtonToggle.h
@@ -0,0 +1,36 @@
+#pragma once
+#include <SDL/SDL.h>
+#include <SDL/SDL_ttf.h>
+
+#include "Button.h"
+
+class ButtonToggle : protected Button {
+public:
+  ButtonToggle(void);
+  ~ButtonToggle(void);
+
+  void SetOverRGB(Uint8 r, Uint8 g, Uint8 b);
+  void SetOverRGB(SDL_Color);
+  void SetOffRGB(Uint8 r, Uint8 g, Uint8 b);
+  void SetOffRGB(SDL_Color);
+  void SetOnRGB(Uint8 r, Uint8 g, Uint8 b);
+  void SetOnRGB(SDL_Color);
+
+  void SetTextRGB(Uint8 r, Uint8 g, Uint8 b);
+  void SetOnText(string);
+  void SetOffText(string);
+
+  void SetState(bool);
+  bool GetState(void) { return _state; }
+
+  bool CheckMouseOver(void);
+
+  void Render(void);
+
+private:
+  bool _state;
+
+  SDL_Colour _onColour;
+
+  Text _onText;
+};
diff --git a/src/libUnuk/Ui/Font.cpp b/src/libUnuk/Ui/Font.cpp
new file mode 100644
index 0000000..bee12a5
--- /dev/null
+++ b/src/libUnuk/Ui/Font.cpp
@@ -0,0 +1,11 @@
+#include "Font.h"
+
+TTF_Font* Font(const char* filename, const int size) {
+  ifstream font(filename);
+
+  if(font.is_open() == false) {
+    Debug::logger->message("Font: %s cannot be found.");
+    exit(-1);
+  }
+  return TTF_OpenFont(filename, size);
+}
diff --git a/src/libUnuk/Ui/Font.h b/src/libUnuk/Ui/Font.h
new file mode 100644
index 0000000..fc2617b
--- /dev/null
+++ b/src/libUnuk/Ui/Font.h
@@ -0,0 +1,8 @@
+#pragma once
+#include <SDL/SDL_ttf.h>
+#include <fstream>
+#include <assert.h>
+#include "../System/Debug.h"
+using namespace std;
+
+TTF_Font* Font(const char* filename, const int size);
diff --git a/src/libUnuk/Ui/IngameMenu.cpp b/src/libUnuk/Ui/IngameMenu.cpp
new file mode 100644
index 0000000..c67b91a
--- /dev/null
+++ b/src/libUnuk/Ui/IngameMenu.cpp
@@ -0,0 +1,99 @@
+#include "IngameMenu.h"
+
+IngameMenu::IngameMenu(void) {
+  _active = false;
+
+  Button* btnResume = new Button();
+  btnResume->SetOutRGB(200, 200, 200);
+  btnResume->SetOverRGB(255, 255, 255);
+  btnResume->SetTextRGB(0, 0, 0);
+  btnResume->SetText("Resume Game");
+  btnResume->SetHighlightRGB(255, 128, 0);
+  btnResume->SetHighlighted(false);
+  btnResume->SetXY(SCREEN_WIDTH / 2 - btnResume->GetWidth() / 2, 50);
+
+  Button* btnSaveGame = new Button();
+  btnSaveGame->SetOutRGB(200, 200, 200);
+  btnSaveGame->SetOverRGB(255, 255, 255);
+  btnSaveGame->SetTextRGB(0, 0, 0);
+  btnSaveGame->SetText("SaveGame");
+  btnSaveGame->SetHighlightRGB(255, 128, 0);
+  btnSaveGame->SetHighlighted(false);
+  btnSaveGame->SetXY(SCREEN_WIDTH / 2 - btnSaveGame->GetWidth() / 2, 100);
+
+  Button* btnLoadGame = new Button();
+  btnLoadGame->SetOutRGB(200, 200, 200);
+  btnLoadGame->SetOverRGB(255, 255, 255);
+  btnLoadGame->SetTextRGB(0, 0, 0);
+  btnLoadGame->SetText("LoadGame");
+  btnLoadGame->SetHighlightRGB(255, 128, 0);
+  btnLoadGame->SetHighlighted(false);
+  btnLoadGame->SetXY(SCREEN_WIDTH / 2 - btnLoadGame->GetWidth() / 2, 150);
+
+  Button* btnOptions = new Button();
+  btnOptions->SetOutRGB(200, 200, 200);
+  btnOptions->SetOverRGB(255, 255, 255);
+  btnOptions->SetTextRGB(0, 0, 0);
+  btnOptions->SetText("Options");
+  btnOptions->SetHighlightRGB(255, 128, 0);
+  btnOptions->SetHighlighted(false);
+  btnOptions->SetXY(SCREEN_WIDTH / 2 - btnOptions->GetWidth() / 2, 200);
+
+  Button* btnExitToMenu = new Button();
+  btnExitToMenu->SetOutRGB(200, 200, 200);
+  btnExitToMenu->SetOverRGB(255, 255, 255);
+  btnExitToMenu->SetTextRGB(0, 0, 0);
+  btnExitToMenu->SetText("Exit To Main Menu");
+  btnExitToMenu->SetHighlightRGB(255, 128, 0);
+  btnExitToMenu->SetHighlighted(false);
+  btnExitToMenu->SetXY(SCREEN_WIDTH / 2 - btnExitToMenu->GetWidth() / 2, 250);
+
+  _buttons.AddButton(btnResume);
+  _buttons.AddButton(btnSaveGame);
+  _buttons.AddButton(btnLoadGame);
+  _buttons.AddButton(btnOptions);
+  _buttons.AddButton(btnExitToMenu);
+}
+
+IngameMenu::~IngameMenu(void) {
+}
+
+ingameMenuNavVal_t IngameMenu::HandleInput(void) {
+  while(SDL_PollEvent(&event)) {
+    _buttons.CheckMouseOverDummy();
+
+    if(event.key.type == SDL_KEYDOWN) {
+      if(event.key.keysym.sym == SDLK_ESCAPE) {
+        return ingameMenuResume;
+      } else if(event.key.keysym.sym == SDLK_DOWN) {
+        _buttons.SelectNext();
+      } else if(event.key.keysym.sym == SDLK_UP) {
+        _buttons.SelectPrevious();
+      } else if(event.key.keysym.sym == SDLK_RETURN) {
+        switch(_buttons.GetSelectedButton()) {
+          case 0: return ingameMenuResume;
+          case 1: return ingameMenuSaveGame;
+          case 2: return ingameMenuLoadGame;
+          case 3: return ingameMenuOptions;
+          case 4: return ingameMenuMainMenu;
+        }
+      }
+    }
+    else if(event.type == SDL_MOUSEBUTTONUP) {
+      if(event.button.button == SDL_BUTTON_LEFT) {
+        switch(_buttons.CheckMouseOver()) {
+          case 0: return ingameMenuResume;
+          case 1: return ingameMenuSaveGame;
+          case 2: return ingameMenuLoadGame;
+          case 3: return ingameMenuOptions;
+          case 4: return ingameMenuMainMenu;
+        }
+      }
+    }
+  }
+  return ingameMenuNothing;
+}
+
+void IngameMenu::Render(void) {
+  _buttons.RenderLiteral();
+}
\ No newline at end of file
diff --git a/src/libUnuk/Ui/IngameMenu.h b/src/libUnuk/Ui/IngameMenu.h
new file mode 100644
index 0000000..ef2b84e
--- /dev/null
+++ b/src/libUnuk/Ui/IngameMenu.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include "../../Unuk/Globals.h"
+#include "../../Unuk/Constants.h"
+#include "ButtonGroup.h"
+#include "ButtonToggle.h"
+
+enum ingameMenuNavVal_t {
+  ingameMenuNothing,
+  ingameMenuResume,
+  ingameMenuSaveGame,
+  ingameMenuLoadGame,
+  ingameMenuOptions,
+  ingameMenuMainMenu
+};
+
+class IngameMenu {
+public:
+  IngameMenu(void);
+  ~IngameMenu(void);
+
+  ingameMenuNavVal_t HandleInput(void);
+  void Render(void);
+
+  void SetStatus(bool arg)  { _active = arg; }
+  bool GetStatus(void)      { return _active; }
+
+private:
+  bool _active;
+
+  ButtonGroup _buttons;
+};
diff --git a/src/libUnuk/Ui/MainMenu.cpp b/src/libUnuk/Ui/MainMenu.cpp
new file mode 100644
index 0000000..3b75bcf
--- /dev/null
+++ b/src/libUnuk/Ui/MainMenu.cpp
@@ -0,0 +1,171 @@
+#include "MainMenu.h"
+
+MainMenu::MainMenu(void) {
+  Button* btnNewGame = new Button();
+  btnNewGame->SetOutRGB(200, 200, 200);
+  btnNewGame->SetOverRGB(255, 255, 255);
+  btnNewGame->SetTextRGB(0, 0, 0);
+  btnNewGame->SetText("New Game");
+  btnNewGame->SetXY(100, 150);
+  btnNewGame->SetHighlightRGB(255, 128, 0);
+  btnNewGame->SetHighlighted(false);
+
+  Button* btnLoadGame = new Button();
+  btnLoadGame->SetOutRGB(200, 200, 200);
+  btnLoadGame->SetOverRGB(255, 255, 255);
+  btnLoadGame->SetTextRGB(0, 0, 0);
+  btnLoadGame->SetText("Load Game");
+  btnLoadGame->SetHighlightRGB(255, 128, 0);
+  btnLoadGame->SetHighlighted(false);
+  btnLoadGame->SetXY(100, 200);
+
+  Button* btnOptions = new Button();
+  btnOptions->SetOutRGB(200, 200, 200);
+  btnOptions->SetOverRGB(255, 255, 255);
+  btnOptions->SetTextRGB(0, 0, 0);
+  btnOptions->SetText("Options");
+  btnOptions->SetHighlightRGB(255, 128, 0);
+  btnOptions->SetHighlighted(false);
+  btnOptions->SetXY(100, 250);
+
+  Button* btnExit = new Button();
+  btnExit->SetOutRGB(200, 200, 200);
+  btnExit->SetOverRGB(255, 255, 255);
+  btnExit->SetTextRGB(0, 0, 0);
+  btnExit->SetText("Exit");
+  btnExit->SetHighlightRGB(255, 128, 0);
+  btnExit->SetHighlighted(false);
+  btnExit->SetXY(100, 300);  
+
+  grpMain.AddButton(btnNewGame);
+  grpMain.AddButton(btnLoadGame);
+  grpMain.AddButton(btnOptions);
+  grpMain.AddButton(btnExit);
+
+  btnNewGameActive = false;
+
+  lblNewGame.SetXY(275, 160);
+  lblNewGame.SetTextBlended("This will delete your current game, are you sure?", vsmall, 0, 0, 0);
+
+  rectNewGame.SetRGB(200, 200, 200);
+  rectNewGame.SetXY(250, 150);
+  rectNewGame.SetWidthHeight(lblNewGame.GetWidth() + 50, 90);
+
+  lblMenu.SetXY(100, 75);
+  lblMenu.SetTextBlended("Unuk", vlarge, 0, 0, 0);
+
+  Button* btnNewGameYes = new Button();
+  btnNewGameYes->SetOutRGB(20, 150, 20);
+  btnNewGameYes->SetOverRGB(20, 255, 20);
+  btnNewGameYes->SetTextRGB(0, 0, 0);
+  btnNewGameYes->SetText("Yes");
+  btnNewGameYes->SetHighlightRGB(255, 128, 0);
+  btnNewGameYes->SetHighlighted(false);
+  btnNewGameYes->SetXY(rectNewGame.GetX() + rectNewGame.GetWidth() / 2 - 40 - btnNewGameYes->GetWidth(), 190);
+
+  Button* btnNewGameNo = new Button();
+  btnNewGameNo->SetOutRGB(150, 20, 20);
+  btnNewGameNo->SetOverRGB(255, 20, 20);
+  btnNewGameNo->SetTextRGB(0, 0, 0);
+  btnNewGameNo->SetText("No");
+  btnNewGameNo->SetHighlightRGB(255, 128, 0);
+  btnNewGameNo->SetHighlighted(false);
+  btnNewGameNo->SetXY(rectNewGame.GetX() + rectNewGame.GetWidth() / 2 + 40 - btnNewGameNo->GetWidth(), 190);
+
+  grpNewGame.AddButton(btnNewGameYes);
+  grpNewGame.AddButton(btnNewGameNo);
+
+  //m_background.Load("MainMenu");
+
+  camera.x = 0;
+  camera.y = 0;
+}
+
+MainMenu::~MainMenu(void) {
+
+}
+
+mainMenuNavVal_t MainMenu::Run(void) {
+  FPS fpsLimiter(20);
+
+  bool running = true;
+  while(running) {
+    Render();
+    SDL_Flip(screen);
+
+    while(SDL_PollEvent(&event)) {
+      grpMain.CheckMouseOverDummy();
+
+      if(btnNewGameActive) {
+        grpNewGame.CheckMouseOverDummy();
+      }
+
+      if(event.key.type == SDL_KEYDOWN) {
+        if(event.key.keysym.sym == SDLK_DOWN) {
+          if(btnNewGameActive) {
+            grpNewGame.SelectNext();
+          } else {
+            grpMain.SelectNext();
+          }
+        } else if(event.key.keysym.sym == SDLK_UP) {
+          if(btnNewGameActive) {
+            grpNewGame.SelectPrevious();
+          } else {
+            grpMain.SelectPrevious();
+          }
+        } else if(event.key.keysym.sym == SDLK_RETURN) {
+          if(btnNewGameActive) {
+            switch(grpNewGame.GetSelectedButton()) {
+              case 0: return mainMenuNewGame; break;
+              case 1: btnNewGameActive = false; break;
+            }
+          } else {
+            switch(grpMain.GetSelectedButton()) {
+              case 0: btnNewGameActive = !btnNewGameActive; break;
+              case 1: return mainMenuLoadGame;
+              case 2: return mainMenuOptions;
+              case 3: return mainMenuExitGame;
+            }
+          }
+        }
+      }
+      else if(event.type == SDL_MOUSEBUTTONUP) {
+        if(event.button.button == SDL_BUTTON_LEFT) {
+          switch(grpMain.CheckMouseOver()) {
+            case 0: btnNewGameActive = !btnNewGameActive; break;
+            case 1: return mainMenuLoadGame;
+            case 2: return mainMenuOptions;
+            case 3: return mainMenuExitGame;
+          }
+
+          if(btnNewGameActive) {
+            switch(grpNewGame.CheckMouseOver()) {
+              case 0: return mainMenuNewGame; break;
+              case 1: btnNewGameActive = false; break;
+            }
+          }
+        }
+      }
+      else if(event.type == SDL_QUIT) {
+        return mainMenuExitGame;
+      }
+    }
+
+    fpsLimiter.LimitFPS();
+  }
+  return mainMenuExitGame;
+}
+
+void MainMenu::Render(void) {
+  //m_background.Render();
+
+  lblMenu.Render();
+
+  grpMain.RenderLiteral();
+
+  if(btnNewGameActive) {
+    rectNewGame.Draw();
+    lblNewGame.Render();
+    grpNewGame.RenderLiteral();
+  }
+}
diff --git a/src/libUnuk/Ui/MainMenu.h b/src/libUnuk/Ui/MainMenu.h
new file mode 100644
index 0000000..fc79dd0
--- /dev/null
+++ b/src/libUnuk/Ui/MainMenu.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "../../Unuk/Constants.h"
+#include "../System/FPS.h"
+#include "../Ui/ButtonGroup.h"
+#include "../Map/Map.h"
+#include "../System/Rect.h"
+#include "../Ui/Text.h"
+
+enum mainMenuNavVal_t {
+  mainMenuNewGame,
+  mainMenuLoadGame,
+  mainMenuOptions,
+  mainMenuExitGame
+};
+
+class MainMenu {
+public:
+  MainMenu(void);
+  ~MainMenu(void);
+
+  mainMenuNavVal_t Run(void);
+
+private:
+  void Render(void);
+
+  Map _background;
+
+  Text lblMenu;
+
+  ButtonGroup grpMain;
+
+  bool        btnNewGameActive;
+  Rect        rectNewGame;
+  Text        lblNewGame;
+  ButtonGroup grpNewGame;
+};
diff --git a/src/libUnuk/Ui/Text.cpp b/src/libUnuk/Ui/Text.cpp
new file mode 100644
index 0000000..f76861b
--- /dev/null
+++ b/src/libUnuk/Ui/Text.cpp
@@ -0,0 +1,269 @@
+#include "Text.h"
+
+TTF_Font* Text::vSmallFont   = NULL;
+TTF_Font* Text::smallFont    = NULL;
+TTF_Font* Text::mediumFont   = NULL;
+TTF_Font* Text::largeFont    = NULL;
+TTF_Font* Text::vLargeFont   = NULL;
+
+const static int lineSpacing = 3;
+
+Text::Text(void) {
+  x = 0;
+  y = 0;
+  w = 0;
+  h = 0;
+  lineWidth=50;
+}
+
+Text::~Text(void) {
+  if(!_lines.empty()) {
+    for(std::list<SDL_Surface*>::iterator it = _lines.begin(); it != _lines.end(); ++it) {
+      SDL_FreeSurface(*it);
+    }
+    _lines.clear();
+  }
+}
+
+void Text::LoadFonts(void) {
+  // Load the fonts if they are not already in memory.
+  assert(vSmallFont == NULL);
+  assert(smallFont  == NULL);
+  assert(mediumFont == NULL);
+  assert(largeFont  == NULL);
+  assert(vLargeFont == NULL);
+
+  vSmallFont      = Font("../Data/Media/Fonts/Enigma_2.ttf", 16);
+  smallFont       = Font("../Data/Media/Fonts/Enigma_2.ttf", 23);
+  mediumFont      = Font("../Data/Media/Fonts/Enigma_2.ttf", 27);
+  largeFont       = Font("../Data/Media/Fonts/Enigma_2.ttf", 32);
+  vLargeFont      = Font("../Data/Media/Fonts/Enigma_2.ttf", 48);
+}
+
+void Text::FreeFonts(void) {
+  // If the fonts are loaded, then free them.
+  assert(vSmallFont != NULL);
+  assert(smallFont  != NULL);
+  assert(mediumFont != NULL);
+  assert(largeFont  != NULL);
+  assert(vLargeFont != NULL);
+
+  TTF_CloseFont(vSmallFont);
+  TTF_CloseFont(smallFont);
+  TTF_CloseFont(mediumFont);
+  TTF_CloseFont(largeFont);
+  TTF_CloseFont(vLargeFont);
+}
+
+void Text::SetXY(int xArg, int yArg) {
+  x = xArg;
+  y = yArg;
+}
+
+int Text::SetTextBlended(string textArg, textSizes_t size, SDL_Color colour,bool wordWrap) {
+  _textContents = textArg;
+
+  if(!_lines.empty()) {
+    for(std::list<SDL_Surface*>::iterator it = _lines.begin(); it != _lines.end(); ++it) {
+      SDL_FreeSurface(*it);
+    }
+    _lines.clear();
+  }
+
+  TTF_Font* font = NULL;
+  if(size == vsmall) {
+    font = vSmallFont;
+  } else if(size == small) {
+    font = smallFont;
+  } else if(size == medium) {
+    font = mediumFont;
+  } else if(size == large) {
+    font = largeFont;
+  } else {
+    font = vLargeFont;
+  }
+
+  std::string finalTextContents = textArg;
+
+  if(wordWrap) {
+    finalTextContents = DoWordWrap(font, finalTextContents);
+  }
+  
+  std::list<std::string> lines;
+  std::string line;
+  for(int i = 0; i < (int)finalTextContents.size(); i++) {
+    char c = finalTextContents.at(i);
+    if(c == '\n') {
+      lines.push_back(line);
+      line.clear();
+    } else {
+      line += c;
+    }
+  }
+  if (!line.empty()) {
+    lines.push_back(line);
+  }
+
+  for(std::list<std::string>::iterator it = lines.begin(); it != lines.end(); ++it) {
+    SDL_Surface* lineSurf = TTF_RenderText_Blended(font, it->c_str(), colour);
+
+    int linePixelWidth;
+    int linePixelHeight;
+    TTF_SizeText(font, it->c_str(), &linePixelWidth, &linePixelHeight);
+
+    if(linePixelWidth > w) {
+      w = linePixelWidth;
+    }
+
+    h += linePixelHeight + lineSpacing; 
+
+    _lines.push_back(lineSurf);
+  }
+
+  return 1;
+}
+
+int Text::SetTextBlended(string textArg, textSizes_t size, Uint8 r, Uint8 g, Uint8 b, bool wordWrap) {
+  SDL_Color f = { r, g, b };
+  return SetTextBlended(textArg, size, f, wordWrap);
+}
+
+int Text::SetTextShaded(string textArg, textSizes_t size, SDL_Color colour, SDL_Color bgColour, bool wordWrap) {
+  _textContents = textArg;
+
+  if(!_lines.empty()) {
+    for(std::list<SDL_Surface*>::iterator it = _lines.begin(); it != _lines.end(); ++it) {
+      SDL_FreeSurface(*it);
+    }
+    _lines.clear();
+  }
+
+  TTF_Font* font = NULL;
+  if(size == vsmall) {
+    font = vSmallFont;
+  } else if(size == small) {
+    font = smallFont;
+  } else if(size == medium) {
+    font = mediumFont;
+  } else if(size == large) {
+    font = largeFont;
+  } else {
+    font = vLargeFont;
+  }
+
+  std::string finalTextContents = textArg;
+
+  if(wordWrap) {
+    finalTextContents = DoWordWrap(font, finalTextContents);
+  }
+
+  std::list<std::string> lines;
+  std::string line;
+  for(int i = 0; i < (int)finalTextContents.size(); i++) {
+    char c = finalTextContents.at(i);
+    if(c == '\n') {
+      lines.push_back(line);
+      line.clear();
+    } else {
+      line += c;
+    }
+  }
+  if (!line.empty()) {
+    lines.push_back(line);
+  }
+
+  for(std::list<std::string>::iterator it = lines.begin(); it != lines.end(); ++it) {
+    SDL_Surface* lineSurf = TTF_RenderText_Shaded(font, it->c_str(), colour, bgColour);
+
+    int linePixelWidth;
+    int linePixelHeight;
+    TTF_SizeText(font, it->c_str(), &linePixelWidth, &linePixelHeight);
+
+    if(linePixelWidth > w) {
+      w = linePixelWidth;
+    }
+
+    h += linePixelHeight + lineSpacing; 
+
+    _lines.push_back(lineSurf);
+  }
+
+  return 1;
+}
+
+int Text::SetTextShaded(string textArg, textSizes_t size, Uint8 rF, Uint8 gF, Uint8 bF, Uint8 rB, Uint8 gB, Uint8 bB, bool wordWrap) {
+  SDL_Color f = { rF, gF, bF };
+  SDL_Color b = { rB, gB, bB };
+  return SetTextShaded(textArg, size, f, b, wordWrap);
+}
+
+void Text::Render(void) {
+  int yOffset = 0;
+  for(std::list<SDL_Surface*>::iterator it = _lines.begin(); it != _lines.end(); ++it) {
+    SDL_Surface* lineSurf = *it;
+    ApplySurface(x, y + yOffset, lineSurf, screen);  
+    yOffset += lineSurf->h + lineSpacing; 
+  }
+}
+
+void Text::Render(int xArg, int yArg) {
+  int yOffset = 0;
+  for(std::list<SDL_Surface*>::iterator it = _lines.begin(); it != _lines.end(); ++it) {
+    SDL_Surface* lineSurf = *it;
+    ApplySurface(x + xArg, y + yArg + yOffset, lineSurf, screen);  
+    yOffset += lineSurf->h + lineSpacing; 
+  }
+}
+
+void Text::RenderLiteral(void) {
+  int yOffset = 0;
+  for(std::list<SDL_Surface*>::iterator it = _lines.begin(); it != _lines.end(); ++it) {
+    SDL_Surface* lineSurf = *it;
+    ApplySurfaceLiteral(x, y + yOffset, lineSurf, screen);  
+    yOffset += lineSurf->h + lineSpacing; 
+  }
+}
+
+void Text::RenderLiteral(int xArg, int yArg) {
+  int yOffset = 0;
+  for(std::list<SDL_Surface*>::iterator it = _lines.begin(); it != _lines.end(); ++it) {
+    SDL_Surface* lineSurf = *it;
+    ApplySurfaceLiteral(x + xArg, y + yArg + yOffset, lineSurf, screen);  
+    yOffset += lineSurf->h + lineSpacing; 
+  }
+}
+
+std::string Text::DoWordWrap(TTF_Font* fontArg, const std::string& textArg) {
+  int leftSpace = lineWidth;
+
+  char* tokenizedText = strdup(textArg.c_str());
+  char* tokenizedTextOrigin = tokenizedText;
+
+  std::string wrappedText(textArg);
+  int offsetInWrappedText = 0;
+
+  int spaceWidth;
+  TTF_SizeText(fontArg, " ", &spaceWidth, NULL);
+
+  char* word = strtok(tokenizedText, " ");
+
+  while(word) {
+    int wordWidth;
+    TTF_SizeText(fontArg, word, &wordWidth, NULL);
+
+    if ((wordWidth + spaceWidth) > leftSpace) {
+      wrappedText.insert((word - tokenizedTextOrigin) + offsetInWrappedText, "\n");
+      offsetInWrappedText++;
+
+      leftSpace = lineWidth - wordWidth;
+    } else {
+      leftSpace -= wordWidth + spaceWidth;
+    }
+
+    word = strtok(NULL, " ");
+  }
+
+ // delete[] tokenizedText;
+
+  return wrappedText;
+}
diff --git a/src/libUnuk/Ui/Text.h b/src/libUnuk/Ui/Text.h
new file mode 100644
index 0000000..580e1f0
--- /dev/null
+++ b/src/libUnuk/Ui/Text.h
@@ -0,0 +1,62 @@
+#pragma once
+#include <SDL/SDL.h>
+#include <SDL/SDL_ttf.h>
+#include <string>
+#include <list>
+
+#include "../../Unuk/Globals.h"
+#include "../Sprite/ApplySurface.h"
+#include "../Ui/Font.h"
+#include "../System/Debug.h"
+using namespace std;
+
+enum textSizes_t { vsmall, small, medium, large, vlarge };
+
+class Text {
+public:
+  Text(void);
+  ~Text(void);
+
+  static void LoadFonts(void);
+  static void FreeFonts(void);
+
+  int GetWidth(void)          { return w; }
+  int GetHeight(void)         { return h; }
+  int GetX(void)              { return x; }
+  int GetY(void)              { return y; }
+
+  SDL_Color GetColour(void)   { return _textColour; }
+
+  void SetXY(int xArg, int yArg);
+
+  int GetLineWidth()                  { return lineWidth; }
+  void SetLineWidth(int lineWidthArg) { lineWidth = lineWidthArg; }
+
+  int SetTextBlended(string textArg, textSizes_t size, SDL_Color, bool wordWrap=false);
+  int SetTextBlended(string textArg, textSizes_t size, Uint8 r, Uint8 g, Uint8 b, bool wordWrap=false);
+  int SetTextShaded(string textArg, textSizes_t size, SDL_Color, SDL_Color, bool wordWrap=false);
+  int SetTextShaded(string textArg, textSizes_t size, Uint8 rF, Uint8 gF, Uint8 bF, Uint8 rB, Uint8 gB, Uint8 bB, bool wordWrap=false);
+
+  string GetText(void)        { return _textContents; }
+
+  void Render(void);
+  void Render(int xArg, int yArg);
+  void RenderLiteral(void);
+  void RenderLiteral(int xArg, int yArg);
+
+private:
+  int x, y, w, h;
+  int lineWidth;
+
+  string _textContents;
+  SDL_Color _textColour;
+  std::list<SDL_Surface*> _lines;
+
+  std::string DoWordWrap(TTF_Font* fontArg, const std::string& textArg);
+
+  static TTF_Font* vSmallFont;
+  static TTF_Font* smallFont;
+  static TTF_Font* mediumFont;
+  static TTF_Font* largeFont;
+  static TTF_Font* vLargeFont;
+};