]> git.localhorst.tv Git - sdl-test7.git/commitdiff
imported current version
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 25 Apr 2012 19:00:27 +0000 (19:00 +0000)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 25 Apr 2012 19:00:27 +0000 (19:00 +0000)
31 files changed:
data/font/Magra-Regular.ttf [new file with mode: 0644]
src/app/Application.cpp [new file with mode: 0644]
src/app/Application.h [new file with mode: 0644]
src/app/Control.h [new file with mode: 0644]
src/app/State.h [new file with mode: 0644]
src/game/Collision.h [new file with mode: 0644]
src/game/Entity.cpp [new file with mode: 0644]
src/game/Entity.h [new file with mode: 0644]
src/geometry/AABB.cpp [new file with mode: 0644]
src/geometry/AABB.h [new file with mode: 0644]
src/geometry/Circle.cpp [new file with mode: 0644]
src/geometry/Circle.h [new file with mode: 0644]
src/geometry/FakeLens.cpp [new file with mode: 0644]
src/geometry/FakeLens.h [new file with mode: 0644]
src/geometry/Shape.h [new file with mode: 0644]
src/geometry/Vector2D.h [new file with mode: 0644]
src/pong/Ball.cpp [new file with mode: 0644]
src/pong/Ball.h [new file with mode: 0644]
src/pong/CountingWall.cpp [new file with mode: 0644]
src/pong/CountingWall.h [new file with mode: 0644]
src/pong/Match.cpp [new file with mode: 0644]
src/pong/Match.h [new file with mode: 0644]
src/pong/Paddle.cpp [new file with mode: 0644]
src/pong/Paddle.h [new file with mode: 0644]
src/sdl-test7.cpp [new file with mode: 0644]
src/sdl/InitSDL.cpp [new file with mode: 0644]
src/sdl/InitSDL.h [new file with mode: 0644]
src/sdl/InitScreen.cpp [new file with mode: 0644]
src/sdl/InitScreen.h [new file with mode: 0644]
src/sdl/InitTTF.cpp [new file with mode: 0644]
src/sdl/InitTTF.h [new file with mode: 0644]

diff --git a/data/font/Magra-Regular.ttf b/data/font/Magra-Regular.ttf
new file mode 100644 (file)
index 0000000..6e252b0
Binary files /dev/null and b/data/font/Magra-Regular.ttf differ
diff --git a/src/app/Application.cpp b/src/app/Application.cpp
new file mode 100644 (file)
index 0000000..5b1b359
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Application.cpp
+ *
+ *  Created on: Apr 8, 2012
+ *      Author: holy
+ */
+
+#include "Application.h"
+
+#include "State.h"
+
+#include <cassert>
+
+namespace app {
+
+Application::Application(sdl::InitScreen *screen, State *initialState)
+: screen(screen)
+, states()
+, last(SDL_GetTicks()) {
+       assert(screen && "cannot create application without screen");
+       assert(initialState && "cannot create application without initial state");
+       RealPushState(initialState);
+}
+
+Application::~Application(void) {
+       PopAllStates();
+}
+
+
+State *Application::CurrentState(void) {
+       return states.top();
+}
+
+void Application::ChangeState(State *s) {
+       RealPopState();
+       RealPushState(s);
+}
+
+void Application::PushState(State *s) {
+       RealPushState(s);
+}
+
+void Application::RealPushState(State *s) {
+       states.push(s);
+       s->EnterState(this, screen->Screen());
+}
+
+void Application::PopState(void) {
+       RealPopState();
+}
+
+void Application::RealPopState(void) {
+       if (states.empty()) return;
+       states.top()->ExitState();
+       delete states.top();
+       states.pop();
+}
+
+void Application::Quit(void) {
+       PopAllStates();
+}
+
+void Application::PopAllStates(void) {
+       while (!states.empty()) {
+               RealPopState();
+       }
+}
+
+
+void Application::Run(void) {
+       while (CurrentState()) {
+               Loop();
+       }
+}
+
+void Application::Loop(void) {
+       Uint32 now(SDL_GetTicks());
+       Uint32 deltaT(now - last);
+       if (deltaT > 34) deltaT = 34;
+
+       HandleEvents();
+       UpdateWorld(deltaT);
+       Render();
+
+       last = now;
+}
+
+
+void Application::HandleEvents(void) {
+       if (!CurrentState()) return;
+       SDL_Event event;
+       while (SDL_PollEvent(&event)) {
+               switch (event.type) {
+                       case SDL_QUIT:
+                               PopAllStates();
+                               break;
+                       default:
+                               CurrentState()->HandleEvent(event);
+                               break;
+               }
+       }
+}
+
+void Application::UpdateWorld(Uint32 deltaT) {
+       if (!CurrentState()) return;
+       for (Uint32 i(0); i < deltaT; ++i) {
+               CurrentState()->UpdateWorld(0.001f);
+       }
+}
+
+void Application::Render(void) {
+       if (!CurrentState()) return;
+       CurrentState()->Render(screen->Screen());
+       screen->Flip();
+}
+
+}
diff --git a/src/app/Application.h b/src/app/Application.h
new file mode 100644 (file)
index 0000000..a8a87c8
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Application.h
+ *
+ *  Created on: Apr 8, 2012
+ *      Author: holy
+ */
+
+#ifndef APP_APPLICATION_H_
+#define APP_APPLICATION_H_
+
+#include "Control.h"
+#include "../sdl/InitScreen.h"
+
+#include <stack>
+#include <SDL/SDL.h>
+
+
+namespace app {
+
+class State;
+
+class Application
+: public Control {
+
+       public:
+               explicit Application(sdl::InitScreen *screen, State *initialState);
+               virtual ~Application(void);
+       private:
+               Application(const Application &);
+               Application &operator =(const Application &);
+
+       public:
+               void Run(void);
+               void Loop(void);
+
+       public:
+               virtual void ChangeState(State *);
+               virtual void PushState(State *);
+               virtual void PopState(void);
+               virtual void Quit(void);
+
+       private:
+               State *CurrentState(void);
+               void RealPushState(State *);
+               void RealPopState(void);
+               void PopAllStates(void);
+
+       private:
+               void HandleEvents(void);
+               void UpdateWorld(Uint32 deltaT);
+               void Render(void);
+
+       private:
+               sdl::InitScreen *screen;
+               std::stack<State *> states;
+               Uint32 last;
+
+};
+
+}
+
+#endif /* APP_APPLICATION_H_ */
diff --git a/src/app/Control.h b/src/app/Control.h
new file mode 100644 (file)
index 0000000..b6cd742
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Control.h
+ *
+ *  Created on: Apr 19, 2012
+ *      Author: holy
+ */
+
+#ifndef APP_CONTROL_H_
+#define APP_CONTROL_H_
+
+namespace app {
+
+class State;
+
+class Control {
+
+       public:
+               virtual ~Control(void) { };
+
+       public:
+               virtual void ChangeState(State *) = 0;
+               virtual void PushState(State *) = 0;
+               virtual void PopState(void) = 0;
+               virtual void Quit(void) = 0;
+};
+
+}
+
+#endif /* APP_CONTROL_H_ */
diff --git a/src/app/State.h b/src/app/State.h
new file mode 100644 (file)
index 0000000..1c93eeb
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * State.h
+ *
+ *  Created on: Apr 8, 2012
+ *      Author: holy
+ */
+
+#ifndef APP_APPLICATIONSTATE_H_
+#define APP_APPLICATIONSTATE_H_
+
+#include <SDL/SDL.h>
+
+namespace app {
+
+class Control;
+
+class State {
+
+       public:
+               virtual ~State(void) { };
+
+       public:
+               virtual void EnterState(Control *ctrl, SDL_Surface *screen) = 0;
+               virtual void ExitState(void) = 0;
+
+               virtual void HandleEvent(const SDL_Event &) = 0;
+               virtual void UpdateWorld(float deltaT) = 0;
+               virtual void Render(SDL_Surface *) = 0;
+
+};
+
+}
+
+#endif /* APP_STATE_H_ */
diff --git a/src/game/Collision.h b/src/game/Collision.h
new file mode 100644 (file)
index 0000000..2da65a7
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Collision.h
+ *
+ *  Created on: Apr 22, 2012
+ *      Author: holy
+ */
+
+#ifndef GAME_COLLISION_H_
+#define GAME_COLLISION_H_
+
+#include "Entity.h"
+
+
+namespace game {
+
+class Collision {
+
+       public:
+               Collision(Entity *left, Entity *right, const Entity::Vector &normal) : left(left), right(right), normal(normal) { };
+               ~Collision(void) { };
+
+       public:
+               Entity *left, *right;
+               Entity::Vector normal;
+
+};
+
+}
+
+#endif /* GAME_COLLISION_H_ */
diff --git a/src/game/Entity.cpp b/src/game/Entity.cpp
new file mode 100644 (file)
index 0000000..d7f0329
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Entity.cpp
+ *
+ *  Created on: Apr 9, 2012
+ *      Author: holy
+ */
+
+#include "Entity.h"
+
+#include <limits>
+
+#include <iostream>
+using namespace std;
+
+using geometry::Shape;
+using std::numeric_limits;
+
+
+namespace game {
+
+Entity::Entity(Shape *shape)
+: bounds(shape)
+, position()
+, velocity()
+, nextVelocity()
+, maxVelocitySquared(numeric_limits<Scalar>::infinity())
+, dynamic(true)
+, updateVelocity(false) {
+
+}
+
+Entity::Entity(const Vector &position, Shape *shape)
+: bounds(shape)
+, position(position)
+, velocity()
+, nextVelocity()
+, maxVelocitySquared(numeric_limits<Scalar>::infinity())
+, dynamic(true)
+, updateVelocity(false) {
+
+}
+
+Entity::~Entity(void) {
+
+}
+
+
+void Entity::Move(const Vector &delta) {
+       position += delta;
+       bounds->SetPosition(position);
+}
+
+void Entity::SetPosition(const Vector &p) {
+       position = p;
+       bounds->SetPosition(position);
+}
+
+
+void Entity::SetVelocity(const Vector &v) {
+       if (updateVelocity) {
+               nextVelocity = v;
+       } else {
+               velocity = v;
+       }
+}
+
+
+Entity::Vector Entity::Center(void) const {
+       return bounds->Center();
+}
+
+
+void Entity::Accelerate(Scalar factor) {
+       if (updateVelocity) {
+               Vector scaled(nextVelocity * factor);
+               float speedSquared(scaled.LengthSquared());
+               if (speedSquared <= maxVelocitySquared) {
+                       nextVelocity = scaled;
+               }
+       } else {
+               Vector scaled(velocity * factor);
+               float speedSquared(scaled.LengthSquared());
+               if (speedSquared <= maxVelocitySquared) {
+                       velocity = scaled;
+               }
+       }
+}
+
+void Entity::SetMaxVelocity(Scalar max) {
+       maxVelocitySquared = max * max;
+}
+
+
+void Entity::Update(float deltaT) {
+       if (velocity.X() == Limits::quiet_NaN() || velocity.X() == -Limits::quiet_NaN()) {
+               cout << "NaN! " << velocity << endl;
+       }
+       position += velocity * deltaT;
+       bounds->SetPosition(position);
+}
+
+void Entity::Revert(float deltaT) {
+       position -= velocity * deltaT;
+       bounds->SetPosition(position);
+}
+
+void Entity::Collide(Entity &other, const Vector &normal) {
+       nextVelocity = velocity;
+       nextVelocity.Reflect(normal);
+       updateVelocity = true;
+}
+
+void Entity::PostCollide(void) {
+       if (updateVelocity) {
+               velocity = nextVelocity;
+               updateVelocity = false;
+       }
+}
+
+}
diff --git a/src/game/Entity.h b/src/game/Entity.h
new file mode 100644 (file)
index 0000000..0bd02ec
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Entity.h
+ *
+ *  Created on: Apr 9, 2012
+ *      Author: holy
+ */
+
+#ifndef GAME_ENTITY_H_
+#define GAME_ENTITY_H_
+
+#include "../geometry/Shape.h"
+#include "../geometry/Vector2D.h"
+
+#include <cmath>
+#include <ostream>
+#include <SDL/SDL.h>
+
+
+namespace game {
+
+class Entity {
+
+       public:
+               typedef geometry::Shape::Scalar Scalar;
+               typedef geometry::Shape::Vector Vector;
+               typedef geometry::Shape::Limits Limits;
+
+       public:
+               explicit Entity(geometry::Shape *);
+               Entity(const Vector &position, geometry::Shape *);
+               virtual ~Entity(void);
+
+       public:
+               void Move(const Vector &d);
+
+               void SetPosition(const Vector &);
+
+       public:
+               const Vector &Position(void) const { return position; };
+               Vector Center(void) const;
+               const Vector &Velocity() const { return velocity; };
+               void SetVelocity(const Vector &);
+
+       public:
+               const geometry::Shape &Bounds(void) const { return *bounds; };
+               bool Overlaps(const Entity &other, Vector &normal) {
+                       return bounds->Overlaps(*other.bounds, normal);
+               };
+
+       public:
+               void Update(float deltaT);
+               void Revert(float deltaT);
+               virtual void Collide(Entity &, const Vector &normal);
+               virtual void PostCollide(void);
+               virtual void Render(SDL_Surface *dest) { };
+
+       public:
+               bool IsDynamic(void) const { return dynamic; };
+               bool IsStatic(void) const { return !dynamic; };
+               void SetDynamic(void) { dynamic = true; };
+               void SetStatic(void) { dynamic = false; };
+
+       public:
+               void Accelerate(float factor);
+               void SetMaxVelocity(float);
+
+       private:
+               geometry::Shape *bounds;
+               Vector position, velocity, nextVelocity;
+               Scalar maxVelocitySquared;
+               bool dynamic, updateVelocity;
+};
+
+}
+
+#endif /* GAME_ENTITY_H_ */
diff --git a/src/geometry/AABB.cpp b/src/geometry/AABB.cpp
new file mode 100644 (file)
index 0000000..e40c69f
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * AABB.cpp
+ *
+ *  Created on: Apr 20, 2012
+ *      Author: holy
+ */
+
+#include "AABB.h"
+
+#include "Circle.h"
+#include "FakeLens.h"
+
+namespace geometry {
+
+bool AABB::Overlaps(const Shape &other, Vector &normal) const {
+       if (other.Overlaps(*this, normal)) {
+               normal *= -1;
+               return true;
+       } else {
+               return false;
+       }
+}
+
+bool AABB::Overlaps(const AABB &other, Vector &normal) const {
+       if (Bottom() <= other.Top()) return false;
+       if (other.Bottom() <= Top()) return false;
+       if (Right() <= other.Left()) return false;
+       if (other.Right() <= Left()) return false;
+
+       if (HorizontalOverlap(other)) {
+               if (Top() < other.Top()) {
+                       normal = Vector(0, -1);
+               } else {
+                       normal = Vector(0, 1);
+               }
+       } else {
+               if (Left() < other.Left()) {
+                       normal = Vector(-1, 0);
+               } else {
+                       normal = Vector(1, 0);
+               }
+       }
+
+       return true;
+}
+
+bool AABB::Overlaps(const Circle &other, Vector &normal) const {
+       if (other.Overlaps(*this, normal)) {
+               normal *= -1;
+               return true;
+       } else {
+               return false;
+       }
+}
+
+bool AABB::Overlaps(const FakeLens &other, Vector &normal) const {
+       if (other.Overlaps(*this, normal)) {
+               normal *= -1;
+               return true;
+       } else {
+               return false;
+       }
+}
+
+std::ostream &AABB::Write(std::ostream &out) const {
+       return out << "AABB(" << Width() << 'x' << Height() << '+' << X() << '+' << Y() << ')';
+}
+
+} /* namespace geometry */
diff --git a/src/geometry/AABB.h b/src/geometry/AABB.h
new file mode 100644 (file)
index 0000000..db009da
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * AABB.h
+ *
+ *  Created on: Apr 10, 2012
+ *      Author: holy
+ */
+
+#ifndef GEOMETRY_AABB_H_
+#define GEOMETRY_AABB_H_
+
+#include "Shape.h"
+
+#include <ostream>
+#include <SDL/SDL.h>
+
+
+namespace geometry {
+
+class AABB
+: public Shape {
+
+       public:
+               AABB(void) : leftTop(), rightBottom() { };
+               explicit AABB(const Vector &size) : leftTop(), rightBottom(size) { };
+               AABB(const Vector &position, const Vector &size)
+               : leftTop(position), rightBottom(position + size) { };
+               virtual ~AABB(void) { };
+
+       public:
+               Scalar Left(void) const { return leftTop.X(); };
+               Scalar Top(void) const { return leftTop.Y(); };
+               Scalar Right(void) const { return rightBottom.X(); };
+               Scalar Bottom(void) const { return rightBottom.Y(); };
+
+               Scalar X(void) const { return Left(); };
+               Scalar Y(void) const { return Top(); };
+               Scalar Width(void) const { return Right() - Left(); };
+               Scalar Height(void) const { return Bottom() - Top(); };
+
+       public:
+               virtual bool Overlaps(const Shape &other, Vector &normal) const;
+               virtual bool Overlaps(const AABB &other, Vector &normal) const;
+               virtual bool Overlaps(const Circle &other, Vector &normal) const;
+               virtual bool Overlaps(const FakeLens &, Vector &normal) const;
+
+               bool VerticalOverlap(const AABB &other) const {
+                       if (Bottom() < other.Top()) return false;
+                       if (other.Bottom() < Top()) return false;
+                       return true;
+               };
+               bool HorizontalOverlap(const AABB &other) const {
+                       if (Right() < other.Left()) return false;
+                       if (other.Right() < Left()) return false;
+                       return true;
+               };
+
+       public:
+               void Move(const Vector &delta) {
+                       leftTop += delta;
+                       rightBottom += delta;
+               };
+
+               void SetBounds(const Vector &position, const Vector &size) {
+                       leftTop = position;
+                       rightBottom = position + size;
+               };
+               void SetPosition(const Vector &position) {
+                       rightBottom = position + (rightBottom - leftTop);
+                       leftTop = position;
+               };
+               void SetSize(const Vector &size) {
+                       rightBottom = leftTop + size;
+               };
+
+               virtual Vector Center(void) const {
+                       return leftTop + (rightBottom - leftTop) / 2;
+               };
+
+               virtual std::ostream &Write(std::ostream &out) const;
+
+       public:
+               void WriteRect(SDL_Rect &rect) const {
+                       rect.x = X();
+                       rect.y = Y();
+                       rect.w = Width();
+                       rect.h = Height();
+               };
+
+       private:
+               Vector leftTop, rightBottom;
+
+};
+
+}
+
+#endif /* GEOMETRY_AABB_H_ */
diff --git a/src/geometry/Circle.cpp b/src/geometry/Circle.cpp
new file mode 100644 (file)
index 0000000..7d923a5
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Circle.cpp
+ *
+ *  Created on: Apr 20, 2012
+ *      Author: holy
+ */
+
+#include "Circle.h"
+
+#include "AABB.h"
+#include "FakeLens.h"
+#include "../game/Entity.h"
+
+
+namespace geometry {
+
+bool Circle::Overlaps(const Shape &other, Vector &normal) const {
+       if (other.Overlaps(*this, normal)) {
+               normal *= -1;
+               return true;
+       } else {
+               return false;
+       }
+}
+
+bool Circle::Overlaps(const AABB &other, Vector &normal) const {
+       // fast checks for far away shapes
+       if (Bottom() <= other.Top()) return false;
+       if (other.Bottom() <= Top()) return false;
+       if (Right() <= other.Left()) return false;
+       if (other.Right() <= Left()) return false;
+
+       int xZone(
+                       X() < other.Left() ? 0 : (
+                       other.Right() < X() ? 2 : 1));
+       int yZone(
+                               Y() < other.Top() ? 0 : (
+                               other.Bottom() < Y() ? 2 : 1));
+       int zone(xZone + 3*yZone);
+
+       if (zone == 4) {
+               normal = (Center() - other.Center()).Unit();
+               return true;
+       }
+
+       if (zone % 2) {
+               if (xZone == 1) { // vertical
+                       if (Bottom() < other.Top()) return false;
+                       if (other.Bottom() < Top()) return false;
+
+                       if (Bottom() < other.Bottom()) {
+                               normal = Vector(0, -1);
+                       } else {
+                               normal = Vector(0, 1);
+                       }
+
+                       return true;
+               } else {
+                       if (Right() < other.Left()) return false;
+                       if (other.Right() < Left()) return false;
+
+                       if (Left() < other.Left()) {
+                               normal = Vector(-1, 0);
+                       } else {
+                               normal = Vector(1, 0);
+                       }
+
+                       return true;
+               }
+       } else {
+               Vector near(
+                               yZone ? other.Right() : other.Left(),
+                               xZone ? other.Bottom() : other.Top());
+               Vector distance(position - near);
+               Sint32 distanceSquared(distance.LengthSquared());
+               if (distanceSquared < (Radius() * Radius())) {
+                       normal = distance.Unit();
+                       return true;
+               } else {
+                       return false;
+               }
+       }
+}
+
+bool Circle::Overlaps(const Circle &other, Vector &normal) const {
+       Vector delta(position - other.position);
+       Sint32 distanceSquared(delta.LengthSquared()), minDistance(Radius() + other.Radius());
+       if (distanceSquared < (minDistance * minDistance)) {
+               normal = delta.Unify();
+               return true;
+       } else {
+               return false;
+       }
+}
+
+bool Circle::Overlaps(const FakeLens &other, Vector &normal) const {
+       if (other.Overlaps(*this, normal)) {
+               normal *= -1;
+               return true;
+       } else {
+               return false;
+       }
+}
+
+std::ostream &Circle::Write(std::ostream &out) const {
+       return out << "Circle(" << Radius() << '+' << Top() << '+' << Left() << ')';
+}
+
+}
diff --git a/src/geometry/Circle.h b/src/geometry/Circle.h
new file mode 100644 (file)
index 0000000..8e3e0e1
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Circle.h
+ *
+ *  Created on: Apr 19, 2012
+ *      Author: holy
+ */
+
+#ifndef GEOMETRY_CIRCLE_H_
+#define GEOMETRY_CIRCLE_H_
+
+#include "Shape.h"
+
+#include "AABB.h"
+
+#include <SDL/SDL.h>
+
+
+namespace geometry {
+
+class Circle
+: public Shape {
+
+       public:
+               Circle(void) : position(), radius() { };
+               explicit Circle(Scalar radius) : position(), radius(radius) { };
+               explicit Circle(const Vector &position, Scalar radius = Scalar()) : position(position), radius(radius) { };
+               virtual ~Circle(void) { };
+
+       public:
+               Scalar X(void) const { return position.X(); };
+               Scalar Y(void) const { return position.Y(); };
+               Scalar Radius(void) const { return radius; };
+               Scalar Diameter(void) const { return 2 * Radius(); };
+
+               Scalar Width(void) const { return Diameter(); };
+               Scalar Height(void) const { return Diameter(); };
+
+               Scalar Left(void) const { return X() - Radius(); };
+               Scalar Top(void) const { return Y() - Radius(); };
+               Scalar Right(void) const { return X() + Radius(); };
+               Scalar Bottom(void) const { return Y() + Radius(); };
+
+       public:
+               virtual bool Overlaps(const Shape &other, Vector &normal) const;
+               virtual bool Overlaps(const AABB &other, Vector &normal) const;
+               virtual bool Overlaps(const Circle &other, Vector &normal) const;
+               virtual bool Overlaps(const FakeLens &, Vector &normal) const;
+
+               bool VerticalOverlap(const AABB &other) const {
+                       if (Bottom() < other.Top()) return false;
+                       if (other.Bottom() < Top()) return false;
+                       return true;
+               };
+               bool HorizontalOverlap(const AABB &other) const {
+                       if (Right() < other.Left()) return false;
+                       if (other.Right() < Left()) return false;
+                       return true;
+               };
+
+       public:
+               void Move(const Vector &delta) {
+                       position += delta;
+               };
+
+               void SetPosition(const Vector &pos) {
+                       position = pos;
+               };
+               void SetRadius(Scalar r) {
+                       radius = r;
+               };
+
+               virtual Vector Center(void) const {
+                       return position;
+               };
+
+               virtual std::ostream &Write(std::ostream &out) const;
+
+       private:
+               Vector position;
+               Scalar radius;
+
+};
+
+}
+
+#endif /* GEOMETRY_CIRCLE_H_ */
diff --git a/src/geometry/FakeLens.cpp b/src/geometry/FakeLens.cpp
new file mode 100644 (file)
index 0000000..4ba8269
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * FakeLens.cpp
+ *
+ *  Created on: Apr 24, 2012
+ *      Author: holy
+ */
+
+#include "FakeLens.h"
+
+#include "Circle.h"
+
+
+#include <iostream>
+using namespace std;
+
+
+namespace geometry {
+
+bool FakeLens::Overlaps(const Shape &other, Vector &normal) const {
+       if (other.Overlaps(*this, normal)) {
+               normal *= -1;
+               return true;
+       } else {
+               return false;
+       }
+}
+
+bool FakeLens::Overlaps(const AABB &other, Vector &normal) const {
+       if (AABB::Overlaps(other, normal)) {
+               MessUpNormal(normal, other);
+               return true;
+       } else {
+               return false;
+       }
+}
+
+bool FakeLens::Overlaps(const Circle &other, Vector &normal) const {
+       if (AABB::Overlaps(other, normal)) {
+               MessUpNormal(normal, other);
+               return true;
+       } else {
+               return false;
+       }
+}
+
+bool FakeLens::Overlaps(const FakeLens &other, Vector &normal) const {
+       if (AABB::Overlaps(static_cast<const AABB &>(other), normal)) {
+               MessUpNormal(normal, other);
+               return true;
+       } else {
+               return false;
+       }
+}
+
+
+std::ostream &FakeLens::Write(std::ostream &out) const {
+       return out << "FakeLens(" << Width() << 'x' << Height() << '+' << X() << '+' << Y() << ')';
+}
+
+
+void FakeLens::MessUpNormal(Vector &normal, const Shape &other) const {
+       Vector direction((Center() - other.Center()).Unify());
+       normal = ((1 - bendFactor) * normal) + (bendFactor* direction);
+       normal.Unify();
+}
+
+}
diff --git a/src/geometry/FakeLens.h b/src/geometry/FakeLens.h
new file mode 100644 (file)
index 0000000..3de4577
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * FakeLens.h
+ *
+ *  Created on: Apr 24, 2012
+ *      Author: holy
+ */
+
+#ifndef GEOMETRY_FAKELENS_H_
+#define GEOMETRY_FAKELENS_H_
+
+#include "AABB.h"
+
+
+namespace geometry {
+
+class FakeLens
+: public AABB {
+
+       public:
+               FakeLens(void) : AABB(), bendFactor(0.22f) { };
+               explicit FakeLens(const Vector &size) : AABB(size), bendFactor(0.22f) { };
+               FakeLens(const Vector &position, const Vector &size, float bendFactor = 0.22f) : AABB(position, size), bendFactor(bendFactor) { };
+
+       public:
+               void SetBendFactor(float b) { bendFactor = b; };
+
+       public:
+               virtual bool Overlaps(const Shape &, Vector &normal) const;
+
+               virtual bool Overlaps(const AABB &, Vector &normal) const;
+               virtual bool Overlaps(const Circle &, Vector &normal) const;
+               virtual bool Overlaps(const FakeLens &, Vector &normal) const;
+
+       public:
+               virtual std::ostream &Write(std::ostream &out) const;
+
+       private:
+               void MessUpNormal(Vector &normal, const Shape &other) const;
+
+       private:
+               float bendFactor;
+
+};
+
+}
+
+#endif /* GEOMETRY_FAKELENS_H_ */
diff --git a/src/geometry/Shape.h b/src/geometry/Shape.h
new file mode 100644 (file)
index 0000000..79c3485
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Shape.h
+ *
+ *  Created on: Apr 20, 2012
+ *      Author: holy
+ */
+
+#ifndef GEOMETRY_SHAPE_H_
+#define GEOMETRY_SHAPE_H_
+
+#include "Vector2D.h"
+
+#include <limits>
+#include <ostream>
+
+namespace geometry {
+
+class AABB;
+class Circle;
+class FakeLens;
+
+class Shape {
+
+       public:
+               typedef float Scalar;
+               typedef Vector2D<Scalar> Vector;
+               typedef std::numeric_limits<Scalar> Limits;
+
+       protected:
+               Shape(void) { };
+               virtual ~Shape(void) { };
+
+       public:
+               virtual bool Overlaps(const Shape &, Vector &normal) const = 0;
+
+               virtual bool Overlaps(const AABB &, Vector &normal) const = 0;
+               virtual bool Overlaps(const Circle &, Vector &normal) const = 0;
+               virtual bool Overlaps(const FakeLens &, Vector &normal) const = 0;
+
+       public:
+               virtual std::ostream &Write(std::ostream &out) const = 0;
+
+       public:
+               virtual void SetPosition(const Vector &) = 0;
+               virtual Vector Center(void) const = 0;
+
+};
+
+}
+
+
+namespace std {
+
+inline ostream &operator <<(ostream &out, const geometry::Shape &s) {
+       return s.Write(out);
+};
+
+}
+
+#endif /* GEOMETRY_SHAPE_H_ */
diff --git a/src/geometry/Vector2D.h b/src/geometry/Vector2D.h
new file mode 100644 (file)
index 0000000..ad7a614
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Vector.h
+ *
+ *  Created on: Apr 23, 2012
+ *      Author: holy
+ */
+
+#ifndef GEOMETRY_VECTOR2D_H_
+#define GEOMETRY_VECTOR2D_H_
+
+#include <cmath>
+#include <ostream>
+
+
+namespace geometry {
+
+template<typename Scalar>
+class Vector2D {
+
+       public:
+               Vector2D(void) : x(), y() { };
+               Vector2D(Scalar x, Scalar y) : x(x), y(y) { };
+
+       public:
+               Scalar X(void) const { return x; };
+               Scalar Y(void) const { return y; };
+
+       public:
+               Scalar Dot(const Vector2D<Scalar> &o) const { return (X() * o.X()) + (Y() * o.Y()); };
+               Scalar LengthSquared(void) const { return Dot(*this); };
+               Scalar Length(void) const { return std::sqrt(LengthSquared()); };
+
+       public:
+               Vector2D<Scalar> &Unify(void) {
+                       if (LengthSquared() == Scalar()) return *this;
+                       *this /= Length();
+                       return *this;
+               };
+               Vector2D<Scalar> Unit(void) const {
+                       if (LengthSquared() == Scalar()) return *this;
+                       return *this / Length();
+               };
+               Vector2D<Scalar> &Reflect(const Vector2D<Scalar> &normal);
+
+       public:
+               Vector2D<Scalar> &operator +=(const Vector2D<Scalar> &o) {
+                       x += o.X();
+                       y += o.Y();
+                       return *this;
+               };
+               Vector2D<Scalar> &operator -=(const Vector2D<Scalar> &o) {
+                       x -= o.X();
+                       y -= o.Y();
+                       return *this;
+               };
+               template<typename T>
+               Vector2D<Scalar> &operator +=(T s) { x += s; y += s; return *this; };
+               template<typename T>
+               Vector2D<Scalar> &operator -=(T s) { x -= s; y -= s; return *this; };
+               template<typename T>
+               Vector2D<Scalar> &operator *=(T s) { x *= s; y *= s; return *this; };
+               template<typename T>
+               Vector2D<Scalar> &operator /=(T s) { x /= s; y /= s; return *this; };
+
+       private:
+               Scalar x, y;
+
+};
+
+template<typename Scalar>
+inline Vector2D<Scalar> &Vector2D<Scalar>::Reflect(const Vector2D<Scalar> &normal) {
+       Scalar doubleDot(2 * Dot(normal));
+       x -= doubleDot * normal.X();
+       y -= doubleDot * normal.Y();
+       return *this;
+};
+
+
+template<typename Scalar>
+inline Vector2D<Scalar> operator +(const Vector2D<Scalar> &v) {
+       return v;
+};
+template<typename Scalar>
+inline Vector2D<Scalar> operator -(const Vector2D<Scalar> &v) {
+       return Vector2D<Scalar>(-v.X(), -v.Y());
+};
+
+template<typename Scalar>
+inline Vector2D<Scalar> operator +(const Vector2D<Scalar> &lhs, const Vector2D<Scalar> &rhs) {
+       Vector2D<Scalar> temp(lhs);
+       temp += rhs;
+       return temp;
+};
+template<typename Scalar>
+inline Vector2D<Scalar> operator -(const Vector2D<Scalar> &lhs, const Vector2D<Scalar> &rhs) {
+       Vector2D<Scalar> temp(lhs);
+       temp -= rhs;
+       return temp;
+};
+
+template<typename VScalar, typename SScalar>
+inline Vector2D<VScalar> operator +(const Vector2D<VScalar> &v, SScalar s) {
+       Vector2D<VScalar> temp(v);
+       temp += s;
+       return temp;
+};
+template<typename VScalar, typename SScalar>
+inline Vector2D<VScalar> operator -(const Vector2D<VScalar> &v, SScalar s) {
+       Vector2D<VScalar> temp(v);
+       temp -= s;
+       return temp;
+};
+
+template<typename VScalar, typename SScalar>
+inline Vector2D<VScalar> operator +(SScalar s, const Vector2D<VScalar> &v) {
+       Vector2D<VScalar> temp(v);
+       temp += s;
+       return temp;
+};
+template<typename VScalar, typename SScalar>
+inline Vector2D<VScalar> operator -(SScalar s, const Vector2D<VScalar> &v) {
+       Vector2D<VScalar> temp(v);
+       temp -= s;
+       return temp;
+};
+
+template<typename VScalar, typename SScalar>
+inline Vector2D<VScalar> operator *(const Vector2D<VScalar> &v, SScalar s) {
+       Vector2D<VScalar> temp(v);
+       temp *= s;
+       return temp;
+};
+template<typename VScalar, typename SScalar>
+inline Vector2D<VScalar> operator *(SScalar s, const Vector2D<VScalar> &v) {
+       Vector2D<VScalar> temp(v);
+       temp *= s;
+       return temp;
+};
+template<typename VScalar, typename SScalar>
+inline Vector2D<VScalar> operator /(const Vector2D<VScalar> &v, SScalar s) {
+       Vector2D<VScalar> temp(v);
+       temp /= s;
+       return temp;
+};
+template<typename VScalar, typename SScalar>
+inline Vector2D<VScalar> operator /(SScalar s, const Vector2D<VScalar> &v) {
+       Vector2D<VScalar> temp(v);
+       temp /= s;
+       return temp;
+};
+
+
+template<typename Scalar>
+std::ostream &operator <<(std::ostream &out, const Vector2D<Scalar> &v) {
+       return out << '<' << v.X() << '|' << v.Y() << '>';
+}
+
+}
+
+#endif /* GEOMETRY_VECTOR2D_H_ */
diff --git a/src/pong/Ball.cpp b/src/pong/Ball.cpp
new file mode 100644 (file)
index 0000000..69ba33e
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Ball.cpp
+ *
+ *  Created on: Apr 9, 2012
+ *      Author: holy
+ */
+
+#include "Ball.h"
+
+#include "Paddle.h"
+
+#include <cmath>
+#include <SDL/SDL_gfxPrimitives.h>
+
+using game::Entity;
+
+
+namespace pong {
+
+Ball::Ball(Scalar radius)
+: Entity(&shape)
+, shape(radius) {
+
+}
+
+Ball::Ball(const Vector &position, Scalar radius)
+: Entity(position, &shape)
+, shape(position, radius) {
+
+}
+
+
+void Ball::Collide(Entity &other, const Vector &normal) {
+       Entity::Collide(other, normal);
+
+       if (dynamic_cast<Paddle *>(&other)) {
+               Accelerate(1.015f);
+       }
+}
+
+void Ball::Render(SDL_Surface *screen) {
+       circleRGBA(screen, shape.X(), shape.Y(), shape.Radius(), 0xFF, 0xFF, 0xFF, 0xFF);
+}
+
+}
diff --git a/src/pong/Ball.h b/src/pong/Ball.h
new file mode 100644 (file)
index 0000000..0715cba
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Ball.h
+ *
+ *  Created on: Apr 9, 2012
+ *      Author: holy
+ */
+
+#ifndef PONG_BALL_H_
+#define PONG_BALL_H_
+
+#include "../game/Entity.h"
+#include "../geometry/Circle.h"
+
+#include <SDL/SDL.h>
+
+
+namespace pong {
+
+class Ball
+: public game::Entity {
+
+       public:
+               explicit Ball(Scalar radius);
+               Ball(const Vector &position, Scalar radius);
+
+       public:
+               virtual void Collide(Entity &, const Vector &normal);
+               virtual void Render(SDL_Surface *dest);
+
+       private:
+               geometry::Circle shape;
+
+};
+
+}
+
+#endif /* PONG_BALL_H_ */
diff --git a/src/pong/CountingWall.cpp b/src/pong/CountingWall.cpp
new file mode 100644 (file)
index 0000000..76989a7
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * CountingWall.cpp
+ *
+ *  Created on: Apr 17, 2012
+ *      Author: holy
+ */
+
+#include "CountingWall.h"
+
+using game::Entity;
+
+
+namespace pong {
+
+CountingWall::CountingWall(const Vector &size)
+: Entity(&shape)
+, shape(size)
+, count(0) {
+
+}
+
+CountingWall::~CountingWall(void) {
+
+}
+
+
+void CountingWall::Collide(Entity &e, const Vector &normal) {
+       ++count;
+}
+
+void CountingWall::Render(SDL_Surface *dest) {
+
+}
+
+}
diff --git a/src/pong/CountingWall.h b/src/pong/CountingWall.h
new file mode 100644 (file)
index 0000000..98ad0e7
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * CountingWall.h
+ *
+ *  Created on: Apr 17, 2012
+ *      Author: holy
+ */
+
+#ifndef PONG_COUNTINGWALL_H_
+#define PONG_COUNTINGWALL_H_
+
+#include "../game/Entity.h"
+#include "../geometry/AABB.h"
+
+#include <SDL/SDL.h>
+
+namespace pong {
+
+class CountingWall
+: public game::Entity {
+
+       public:
+               explicit CountingWall(const Vector &size);
+               virtual ~CountingWall(void);
+
+       public:
+               int HitCount(void) { return count; };
+
+       public:
+               virtual void Collide(Entity &, const Vector &normal);
+               virtual void Render(SDL_Surface *dest);
+
+       private:
+               geometry::AABB shape;
+               int count;
+
+};
+
+}
+
+#endif /* PONG_COUNTINGWALL_H_ */
diff --git a/src/pong/Match.cpp b/src/pong/Match.cpp
new file mode 100644 (file)
index 0000000..683defe
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Match.cpp
+ *
+ *  Created on: Apr 9, 2012
+ *      Author: holy
+ */
+
+#include "Match.h"
+
+#include "../app/Control.h"
+
+#include <sstream>
+#include <stdexcept>
+#include <utility>
+#include <SDL/SDL.h>
+
+using app::Control;
+using game::Collision;
+using game::Entity;
+using std::runtime_error;
+using std::stringstream;
+using std::vector;
+
+
+namespace pong {
+
+Match::Match(void)
+: ctrl(0)
+, scoreFont(TTF_OpenFont("data/font/Magra-Regular.ttf", 30))
+, leftScoreText(0)
+, rightScoreText(0)
+, paddleSpeed(150)
+, worldWidth(800)
+, worldHeight(480)
+, ball(10)
+, secondBall(7)
+, leftPaddle(Entity::Vector(10, 100))
+, rightPaddle(Entity::Vector(10, 100))
+, topWall(Entity::Vector(800, 10))
+, bottomWall(Entity::Vector(800, 10))
+, leftWall(Entity::Vector(10, 480))
+, rightWall(Entity::Vector(10, 480))
+, entities()
+, collisions()
+, updateScore(true) {
+
+       if (!scoreFont) {
+               throw runtime_error("failed to load score font");
+       }
+
+       ball.SetPosition(Entity::Vector(400, 240));
+       ball.SetVelocity(Entity::Vector(180, 180));
+       ball.SetMaxVelocity(500.0f);
+
+       secondBall.SetPosition(Entity::Vector(300, 240));
+       secondBall.SetVelocity(Entity::Vector(-20, -20));
+       secondBall.SetMaxVelocity(600.0f);
+
+       leftPaddle.SetPosition(Entity::Vector(0, 200));
+       rightPaddle.SetPosition(Entity::Vector(790, 280));
+
+       leftPaddle.SetMovementSpeed(Entity::Vector(0, paddleSpeed));
+       rightPaddle.SetMovementSpeed(Entity::Vector(0, paddleSpeed));
+
+       leftPaddle.SetStatic();
+       rightPaddle.SetStatic();
+
+       topWall.SetPosition(Entity::Vector(0, -10));
+       rightWall.SetPosition(Entity::Vector(800, 0));
+       bottomWall.SetPosition(Entity::Vector(0, 480));
+       leftWall.SetPosition(Entity::Vector(-10, 0));
+
+       topWall.SetStatic();
+       rightWall.SetStatic();
+       bottomWall.SetStatic();
+       leftWall.SetStatic();
+
+       entities.reserve(8);
+       entities.push_back(&ball);
+       entities.push_back(&secondBall);
+       entities.push_back(&leftPaddle);
+       entities.push_back(&rightPaddle);
+       entities.push_back(&topWall);
+       entities.push_back(&bottomWall);
+       entities.push_back(&leftWall);
+       entities.push_back(&rightWall);
+
+       collisions.reserve(2 * entities.size());
+}
+
+Match::~Match(void) {
+
+}
+
+
+void Match::EnterState(Control *c, SDL_Surface *screen) {
+       ctrl = c;
+}
+
+void Match::ExitState(void) {
+       if (scoreFont) {
+               TTF_CloseFont(scoreFont);
+               scoreFont = 0;
+       }
+}
+
+void Match::HandleEvent(const SDL_Event &e) {
+       if (e.type == SDL_KEYDOWN) {
+               if (e.key.keysym.sym == SDLK_w) {
+                       leftPaddle.StartMovingUp();
+               } else if (e.key.keysym.sym == SDLK_s) {
+                       leftPaddle.StartMovingDown();
+               } else if (e.key.keysym.sym == SDLK_UP) {
+                       rightPaddle.StartMovingUp();
+               } else if (e.key.keysym.sym == SDLK_DOWN) {
+                       rightPaddle.StartMovingDown();
+               }
+       } else if (e.type == SDL_KEYUP) {
+               if (e.key.keysym.sym == SDLK_w) {
+                       leftPaddle.StopMovingUp();
+               } else if (e.key.keysym.sym == SDLK_s) {
+                       leftPaddle.StopMovingDown();
+               } else if (e.key.keysym.sym == SDLK_UP) {
+                       rightPaddle.StopMovingUp();
+               } else if (e.key.keysym.sym == SDLK_DOWN) {
+                       rightPaddle.StopMovingDown();
+               } else if (e.key.keysym.sym == SDLK_q) {
+                       if (ctrl) ctrl->Quit();
+               }
+       }
+}
+
+void Match::UpdateWorld(float deltaT) {
+       UpdateEntities(deltaT);
+       CheckCollisions(deltaT);
+       HandleCollisions(deltaT);
+}
+
+void Match::UpdateEntities(float deltaT) {
+       for (vector<Entity *>::const_iterator i(entities.begin()), end(entities.end()); i != end; ++i) {
+               (*i)->Update(deltaT);
+       }
+}
+
+void Match::CheckCollisions(float deltaT) {
+       Entity::Vector normal;
+       for (vector<Entity *>::const_iterator i(entities.begin()), end(entities.end()); i != end; ++i) {
+               for (vector<Entity *>::const_iterator j(i + 1); j != end; ++j) {
+                       if ((*i)->Overlaps(**j, normal)) {
+                               if ((*i)->IsDynamic()) {
+                                       (*i)->Move(normal);
+                                       while ((*i)->Overlaps(**j, normal)) {
+                                               (*i)->Move(normal);
+                                       }
+                               } else if ((*j)->IsDynamic()) {
+                                       (*j)->Move(normal);
+                                       while ((*j)->Overlaps(**i, normal)) {
+                                               (*j)->Move(normal);
+                                       }
+                               } else {
+                                       (*i)->Revert(deltaT);
+                                       (*j)->Revert(deltaT);
+                               }
+                               collisions.push_back(Collision(*i, *j, normal));
+                       }
+               }
+       }
+}
+
+void Match::HandleCollisions(float deltaT) {
+       for (vector<Collision>::const_iterator i(collisions.begin()), end(collisions.end()); i != end; ++i) {
+               i->left->Collide(*(i->right), i->normal);
+               i->right->Collide(*(i->left), -(i->normal));
+               i->left->PostCollide();
+               i->right->PostCollide();
+
+       }
+       if (!collisions.empty()) {
+               updateScore = true;
+       }
+       collisions.clear();
+}
+
+
+void Match::Render(SDL_Surface *screen) {
+       SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
+       for (vector<Entity *>::const_iterator i(entities.begin()), end(entities.end()); i != end; ++i) {
+               (*i)->Render(screen);
+       }
+       RenderHUD(screen);
+}
+
+void Match::RenderHUD(SDL_Surface *screen) {
+       if (updateScore) {
+               UpdateScore(screen);
+               updateScore = false;
+       }
+       RenderScore(screen);
+}
+
+void Match::RenderScore(SDL_Surface *screen) {
+       SDL_Rect dest = { 2, 2, 0, 0 };
+       SDL_BlitSurface(leftScoreText, 0, screen, &dest);
+
+       dest.x = screen->w - rightScoreText->w - 2;
+       SDL_BlitSurface(rightScoreText, 0, screen, &dest);
+}
+
+void Match::UpdateScore(SDL_Surface *screen) {
+       if (!scoreFont) return;
+       if (leftScoreText) SDL_FreeSurface(leftScoreText);
+       if (rightScoreText) SDL_FreeSurface(rightScoreText);
+
+       SDL_Color color;
+       color.r = 0xFF;
+       color.g = 0xFF;
+       color.b = 0xFF;
+
+       stringstream s;
+       s << rightWall.HitCount();
+       leftScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);
+
+       s.str("");
+       s << leftWall.HitCount();
+       rightScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);
+}
+
+}
diff --git a/src/pong/Match.h b/src/pong/Match.h
new file mode 100644 (file)
index 0000000..ce7c0e1
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Match.h
+ *
+ *  Created on: Apr 9, 2012
+ *      Author: holy
+ */
+
+#ifndef PONG_MATCH_H_
+#define PONG_MATCH_H_
+
+#include "Ball.h"
+#include "CountingWall.h"
+#include "Paddle.h"
+#include "../app/State.h"
+#include "../game/Collision.h"
+#include "../game/Entity.h"
+
+#include <utility>
+#include <vector>
+#include <SDL/SDL_ttf.h>
+
+
+namespace pong {
+
+class Match
+: public app::State {
+
+       public:
+               Match(void);
+               virtual ~Match(void);
+
+       public:
+               virtual void EnterState(app::Control *ctrl, SDL_Surface *screen);
+               virtual void ExitState(void);
+
+               virtual void HandleEvent(const SDL_Event &);
+               virtual void UpdateWorld(float deltaT);
+               virtual void Render(SDL_Surface *);
+
+       private:
+               void UpdateEntities(float deltaT);
+               void CheckCollisions(float deltaT);
+               void CheckWorldCollisions(float deltaT);
+               void HandleCollisions(float deltaT);
+               void UpdateScore(SDL_Surface *);
+               void RenderHUD(SDL_Surface *);
+               void RenderScore(SDL_Surface *);
+
+       private:
+               app::Control *ctrl;
+               TTF_Font *scoreFont;
+               SDL_Surface *leftScoreText, *rightScoreText;
+               Sint32 paddleSpeed;
+               Uint32 worldWidth, worldHeight;
+               Ball ball, secondBall;
+               Paddle leftPaddle, rightPaddle;
+               CountingWall topWall, bottomWall, leftWall, rightWall;
+               std::vector<game::Entity *> entities;
+               std::vector<game::Collision> collisions;
+               bool updateScore;
+
+};
+
+}
+
+#endif /* PONG_MATCH_H_ */
diff --git a/src/pong/Paddle.cpp b/src/pong/Paddle.cpp
new file mode 100644 (file)
index 0000000..0169689
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Paddle.cpp
+ *
+ *  Created on: Apr 10, 2012
+ *      Author: holy
+ */
+
+#include "Paddle.h"
+
+#include "Ball.h"
+
+
+namespace pong {
+
+Paddle::Paddle(const Vector &size)
+: Entity(&shape)
+, shape(size) {
+
+}
+
+
+void Paddle::Collide(game::Entity &other, const Vector &normal) {
+
+}
+
+void Paddle::Render(SDL_Surface *screen) {
+       SDL_Rect destRect;
+       shape.WriteRect(destRect);
+       SDL_FillRect(screen, &destRect, SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF));
+}
+
+
+void Paddle::SetMovementSpeed(Vector s) {
+       movementSpeed = s;
+
+       Vector v;
+       v = Velocity();
+       SetVelocity(v.Unify() * s.Length());
+}
+
+
+void Paddle::StartMovingUp(void) {
+       SetVelocity(Velocity() - movementSpeed);
+}
+
+void Paddle::StopMovingUp(void) {
+       SetVelocity(Velocity() + movementSpeed);
+}
+
+void Paddle::StartMovingDown(void) {
+       SetVelocity(Velocity() + movementSpeed);
+}
+
+void Paddle::StopMovingDown(void) {
+       SetVelocity(Velocity() - movementSpeed);
+}
+
+}
diff --git a/src/pong/Paddle.h b/src/pong/Paddle.h
new file mode 100644 (file)
index 0000000..a0f90b8
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Paddle.h
+ *
+ *  Created on: Apr 10, 2012
+ *      Author: holy
+ */
+
+#ifndef PONG_PADDLE_H_
+#define PONG_PADDLE_H_
+
+#include "../game/Entity.h"
+#include "../geometry/FakeLens.h"
+
+#include <SDL/SDL.h>
+
+namespace pong {
+
+class Paddle
+: public game::Entity {
+
+       public:
+               explicit Paddle(const Vector &size);
+
+       public:
+               virtual void Collide(game::Entity &, const Vector &normal);
+               virtual void Render(SDL_Surface *dest);
+
+       public:
+               void SetMovementSpeed(Vector);
+
+               void StartMovingUp(void);
+               void StopMovingUp(void);
+               void StartMovingDown(void);
+               void StopMovingDown(void);
+
+       private:
+               geometry::FakeLens shape;
+               Vector movementSpeed;
+
+};
+
+}
+
+#endif /* PONG_PADDLE_H_ */
diff --git a/src/sdl-test7.cpp b/src/sdl-test7.cpp
new file mode 100644 (file)
index 0000000..1f52297
--- /dev/null
@@ -0,0 +1,26 @@
+//============================================================================
+// Name        : sdl-test7.cpp
+// Author      : HolySmoke
+// Version     :
+// Copyright   :
+// Description : Hello World in C++, Ansi-style
+//============================================================================
+
+#include "app/Application.h"
+#include "pong/Match.h"
+#include "sdl/InitScreen.h"
+#include "sdl/InitSDL.h"
+#include "sdl/InitTTF.h"
+
+int main(int argc, char *argv[]) {
+       const int width(800);
+       const int height(480);
+
+       sdl::InitSDL initSDL;
+       sdl::InitTTF initTTF;
+       sdl::InitScreen initScreen(width, height);
+
+       app::Application a(&initScreen, new pong::Match);
+       a.Run();
+       return 0;
+}
diff --git a/src/sdl/InitSDL.cpp b/src/sdl/InitSDL.cpp
new file mode 100644 (file)
index 0000000..0f2eacd
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * InitSDL.cpp
+ *
+ *  Created on: Apr 22, 2012
+ *      Author: holy
+ */
+
+#include "InitSDL.h"
+
+#include <stdexcept>
+
+using std::runtime_error;
+
+
+namespace sdl {
+
+InitSDL::InitSDL(Uint32 flags) {
+       if (SDL_Init(flags) != 0) {
+               throw runtime_error("failed to initialize SDL");
+       }
+}
+
+InitSDL::~InitSDL(void) {
+       SDL_Quit();
+}
+
+}
diff --git a/src/sdl/InitSDL.h b/src/sdl/InitSDL.h
new file mode 100644 (file)
index 0000000..016c0b4
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * InitSDL.h
+ *
+ *  Created on: Apr 22, 2012
+ *      Author: holy
+ */
+
+#ifndef SDL_INITSDL_H_
+#define SDL_INITSDL_H_
+
+#include <SDL/SDL.h>
+
+
+namespace sdl {
+
+class InitSDL {
+
+       public:
+               explicit InitSDL(Uint32 flags = SDL_INIT_EVERYTHING);
+               virtual ~InitSDL(void);
+       private:
+               InitSDL(const InitSDL &);
+               InitSDL &operator =(const InitSDL &);
+
+};
+
+}
+
+#endif /* SDL_INITSDL_H_ */
diff --git a/src/sdl/InitScreen.cpp b/src/sdl/InitScreen.cpp
new file mode 100644 (file)
index 0000000..c9b275f
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * InitScreen.cpp
+ *
+ *  Created on: Apr 22, 2012
+ *      Author: holy
+ */
+
+#include "InitScreen.h"
+
+#include <stdexcept>
+
+using std::runtime_error;
+
+
+namespace sdl {
+
+InitScreen::InitScreen(int width, int height, int bpp, Sint32 flags)
+: screen(SDL_SetVideoMode(width, height, bpp, flags)) {
+       if (!screen) {
+               throw runtime_error("failed to open screen");
+       }
+}
+
+InitScreen::~InitScreen(void) {
+
+}
+
+}
diff --git a/src/sdl/InitScreen.h b/src/sdl/InitScreen.h
new file mode 100644 (file)
index 0000000..ba731da
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * InitScreen.h
+ *
+ *  Created on: Apr 22, 2012
+ *      Author: holy
+ */
+
+#ifndef SDL_INITSCREEN_H_
+#define SDL_INITSCREEN_H_
+
+#include <SDL/SDL.h>
+
+namespace sdl {
+
+class InitScreen {
+
+       public:
+               InitScreen(int width, int height, int bpp = 32, Sint32 flags = SDL_HWSURFACE | SDL_DOUBLEBUF);
+               virtual ~InitScreen(void);
+       private:
+               InitScreen(const InitScreen &);
+               InitScreen &operator =(const InitScreen &);
+
+       public:
+               SDL_Surface *Screen(void) { return screen; };
+               const SDL_Surface *Screen(void) const { return screen; };
+
+               void Flip(void) { SDL_Flip(screen); };
+
+       private:
+               SDL_Surface *screen;
+
+};
+
+}
+
+#endif /* SDL_INITSCREEN_H_ */
diff --git a/src/sdl/InitTTF.cpp b/src/sdl/InitTTF.cpp
new file mode 100644 (file)
index 0000000..5818a73
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * InitTTF.cpp
+ *
+ *  Created on: Apr 22, 2012
+ *      Author: holy
+ */
+
+#include "InitTTF.h"
+
+#include <stdexcept>
+#include <SDL/SDL_ttf.h>
+
+using std::runtime_error;
+
+
+namespace sdl {
+
+InitTTF::InitTTF(void) {
+       if (TTF_Init() != 0) {
+               throw runtime_error("failed to initialize SDL TTF");
+       }
+}
+
+InitTTF::~InitTTF(void) {
+       TTF_Quit();
+}
+
+}
diff --git a/src/sdl/InitTTF.h b/src/sdl/InitTTF.h
new file mode 100644 (file)
index 0000000..6f0306c
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * InitTTF.h
+ *
+ *  Created on: Apr 22, 2012
+ *      Author: holy
+ */
+
+#ifndef SDL_INITTTF_H_
+#define SDL_INITTTF_H_
+
+namespace sdl {
+
+class InitTTF {
+
+       public:
+               InitTTF(void);
+               virtual ~InitTTF(void);
+       private:
+               InitTTF(const InitTTF &);
+               InitTTF &operator =(const InitTTF &);
+
+};
+
+}
+
+#endif /* SDL_INITTTF_H_ */