HEADER TAGS
The std header tags are now subdir/file.ext
committer: Markus Bröker <mbroeker@largo.homelinux.org>
/**
* pmc/surface.cc
* Copyright (C) 2008 Markus Broeker
*/
#include <surface.hpp>
#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);
green = SDL_MapRGB (screen->format, 0x00, 0xff, 0x00);
blue = SDL_MapRGB (screen->format, 0x00, 0x00, 0xff);
black = SDL_MapRGB (screen->format, 0x00, 0x00, 0x00);
color = red;
bpp = screen->format->BytesPerPixel;
refCounter++;
}
Surface::~Surface ()
{
SDL_FreeSurface (screen);
SDL_Quit ();
}
void Surface::drawPixel (int x, int y)
{
if (x < 0 || y < 0)
return;
if (x > width || y > height)
return;
if (SDL_MUSTLOCK (screen)) {
if (SDL_LockSurface (screen) < 0) {
return;
}
}
switch (bpp) {
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;
dx = x2 - x1;
ax = abs (dx) << 1;
sx = sign (dx);
dy = y2 - y1;
ay = abs (dy) << 1;
sy = sign (dy);
x = x1;
y = y1;
if (ax > ay) { /* x dominant */
d = ay - (ax >> 1);
for (;;) {
drawPixel (x, y);
if (x == x2) {
return;
}
if (d >= 0) {
y += sy;
d -= ax;
}
x += sx;
d += ay;
}
} else { /* y dominant */
d = ax - (ay >> 1);
for (;;) {
drawPixel (x, y);
if (y == y2) {
return;
}
if (d >= 0) {
x += sx;
d -= ay;
}
y += sy;
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;
case GREEN:
color = green;
break;
case BLUE:
color = blue;
break;
default:
color = red;
};
}