31 #include "util/base/exception.h"
32 #include "util/math/fife_math.h"
33 #include "util/log/logger.h"
34 #include "video/devicecaps.h"
36 #include "renderbackendsdl.h"
38 #include "SDL_image.h"
39 #include "SDL_getenv.h"
42 static Logger _log(LM_VIDEO);
44 RenderBackendSDL::RenderBackendSDL(
const SDL_Color& colorkey) :
45 RenderBackend(colorkey){
48 RenderBackendSDL::~RenderBackendSDL() {
53 static std::string backend_name =
"SDL";
60 std::string envVar = std::string(
"SDL_VIDEODRIVER=") + driver;
61 buf =
const_cast<char*
>(envVar.c_str());
65 if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
66 throw SDLException(SDL_GetError());
68 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
77 SDL_SetClipRect(m_screen, &rect);
78 SDL_FillRect(m_screen, 0, 0x00);
83 SDL_Surface *img = IMG_Load(icon.c_str());
85 SDL_WM_SetIcon(img, 0);
91 SDL_WM_SetCaption(title.c_str(), 0);
95 uint16_t width = mode.getWidth();
96 uint16_t height = mode.getHeight();
97 uint16_t bitsPerPixel = mode.getBPP();
98 bool fs = mode.isFullScreen();
99 uint32_t flags = mode.getSDLFlags();
101 if (bitsPerPixel != 0) {
102 uint16_t bpp = SDL_VideoModeOK(width, height, bitsPerPixel, flags);
104 throw SDLException(
"Selected video mode not supported!");
109 SDL_FreeSurface(m_screen);
111 m_screen = SDL_SetVideoMode(width, height, bitsPerPixel, flags);
113 throw SDLException(
"Unable to set video mode selected!");
117 FL_LOG(_log,
LMsg(
"RenderBackendSDL")
118 <<
"Videomode " << width <<
"x" << height
119 <<
" at " << int32_t(m_screen->format->BitsPerPixel) <<
" bpp");
121 m_rgba_format = *(m_screen->format);
122 m_rgba_format.Rmask = RMASK;
123 m_rgba_format.Gmask = GMASK;
124 m_rgba_format.Bmask = BMASK;
125 m_rgba_format.Amask = AMASK;
128 m_screenMode = ScreenMode(width,
143 Image* RenderBackendSDL::createImage(IResourceLoader* loader) {
147 Image* RenderBackendSDL::createImage(
const std::string& name, IResourceLoader* loader) {
148 return new SDLImage(name, loader);
151 Image* RenderBackendSDL::createImage(SDL_Surface* surface) {
155 Image* RenderBackendSDL::createImage(
const std::string& name, SDL_Surface* surface) {
159 Image* RenderBackendSDL::createImage(
const uint8_t* data, uint32_t width, uint32_t height) {
160 return new SDLImage(data, width, height);
163 Image* RenderBackendSDL::createImage(
const std::string& name,
const uint8_t* data, uint32_t width, uint32_t height) {
164 return new SDLImage(name, data, width, height);
168 SDLException(
"Lighting not available under SDL");
206 int32_t dx = ABS(x2 - x1);
207 int32_t dy = ABS(y2 - y1);
226 for (int32_t x = x1; x <= x2; x++) {
239 for (int32_t x = x1; x <= x2; x++) {
267 for (int32_t y = y1; y <= y2; y++) {
280 for (int32_t y = y1; y <= y2; y++) {
299 Point p1, p2, p3, p4;
323 Uint32 color = SDL_MapRGBA(m_target->format, r, g, b, a);
324 SDL_FillRect(m_target, &rect, color);
328 fillRectangle(p1, static_cast<uint16_t>(p3.x-p1.x), static_cast<uint16_t>(p3.y-p1.y), r, g, b, a);
348 const uint32_t swidth = getWidth();
349 const uint32_t sheight = getHeight();
351 SDL_Surface* surface = SDL_CreateRGBSurface(SDL_SWSURFACE, swidth, sheight, 24,
352 RMASK, GMASK, BMASK, NULLMASK);
358 SDL_BlitSurface(m_screen, NULL, surface, NULL);
361 SDL_FreeSurface(surface);
367 const uint32_t swidth = getWidth();
368 const uint32_t sheight = getHeight();
369 const bool same_size = (width == swidth && height == sheight);
371 if (width < 1 || height < 1) {
380 SDL_Surface* src = SDL_CreateRGBSurface(SDL_SWSURFACE, swidth, sheight, 32,
381 RMASK, GMASK, BMASK, AMASK);
387 SDL_BlitSurface(m_screen, NULL, src, NULL);
389 SDL_Surface* dst = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32,
390 RMASK, GMASK, BMASK, AMASK);
392 uint32_t* src_pointer =
static_cast<uint32_t*
>(src->pixels);
393 uint32_t* src_help_pointer = src_pointer;
394 uint32_t* dst_pointer =
static_cast<uint32_t*
>(dst->pixels);
396 int32_t x, y, *sx_ca, *sy_ca;
397 int32_t sx =
static_cast<int32_t
>(0xffff * src->w / dst->w);
398 int32_t sy =
static_cast<int32_t
>(0xffff * src->h / dst->h);
403 int32_t* sx_a =
new int32_t[dst->w + 1];
405 for (x = 0; x <= dst->w; x++) {
412 int32_t* sy_a =
new int32_t[dst->h + 1];
414 for (y = 0; y <= dst->h; y++) {
424 if (SDL_MUSTLOCK(src)) {
425 SDL_LockSurface(src);
428 if (SDL_MUSTLOCK(dst)) {
429 SDL_LockSurface(dst);
432 for (y = 0; y < dst->h; y++) {
433 src_pointer = src_help_pointer;
435 for (x = 0; x < dst->w; x++) {
436 *dst_pointer = *src_pointer;
438 src_pointer += (*sx_ca >> 16);
442 src_help_pointer = (uint32_t*)((uint8_t*)src_help_pointer + (*sy_ca >> 16) * src->pitch);
445 if (SDL_MUSTLOCK(dst)) {
446 SDL_UnlockSurface(dst);
448 if (SDL_MUSTLOCK(src)) {
449 SDL_UnlockSurface(src);
455 SDL_FreeSurface(src);
456 SDL_FreeSurface(dst);
468 SDL_SetClipRect(m_target, &rect);
471 if (m_isbackgroundcolor) {
472 color = SDL_MapRGB(m_target->format, m_backgroundcolor.r, m_backgroundcolor.g, m_backgroundcolor.b);
474 SDL_FillRect(m_target, &rect, color);
479 m_target = img->getSurface();