pmc/surface.cc
changeset 42 83b8151b966d
child 46 4b9e1ac40246
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;
+    };
+}