]> git.localhorst.tv Git - space.git/commitdiff
move to SDL2
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 23 Dec 2013 13:59:45 +0000 (14:59 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 23 Dec 2013 13:59:45 +0000 (14:59 +0100)
wow, this is great. yay

25 files changed:
build/config.mk
build/space.mk
src/app/Application.cpp
src/app/Application.h
src/app/SDL.cpp [new file with mode: 0644]
src/app/SDL.h [new file with mode: 0644]
src/entity/Entity.h
src/graphics/Camera.cpp
src/graphics/Camera.h
src/graphics/Canvas.cpp [new file with mode: 0644]
src/graphics/Canvas.h [new file with mode: 0644]
src/graphics/Color.h
src/graphics/Moveable.h
src/graphics/Vector.h [new file with mode: 0644]
src/graphics/Window.cpp [new file with mode: 0644]
src/graphics/Window.h [new file with mode: 0644]
src/graphics/primitive.cpp [deleted file]
src/graphics/primitive.h [deleted file]
src/math/Vector.h [deleted file]
src/sdl/InitSDL.cpp [deleted file]
src/sdl/InitSDL.h [deleted file]
src/sdl/InitScreen.cpp [deleted file]
src/sdl/InitScreen.h [deleted file]
src/space.cpp
src/world/Universe.h

index efbf376a49381cfb132a95b7dde693964d358977..d5a8fab1fc884758fc688464643f8739f8aaa845 100644 (file)
@@ -17,11 +17,8 @@ LDFLAGS ?=
 CXXFLAGS += -Wall -Werror
 
 # libraries
-SDL_FLAGS = $(shell pkg-config --cflags sdl)
-SDL_LIBS = $(shell pkg-config --libs sdl)
-
-SDL_IMG_FLAGS = $(shell pkg-config --cflags SDL_image)
-SDL_IMG_LIBS = $(shell pkg-config --libs SDL_image)
+SDL_FLAGS = $(shell pkg-config --cflags sdl2)
+SDL_LIBS = $(shell pkg-config --libs sdl2)
 
 CPPUNIT_FLAGS = $(shell pkg-config --cflags cppunit)
 CPPUNIT_LIBS = $(shell pkg-config --libs cppunit)
index 8a6f147324e7f470cdbb89817848ec6bd222cc9c..446cf04c05b3b26b3885304a6ed77fe55c66699f 100644 (file)
@@ -12,11 +12,9 @@ SPACE_TEST_EXES := test-all
 
 SPACE_FLAGS = $(sort $(strip \
                $(SDL_FLAGS) \
-               $(SDL_IMG_FLAGS) \
                ))
 SPACE_LIBS = $(sort $(strip \
                $(SDL_LIBS) \
-               $(SDL_IMG_LIBS) \
                ))
 
 SPACE_TEST_FLAGS = $(SPACE_FLAGS) $(CPPUNIT_FLAGS)
index 20c371887c153e9a48edbc474926e4c532442751..488b952243b94880e12886185d0b612080466b81 100644 (file)
@@ -1,17 +1,16 @@
 #include "Application.h"
 
+#include "../graphics/Canvas.h"
 #include "../graphics/Color.h"
-#include "../graphics/primitive.h"
-#include "../sdl/InitScreen.h"
 
 
 namespace space {
 
-Application::Application(InitScreen &s)
-: screen(s)
+Application::Application(Canvas &c)
+: canvas(c)
 , univ(Vector<int>(10, 10), Vector<int>(10, 10), Vector<int>(10, 10))
 , focus(Vector<float>(500, 500), 500)
-, cam(800, 800, focus.Pos())
+, cam(c.Size(), focus.Pos())
 , last(SDL_GetTicks())
 , running(false) {
        controlled = univ.AddEntity(Entity());
@@ -33,7 +32,7 @@ void Application::Loop(int delta) {
        HandleEvents();
        Update(delta);
        Render();
-       screen.Flip();
+       canvas.Present();
 }
 
 
@@ -44,15 +43,20 @@ void Application::HandleEvents() {
                        case SDL_QUIT:
                                running = false;
                                break;
-                       case SDL_VIDEORESIZE:
-                               screen.Resize(event.resize.w, event.resize.h);
-                               cam.Resize(event.resize.w, event.resize.h);
+                       case SDL_WINDOWEVENT:
+                               if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
+                                       cam.Resize(event.window.data1, event.window.data2);
+                               }
                                break;
                        case SDL_KEYDOWN:
-                               OnKeyDown(event.key);
+                               if (!event.key.repeat) {
+                                       OnKeyDown(event.key);
+                               }
                                break;
                        case SDL_KEYUP:
-                               OnKeyUp(event.key);
+                               if (!event.key.repeat) {
+                                       OnKeyUp(event.key);
+                               }
                                break;
                        default:
                                // skip event
@@ -153,18 +157,25 @@ void Application::Render() {
        constexpr Color entityColor(0x00, 0xAA, 0xAA);
        constexpr Color focusColor(0xFA, 0xFA, 0x00);
 
-       SDL_Surface *dst = screen.Screen();
-       const Vector<int> begin = cam.ToScreen(Vector<float>(0, 0));
-       const Vector<int> end =
-               cam.ToScreen((univ.size * univ.secSize * univ.areaSize))
-                       + Vector<int>(1, 1);
+       canvas.SetColor(background);
+       canvas.Fill();
 
-       Fill(dst, background);
-       Grid2(dst, begin, end, cam.ToScale(univ.areaSize), univ.secSize, secGrid, univGrid);
-       Cross(dst, cam.ToScreen(focus.Pos()), 15, focusColor);
+       canvas.Grid2(
+               cam.ToScreen(Vector<float>(0, 0)),
+               cam.ToScale(univ.size * univ.secSize * univ.areaSize),
+               cam.ToScale(univ.areaSize),
+               univ.secSize,
+               secGrid,
+               univGrid);
 
+       canvas.SetColor(focusColor);
+       canvas.Cross(cam.ToScreen(focus.Pos()), 15);
+
+       canvas.SetColor(entityColor);
        for (const Entity &e : univ.Entities()) {
-               Cross(dst, cam.ToScreen((e.area * univ.areaSize) + Vector<int>(e.pos)), 10, entityColor);
+               canvas.Cross(
+                       cam.ToScreen(Vector<float>(e.area * univ.areaSize) + e.pos),
+                       10);
        }
 }
 
index 61c3f45a5ab7e8ebe3ed740643e7097e17ee1246..b5f0a6b607ff362b052be126771705cd1b53996a 100644 (file)
@@ -3,21 +3,21 @@
 
 #include "../graphics/Camera.h"
 #include "../graphics/Moveable.h"
-#include "../math/Vector.h"
+#include "../graphics/Vector.h"
 #include "../world/Universe.h"
 
-#include <SDL/SDL.h>
+#include <SDL.h>
 
 
 namespace space {
 
-class InitScreen;
+class Canvas;
 class Entity;
 
 class Application {
 
 public:
-       explicit Application(InitScreen &);
+       explicit Application(Canvas &);
 
 public:
        void Run();
@@ -34,7 +34,7 @@ private:
        void Render();
 
 private:
-       InitScreen &screen;
+       Canvas &canvas;
 
        Universe univ;
 
diff --git a/src/app/SDL.cpp b/src/app/SDL.cpp
new file mode 100644 (file)
index 0000000..e5b48ca
--- /dev/null
@@ -0,0 +1,19 @@
+#include "SDL.h"
+
+#include <stdexcept>
+#include <string>
+
+
+namespace space {
+
+SDL::SDL(Uint32 flags) {
+       if (SDL_Init(flags) != 0) {
+               throw std::runtime_error(std::string("init SDL: ") + SDL_GetError());
+       }
+}
+
+SDL::~SDL() {
+       SDL_Quit();
+}
+
+}
diff --git a/src/app/SDL.h b/src/app/SDL.h
new file mode 100644 (file)
index 0000000..ea2a198
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef SPACE_SDL_H_
+#define SPACE_SDL_H_
+
+#include <SDL.h>
+
+
+namespace space {
+
+class SDL {
+
+public:
+       explicit SDL(Uint32 flags);
+       ~SDL();
+
+       SDL(const SDL &) = delete;
+       SDL &operator =(const SDL &) = delete;
+
+};
+
+}
+
+#endif
index 9fd2dff483f06a62a4467b254e62dde7890c40a5..eb95331e4cf48d130932d26fbe06adff5a79ad02 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef SPACE_ENTITY_H_
 #define SPACE_ENTITY_H_
 
-#include "../math/Vector.h"
+#include "../graphics/Vector.h"
 
 
 namespace space {
index ea2f97de328f5270a0edeab91c998d9444b9aefa..74ebd5f6fb3759f99870ec618af5ed20b5c707e6 100644 (file)
@@ -3,9 +3,9 @@
 
 namespace space {
 
-Camera::Camera(int w, int h, const Vector<float> &t)
+Camera::Camera(Vector<int> s, const Vector<float> &t)
 : target(&t)
-, size(w, h)
+, size(s)
 , offset(size / 2)
 , zoom(1)
 , zoomAcc(0) {
@@ -13,8 +13,8 @@ Camera::Camera(int w, int h, const Vector<float> &t)
 }
 
 
-void Camera::Resize(int w, int h) {
-       size = Vector<int>(w, h);
+void Camera::Resize(Vector<int> s) {
+       size = s;
        offset = size / 2;
 }
 
index 4d49cb618d6ece6ecb2c40635aa4c66a219231f5..815b4b047fdf1e107b3190034ac8ffe02b4a9071 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef SPACE_CAMERA_H_
 #define SPACE_CAMERA_H_
 
-#include "../math/Vector.h"
+#include "Vector.h"
 
 
 namespace space {
@@ -9,7 +9,7 @@ namespace space {
 class Camera {
 
 public:
-       Camera(int w, int h, const Vector<float> &);
+       Camera(Vector<int> size, const Vector<float> &);
 
 public:
        void SetTarget(const Vector<float> &t) { target = &t; }
@@ -18,7 +18,8 @@ public:
        Vector<int> ScreenSize() const { return size; }
        float Zoom() const { return zoom; }
 
-       void Resize(int w, int h);
+       void Resize(int w, int h) { Resize(Vector<int>(w, h)); }
+       void Resize(Vector<int>);
        void Update(float deltaT);
 
        void StartZoom();
diff --git a/src/graphics/Canvas.cpp b/src/graphics/Canvas.cpp
new file mode 100644 (file)
index 0000000..45997c6
--- /dev/null
@@ -0,0 +1,227 @@
+#include "Canvas.h"
+
+#include <algorithm>
+#include <cassert>
+#include <stdexcept>
+#include <string>
+
+using std::runtime_error;
+
+
+namespace space {
+
+Canvas::Canvas(SDL_Window *win, int index, Uint32 flags)
+: canv(SDL_CreateRenderer(win, index, flags)) {
+       if (!canv) {
+               throw runtime_error(std::string("create canvas: ") + SDL_GetError());
+       }
+}
+
+Canvas::~Canvas() {
+       if (canv) SDL_DestroyRenderer(canv);
+}
+
+Canvas::Canvas(Canvas &&other)
+: canv(other.canv) {
+       other.canv = nullptr;
+}
+
+Canvas &Canvas::operator =(Canvas &&other) {
+       std::swap(canv, other.canv);
+       return *this;
+}
+
+
+void Canvas::Present() {
+       SDL_RenderPresent(canv);
+}
+
+
+Vector<int> Canvas::Size() const {
+       assert(canv);
+       Vector<int> size;
+       SDL_GetRendererOutputSize(canv, &size.x, &size.y);
+       return size;
+}
+
+
+void Canvas::SetColor(Color c) {
+       SDL_SetRenderDrawColor(canv, c.r, c.g, c.b, c.a);
+}
+
+
+void Canvas::Fill() {
+       SDL_RenderClear(canv);
+}
+
+void Canvas::Outline() {
+       SDL_RenderDrawRect(canv, nullptr);
+}
+
+
+void Canvas::Line(Vector<int> from, Vector<int> to) {
+       SDL_RenderDrawLine(canv, from.x, from.y, to.x, to.y);
+}
+
+void Canvas::FillRect(Vector<int> pos, Vector<int> size) {
+       SDL_Rect destRect;
+       destRect.x = pos.x;
+       destRect.y = pos.y;
+       destRect.w = size.x;
+       destRect.h = size.y;
+       SDL_RenderFillRect(canv, &destRect);
+}
+
+void Canvas::OutlineRect(Vector<int> pos, Vector<int> size) {
+       SDL_Rect destRect;
+       destRect.x = pos.x;
+       destRect.y = pos.y;
+       destRect.w = size.x;
+       destRect.h = size.y;
+       SDL_RenderDrawRect(canv, &destRect);
+}
+
+
+void Canvas::Dot(Vector<int> pos) {
+       SDL_RenderDrawPoint(canv, pos.x, pos.y);
+}
+
+void Canvas::Cross(Vector<int> pos, int extent) {
+       Line(
+               Vector<int>(pos.x - extent, pos.y),
+               Vector<int>(pos.x + extent, pos.y));
+       Line(
+               Vector<int>(pos.x, pos.y - extent),
+               Vector<int>(pos.x, pos.y + extent));
+}
+
+
+namespace {
+
+template<class Scalar>
+void GridImpl(
+               Canvas &canv,
+               Vector<int> pos,
+               Vector<int> size,
+               Vector<Scalar> step) {
+       Vector<int> from(pos);
+       Vector<int> to(pos + size);
+       Vector<int> clip(canv.Size());
+
+       if (from.x > clip.x || from.y > clip.y || to.x < 0 || to.y < 0) {
+               return;
+       }
+       if (step.x <= 1 || step.y <= 1) {
+               canv.FillRect(pos, size);
+               return;
+       }
+
+       if (from.x < -step.x) {
+               int skip = from.x / -step.x;
+               from.x += skip * step.x;
+       }
+       if (from.y < -step.y) {
+               int skip = from.y / -step.y;
+               from.y += skip * step.y;
+       }
+       if (to.x > clip.x + step.x) {
+               int skip = (to.x - clip.x) / step.x;
+               to.x -= skip * step.x;
+       }
+       if (to.y > clip.y + step.y) {
+               int skip = (to.y - clip.y) / step.y;
+               to.y -= skip * step.y;
+       }
+
+       int width = to.x - from.x;
+       int height = to.y - from.y;
+
+       for (Vector<Scalar> pos(from); pos.x <= to.x; pos.x += step.x) {
+               canv.Line(pos, Vector<int>(pos.x, pos.y + height));
+       }
+       for (Vector<Scalar> pos(from); pos.y <= to.y; pos.y += step.y) {
+               canv.Line(pos, Vector<int>(pos.x + width, pos.y));
+       }
+}
+
+template<class Scalar>
+void Grid2Impl(
+               Canvas &canv,
+               Vector<int> pos,
+               Vector<int> size,
+               Vector<Scalar> step,
+               Vector<int> n,
+               Color c1,
+               Color c2) {
+       Vector<int> from(pos);
+       Vector<int> to(pos + size);
+       Vector<int> clip(canv.Size());
+
+       if (from.x > clip.x || from.y > clip.y || to.x < 0 || to.y < 0) {
+               return;
+       }
+       if (step.x <= 1 || step.y <= 1) {
+               canv.SetColor(c1);
+               canv.FillRect(pos, size);
+               canv.SetColor(c2);
+               GridImpl(canv, pos, size, step);
+               return;
+       }
+
+       Vector<int> i(0, 0);
+
+       if (from.x < -step.x) {
+               int skip = from.x / -step.x;
+               from.x += skip * step.x;
+               i.x += skip;
+       }
+       if (from.y < -step.y) {
+               int skip = from.y / -step.y;
+               from.y += skip * step.y;
+               i.y += skip;
+       }
+       if (to.x > clip.x + step.x) {
+               int skip = (to.x - clip.x) / step.x;
+               to.x -= skip * step.x;
+       }
+       if (to.y > clip.y + step.y) {
+               int skip = (to.y - clip.y) / step.y;
+               to.y -= skip * step.y;
+       }
+
+       int width = to.x - from.x;
+       int height = to.y - from.y;
+
+       for (Vector<Scalar> pos(from); pos.x <= to.x; pos.x += step.x) {
+               canv.SetColor((i.x++ % n.x) ? c1 : c2);
+               canv.Line(pos, Vector<int>(pos.x, pos.y + height));
+       }
+       for (Vector<Scalar> pos(from); pos.y <= to.y; pos.y += step.y) {
+               canv.SetColor((i.y++ % n.y) ? c1 : c2);
+               canv.Line(pos, Vector<int>(pos.x + width, pos.y));
+       }
+}
+
+}
+
+void Canvas::Grid(Vector<int> pos, Vector<int> size, Vector<int> step) {
+       GridImpl(*this, pos, size, step);
+}
+
+void Canvas::Grid(Vector<int> pos, Vector<int> size, Vector<float> step) {
+       GridImpl(*this, pos, size, step);
+}
+
+void Canvas::Grid2(
+               Vector<int> pos, Vector<int> size, Vector<int> step,
+               Vector<int> n, Color c1, Color c2) {
+       Grid2Impl(*this, pos, size, step, n, c1, c2);
+}
+
+void Canvas::Grid2(
+               Vector<int> pos, Vector<int> size, Vector<float> step,
+               Vector<int> n, Color c1, Color c2) {
+       Grid2Impl(*this, pos, size, step, n, c1, c2);
+}
+
+}
diff --git a/src/graphics/Canvas.h b/src/graphics/Canvas.h
new file mode 100644 (file)
index 0000000..032c7db
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef SPACE_CANVAS_H_
+#define SPACE_CANVAS_H_
+
+#include "Color.h"
+#include "Vector.h"
+
+#include <SDL.h>
+
+
+namespace space {
+
+class Canvas {
+
+public:
+       Canvas() : canv(nullptr) { }
+       Canvas(SDL_Window *win, int index, Uint32 flags);
+       ~Canvas();
+
+       Canvas(Canvas &&);
+       Canvas &operator =(Canvas &&);
+
+       Canvas(const Canvas &) = delete;
+       Canvas &operator =(const Canvas &) = delete;
+
+public:
+       Vector<int> Size() const;
+
+       void Present();
+
+       void SetColor(Color);
+
+       void Fill();
+       void Outline();
+
+       void Line(Vector<int> from, Vector<int> to);
+       void FillRect(Vector<int> pos, Vector<int> size);
+       void OutlineRect(Vector<int> pos, Vector<int> size);
+
+       void Dot(Vector<int> pos);
+       void Cross(Vector<int> pos, int extent);
+
+       void Grid(Vector<int> pos, Vector<int> size, Vector<int> step);
+       void Grid(Vector<int> pos, Vector<int> size, Vector<float> step);
+
+       void Grid2(Vector<int> pos, Vector<int> size, Vector<int> step,
+                       Vector<int> n, Color, Color);
+       void Grid2(Vector<int> pos, Vector<int> size, Vector<float> step,
+                       Vector<int> n, Color, Color);
+
+private:
+       SDL_Renderer *canv;
+
+};
+
+}
+
+#endif
index d561fc8dc3b119b2ae8675908474c009561efd3f..9260ad9560e0350a479fdcb7925bd49b7676e981 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef SPACE_COLOR_H_
 #define SPACE_COLOR_H_
 
-#include <SDL/SDL.h>
+#include <SDL.h>
 
 
 namespace space {
@@ -13,16 +13,6 @@ struct Color {
        constexpr Color(Uint8 r, Uint8 g, Uint8 b, Uint8 a = 0xFF)
        : r(r), g(g), b(b), a(a) { }
 
-       Uint32 MapRGB(SDL_Surface *s) const
-               { return MapRGB(s->format); }
-       Uint32 MapRGB(SDL_PixelFormat *f) const
-               { return SDL_MapRGB(f, r, g, b); }
-
-       Uint32 MapRGBA(SDL_Surface *s) const
-               { return MapRGBA(s->format); }
-       Uint32 MapRGBA(SDL_PixelFormat *f) const
-               { return SDL_MapRGBA(f, r, g, b, a); }
-
        Uint8 r, g, b, a;
 
 };
index 71f590919678d72f654c23f04e95b8525a5982ca..7627283ffedb958d2ba9acbd0b588314af7ebc3b 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef SPACE_MOVEABLE_H_
 #define SPACE_MOVEABLE_H_
 
-#include "../math/Vector.h"
+#include "Vector.h"
 
 
 namespace space {
diff --git a/src/graphics/Vector.h b/src/graphics/Vector.h
new file mode 100644 (file)
index 0000000..b5c6d7d
--- /dev/null
@@ -0,0 +1,130 @@
+#ifndef SPACE_VECTOR_H_
+#define SPACE_VECTOR_H_
+
+#include <algorithm>
+#include <ostream>
+
+
+namespace space {
+
+template<class Scalar>
+class Vector {
+
+public:
+       constexpr Vector() : x(0), y(0) { }
+       constexpr Vector(Scalar x, Scalar y) : x(x), y(y) { }
+
+       template<class Other>
+       constexpr Vector(Vector<Other> other) : x(other.x), y(other.y) { }
+
+public:
+       Vector<Scalar> &operator +=(Vector<Scalar> other) {
+               x += other.x;
+               y += other.y;
+               return *this;
+       }
+       Vector<Scalar> &operator -=(Vector<Scalar> other) {
+               x -= other.x;
+               y -= other.y;
+               return *this;
+       }
+
+public:
+       Scalar x;
+       Scalar y;
+
+};
+
+
+template<class Scalar>
+constexpr Vector<Scalar> operator -(Vector<Scalar> v) {
+       return Vector<Scalar>(-v.x, -v.y);
+}
+
+
+template<class Scalar>
+constexpr Vector<Scalar> operator +(Vector<Scalar> lhs, Vector<Scalar> rhs) {
+       return Vector<Scalar>(lhs.x + rhs.x, lhs.y + rhs.y);
+}
+
+template<class Scalar>
+constexpr Vector<Scalar> operator -(Vector<Scalar> lhs, Vector<Scalar> rhs) {
+       return Vector<Scalar>(lhs.x - rhs.x, lhs.y - rhs.y);
+}
+
+
+template<class Scalar>
+constexpr Vector<Scalar> operator *(Vector<Scalar> lhs, Scalar rhs) {
+       return Vector<Scalar>(lhs.x * rhs, lhs.y * rhs);
+}
+
+template<class Scalar>
+constexpr Vector<Scalar> operator *(Scalar lhs, Vector<Scalar> rhs) {
+       return rhs * lhs;
+}
+template<class Scalar>
+constexpr Vector<Scalar> operator *(Vector<Scalar> lhs, Vector<Scalar> rhs) {
+       return Vector<Scalar>(lhs.x * rhs.x, lhs.y * rhs.y);
+}
+
+
+template<class Scalar>
+constexpr Vector<Scalar> operator /(Vector<Scalar> lhs, Scalar rhs) {
+       return Vector<Scalar>(lhs.x / rhs, lhs.y / rhs);
+}
+
+template<class Scalar>
+constexpr Vector<Scalar> operator /(Scalar lhs, Vector<Scalar> rhs) {
+       return rhs / lhs;
+}
+template<class Scalar>
+constexpr Vector<Scalar> operator /(Vector<Scalar> lhs, Vector<Scalar> rhs) {
+       return Vector<Scalar>(lhs.x / rhs.x, lhs.y / rhs.y);
+}
+
+
+template<class Scalar>
+constexpr bool operator ==(Vector<Scalar> lhs, Vector<Scalar> rhs) {
+       return lhs.x == rhs.x && lhs.y == rhs.y;
+}
+template<class Scalar>
+constexpr bool operator !=(Vector<Scalar> lhs, Vector<Scalar> rhs) {
+       return lhs.x != rhs.x && lhs.y != rhs.y;
+}
+
+
+template<class Scalar>
+inline std::ostream &operator <<(std::ostream &out, Vector<Scalar> v) {
+       return out << '<' << v.x << ',' << v.y << '>';
+}
+
+}
+
+
+namespace std {
+
+template<class Scalar>
+constexpr space::Vector<Scalar> min(
+               space::Vector<Scalar> lhs,
+               space::Vector<Scalar> rhs
+) {
+       return space::Vector<Scalar>(
+               min(lhs.x, rhs.x),
+               min(lhs.y, rhs.y)
+       );
+}
+
+template<class Scalar>
+constexpr space::Vector<Scalar> max(
+               space::Vector<Scalar> lhs,
+               space::Vector<Scalar> rhs
+) {
+       return space::Vector<Scalar>(
+               max(lhs.x, rhs.x),
+               max(lhs.y, rhs.y)
+       );
+}
+
+}
+
+#endif
diff --git a/src/graphics/Window.cpp b/src/graphics/Window.cpp
new file mode 100644 (file)
index 0000000..7cf1b3a
--- /dev/null
@@ -0,0 +1,58 @@
+#include "Window.h"
+
+#include <algorithm>
+#include <cassert>
+#include <stdexcept>
+#include <string>
+
+using std::runtime_error;
+
+
+namespace space {
+
+const Vector<int> Window::POS_CENTER(
+       SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
+const Vector<int> Window::POS_UNDEF(
+       SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED);
+
+
+Window::Window(
+       const char *title,
+       Vector<int> pos,
+       Vector<int> size,
+       Uint32 flags)
+: win(SDL_CreateWindow(title, pos.x, pos.y, size.x, size.y, flags)) {
+       if (!win) {
+               throw runtime_error(std::string("create window ") + title
+                       + ": " + SDL_GetError());
+       }
+}
+
+Window::~Window() {
+       if (win) SDL_DestroyWindow(win);
+}
+
+Window::Window(Window &&other)
+: win(other.win) {
+       other.win = nullptr;
+}
+
+Window &Window::operator =(Window &&other) {
+       std::swap(win, other.win);
+       return *this;
+}
+
+
+Vector<int> Window::Size() const {
+       assert(win);
+       Vector<int> size;
+       SDL_GetWindowSize(win, &size.x, &size.y);
+       return size;
+}
+
+
+Canvas Window::CreateCanvas(Uint32 flags) {
+       return Canvas(win, -1, flags);
+}
+
+}
diff --git a/src/graphics/Window.h b/src/graphics/Window.h
new file mode 100644 (file)
index 0000000..00418af
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef SPACE_WINDOW_H_
+#define SPACE_WINDOW_H
+
+#include "Canvas.h"
+#include "Vector.h"
+
+#include <SDL.h>
+
+
+namespace space {
+
+class Window {
+
+public:
+       static const Vector<int> POS_CENTER;
+       static const Vector<int> POS_UNDEF;
+
+public:
+       Window() : win(nullptr) { }
+       Window(const char *title, Vector<int> pos, Vector<int> size, Uint32 flags);
+       ~Window();
+
+       Window(Window &&);
+       Window &operator =(Window &&);
+
+       Window(const Window &) = delete;
+       Window &operator =(const Window &) = delete;
+
+public:
+       Vector<int> Size() const;
+
+       Canvas CreateCanvas(Uint32 flags);
+
+private:
+       SDL_Window *win;
+
+};
+
+}
+
+#endif
diff --git a/src/graphics/primitive.cpp b/src/graphics/primitive.cpp
deleted file mode 100644 (file)
index f8b5863..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-#include "primitive.h"
-
-#include <algorithm>
-
-using namespace std;
-
-
-namespace space {
-
-void Fill(SDL_Surface *dst, Color c) {
-       Fill(dst, c.MapRGBA(dst));
-}
-
-void Fill(SDL_Surface *dst, Uint32 color) {
-       SDL_FillRect(dst, nullptr, color);
-}
-
-
-void HLine(SDL_Surface *dst, Vector<int> pos, int len, Color c) {
-       HLine(dst, pos, len, c.MapRGBA(dst));
-}
-
-void HLine(SDL_Surface *dst, Vector<int> pos, int len, Uint32 c) {
-       FillRect(dst, pos, Vector<int>(len, 1), c);
-}
-
-void VLine(SDL_Surface *dst, Vector<int> pos, int len, Color c) {
-       VLine(dst, pos, len, c.MapRGBA(dst));
-}
-
-void VLine(SDL_Surface *dst, Vector<int> pos, int len, Uint32 c) {
-       FillRect(dst, pos, Vector<int>(1, len), c);
-}
-
-
-void FillRect(SDL_Surface *dst, Vector<int> pos, Vector<int> size, Color c) {
-       FillRect(dst, pos, size, c.MapRGBA(dst));
-}
-
-void FillRect(SDL_Surface *dst, Vector<int> pos, Vector<int> size, Uint32 c) {
-       SDL_Rect destRect;
-       destRect.x = pos.x;
-       destRect.y = pos.y;
-       destRect.w = size.x;
-       destRect.h = size.y;
-       SDL_FillRect(dst, &destRect, c);
-}
-
-void OutlineRect(SDL_Surface *dst, Vector<int> pos, Vector<int> size, Color c) {
-       OutlineRect(dst, pos, size, c.MapRGBA(dst));
-}
-
-void OutlineRect(SDL_Surface *dst, Vector<int> pos, Vector<int> size, Uint32 c) {
-       SDL_Rect destRect;
-
-       destRect.x = pos.x;
-       destRect.y = pos.y;
-       destRect.w = size.x;
-       destRect.h = 1;
-       SDL_FillRect(dst, &destRect, c);
-
-       destRect.x = pos.x;
-       destRect.y = pos.y + size.y - 1;
-       destRect.w = size.x;
-       destRect.h = 1;
-       SDL_FillRect(dst, &destRect, c);
-
-       destRect.x = pos.x;
-       destRect.y = pos.y;
-       destRect.w = 1;
-       destRect.h = size.y;
-       SDL_FillRect(dst, &destRect, c);
-
-       destRect.x = pos.x + size.x - 1;
-       destRect.y = pos.y;
-       destRect.w = 1;
-       destRect.h = size.y;
-       SDL_FillRect(dst, &destRect, c);
-}
-
-
-void Cross(
-               SDL_Surface *dst,
-               Vector<int> pos,
-               int extent,
-               Color color) {
-       Uint32 c = color.MapRGBA(dst);
-       int len = 2 * extent + 1;
-
-       HLine(dst, Vector<int>(pos.x - extent, pos.y), len, c);
-       VLine(dst, Vector<int>(pos.x, pos.y - extent), len, c);
-}
-
-
-void Grid(
-               SDL_Surface *dst,
-               Vector<int> first,
-               Vector<int> second,
-               Vector<int> size,
-               Color color) {
-       Uint32 c = color.MapRGBA(dst);
-
-       Vector<int> from = min(first, second);
-       Vector<int> to = max(first, second);
-
-       if (size.x <= 1 || size.y <= 1) {
-               FillRect(dst, from, to - from, c);
-               return;
-       }
-
-       if (from.x > dst->w || from.y > dst->h || to.x < 0 || to.y < 0) {
-               return;
-       }
-
-       while (from.x < -size.x) from.x += size.x;
-       while (from.y < -size.y) from.y += size.y;
-       while (to.x > dst->w + size.x) to.x -= size.x;
-       while (to.y > dst->h + size.y) to.y -= size.y;
-
-       int width = to.x - from.x;
-       int height = to.y - from.y;
-
-       for (Vector<int> pos(from); pos.x <= to.x; pos.x += size.x) {
-               VLine(dst, pos, height, c);
-       }
-       for (Vector<int> pos(from); pos.y <= to.y; pos.y += size.y) {
-               HLine(dst, pos, width, c);
-       }
-}
-
-void Grid(
-               SDL_Surface *dst,
-               Vector<int> first,
-               Vector<int> second,
-               Vector<float> size,
-               Color color) {
-       Uint32 c = color.MapRGBA(dst);
-
-       Vector<int> from = min(first, second);
-       Vector<int> to = max(first, second);
-
-       if (size.x <= 1 || size.y <= 1) {
-               FillRect(dst, from, to - from, c);
-               return;
-       }
-
-       if (from.x > dst->w || from.y > dst->h || to.x < 0 || to.y < 0) {
-               return;
-       }
-
-       while (from.x < -size.x) from.x += size.x;
-       while (from.y < -size.y) from.y += size.y;
-       while (to.x > dst->w + size.x) to.x -= size.x;
-       while (to.y > dst->h + size.y) to.y -= size.y;
-
-       float width = to.x - from.x;
-       float height = to.y - from.y;
-
-       for (Vector<float> pos(from); pos.x <= to.x; pos.x += size.x) {
-               VLine(dst, pos, height, c);
-       }
-       for (Vector<float> pos(from); pos.y <= to.y; pos.y += size.y) {
-               HLine(dst, pos, width, c);
-       }
-}
-
-void Grid2(
-               SDL_Surface *dst,
-               Vector<int> first,
-               Vector<int> second,
-               Vector<int> size,
-               Vector<int> n,
-               Color color1,
-               Color color2) {
-       Uint32 c1 = color1.MapRGBA(dst);
-       Uint32 c2 = color2.MapRGBA(dst);
-
-       Vector<int> from = min(first, second);
-       Vector<int> to = max(first, second);
-
-       if (size.x <= 1 || size.y <= 1) {
-               FillRect(dst, from, to - from, c1);
-               Grid(dst, from, to, size * n, color2);
-               return;
-       }
-
-       if (from.x > dst->w || from.y > dst->h || to.x < 0 || to.y < 0) {
-               return;
-       }
-
-       Vector<int> i(0, 0);
-       while (from.x < -size.x) { from.x += size.x; ++i.x; }
-       while (from.y < -size.y) { from.y += size.y; ++i.y; }
-       while (to.x > dst->w + size.x) to.x -= size.x;
-       while (to.y > dst->h + size.y) to.y -= size.y;
-
-       int width = to.x - from.x;
-       int height = to.y - from.y;
-
-       for (Vector<int> pos(from); pos.x <= to.x; pos.x += size.x) {
-               VLine(dst, pos, height, (i.x++ % n.x) ? c1 : c2);
-       }
-       for (Vector<int> pos(from); pos.y <= to.y; pos.y += size.y) {
-               HLine(dst, pos, width, (i.y++ % n.y) ? c1 : c2);
-       }
-}
-
-void Grid2(
-               SDL_Surface *dst,
-               Vector<int> first,
-               Vector<int> second,
-               Vector<float> size,
-               Vector<int> n,
-               Color color1,
-               Color color2) {
-       Uint32 c1 = color1.MapRGBA(dst);
-       Uint32 c2 = color2.MapRGBA(dst);
-
-       Vector<int> from = min(first, second);
-       Vector<int> to = max(first, second);
-
-       if (size.x <= 1 || size.y <= 1) {
-               FillRect(dst, from, to - from, c1);
-               Grid(dst, from, to, size * Vector<float>(n), color2);
-               return;
-       }
-
-       if (from.x > dst->w || from.y > dst->h || to.x < 0 || to.y < 0) {
-               return;
-       }
-
-       Vector<int> i(0, 0);
-       while (from.x < -size.x) { from.x += size.x; ++i.x; }
-       while (from.y < -size.y) { from.y += size.y; ++i.y; }
-       while (to.x > dst->w + size.x) to.x -= size.x;
-       while (to.y > dst->h + size.y) to.y -= size.y;
-
-       float width = to.x - from.x;
-       float height = to.y - from.y;
-
-       for (Vector<float> pos(from); pos.x <= to.x; pos.x += size.x) {
-               VLine(dst, pos, height, (i.x++ % n.x) ? c1 : c2);
-       }
-       for (Vector<float> pos(from); pos.y <= to.y; pos.y += size.y) {
-               HLine(dst, pos, width, (i.y++ % n.y) ? c1 : c2);
-       }
-}
-
-}
diff --git a/src/graphics/primitive.h b/src/graphics/primitive.h
deleted file mode 100644 (file)
index 6dcc6fe..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef SPACE_PRIMITIVE_H_
-#define SPACE_PRIMITIVE_H_
-
-#include "Color.h"
-#include "../math/Vector.h"
-
-#include <SDL/SDL.h>
-
-
-namespace space {
-
-void Fill(SDL_Surface *, Color);
-void Fill(SDL_Surface *, Uint32 color);
-
-void HLine(SDL_Surface *, Vector<int> pos, int len, Color);
-void HLine(SDL_Surface *, Vector<int> pos, int len, Uint32 color);
-void VLine(SDL_Surface *, Vector<int> pos, int len, Color);
-void VLine(SDL_Surface *, Vector<int> pos, int len, Uint32 color);
-
-void FillRect(SDL_Surface *, Vector<int> pos, Vector<int> size, Color);
-void FillRect(SDL_Surface *, Vector<int> pos, Vector<int> size, Uint32 color);
-void OutlineRect(SDL_Surface *, Vector<int> pos, Vector<int> size, Color);
-void OutlineRect(SDL_Surface *, Vector<int> pos, Vector<int> size, Uint32 color);
-
-void Cross(
-       SDL_Surface *,
-       Vector<int> pos,
-       int extent,
-       Color);
-
-void Grid(
-       SDL_Surface *,
-       Vector<int> from,
-       Vector<int> to,
-       Vector<int> size,
-       Color);
-void Grid(
-       SDL_Surface *,
-       Vector<int> from,
-       Vector<int> to,
-       Vector<float> size,
-       Color);
-
-void Grid2(
-       SDL_Surface *,
-       Vector<int> from,
-       Vector<int> to,
-       Vector<int> size,
-       Vector<int> n,
-       Color,
-       Color);
-void Grid2(
-       SDL_Surface *,
-       Vector<int> from,
-       Vector<int> to,
-       Vector<float> size,
-       Vector<int> n,
-       Color,
-       Color);
-
-}
-
-#endif
diff --git a/src/math/Vector.h b/src/math/Vector.h
deleted file mode 100644 (file)
index b5c6d7d..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-#ifndef SPACE_VECTOR_H_
-#define SPACE_VECTOR_H_
-
-#include <algorithm>
-#include <ostream>
-
-
-namespace space {
-
-template<class Scalar>
-class Vector {
-
-public:
-       constexpr Vector() : x(0), y(0) { }
-       constexpr Vector(Scalar x, Scalar y) : x(x), y(y) { }
-
-       template<class Other>
-       constexpr Vector(Vector<Other> other) : x(other.x), y(other.y) { }
-
-public:
-       Vector<Scalar> &operator +=(Vector<Scalar> other) {
-               x += other.x;
-               y += other.y;
-               return *this;
-       }
-       Vector<Scalar> &operator -=(Vector<Scalar> other) {
-               x -= other.x;
-               y -= other.y;
-               return *this;
-       }
-
-public:
-       Scalar x;
-       Scalar y;
-
-};
-
-
-template<class Scalar>
-constexpr Vector<Scalar> operator -(Vector<Scalar> v) {
-       return Vector<Scalar>(-v.x, -v.y);
-}
-
-
-template<class Scalar>
-constexpr Vector<Scalar> operator +(Vector<Scalar> lhs, Vector<Scalar> rhs) {
-       return Vector<Scalar>(lhs.x + rhs.x, lhs.y + rhs.y);
-}
-
-template<class Scalar>
-constexpr Vector<Scalar> operator -(Vector<Scalar> lhs, Vector<Scalar> rhs) {
-       return Vector<Scalar>(lhs.x - rhs.x, lhs.y - rhs.y);
-}
-
-
-template<class Scalar>
-constexpr Vector<Scalar> operator *(Vector<Scalar> lhs, Scalar rhs) {
-       return Vector<Scalar>(lhs.x * rhs, lhs.y * rhs);
-}
-
-template<class Scalar>
-constexpr Vector<Scalar> operator *(Scalar lhs, Vector<Scalar> rhs) {
-       return rhs * lhs;
-}
-template<class Scalar>
-constexpr Vector<Scalar> operator *(Vector<Scalar> lhs, Vector<Scalar> rhs) {
-       return Vector<Scalar>(lhs.x * rhs.x, lhs.y * rhs.y);
-}
-
-
-template<class Scalar>
-constexpr Vector<Scalar> operator /(Vector<Scalar> lhs, Scalar rhs) {
-       return Vector<Scalar>(lhs.x / rhs, lhs.y / rhs);
-}
-
-template<class Scalar>
-constexpr Vector<Scalar> operator /(Scalar lhs, Vector<Scalar> rhs) {
-       return rhs / lhs;
-}
-template<class Scalar>
-constexpr Vector<Scalar> operator /(Vector<Scalar> lhs, Vector<Scalar> rhs) {
-       return Vector<Scalar>(lhs.x / rhs.x, lhs.y / rhs.y);
-}
-
-
-template<class Scalar>
-constexpr bool operator ==(Vector<Scalar> lhs, Vector<Scalar> rhs) {
-       return lhs.x == rhs.x && lhs.y == rhs.y;
-}
-template<class Scalar>
-constexpr bool operator !=(Vector<Scalar> lhs, Vector<Scalar> rhs) {
-       return lhs.x != rhs.x && lhs.y != rhs.y;
-}
-
-
-template<class Scalar>
-inline std::ostream &operator <<(std::ostream &out, Vector<Scalar> v) {
-       return out << '<' << v.x << ',' << v.y << '>';
-}
-
-}
-
-
-namespace std {
-
-template<class Scalar>
-constexpr space::Vector<Scalar> min(
-               space::Vector<Scalar> lhs,
-               space::Vector<Scalar> rhs
-) {
-       return space::Vector<Scalar>(
-               min(lhs.x, rhs.x),
-               min(lhs.y, rhs.y)
-       );
-}
-
-template<class Scalar>
-constexpr space::Vector<Scalar> max(
-               space::Vector<Scalar> lhs,
-               space::Vector<Scalar> rhs
-) {
-       return space::Vector<Scalar>(
-               max(lhs.x, rhs.x),
-               max(lhs.y, rhs.y)
-       );
-}
-
-}
-
-#endif
diff --git a/src/sdl/InitSDL.cpp b/src/sdl/InitSDL.cpp
deleted file mode 100644 (file)
index 0676dfb..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "InitSDL.h"
-
-#include <stdexcept>
-
-using std::runtime_error;
-
-
-namespace space {
-
-InitSDL::InitSDL(Uint32 flags) {
-       if (SDL_Init(flags) != 0) {
-               throw runtime_error("failed to initialize SDL");
-       }
-}
-
-InitSDL::~InitSDL() {
-       SDL_Quit();
-}
-
-}
diff --git a/src/sdl/InitSDL.h b/src/sdl/InitSDL.h
deleted file mode 100644 (file)
index dd3cf72..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef SPACE_INITSDL_H_
-#define SPACE_INITSDL_H_
-
-#include <SDL/SDL.h>
-
-
-namespace space {
-
-class InitSDL {
-
-public:
-       explicit InitSDL(Uint32 flags = SDL_INIT_EVERYTHING);
-       ~InitSDL();
-
-       InitSDL(const InitSDL &) = delete;
-       InitSDL &operator =(const InitSDL &) = delete;
-
-};
-
-}
-
-#endif
diff --git a/src/sdl/InitScreen.cpp b/src/sdl/InitScreen.cpp
deleted file mode 100644 (file)
index 2ed13dd..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "InitScreen.h"
-
-#include <stdexcept>
-
-using std::runtime_error;
-
-
-namespace space {
-
-InitScreen::InitScreen(int width, int height, int bpp, Sint32 flags)
-: screen(SDL_SetVideoMode(width, height, bpp, flags))
-, bpp(bpp)
-, flags(flags) {
-       if (!screen) {
-               throw runtime_error("failed to open screen");
-       }
-}
-
-InitScreen::~InitScreen() {
-
-}
-
-
-SDL_Surface *InitScreen::Resize(int width, int height) {
-       SDL_Surface *newScreen(SDL_SetVideoMode(width, height, bpp, flags));
-       if (!newScreen) {
-               throw runtime_error("failed to resize screen");
-       }
-       return screen = newScreen;
-}
-
-void InitScreen::Flip() {
-       SDL_Flip(screen);
-       if (!(screen->flags & SDL_HWSURFACE)) {
-               // probably got no vsync, so suspend execution for a while
-               SDL_Delay(1);
-       }
-}
-
-}
diff --git a/src/sdl/InitScreen.h b/src/sdl/InitScreen.h
deleted file mode 100644 (file)
index 38ac9da..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef SPACE_INITSCREEN_H_
-#define SPACE_INITSCREEN_H_
-
-#include <SDL/SDL.h>
-
-namespace space {
-
-class InitScreen {
-
-public:
-       InitScreen(int width, int height, int bpp = 32, Sint32 flags = SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_RESIZABLE);
-       ~InitScreen();
-
-       InitScreen(const InitScreen &) = delete;
-       InitScreen &operator =(const InitScreen &) = delete;
-
-public:
-       SDL_Surface *Screen() { return screen; };
-       const SDL_Surface *Screen() const { return screen; };
-
-       void Flip();
-       SDL_Surface *Resize(int width, int height);
-
-private:
-       SDL_Surface *screen;
-       int bpp;
-       Sint32 flags;
-
-};
-
-}
-
-#endif
index 5cd6bd7f363681680296e24f1c392550fa112f42..c3ffb68b225a672287010ef6299bc7b918294022 100644 (file)
@@ -1,15 +1,24 @@
 #include "app/Application.h"
-#include "sdl/InitSDL.h"
-#include "sdl/InitScreen.h"
+#include "app/SDL.h"
+#include "graphics/Canvas.h"
+#include "graphics/Window.h"
 
 using namespace space;
 
 
 int main(int argc, const char *argv[]) {
-       InitSDL sdl;
-       InitScreen screen(800, 600);
+       SDL sdl(SDL_INIT_VIDEO);
+       Window win(
+               "space",
+               Window::POS_UNDEF,
+               Vector<int>(800, 600),
+               SDL_WINDOW_RESIZABLE
+       );
+       Canvas canv(win.CreateCanvas(
+               0
+       ));
 
-       Application app(screen);
+       Application app(canv);
        app.Run();
 
        return 0;
index 740592690fb86935f68fccb92eaadd9527fcda1d..55b86f95122b3d51c2657ecce125bfcd6c20e865 100644 (file)
@@ -2,7 +2,7 @@
 #define SPACE_UNIVERSE_H_
 
 #include "../entity/Entity.h"
-#include "../math/Vector.h"
+#include "../graphics/Vector.h"
 
 #include <list>