diff --git a/pmc/surface.cc b/pmc/surface.cc 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 + +#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; + }; +}