new file mode 100644
--- /dev/null
+++ b/pmc/surface.cc
@@ -0,0 +1,174 @@
+/**
+ * test/demos/pmc/surface.cc
+ * Copyright (C) 2008 Markus Broeker
+ */
+
+#include <surface.h>
+
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define abs(a) (((a)<0) ? -(a) : (a))
+#define sign(a) (((a)<0) ? -1 : (a)>0 ? 1 : 0)
+
+Surface::Surface (int w, int h, int d)
+{
+ width = w;
+ height = h;
+ depth = d;
+
+ SDL_Init (SDL_INIT_VIDEO);
+ screen = SDL_SetVideoMode (width, height, depth, SDL_HWSURFACE);
+ red = SDL_MapRGB (screen->format, 0xff, 0x00, 0x00);
+ black = SDL_MapRGB (screen->format, 0x00, 0x00, 0x00);
+
+ color = red;
+}
+
+Surface::~Surface ()
+{
+ SDL_Quit ();
+}
+
+void Surface::drawPixel (int x, int y)
+{
+ if (SDL_MUSTLOCK (screen)) {
+ if (SDL_LockSurface (screen) < 0) {
+ return;
+ }
+ }
+
+ switch (screen->format->BytesPerPixel) {
+ case 1:{ /* vermutlich 8 Bit */
+ Uint8 *bufp;
+
+ bufp = (Uint8 *) screen->pixels + y * screen->pitch + x;
+ *bufp = color;
+ }
+ break;
+
+ case 2:{ /* vermutlich 15 Bit oder 16 Bit */
+ Uint16 *bufp;
+
+ bufp = (Uint16 *) screen->pixels + y * screen->pitch / 2 + x;
+ *bufp = color;
+ }
+ break;
+
+ case 3:{ /* langsamer 24-Bit-Modus, selten verwendet */
+ Uint8 *bufp;
+
+ bufp = (Uint8 *) screen->pixels + y * screen->pitch + x * 3;
+ if (SDL_BYTEORDER == SDL_LIL_ENDIAN) {
+ bufp[0] = color;
+ bufp[1] = color >> 8;
+ bufp[2] = color >> 16;
+ } else {
+ bufp[2] = color;
+ bufp[1] = color >> 8;
+ bufp[0] = color >> 16;
+ }
+ }
+ break;
+
+ case 4:{ /* vermutlich 32 Bit */
+ Uint32 *bufp;
+
+ bufp = (Uint32 *) screen->pixels + y * screen->pitch / 4 + x;
+ *bufp = color;
+ }
+ break;
+ }
+
+ if (SDL_MUSTLOCK (screen)) {
+ SDL_UnlockSurface (screen);
+ }
+}
+
+void Surface::drawLine (int x1, int y1, int x2, int y2)
+{
+ int d;
+ int x;
+ int y;
+ int ax;
+ int ay;
+ int sx;
+ int sy;
+ int dx;
+ int dy;
+
+ Uint8 *lineAddr;
+ Sint32 yOffset;
+
+ /*
+ * SANITY CHECK: fix segfault in *((Uint16 *) (lineAddr + (x << 1))) = (Uint16) color;
+ */
+ if (y1 < 0 || y2 < 0)
+ return;
+
+ if (x1 < 0 || x2 < 0)
+ return;
+
+ dx = x2 - x1;
+ ax = abs (dx) << 1;
+ sx = sign (dx);
+
+ dy = y2 - y1;
+ ay = abs (dy) << 1;
+ sy = sign (dy);
+ yOffset = sy * screen->pitch;
+
+ x = x1;
+ y = y1;
+
+ lineAddr = ((Uint8 *) screen->pixels) + (y * screen->pitch);
+ if (ax > ay) { /* x dominant */
+ d = ay - (ax >> 1);
+ for (;;) {
+ *((Uint16 *) (lineAddr + (x << 1))) = (Uint16) color;
+
+ if (x == x2) {
+ return;
+ }
+ if (d >= 0) {
+ y += sy;
+ lineAddr += yOffset;
+ d -= ax;
+ }
+ x += sx;
+ d += ay;
+ }
+ } else { /* y dominant */
+ d = ax - (ay >> 1);
+ for (;;) {
+ *((Uint16 *) (lineAddr + (x << 1))) = (Uint16) color;
+
+ if (y == y2) {
+ return;
+ }
+ if (d >= 0) {
+ x += sx;
+ d -= ay;
+ }
+ y += sy;
+ lineAddr += yOffset;
+ d += ax;
+ }
+ }
+}
+
+void Surface::flip ()
+{
+ SDL_Flip (screen);
+}
+
+void Surface::setColor (foregroundColor c)
+{
+ switch (c) {
+ case BLACK:
+ color = black;
+ break;
+ case RED:
+ color = red;
+ break;
+ };
+}