FIFE  2008.0
 All Classes Namespaces Functions Variables Enumerations Enumerator
renderbackendsdl.cpp
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2008 by the FIFE team                              *
00003  *   http://www.fifengine.de                                               *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 // Standard C++ library includes
00023 
00024 // 3rd party library includes
00025 #include <SDL.h>
00026 
00027 // FIFE includes
00028 // These includes are split up in two parts, separated by one empty line
00029 // First block: files included from the FIFE root src directory
00030 // Second block: files included from the same folder
00031 #include "util/base/exception.h"
00032 #include "util/math/fife_math.h"
00033 #include "util/log/logger.h"
00034 #include "video/devicecaps.h"
00035 
00036 #include "renderbackendsdl.h"
00037 #include "sdlimage.h"
00038 #include "SDL_image.h"
00039 #include "SDL_getenv.h"
00040 
00041 namespace FIFE {
00042     static Logger _log(LM_VIDEO);
00043 
00044     RenderBackendSDL::RenderBackendSDL(const SDL_Color& colorkey) : RenderBackend(colorkey) {
00045     }
00046 
00047 
00048     RenderBackendSDL::~RenderBackendSDL() {
00049         deinit();
00050     }
00051 
00052     const std::string& RenderBackendSDL::getName() const {
00053         static std::string backend_name = "SDL";
00054         return backend_name;
00055     }
00056 
00057     void RenderBackendSDL::init(const std::string& driver) {
00058         char* buf;
00059         if (driver != "") {
00060             std::string envVar = std::string("SDL_VIDEODRIVER=") + driver;
00061             buf = const_cast<char*>(envVar.c_str());
00062             putenv(buf);
00063         }
00064 
00065         if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
00066             throw SDLException(SDL_GetError());
00067 
00068         SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); // temporary hack
00069     }
00070 
00071     void RenderBackendSDL::clearBackBuffer() {
00072         SDL_Rect rect;
00073         rect.x = 0;
00074         rect.y = 0;
00075         rect.w = getWidth();
00076         rect.h = getHeight();
00077         SDL_SetClipRect(m_screen->getSurface(), &rect);
00078         SDL_FillRect(m_screen->getSurface(), 0, 0x00);
00079     }
00080 
00081     Image* RenderBackendSDL::createMainScreen(const ScreenMode& mode, const std::string& title, const std::string& icon){
00082         if(icon != "") {
00083             SDL_Surface *img = IMG_Load(icon.c_str());
00084             if(img != NULL) {
00085                 SDL_WM_SetIcon(img, 0);
00086             }
00087         }
00088 
00089         Image *image = setScreenMode(mode);
00090 
00091         SDL_WM_SetCaption(title.c_str(), 0);
00092 
00093         return image;
00094     }
00095 
00096     Image* RenderBackendSDL::setScreenMode(const ScreenMode& mode) {
00097         uint16_t width = mode.getWidth();
00098         uint16_t height = mode.getHeight();
00099         uint16_t bitsPerPixel = mode.getBPP();
00100         bool fs = mode.isFullScreen();
00101         uint32_t flags = mode.getSDLFlags();
00102 
00103         SDL_Surface* screen = NULL;
00104 
00105         if (bitsPerPixel != 0) {
00106             uint16_t bpp = SDL_VideoModeOK(width, height, bitsPerPixel, flags);
00107             if (!bpp){
00108                 throw SDLException("Selected video mode not supported!");
00109             }
00110         }
00111 
00112         screen = SDL_SetVideoMode(width, height, bitsPerPixel, flags);
00113         if( !screen ) {
00114             throw SDLException("Unable to set video mode selected!");
00115         }
00116 
00117         FL_LOG(_log, LMsg("RenderBackendSDL")
00118             << "Videomode " << width << "x" << height
00119             << " at " << int(screen->format->BitsPerPixel) << " bpp");
00120 
00121         //update the screen mode with the actual flags used
00122         m_screenMode = ScreenMode(width,
00123                                   height,
00124                                   bitsPerPixel,
00125                                   screen->flags);
00126 
00127         if (!screen) {
00128             throw SDLException(SDL_GetError());
00129         }
00130 
00131         delete m_screen;
00132         m_screen = new SDLImage(screen);
00133         return m_screen;
00134     }
00135 
00136     void RenderBackendSDL::startFrame() {
00137     }
00138 
00139     void RenderBackendSDL::endFrame() {
00140         SDL_Flip(m_screen->getSurface());
00141     }
00142 
00143     Image* RenderBackendSDL::createImage(SDL_Surface* surface) {
00144         return new SDLImage(surface);
00145     }
00146 
00147     Image* RenderBackendSDL::createImage(const uint8_t* data, unsigned int width, unsigned int height) {
00148         return new SDLImage(data, width, height);
00149     }
00150 
00151     void RenderBackendSDL::setLightingModel(unsigned int lighting) {
00152         SDLException("Lighting not available under SDL");
00153     }
00154 
00155     unsigned int RenderBackendSDL::getLightingModel() const {
00156         return 0;
00157     }
00158 
00159     void RenderBackendSDL::enableLighting() {
00160     }
00161 
00162     void RenderBackendSDL::disableLighting() {
00163     }
00164 
00165     void RenderBackendSDL::setLighting(float red, float green, float blue, float alpha) {
00166     }
00167 
00168     void RenderBackendSDL::resetLighting() {
00169     }
00170 
00171     void RenderBackendSDL::enableStencilTest() {
00172     }
00173 
00174     void RenderBackendSDL::disableStencilTest() {
00175     }
00176 
00177     void RenderBackendSDL::setStencilTest(uint8_t stencil_ref, unsigned int stencil_op, unsigned int stencil_func) {
00178     }
00179 
00180     void RenderBackendSDL::resetStencilBuffer(uint8_t buffer) {
00181     }
00182 
00183     uint8_t RenderBackendSDL::getStencilRef() const {
00184         return 0;
00185     }
00186 
00187     void RenderBackendSDL::enableAlphaTest() {
00188     }
00189 
00190     void RenderBackendSDL::disableAlphaTest() {
00191     }
00192 
00193     void RenderBackendSDL::setAlphaTest(float ref_alpha) {
00194     }
00195 
00196     void RenderBackendSDL::changeBlending(int scr, int dst){
00197     }
00198 
00199     bool RenderBackendSDL::putPixel(int x, int y, int r, int g, int b, int a) {
00200         return static_cast<SDLImage*>(m_screen)->putPixel(x, y, r, g, b, a);
00201     }
00202 
00203     void RenderBackendSDL::drawLine(const Point& p1, const Point& p2, int r, int g, int b, int a) {
00204         static_cast<SDLImage*>(m_screen)->drawLine(p1, p2, r, g, b, a);
00205     }
00206 
00207     void RenderBackendSDL::drawTriangle(const Point& p1, const Point& p2, const Point& p3, int r, int g, int b, int a) {
00208         static_cast<SDLImage*>(m_screen)->drawTriangle(p1, p2, p3, r, g, b, a);
00209     }
00210 
00211     void RenderBackendSDL::drawRectangle(const Point& p, uint16_t w, uint16_t h, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00212         static_cast<SDLImage*>(m_screen)->drawRectangle(p, w, h, r, g, b, a);
00213     }
00214 
00215     void RenderBackendSDL::fillRectangle(const Point& p, uint16_t w, uint16_t h, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00216         static_cast<SDLImage*>(m_screen)->fillRectangle(p, w, h, r, g, b, a);
00217     }
00218 
00219     void RenderBackendSDL::drawQuad(const Point& p1, const Point& p2, const Point& p3, const Point& p4,  int r, int g, int b, int a) {
00220         static_cast<SDLImage*>(m_screen)->drawQuad(p1, p2, p3, p4, r, g, b, a);
00221     }
00222 
00223     void RenderBackendSDL::drawVertex(const Point& p, const uint8_t size, int r, int g, int b, int a){
00224         static_cast<SDLImage*>(m_screen)->drawVertex(p, 2, r, g, b, a);
00225     }
00226 
00227     void RenderBackendSDL::drawLightPrimitive(const Point& p, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t red, uint8_t green, uint8_t blue){
00228         static_cast<SDLImage*>(m_screen)->drawLightPrimitive(p, intensity, radius, subdivisions, xstretch, ystretch, red, green, blue);
00229     }
00230 }//FIFE