00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <SDL.h>
00026
00027
00028
00029
00030
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);
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
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 }