2011-06-22 20:12:22 +00:00
|
|
|
#include "drawutils.h"
|
2011-06-23 16:07:45 +00:00
|
|
|
#include "mathutils.h"
|
2011-07-01 17:15:30 +00:00
|
|
|
#include <cmath>
|
2011-06-22 20:12:22 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2011-06-22 20:42:54 +00:00
|
|
|
|
2011-07-01 16:24:52 +00:00
|
|
|
|
2011-06-23 01:54:35 +00:00
|
|
|
void DrawUtils::draw_line(SDL_Surface* dest, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint16 width, Uint32 colour)
|
2011-06-22 20:42:54 +00:00
|
|
|
{
|
|
|
|
float dx, dy, len;
|
|
|
|
float cx, cy; // our current coords
|
|
|
|
|
|
|
|
SDL_Rect pen;
|
|
|
|
|
2011-07-01 16:24:52 +00:00
|
|
|
len = MathUtils::distance(x1, y1, 0, x2, y2, 0);
|
2011-06-22 20:42:54 +00:00
|
|
|
|
2011-06-23 16:37:43 +00:00
|
|
|
// dx and dy represent the amount we move
|
2011-06-22 20:42:54 +00:00
|
|
|
// each step in our drawing loop
|
2011-06-23 16:07:45 +00:00
|
|
|
dx = static_cast<float>(x2-x1) / len;
|
|
|
|
dy = static_cast<float>(y2-y1) / len;
|
2011-06-22 20:42:54 +00:00
|
|
|
|
|
|
|
int j = static_cast<int>(len);
|
|
|
|
|
|
|
|
cx = static_cast<float>(x1 - (width>>1));
|
|
|
|
cy = static_cast<float>(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;
|
|
|
|
}
|
|
|
|
}
|
2011-06-22 22:24:20 +00:00
|
|
|
|
2011-06-23 18:34:53 +00:00
|
|
|
// 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)
|
2011-06-23 03:52:22 +00:00
|
|
|
{
|
|
|
|
float x = static_cast<float> (int_x);
|
|
|
|
float y = static_cast<float> (int_y);
|
|
|
|
float r = static_cast<float> (int_r);
|
|
|
|
|
|
|
|
SDL_Rect pen;
|
|
|
|
float i;
|
|
|
|
|
|
|
|
for (i=0; i < 6.28318531; i += 0.0034906585)
|
|
|
|
{
|
|
|
|
pen.x = static_cast<int> (x + cos(i) * r);
|
|
|
|
pen.y = static_cast<int> (y + sin(i) * r);
|
2011-06-23 04:09:34 +00:00
|
|
|
int w = static_cast<int> (x - pen.x);
|
|
|
|
int h = static_cast<int> (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;
|
2011-06-23 03:52:22 +00:00
|
|
|
|
|
|
|
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,
|
2011-06-23 04:09:34 +00:00
|
|
|
colour & 0xff, 1));
|
2011-06-23 03:52:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-06-22 22:24:20 +00:00
|
|
|
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;
|
|
|
|
}
|
2011-07-01 17:15:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
// Modified from
|
|
|
|
// http://www.parallelrealities.co.uk/tutorials/basic/tutorial7.php
|
|
|
|
void DrawUtils::draw_text(SDL_Surface* display, string text, int x, int y,
|
2011-07-02 02:23:16 +00:00
|
|
|
TTF_Font *font, unsigned int colour,
|
|
|
|
bool center_x, bool center_y)
|
2011-07-01 17:15:30 +00:00
|
|
|
{
|
|
|
|
SDL_Rect dest;
|
|
|
|
SDL_Surface *surface;
|
|
|
|
SDL_Color color;
|
|
|
|
|
2011-07-02 02:23:16 +00:00
|
|
|
color.r = (colour >> 16) & 0xff;
|
|
|
|
color.g = (colour >> 8) & 0xff;
|
|
|
|
color.b = colour & 0xff;
|
2011-07-01 17:15:30 +00:00
|
|
|
|
|
|
|
surface = TTF_RenderUTF8_Blended(font, text.c_str(), color);
|
|
|
|
|
|
|
|
if (surface == NULL)
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
fprintf(stderr, "Couldn't create String '%s': %s\n", text.c_str(),
|
|
|
|
SDL_GetError());
|
|
|
|
#endif
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Blit the surface */
|
2011-07-02 02:23:16 +00:00
|
|
|
dest.x = center_x ? x - (surface->w / 2) : x;
|
|
|
|
dest.y = center_y ? y - (surface->h / 2) : y;
|
2011-07-01 17:15:30 +00:00
|
|
|
dest.w = surface->w;
|
|
|
|
dest.h = surface->h;
|
|
|
|
|
|
|
|
SDL_BlitSurface(surface, NULL, display, &dest);
|
|
|
|
SDL_FreeSurface(surface);
|
|
|
|
}
|
2011-07-01 21:44:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
void DrawUtils::draw_circle(SDL_Surface* dest, Sint16 int_x, Sint16 int_y,
|
|
|
|
Uint16 int_r, Uint32 colour)
|
|
|
|
{
|
|
|
|
float x = static_cast<float> (int_x);
|
|
|
|
float y = static_cast<float> (int_y);
|
|
|
|
float r = static_cast<float> (int_r);
|
|
|
|
|
|
|
|
SDL_Rect pen;
|
|
|
|
float i;
|
|
|
|
|
|
|
|
for (i=0; i < 6.28318531; i += 0.0034906585)
|
|
|
|
{
|
|
|
|
pen.x = static_cast<int> (x + cos(i) * r);
|
|
|
|
pen.y = static_cast<int> (y + sin(i) * r);
|
|
|
|
int w = 2;
|
|
|
|
int h = 2;
|
|
|
|
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
}
|