Precalculated renderer specific surface data, better management of multiple renderers...
authorTim Goya <tuxdev103@gmail.com>
Sat, 18 Aug 2007 01:21:26 +0000 (01:21 +0000)
committerTim Goya <tuxdev103@gmail.com>
Sat, 18 Aug 2007 01:21:26 +0000 (01:21 +0000)
SVN-Revision: 5143

20 files changed:
src/gameconfig.cpp
src/gameconfig.hpp
src/video/color.cpp [new file with mode: 0644]
src/video/color.hpp
src/video/drawing_context.cpp
src/video/gl_lightmap.cpp
src/video/gl_renderer.cpp
src/video/gl_surface_data.hpp [new file with mode: 0644]
src/video/image_texture.cpp [deleted file]
src/video/image_texture.hpp [deleted file]
src/video/sdl_lightmap.cpp
src/video/sdl_lightmap.hpp
src/video/sdl_renderer.cpp
src/video/sdl_renderer.hpp
src/video/sdl_surface_data.hpp [new file with mode: 0644]
src/video/sdl_texture.cpp
src/video/surface.hpp
src/video/texture_manager.cpp
src/video/video_systems.cpp [new file with mode: 0644]
src/video/video_systems.hpp [new file with mode: 0644]

index 80f27c0..61ca19e 100644 (file)
@@ -36,11 +36,7 @@ Config* config = 0;
 Config::Config()
 {
   use_fullscreen = true;
-#ifdef HAVE_OPENGL
-  video = "opengl";
-#else
-  video = "sdl";
-#endif
+  video = OPENGL;
   try_vsync = true;
   show_fps = false;
   sound_enabled = true;
@@ -78,7 +74,9 @@ Config::load()
   const lisp::Lisp* config_video_lisp = config_lisp->get_lisp("video");
   if(config_video_lisp) {
     config_video_lisp->get("fullscreen", use_fullscreen);
-    config_video_lisp->get("video", video);
+    std::string video_string;
+    config_video_lisp->get("video", video_string);
+    video = get_video_system(video_string);
     config_video_lisp->get("vsync", try_vsync);
     config_video_lisp->get("width", screenwidth);
     config_video_lisp->get("height", screenheight);
@@ -110,7 +108,7 @@ Config::save()
 
   writer.start_list("video");
   writer.write_bool("fullscreen", use_fullscreen);
-  writer.write_string("video", video);
+  writer.write_string("video", get_video_string(video));
   writer.write_bool("vsync", try_vsync);
   writer.write_int("width", screenwidth);
   writer.write_int("height", screenheight);
index 0efeacd..ac45730 100644 (file)
@@ -23,6 +23,8 @@
 
 #include <string>
 
+#include "video/video_systems.hpp"
+
 class Config
 {
 public:
@@ -41,7 +43,7 @@ public:
   float aspect_ratio;
 
   bool use_fullscreen;
-  std::string video;
+  VideoSystem video;
   bool try_vsync;
   bool show_fps;
   bool sound_enabled;
diff --git a/src/video/color.cpp b/src/video/color.cpp
new file mode 100644 (file)
index 0000000..46bccc4
--- /dev/null
@@ -0,0 +1,30 @@
+//  $Id: color.cpp 5063 2007-05-27 11:32:00Z matzeb $
+//
+//  SuperTux
+//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#include <config.h>
+
+#include "color.hpp"
+
+const Color Color::BLACK(0.0, 0.0, 0.0);
+const Color Color::RED(1.0, 0.0, 0.0);
+const Color Color::GREEN(0.0, 1.0, 0.0);
+const Color Color::BLUE(0.0, 0.0, 1.0);
+const Color Color::CYAN(0.0, 1.0, 1.0);
+const Color Color::MAGENTA(1.0, 0.0, 1.0);
+const Color Color::YELLOW(1.0, 1.0, 0.0);
+const Color Color::WHITE(1.0, 1.0, 1.0);
index e3ff678..f0bd76d 100644 (file)
@@ -77,6 +77,15 @@ public:
   }
 
   float red, green, blue, alpha;
+
+  static const Color BLACK;
+  static const Color RED;
+  static const Color GREEN;
+  static const Color BLUE;
+  static const Color CYAN;
+  static const Color MAGENTA;
+  static const Color YELLOW;
+  static const Color WHITE;
 };
 
 #endif
index 428454d..0a64850 100644 (file)
 
 #include "drawing_context.hpp"
 #include "drawing_request.hpp"
-#include "gl_renderer.hpp"
-#include "gl_lightmap.hpp"
-#include "sdl_renderer.hpp"
-#include "sdl_lightmap.hpp"
+#include "video_systems.hpp"
+#include "renderer.hpp"
+#include "lightmap.hpp"
 #include "surface.hpp"
 #include "main.hpp"
 #include "gameconfig.hpp"
@@ -68,23 +67,11 @@ DrawingContext::~DrawingContext()
 void
 DrawingContext::init_renderer()
 {
-  if(renderer)
-    delete renderer;
-  if(lightmap)
-    delete lightmap;
+  delete renderer;
+  delete lightmap;
 
-#ifdef HAVE_OPENGL
-  if(config->video == "opengl")
-  {
-    renderer = new GL::Renderer();
-    lightmap = new GL::Lightmap();
-  }
-  else
-#endif
-  {
-    renderer = new SDL::Renderer();
-    lightmap = new SDL::Lightmap();
-  }
+  renderer = new_renderer();
+  lightmap = new_lightmap();
 }
 
 void
index 6649a0e..bc4c12b 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "glutil.hpp"
 #include "gl_lightmap.hpp"
+#include "gl_surface_data.hpp"
 #include "drawing_context.hpp"
 #include "drawing_request.hpp"
 #include "renderer.hpp"
@@ -195,14 +196,16 @@ namespace GL
   {
     const Surface* surface = (const Surface*) request.request_data;
     GL::Texture *gltexture = dynamic_cast<GL::Texture *>(surface->get_texture());
+    GL::SurfaceData *surface_data = reinterpret_cast<GL::SurfaceData *>(surface->get_surface_data());
+
     glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
     intern_draw(request.pos.x, request.pos.y,
                 request.pos.x + surface->get_width(),
                 request.pos.y + surface->get_height(),
-                surface->get_uv_left(),
-                surface->get_uv_top(),
-                surface->get_uv_right(),
-                surface->get_uv_bottom(),
+                surface_data->get_uv_left(),
+                surface_data->get_uv_top(),
+                surface_data->get_uv_right(),
+                surface_data->get_uv_bottom(),
                 request.angle,
                 request.alpha,
                 request.color,
@@ -217,14 +220,15 @@ namespace GL
       = (SurfacePartRequest*) request.request_data;
     const Surface *surface = surfacepartrequest->surface;
     GL::Texture *gltexture = dynamic_cast<GL::Texture *>(surface->get_texture());
+    GL::SurfaceData *surface_data = reinterpret_cast<GL::SurfaceData *>(surface->get_surface_data());
 
-    float uv_width = surface->get_uv_right() - surface->get_uv_left();
-    float uv_height = surface->get_uv_bottom() - surface->get_uv_top();
+    float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left();
+    float uv_height = surface_data->get_uv_bottom() - surface_data->get_uv_top();
 
-    float uv_left = surface->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width();
-    float uv_top = surface->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height();
-    float uv_right = surface->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width();
-    float uv_bottom = surface->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height();
+    float uv_left = surface_data->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width();
+    float uv_top = surface_data->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height();
+    float uv_right = surface_data->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width();
+    float uv_bottom = surface_data->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height();
 
     glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
     intern_draw(request.pos.x, request.pos.y,
index 8158874..9fa6b03 100644 (file)
@@ -33,6 +33,7 @@
 #include "glutil.hpp"
 #include "gl_renderer.hpp"
 #include "gl_texture.hpp"
+#include "gl_surface_data.hpp"
 #include "drawing_context.hpp"
 #include "drawing_request.hpp"
 #include "surface.hpp"
@@ -164,14 +165,16 @@ namespace GL
   {
     const Surface* surface = (const Surface*) request.request_data;
     GL::Texture *gltexture = dynamic_cast<GL::Texture *>(surface->get_texture());
+    GL::SurfaceData *surface_data = reinterpret_cast<GL::SurfaceData *>(surface->get_surface_data());
+
     glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
     intern_draw(request.pos.x, request.pos.y,
                 request.pos.x + surface->get_width(),
                 request.pos.y + surface->get_height(),
-                surface->get_uv_left(),
-                surface->get_uv_top(),
-                surface->get_uv_right(),
-                surface->get_uv_bottom(),
+                surface_data->get_uv_left(),
+                surface_data->get_uv_top(),
+                surface_data->get_uv_right(),
+                surface_data->get_uv_bottom(),
                 request.angle,
                 request.alpha,
                 request.color,
@@ -186,14 +189,15 @@ namespace GL
       = (SurfacePartRequest*) request.request_data;
     const Surface *surface = surfacepartrequest->surface;
     GL::Texture *gltexture = dynamic_cast<GL::Texture *>(surface->get_texture());
+    GL::SurfaceData *surface_data = reinterpret_cast<GL::SurfaceData *>(surface->get_surface_data());
 
-    float uv_width = surface->get_uv_right() - surface->get_uv_left();
-    float uv_height = surface->get_uv_bottom() - surface->get_uv_top();
+    float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left();
+    float uv_height = surface_data->get_uv_bottom() - surface_data->get_uv_top();
 
-    float uv_left = surface->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width();
-    float uv_top = surface->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height();
-    float uv_right = surface->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width();
-    float uv_bottom = surface->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height();
+    float uv_left = surface_data->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width();
+    float uv_top = surface_data->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height();
+    float uv_right = surface_data->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width();
+    float uv_bottom = surface_data->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height();
 
     glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
     intern_draw(request.pos.x, request.pos.y,
diff --git a/src/video/gl_surface_data.hpp b/src/video/gl_surface_data.hpp
new file mode 100644 (file)
index 0000000..a441f10
--- /dev/null
@@ -0,0 +1,73 @@
+//  $Id: gl_surface_data.hpp 4063 2006-07-21 21:05:23Z anmaster $
+//
+//  SuperTux
+//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#include <config.h>
+
+#ifdef HAVE_OPENGL
+
+#ifndef __GL_SURFACE_DATA_HPP__
+#define __GL_SURFACE_DATA_HPP__
+
+#include "surface.hpp"
+
+namespace GL
+{
+  class SurfaceData
+  {
+  private:
+    const Surface &surface;
+    float uv_left;
+    float uv_top;
+    float uv_right;
+    float uv_bottom;
+
+  public:
+    SurfaceData(const Surface &surface) :
+      surface(surface)
+    {
+      uv_left = (float) surface.get_x() / surface.get_texture()->get_texture_width();
+      uv_top = (float) surface.get_y() / surface.get_texture()->get_texture_height();
+      uv_right = (float) (surface.get_x() + surface.get_width()) / surface.get_texture()->get_texture_width();
+      uv_bottom = (float) (surface.get_y() + surface.get_height()) / surface.get_texture()->get_texture_height();
+    }
+
+    float get_uv_left() const
+    {
+      return surface.get_flipx() ? uv_right : uv_left;
+    }
+
+    float get_uv_top() const
+    {
+      return uv_top;
+    }
+
+    float get_uv_right() const
+    {
+      return surface.get_flipx() ? uv_left : uv_right;
+    }
+
+    float get_uv_bottom() const
+    {
+      return uv_bottom;
+    }
+  };
+}
+
+#endif
+
+#endif
diff --git a/src/video/image_texture.cpp b/src/video/image_texture.cpp
deleted file mode 100644 (file)
index c9a0de1..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-//  $Id$
-//
-//  SuperTux
-//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-//  This program is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU General Public License
-//  as published by the Free Software Foundation; either version 2
-//  of the License, or (at your option) any later version.
-//
-//  This program is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
-//
-//  You should have received a copy of the GNU General Public License
-//  along with this program; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-#if 0
-#include <config.h>
-
-#include "image_texture.hpp"
-#include "texture_manager.hpp"
-
-ImageTexture::ImageTexture(SDL_Surface* surface)
-  : Texture(surface, GL_RGBA), refcount(0)
-{
-}
-
-ImageTexture::~ImageTexture()
-{
-}
-
-void
-ImageTexture::release()
-{
-  texture_manager->release(this);
-}
-#endif
diff --git a/src/video/image_texture.hpp b/src/video/image_texture.hpp
deleted file mode 100644 (file)
index 9d32f76..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-//  $Id$
-//
-//  SuperTux
-//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-//  This program is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU General Public License
-//  as published by the Free Software Foundation; either version 2
-//  of the License, or (at your option) any later version.
-//
-//  This program is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
-//
-//  You should have received a copy of the GNU General Public License
-//  along with this program; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-#if 0
-#ifndef __SURFACE_TEXTURE_HPP__
-#define __SURFACE_TEXTURE_HPP__
-
-#include <string>
-#include <assert.h>
-#include "texture.hpp"
-
-class ImageTexture : public Texture
-{
-private:
-  std::string filename;
-  float image_width;
-  float image_height;
-  int refcount;
-
-public:
-  float get_image_width() const
-  {
-    return image_width;
-  }
-
-  float get_image_height() const
-  {
-    return image_height;
-  }
-
-  float get_uv_right() const
-  {
-    return image_width / static_cast<float> (get_width());
-  }
-
-  float get_uv_bottom() const
-  {
-    return image_height / static_cast<float> (get_height());
-  }
-
-  void ref()
-  {
-    refcount++;
-  }
-
-  void unref()
-  {
-    assert(refcount > 0);
-    refcount--;
-    if(refcount == 0)
-      release();
-  }
-
-private:
-  friend class TextureManager;
-
-  ImageTexture(SDL_Surface* surface);
-  virtual ~ImageTexture();
-
-  void release();
-};
-
-#endif
-#endif
index 52294b9..1020d03 100644 (file)
@@ -30,6 +30,7 @@
 #include "glutil.hpp"
 #include "sdl_lightmap.hpp"
 #include "sdl_texture.hpp"
+#include "sdl_surface_data.hpp"
 #include "drawing_context.hpp"
 #include "drawing_request.hpp"
 #include "renderer.hpp"
@@ -50,6 +51,19 @@ namespace SDL
     width = screen->w;
     height = screen->h;
 
+    float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
+    float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
+    if(xfactor < yfactor)
+    {
+      numerator = config->screenwidth;
+      denominator = SCREEN_WIDTH;
+    }
+    else
+    {
+      numerator = config->screenheight;
+      denominator = SCREEN_HEIGHT;
+    }
+
     red_channel = (Uint8 *)malloc(width * height * sizeof(Uint8));
     green_channel = (Uint8 *)malloc(width * height * sizeof(Uint8));
     blue_channel = (Uint8 *)malloc(width * height * sizeof(Uint8));
@@ -144,14 +158,13 @@ namespace SDL
     }
   }
 
-  void Lightmap::light_blit(SDL_Surface *src, int dstx, int dsty,
-                            int srcx, int srcy, int blit_width, int blit_height)
+  void Lightmap::light_blit(SDL_Surface *src, SDL_Rect *src_rect, int dstx, int dsty)
   {
     int bpp = src->format->BytesPerPixel;
-      Uint8 *pixel = (Uint8 *) src->pixels + srcy * src->pitch + srcx * bpp;
+      Uint8 *pixel = (Uint8 *) src->pixels + src_rect->y * src->pitch + src_rect->x * bpp;
     int loc = dsty * width + dstx;
-    for(int y = 0;y < blit_height;y++) {
-      for(int x = 0;x < blit_width;x++, pixel += bpp, loc++) {
+    for(int y = 0;y < src_rect->h;y++) {
+      for(int x = 0;x < src_rect->w;x++, pixel += bpp, loc++) {
         if(x + dstx < 0 || y + dsty < 0 || x + dstx >= width || y + dsty >= height)
         {
           continue;
@@ -203,8 +216,8 @@ namespace SDL
           blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
         }
       }
-      pixel += src->pitch - blit_width * bpp;
-      loc += width - blit_width;
+      pixel += src->pitch - src_rect->w * bpp;
+      loc += width - src_rect->w;
     }
   }
 
@@ -219,6 +232,8 @@ namespace SDL
  
     const Surface* surface = (const Surface*) request.request_data;
     SDL::Texture *sdltexture = dynamic_cast<SDL::Texture *>(surface->get_texture());
+    SDL::SurfaceData *surface_data = reinterpret_cast<SDL::SurfaceData *>(surface->get_surface_data());
+
     DrawingEffect effect = request.drawing_effect;
     if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
 
@@ -230,45 +245,10 @@ namespace SDL
       return;
     }  
 
-    int ox, oy;
-    if (effect == HORIZONTAL_FLIP)
-    {
-      ox = sdltexture->get_texture_width() - surface->get_x() - surface->get_width();
-    }
-    else
-    {
-      ox = surface->get_x();
-    }
-    if (effect == VERTICAL_FLIP)
-    {
-      oy = sdltexture->get_texture_height() - surface->get_y() - surface->get_height();
-    }
-    else
-    {
-      oy = surface->get_y();
-    }
-
-    int numerator, denominator;
-    float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
-    float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
-    if(xfactor < yfactor)
-    {
-      numerator = config->screenwidth;
-      denominator = SCREEN_WIDTH;
-    }
-    else
-    {
-      numerator = config->screenheight;
-      denominator = SCREEN_HEIGHT;
-    }
-
+    SDL_Rect *src_rect = surface_data->get_src_rect(effect);
     int dstx = (int) request.pos.x * numerator / denominator;
     int dsty = (int) request.pos.y * numerator / denominator;
-    int srcx = ox * numerator / denominator;
-    int srcy = oy * numerator / denominator;
-    int blit_width = surface->get_width() * numerator / denominator;
-    int blit_height = surface->get_height() * numerator / denominator;
-    light_blit(transform, dstx, dsty, srcx, srcy, blit_width, blit_height);
+    light_blit(transform, src_rect, dstx, dsty);
   }
 
   void
@@ -279,6 +259,7 @@ namespace SDL
 
     const Surface* surface = surfacepartrequest->surface;
     SDL::Texture *sdltexture = dynamic_cast<SDL::Texture *>(surface->get_texture());
+
     DrawingEffect effect = request.drawing_effect;
     if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
 
@@ -308,27 +289,14 @@ namespace SDL
       oy = surface->get_y();
     }
 
-    int numerator, denominator;
-    float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
-    float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
-    if(xfactor < yfactor)
-    {
-      numerator = config->screenwidth;
-      denominator = SCREEN_WIDTH;
-    }
-    else
-    {
-      numerator = config->screenheight;
-      denominator = SCREEN_HEIGHT;
-    }
-
+    SDL_Rect src_rect;
+    src_rect.x = (ox + (int) surfacepartrequest->source.x) * numerator / denominator;
+    src_rect.y = (oy + (int) surfacepartrequest->source.y) * numerator / denominator;
+    src_rect.w = (int) surfacepartrequest->size.x * numerator / denominator;
+    src_rect.h = (int) surfacepartrequest->size.y * numerator / denominator;
     int dstx = (int) request.pos.x * numerator / denominator;
     int dsty = (int) request.pos.y * numerator / denominator;
-    int srcx = (ox + (int) surfacepartrequest->source.x) * numerator / denominator;
-    int srcy = (oy + (int) surfacepartrequest->source.y) * numerator / denominator;
-    int blit_width = (int) surfacepartrequest->size.x * numerator / denominator;
-    int blit_height = (int) surfacepartrequest->size.y * numerator / denominator;
-    light_blit(transform, dstx, dsty, srcx, srcy, blit_width, blit_height);
+    light_blit(transform, &src_rect, dstx, dsty);
   }
 
   void
index 985615a..ab7e1bc 100644 (file)
@@ -50,9 +50,9 @@ namespace SDL
     Uint8 *blue_channel;
     Uint8 *green_channel;
     int width, height;
+    int numerator, denominator;
 
-    void light_blit(SDL_Surface *src, int dstx, int dsty,
-                    int srcx, int srcy, int blit_width, int blit_height);
+    void light_blit(SDL_Surface *src, SDL_Rect *src_rect, int dstx, int dsty);
   };
 }
 
index 25fa832..90ee2a1 100644 (file)
 #include "glutil.hpp"
 #include "sdl_renderer.hpp"
 #include "sdl_texture.hpp"
+#include "sdl_surface_data.hpp"
 #include "drawing_context.hpp"
 #include "drawing_request.hpp"
 #include "surface.hpp"
 #include "font.hpp"
 #include "main.hpp"
 #include "gameconfig.hpp"
+#include "log.hpp"
 #include "texture.hpp"
 #include "texture_manager.hpp"
 #include "obstack/obstackpp.hpp"
@@ -45,21 +47,43 @@ namespace SDL
 {
   Renderer::Renderer()
   {
-    int flags = SDL_SWSURFACE;
+    const SDL_VideoInfo *info = SDL_GetVideoInfo();
+    log_info << "Hardware surfaces are " << (info->hw_available ? "" : "not ") << "available." << std::endl;
+    log_info << "Hardware to hardware blits are " << (info->blit_hw ? "" : "not ") << "accelerated." << std::endl;
+    log_info << "Hardware to hardware blits with colorkey are " << (info->blit_hw_CC ? "" : "not ") << "accelerated." << std::endl;
+    log_info << "Hardware to hardware blits with alpha are " << (info->blit_hw_A ? "" : "not ") << "accelerated." << std::endl;
+    log_info << "Software to hardware blits are " << (info->blit_sw ? "" : "not ") << "accelerated." << std::endl;
+    log_info << "Software to hardware blits with colorkey are " << (info->blit_sw_CC ? "" : "not ") << "accelerated." << std::endl;
+    log_info << "Software to hardware blits with alpha are " << (info->blit_sw_A ? "" : "not ") << "accelerated." << std::endl;
+    log_info << "Color fills are " << (info->blit_fill ? "" : "not ") << "accelerated." << std::endl;
+
+    int flags = SDL_SWSURFACE | SDL_ANYFORMAT;
     if(config->use_fullscreen)
       flags |= SDL_FULLSCREEN;
     int width = config->screenwidth;
     int height = config->screenheight;
-    int bpp = 0;
 
-    screen = SDL_SetVideoMode(width, height, bpp, flags);
+    screen = SDL_SetVideoMode(width, height, 0, flags);
     if(screen == 0) {
       std::stringstream msg;
       msg << "Couldn't set video mode (" << width << "x" << height
-          << "-" << bpp << "bpp): " << SDL_GetError();
+          << "): " << SDL_GetError();
       throw std::runtime_error(msg.str());
     }
 
+    float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
+    float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
+    if(xfactor < yfactor)
+    {
+      numerator = config->screenwidth;
+      denominator = SCREEN_WIDTH;
+    }
+    else
+    {
+      numerator = config->screenheight;
+      denominator = SCREEN_HEIGHT;
+    }
+
     if(texture_manager == 0)
       texture_manager = new TextureManager();
   }
@@ -73,7 +97,9 @@ namespace SDL
   {
     //FIXME: support parameters request.alpha, request.angle, request.blend
     const Surface* surface = (const Surface*) request.request_data;
-    SDL::Texture *sdltexture = dynamic_cast<Texture *>(surface->get_texture());
+    SDL::Texture *sdltexture = dynamic_cast<SDL::Texture *>(surface->get_texture());
+    SDL::SurfaceData *surface_data = reinterpret_cast<SDL::SurfaceData *>(surface->get_surface_data());
+
     DrawingEffect effect = request.drawing_effect;
     if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
 
@@ -85,49 +111,12 @@ namespace SDL
       return;
     }  
 
-    int ox, oy;
-    if (effect == HORIZONTAL_FLIP)
-    {
-      ox = sdltexture->get_texture_width() - surface->get_x() - surface->get_width();
-    }
-    else
-    {
-      ox = surface->get_x();
-    }
-    if (effect == VERTICAL_FLIP)
-    {
-      oy = sdltexture->get_texture_height() - surface->get_y() - surface->get_height();
-    }
-    else
-    {
-      oy = surface->get_y();
-    }
-
-    int numerator, denominator;
-    float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
-    float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
-    if(xfactor < yfactor)
-    {
-      numerator = config->screenwidth;
-      denominator = SCREEN_WIDTH;
-    }
-    else
-    {
-      numerator = config->screenheight;
-      denominator = SCREEN_HEIGHT;
-    }
-
-    SDL_Rect srcRect;
-    srcRect.x = ox * numerator / denominator;
-    srcRect.y = oy * numerator / denominator;
-    srcRect.w = surface->get_width() * numerator / denominator;
-    srcRect.h = surface->get_height() * numerator / denominator;
-
-    SDL_Rect dstRect;
-    dstRect.x = (int) request.pos.x * numerator / denominator;
-    dstRect.y = (int) request.pos.y * numerator / denominator;
+    SDL_Rect *src_rect = surface_data->get_src_rect(effect);
+    SDL_Rect dst_rect;
+    dst_rect.x = (int) request.pos.x * numerator / denominator;
+    dst_rect.y = (int) request.pos.y * numerator / denominator;
 
-    SDL_BlitSurface(transform, &srcRect, screen, &dstRect);
+    SDL_BlitSurface(transform, src_rect, screen, &dst_rect);
   }
 
   void
@@ -137,7 +126,8 @@ namespace SDL
       = (SurfacePartRequest*) request.request_data;
 
     const Surface* surface = surfacepartrequest->surface;
-    SDL::Texture *sdltexture = dynamic_cast<Texture *>(surface->get_texture());
+    SDL::Texture *sdltexture = dynamic_cast<SDL::Texture *>(surface->get_texture());
+
     DrawingEffect effect = request.drawing_effect;
     if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
 
@@ -167,31 +157,17 @@ namespace SDL
       oy = surface->get_y();
     }
 
-    int numerator, denominator;
-    float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
-    float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
-    if(xfactor < yfactor)
-    {
-      numerator = config->screenwidth;
-      denominator = SCREEN_WIDTH;
-    }
-    else
-    {
-      numerator = config->screenheight;
-      denominator = SCREEN_HEIGHT;
-    }
-
-    SDL_Rect srcRect;
-    srcRect.x = (ox + (int) surfacepartrequest->source.x) * numerator / denominator;
-    srcRect.y = (oy + (int) surfacepartrequest->source.y) * numerator / denominator;
-    srcRect.w = (int) surfacepartrequest->size.x * numerator / denominator;
-    srcRect.h = (int) surfacepartrequest->size.y * numerator / denominator;
+    SDL_Rect src_rect;
+    src_rect.x = (ox + (int) surfacepartrequest->source.x) * numerator / denominator;
+    src_rect.y = (oy + (int) surfacepartrequest->source.y) * numerator / denominator;
+    src_rect.w = (int) surfacepartrequest->size.x * numerator / denominator;
+    src_rect.h = (int) surfacepartrequest->size.y * numerator / denominator;
 
-    SDL_Rect dstRect;
-    dstRect.x = (int) request.pos.x * numerator / denominator;
-    dstRect.y = (int) request.pos.y * numerator / denominator;
+    SDL_Rect dst_rect;
+    dst_rect.x = (int) request.pos.x * numerator / denominator;
+    dst_rect.y = (int) request.pos.y * numerator / denominator;
 
-    SDL_BlitSurface(transform, &srcRect, screen, &dstRect);
+    SDL_BlitSurface(transform, &src_rect, screen, &dst_rect);
   }
 
   void
index 8c943f1..24dcb84 100644 (file)
@@ -40,6 +40,7 @@ namespace SDL
     void flip();
   private:
     SDL_Surface *screen;
+    int numerator, denominator;
   };
 }
 
diff --git a/src/video/sdl_surface_data.hpp b/src/video/sdl_surface_data.hpp
new file mode 100644 (file)
index 0000000..1e46e68
--- /dev/null
@@ -0,0 +1,80 @@
+//  $Id: gl_surface_data.hpp 4063 2006-07-21 21:05:23Z anmaster $
+//
+//  SuperTux
+//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#ifndef __SDL_SURFACE_DATA_HPP__
+#define __SDL_SURFACE_DATA_HPP__
+
+#include <config.h>
+
+#include "surface.hpp"
+#include "texture.hpp"
+#include "main.hpp"
+#include "gameconfig.hpp"
+
+namespace SDL
+{
+  class SurfaceData
+  {
+  private:
+    const Surface &surface;
+    SDL_Rect src_rects[NUM_EFFECTS];
+
+  public:
+    SurfaceData(const Surface &surface) :
+      surface(surface)
+    {
+      int numerator, denominator;
+      float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
+      float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
+      if(xfactor < yfactor)
+      {
+        numerator = config->screenwidth;
+        denominator = SCREEN_WIDTH;
+      }
+      else
+      {
+        numerator = config->screenheight;
+        denominator = SCREEN_HEIGHT;
+      }
+
+      src_rects[NO_EFFECT].x = surface.get_x() * numerator / denominator;
+      src_rects[NO_EFFECT].y = surface.get_y() * numerator / denominator;
+      src_rects[NO_EFFECT].w = surface.get_width() * numerator / denominator;
+      src_rects[NO_EFFECT].h = surface.get_height() * numerator / denominator;
+
+      int flipped_x = surface.get_texture()->get_texture_width() - surface.get_x() - surface.get_width();
+      src_rects[HORIZONTAL_FLIP].x = flipped_x * numerator / denominator;
+      src_rects[HORIZONTAL_FLIP].y = surface.get_y() * numerator / denominator;
+      src_rects[HORIZONTAL_FLIP].w = surface.get_width() * numerator / denominator;
+      src_rects[HORIZONTAL_FLIP].h = surface.get_height() * numerator / denominator;
+
+      int flipped_y = surface.get_texture()->get_texture_height() - surface.get_y() - surface.get_height();
+      src_rects[VERTICAL_FLIP].x = flipped_y * numerator / denominator;
+      src_rects[VERTICAL_FLIP].y = surface.get_y() * numerator / denominator;
+      src_rects[VERTICAL_FLIP].w = surface.get_width() * numerator / denominator;
+      src_rects[VERTICAL_FLIP].h = surface.get_height() * numerator / denominator;
+    }
+
+    SDL_Rect *get_src_rect(DrawingEffect effect)
+    {
+      return src_rects + effect;
+    }
+  };
+}
+
+#endif
index 917a4df..2eb5de6 100644 (file)
@@ -327,8 +327,6 @@ namespace
     return dst;
   }
 
-  const Color white(1.0, 1.0, 1.0);
-
   SDL_Surface *colorize(SDL_Surface *src, const Color &color)
   {
     // FIXME: This is really slow
@@ -416,7 +414,7 @@ namespace SDL
       numerator = config->screenheight;
       denominator = SCREEN_HEIGHT;
     }
-    cache[NO_EFFECT][white] = scale(texture, numerator, denominator);
+    cache[NO_EFFECT][Color::WHITE] = scale(texture, numerator, denominator);
   }
 
   Texture::~Texture()
@@ -427,8 +425,8 @@ namespace SDL
   SDL_Surface *Texture::get_transform(const Color &color, DrawingEffect effect)
   {
     if(cache[NO_EFFECT][color] == 0) {
-      assert(cache[NO_EFFECT][white]);
-      cache[NO_EFFECT][color] = colorize(cache[NO_EFFECT][white], color);
+      assert(cache[NO_EFFECT][Color::WHITE]);
+      cache[NO_EFFECT][color] = colorize(cache[NO_EFFECT][Color::WHITE], color);
     }
     if(cache[effect][color] == 0) {
       assert(cache[NO_EFFECT][color]);
index e1b7cd4..d90494b 100644 (file)
@@ -26,6 +26,7 @@
 #include <SDL.h>
 #include "math/vector.hpp"
 #include "texture.hpp"
+#include "video_systems.hpp"
 
 /**
  * A rectangular image.
@@ -36,6 +37,7 @@ class Surface
 {
 private:
   Texture* texture;
+  void *surface_data;
   int x;
   int y;
   int w;
@@ -51,6 +53,7 @@ public:
     texture->ref();
     w = texture->get_image_width();
     h = texture->get_image_height();
+    surface_data = new_surface_data(*this);
   }
 
   Surface(const std::string& file, int x, int y, int w, int h) :
@@ -59,6 +62,7 @@ public:
     flipx(false)
   {
     texture->ref();
+    surface_data = new_surface_data(*this);
   }
 
   Surface(const Surface& other) :
@@ -68,10 +72,12 @@ public:
     flipx(false)
   {
     texture->ref();
+    surface_data = new_surface_data(*this);
   }
 
   ~Surface()
   {
+    free_surface_data(surface_data);
     texture->unref();
   }
 
@@ -103,6 +109,11 @@ public:
     return texture;
   }
 
+  void *get_surface_data() const
+  {
+    return surface_data;
+  }
+
   int get_x() const
   {
     return x;
@@ -131,30 +142,6 @@ public:
    */
   Vector get_size() const
   { return Vector(get_width(), get_height()); }
-
-  float get_uv_left() const
-  {
-    return (float) (x + (flipx ? w : 0)) / texture->get_texture_width();
-  }
-
-  float get_uv_top() const
-  {
-    return (float) y / texture->get_texture_height();
-  }
-
-  float get_uv_right() const
-  {
-    return (float) (x + (flipx ? 0 : w)) / texture->get_texture_width();
-  }
-
-  float get_uv_bottom() const
-  {
-    return (float) (y + h) / texture->get_texture_height();
-  }
-
-  //void draw_part(float src_x, float src_y, float dst_x, float dst_y,
-  //               float width, float height, float alpha,
-  //               DrawingEffect effect) const;
 };
 
 #endif
index 7b556a6..0e00086 100644 (file)
@@ -28,8 +28,8 @@
 #include <sstream>
 #include <stdexcept>
 #include "physfs/physfs_sdl.hpp"
+#include "video_systems.hpp"
 #include "gl_texture.hpp"
-#include "sdl_texture.hpp"
 #include "glutil.hpp"
 #include "gameconfig.hpp"
 #include "file_system.hpp"
@@ -103,16 +103,7 @@ TextureManager::create_image_texture(const std::string& filename)
 
   Texture* result = 0;
   try {
-#ifdef HAVE_OPENGL
-    if(config->video == "opengl")
-    {
-      result = new GL::Texture(image);
-    }
-    else
-#endif
-    {
-      result = new SDL::Texture(image);
-    }
+    result = new_texture(image);
     result->set_filename(filename);
   } catch(...) {
     delete result;
diff --git a/src/video/video_systems.cpp b/src/video/video_systems.cpp
new file mode 100644 (file)
index 0000000..29404e0
--- /dev/null
@@ -0,0 +1,139 @@
+//  $Id: video_systems.cpp 5063 2007-05-27 11:32:00Z matzeb $
+//
+//  SuperTux
+//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#include <config.h>
+
+#include "video_systems.hpp"
+#include "gameconfig.hpp"
+#include "renderer.hpp"
+#include "gl_renderer.hpp"
+#include "sdl_renderer.hpp"
+#include "lightmap.hpp"
+#include "gl_lightmap.hpp"
+#include "sdl_lightmap.hpp"
+#include "texture.hpp"
+#include "gl_texture.hpp"
+#include "sdl_texture.hpp"
+#include "gl_surface_data.hpp"
+#include "sdl_surface_data.hpp"
+
+Renderer *new_renderer()
+{
+  switch(config->video)
+  {
+#ifdef HAVE_OPENGL
+    case OPENGL:
+      return new GL::Renderer();
+#endif
+    case PURE_SDL:
+      return new SDL::Renderer();
+    default:
+      assert(0 && "invalid video system in config");
+      return new SDL::Renderer();
+  }
+}
+
+Lightmap *new_lightmap()
+{
+  switch(config->video)
+  {
+#ifdef HAVE_OPENGL
+    case OPENGL:
+      return new GL::Lightmap();
+#endif
+    case PURE_SDL:
+      return new SDL::Lightmap();
+    default:
+      assert(0 && "invalid video system in config");
+      return new SDL::Lightmap();
+  }
+}
+
+Texture *new_texture(SDL_Surface *image)
+{
+  switch(config->video)
+  {
+#ifdef HAVE_OPENGL
+    case OPENGL:
+      return new GL::Texture(image);
+#endif
+    case PURE_SDL:
+      return new SDL::Texture(image);
+    default:
+      assert(0 && "invalid video system in config");
+      return new SDL::Texture(image);
+  }
+}
+
+void *new_surface_data(const Surface &surface)
+{
+  switch(config->video)
+  {
+#ifdef HAVE_OPENGL
+    case OPENGL:
+      return new GL::SurfaceData(surface);
+#endif
+    case PURE_SDL:
+      return new SDL::SurfaceData(surface);
+    default:
+      assert(0 && "invalid video system in config");
+      return new SDL::SurfaceData(surface);
+  }
+}
+
+void free_surface_data(void *surface_data)
+{
+  delete reinterpret_cast<char *>(surface_data);
+}
+
+VideoSystem get_video_system(const std::string &video)
+{
+  if(0) {}
+#ifdef HAVE_OPENGL
+  else if(video == "opengl")
+  {
+    return OPENGL;
+  }
+#endif
+  else if(video == "sdl")
+  {
+    return PURE_SDL;
+  }
+  else
+  {
+#ifdef HAVE_OPENGL
+    return OPENGL;
+#else
+    return PURE_SDL;
+#endif
+  }
+}
+
+std::string get_video_string(VideoSystem video)
+{
+  switch(video)
+  {
+    case OPENGL:
+      return "opengl";
+    case PURE_SDL:
+      return "sdl";
+    default:
+      assert(0 && "invalid video system in config");
+      return "sdl";
+  }
+}
diff --git a/src/video/video_systems.hpp b/src/video/video_systems.hpp
new file mode 100644 (file)
index 0000000..4f3a991
--- /dev/null
@@ -0,0 +1,47 @@
+//  $Id: video_systems.hpp 5138 2007-08-15 01:02:22Z tuxdev $
+//
+//  SuperTux
+//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+//  02111-1307, USA.
+#ifndef __RENDER_SYTSTEMS_HPP__
+#define __RENDER_SYTSTEMS_HPP__
+
+#include <config.h>
+
+#include <string>
+#include <SDL.h>
+
+class Renderer;
+class Lightmap;
+class Texture;
+class Surface;
+
+enum VideoSystem {
+  OPENGL,
+  PURE_SDL,
+  NUM_SYSTEMS
+};
+
+Renderer *new_renderer();
+Lightmap *new_lightmap();
+Texture *new_texture(SDL_Surface *image);
+void *new_surface_data(const Surface &surface);
+void free_surface_data(void *surface_data);
+VideoSystem get_video_system(const std::string &video);
+std::string get_video_string(VideoSystem video);
+
+#endif