#include "drawutils.h" #include #include "mathutils.h" SDL_Surface* DrawUtils::load(string file) { SDL_Surface* raw = NULL; SDL_Surface* cooked = NULL; raw = SDL_LoadBMP(file.c_str()); if (raw == NULL) return NULL; cooked = SDL_DisplayFormat(raw); SDL_FreeSurface(raw); // don't consume raw surfaces return cooked; } bool DrawUtils::draw(SDL_Surface* dest, SDL_Surface* drawable, int x, int y) { if (dest == NULL || drawable == NULL) return false; SDL_Rect dest_r; dest_r.x = x; dest_r.y = y; SDL_BlitSurface(drawable, NULL, dest, &dest_r); return true; } bool DrawUtils::draw(SDL_Surface* dest, SDL_Surface* drawable, int x, int y, int x2, int y2, int w, int h) { SDL_Rect dest_r; dest_r.x = x; dest_r.y = y; SDL_Rect src_r; src_r.x = x2; src_r.y = y2; src_r.w = w; src_r.h = h; SDL_BlitSurface(drawable, &src_r, dest, &dest_r); return true; } void DrawUtils::draw_line(SDL_Surface* dest, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint16 width, Uint32 colour) { float dx, dy, len; float cx, cy; // our current coords SDL_Rect pen; len = MathUtils::distance(x1, y1, 0, x2, y2, 0); // dx and dy represent the amount we move // each step in our drawing loop dx = static_cast(x2-x1) / len; dy = static_cast(y2-y1) / len; int j = static_cast(len); cx = static_cast(x1 - (width>>1)); cy = static_cast(y1 - (width>>1)); int i; for(i = 0; i < j; i++) { pen.x = (Sint16)cx; pen.y = (Sint16)cy; pen.w = width; pen.h = width; SDL_FillRect(dest, &pen, colour); cx += dx; cy += dy; } } // There's a funny story behind this function. I'd like to use the // filledCircleRGBA function from SDL_gfx 2.0.22, but 2.0.17 doesn't have that // fcn. So, we get this alpha-less option for now, instead. // I tried using SDL_gfx's boxRGBA, but that is a lot slower, and doesn't // succeed anyway - drawing 1800 overlapping rectangles blends any alpha value // to opaque void DrawUtils::draw_circle_filled(SDL_Surface* dest, Sint16 int_x, Sint16 int_y, Uint16 int_r, Uint32 colour) { float x = static_cast (int_x); float y = static_cast (int_y); float r = static_cast (int_r); SDL_Rect pen; float i; for (i=0; i < 6.28318531; i += 0.0034906585) { pen.x = static_cast (x + cos(i) * r); pen.y = static_cast (y + sin(i) * r); int w = static_cast (x - pen.x); int h = static_cast (y - pen.y); if (w == 0) pen.w = 1; else if (w < 0) { pen.x = x; pen.w = abs(w); } else pen.w = w; if (h == 0) pen.h = 1; else if (h < 0) { pen.y = y; pen.h = abs(h); } else pen.h = h; if (pen.x >= dest->clip_rect.x && pen.y >= dest->clip_rect.y && pen.x + pen.w <= dest->clip_rect.w && pen.y + pen.h <= dest->clip_rect.h) SDL_FillRect(dest, &pen, SDL_MapRGBA(dest->format, (colour >> 16) & 0xff, (colour >> 8) & 0xff, colour & 0xff, 1)); } } bool DrawUtils::transpare(SDL_Surface* surface, int r, int g, int b) { if (surface == NULL) return false; SDL_SetColorKey(surface, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(surface->format, r, g, b)); return true; }