Added experimental and unfinished window resize more fixes will follow later, might...
authorIngo Ruhnke <grumbel@gmx.de>
Wed, 14 May 2008 16:39:43 +0000 (16:39 +0000)
committerIngo Ruhnke <grumbel@gmx.de>
Wed, 14 May 2008 16:39:43 +0000 (16:39 +0000)
SVN-Revision: 5475

15 files changed:
src/gameconfig.cpp
src/gameconfig.hpp
src/main.cpp
src/main.hpp
src/mainloop.cpp
src/options_menu.cpp
src/video/gl_renderer.cpp
src/video/gl_renderer.hpp
src/video/renderer.cpp [new file with mode: 0644]
src/video/renderer.hpp
src/video/sdl_lightmap.cpp
src/video/sdl_renderer.cpp
src/video/sdl_renderer.hpp
src/video/sdl_surface_data.hpp
src/video/sdl_texture.cpp

index c717af5..d3c5896 100644 (file)
@@ -46,11 +46,18 @@ Config::Config()
   console_enabled = false;
   random_seed = 0;          // set by time(), by default (unless in config)
 
-  screenwidth = 800;
-  screenheight = 600;
-  
-  aspect_width  = 800;
-  aspect_height = 600;
+  window_width  = 800;
+  window_height = 600;
+
+  fullscreen_width  = 800;
+  fullscreen_height = 600;
+
+  projection_width  = 800;
+  projection_height = 600;
+  scale_projection  = true;
+
+  aspect_width  = 4;
+  aspect_height = 3;
 
   enable_script_debugger = false;
 
@@ -82,8 +89,17 @@ Config::load()
     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);
+
+    config_video_lisp->get("fullscreen_width",  fullscreen_width);
+    config_video_lisp->get("fullscreen_height", fullscreen_height);
+
+    config_video_lisp->get("window_width",  window_width);
+    config_video_lisp->get("window_height", window_height);
+
+    config_video_lisp->get("projection_width",  projection_width);
+    config_video_lisp->get("projection_height", projection_height);
+    config_video_lisp->get("scale_projection", scale_projection);
+
     config_video_lisp->get("aspect_width",  aspect_width);
     config_video_lisp->get("aspect_height", aspect_height);
   }
@@ -120,10 +136,20 @@ Config::save()
   writer.write_bool("fullscreen", use_fullscreen);
   writer.write_string("video", get_video_string(video));
   writer.write_bool("vsync", try_vsync);
-  writer.write_int("width", screenwidth);
-  writer.write_int("height", screenheight);
-  writer.write_float("aspect_width",  aspect_width);
-  writer.write_float("aspect_height", aspect_height);
+
+  writer.write_int("fullscreen_width",  fullscreen_width);
+  writer.write_int("fullscreen_height", fullscreen_height);
+
+  writer.write_int("window_width",  window_width);
+  writer.write_int("window_height", window_height);
+
+  writer.write_int("projection_width",  projection_width);
+  writer.write_int("projection_height", projection_height);
+  writer.write_bool("scale_projection",  scale_projection);
+
+  writer.write_int("aspect_width",  aspect_width);
+  writer.write_int("aspect_height", aspect_height);
+
   writer.end_list("video");
 
   writer.start_list("audio");
index 775e451..6c3df20 100644 (file)
@@ -36,12 +36,22 @@ public:
 
   int profile;
 
-  /** screen width in pixel (warning: this is the real screen width+height,
-   * you should use the logical SCREEN_WIDTH and SCREEN_HEIGHT for your
-   * rendering code.)
-   */
-  int screenwidth;
-  int screenheight;
+  // the width/height to be used to display the game in fullscreen
+  int fullscreen_width;
+  int fullscreen_height;
+
+  // the width/height of the window managers window 
+  int window_width;
+  int window_height;
+
+  // the projection area size before aspectratio is applied
+  int projection_width;
+  int projection_height;
+  
+  // scale the projection area or leave it at 1:1 pixel mapping
+  bool scale_projection;
+
+  // the aspect ratio
   int aspect_width;
   int aspect_height;
 
index 5006882..c05f579 100644 (file)
@@ -268,50 +268,77 @@ static bool parse_commandline(int argc, char** argv)
       config->use_fullscreen = true;
     } else if(arg == "--default" || arg == "-d") {
       config->use_fullscreen = false;
-      config->aspect_width  = 800;
-      config->aspect_height = 600;
-      config->screenwidth   = 800;
-      config->screenheight  = 600;
+      
+      config->window_width  = 800;
+      config->window_height = 600;
+
+      config->fullscreen_width  = 800;
+      config->fullscreen_height = 600;
+
+      config->projection_width  = 800;
+      config->projection_height = 600;
+      config->scale_projection = true;
+
+      config->aspect_width  = 4;
+      config->aspect_height = 3;
+      
     } else if(arg == "--window" || arg == "-w") {
       config->use_fullscreen = false;
     } else if(arg == "--geometry" || arg == "-g") {
-      if(i+1 >= argc) {
-        print_usage(argv[0]);
-        throw std::runtime_error("Need to specify a parameter for geometry switch");
-      }
       i += 1;
-      if (sscanf(argv[i], "%dx%d:%dx%d",
-                 &config->screenwidth,  &config->screenheight,
-                 &config->aspect_width, &config->aspect_height) != 4 &&
-          sscanf(argv[i], "%dx%d", &config->screenwidth, &config->screenheight) != 2)
+      if(i >= argc) 
         {
           print_usage(argv[0]);
-          throw std::runtime_error("Invalid geometry spec, should be WIDTHxHEIGHT");
+          throw std::runtime_error("Need to specify a parameter for geometry switch");
+        } 
+      else 
+        {
+          int width, height;
+          if (sscanf(argv[i], "%dx%d", &width, &height) != 2)
+            {
+              print_usage(argv[0]);
+              throw std::runtime_error("Invalid geometry spec, should be WIDTHxHEIGHT");
+            }
+          else
+            {
+              config->projection_width  = width;
+              config->projection_height = height;
+
+              config->window_width  = width;
+              config->window_height = height;
+
+              config->fullscreen_width  = width;
+              config->fullscreen_height = height;
+            }
         }
     } else if(arg == "--aspect" || arg == "-a") {
-      if(i+1 >= argc) {
-        print_usage(argv[0]);
-        throw std::runtime_error("Need to specify a parameter for aspect switch");
-      } else {
-        int aspect_width  = 4;
-        int aspect_height = 3;
-        if(sscanf(argv[++i], "%d:%d", &aspect_width, &aspect_height) != 2) {
+      i += 1;
+      if(i >= argc) 
+        {
           print_usage(argv[0]);
-          throw std::runtime_error("Invalid aspect spec, should be WIDTH:HEIGHT");
-        } else {
-          float aspect_ratio = static_cast<double>(config->aspect_width) /
-            static_cast<double>(config->aspect_height);
-
-          // use aspect ratio to calculate logical resolution
-          if (aspect_ratio > 1) {
-            config->aspect_width  = static_cast<int> (600 * aspect_ratio + 0.5);
-            config->aspect_height = 600;
+          throw std::runtime_error("Need to specify a parameter for aspect switch");
+        } 
+      else 
+        {
+          int aspect_width  = 4;
+          int aspect_height = 3;
+          if(sscanf(argv[++i], "%d:%d", &aspect_width, &aspect_height) != 2) {
+            print_usage(argv[0]);
+            throw std::runtime_error("Invalid aspect spec, should be WIDTH:HEIGHT");
           } else {
-            config->aspect_width  = 600;
-            config->aspect_height = static_cast<int> (600 * 1/aspect_ratio + 0.5);
+            float aspect_ratio = static_cast<double>(config->aspect_width) /
+              static_cast<double>(config->aspect_height);
+
+            // use aspect ratio to calculate logical resolution
+            if (aspect_ratio > 1) {
+              config->aspect_width  = static_cast<int> (600 * aspect_ratio + 0.5);
+              config->aspect_height = 600;
+            } else {
+              config->aspect_width  = 600;
+              config->aspect_height = static_cast<int> (600 * 1/aspect_ratio + 0.5);
+            }
           }
         }
-      }
     } else if(arg == "--show-fps") {
       config->show_fps = true;
     } else if(arg == "--no-show-fps") {
@@ -392,8 +419,9 @@ void init_video()
   }
 #endif
   
-  SCREEN_WIDTH  = config->aspect_width;
-  SCREEN_HEIGHT = config->aspect_height;
+  // FIXME: Add aspect handling
+  SCREEN_WIDTH  = config->projection_width;
+  SCREEN_HEIGHT = config->projection_height;
 
   context_pointer->init_renderer();
   screen = SDL_GetVideoSurface();
@@ -420,7 +448,9 @@ void init_video()
   SDL_ShowCursor(0);
 
   log_info << (config->use_fullscreen?"fullscreen ":"window ")
-           << " Window: " << config->screenwidth << "x" << config->screenheight
+           << " Window: " << config->window_width << "x" << config->window_height
+           << " Fullscreen: " << config->fullscreen_width << "x" << config->fullscreen_height
+           << " Projection: " << config->projection_width << "x" << config->projection_height
            << " Area: "   << config->aspect_width << "x" << config->aspect_height << std::endl;
 }
 
index e64b01f..4a79a80 100644 (file)
 void init_video();
 void wait_for_event(float min_delay, float max_delay);
 
-/// The width of the display (this is a logical value, not the physical value)
+/** The width of the display (this is a logical value, not the
+    physical value, since aspect_ration and projection_area might
+    shrink or scale things) */
 extern int SCREEN_WIDTH;
-/// The height of the display (this is a logical value, not the physical value)
+
+/** The width of the display (this is a logical value, not the
+    physical value, since aspect_ration and projection_area might
+    shrink or scale things) */
 extern int SCREEN_HEIGHT;
 
 // global variables
-class JoystickKeyboardController;
+class  JoystickKeyboardController;
 extern JoystickKeyboardController* main_controller;
 
 #endif
index 4d32e54..6ea17aa 100644 (file)
@@ -35,6 +35,7 @@
 #include "screen_fade.hpp"
 #include "timer.hpp"
 #include "player_status.hpp"
+#include "video/renderer.hpp"
 #include "random_generator.hpp"
 
 // the engine will be run with a logical framerate of 64fps.
@@ -180,20 +181,36 @@ MainLoop::process_events()
 {
   main_controller->update();
   SDL_Event event;
-  while(SDL_PollEvent(&event)) {
-    main_controller->process_event(event);
-    if(Menu::current() != NULL)
-      Menu::current()->event(event);
-    if(event.type == SDL_QUIT)
-      quit();
-    else if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_F11) {
-      config->use_fullscreen = !config->use_fullscreen;
-      init_video();
-    }
-    else if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_PRINT) {
-      take_screenshot();
+  while(SDL_PollEvent(&event)) 
+    {
+      main_controller->process_event(event);
+
+      if(Menu::current() != NULL)
+        Menu::current()->event(event);
+
+      switch(event.type)
+        {
+          case SDL_QUIT:
+            quit();
+            break;
+              
+          case SDL_VIDEORESIZE:
+            Renderer::instance()->resize(event.resize.w, event.resize.h);
+            break;
+            
+          case SDL_KEYDOWN:
+            if (event.key.keysym.sym == SDLK_F11) 
+              {
+                config->use_fullscreen = !config->use_fullscreen;
+                init_video();
+              }
+            else if (event.key.keysym.sym == SDLK_PRINT) 
+              {
+                take_screenshot();
+              }
+            break;
+        }
     }
-  }
 }
 
 void
index 000592a..778f77c 100644 (file)
@@ -32,6 +32,8 @@ Menu* options_menu   = 0;
 
 enum OptionsMenuIDs {
   MNID_FULLSCREEN,
+  MNID_FULLSCREEN_RESOLUTION,
+  MNID_PROJECTION_AREA,
   MNID_ASPECTRATIO,
   MNID_SOUND,
   MNID_MUSIC
@@ -123,6 +125,37 @@ OptionsMenu::OptionsMenu()
   add_toggle(MNID_FULLSCREEN,_("Fullscreen"), config->use_fullscreen)
     ->set_help(_("Let the game cover the whole screen"));
 
+  MenuItem* projection = add_string_select(MNID_PROJECTION_AREA, _("Projection Area"));
+  projection->set_help(_("Change the visible area"));
+
+  projection->list.push_back("640x480");
+  projection->list.push_back("800x600");
+  projection->list.push_back("1024x768");
+  projection->list.push_back("1152x864");
+  projection->list.push_back("1280x960");
+  projection->list.push_back("1280x1024");
+  projection->list.push_back("1440x900");
+  projection->list.push_back("1680x1050");
+  projection->list.push_back("1600x1200");
+  projection->list.push_back("1920x1080");
+  projection->list.push_back("1920x1200");
+
+  MenuItem* fullscreen_res = add_string_select(MNID_FULLSCREEN_RESOLUTION, _("Fullscreen Resolution"));
+  fullscreen_res->set_help(_("Change the Fullscreen Resolution"));
+
+  // FIXME: Hardcoded values are evil, these should be queried from the Xorg server
+  fullscreen_res->list.push_back("640x480");
+  fullscreen_res->list.push_back("800x600");
+  fullscreen_res->list.push_back("1024x768");
+  fullscreen_res->list.push_back("1152x864");
+  fullscreen_res->list.push_back("1280x960");
+  fullscreen_res->list.push_back("1280x1024");
+  fullscreen_res->list.push_back("1440x900");
+  fullscreen_res->list.push_back("1680x1050");
+  fullscreen_res->list.push_back("1600x1200");
+  fullscreen_res->list.push_back("1920x1080");
+  fullscreen_res->list.push_back("1920x1200");
+
   MenuItem* aspect = add_string_select(MNID_ASPECTRATIO, _("Aspect Ratio"));
   aspect->set_help(_("Adjust the aspect ratio"));
   
index 7b6d0e0..8f4fbed 100644 (file)
@@ -124,6 +124,8 @@ namespace GL
 {
   Renderer::Renderer()
   {
+    ::Renderer::instance_ = this;
+
     if(texture_manager != 0)
       texture_manager->save_textures();
 
@@ -133,15 +135,27 @@ namespace GL
     }
 
     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
+
+    // Hu? 16bit rendering?
+    SDL_GL_SetAttribute(SDL_GL_RED_SIZE,   5);
     SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
-    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
+    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,  5);
 
     int flags = SDL_OPENGL;
+    int width;
+    int height;
     if(config->use_fullscreen)
-      flags |= SDL_FULLSCREEN;
-    int width = config->screenwidth;
-    int height = config->screenheight;
+      {
+        flags |= SDL_FULLSCREEN;
+        width  = config->fullscreen_width;
+        height = config->fullscreen_height;
+      }
+    else
+      {
+        flags |= SDL_RESIZABLE;
+        width  = config->window_width;
+        height = config->window_height;
+      }
     int bpp = 0;
 
     SDL_Surface *screen = SDL_SetVideoMode(width, height, bpp, flags);
@@ -162,8 +176,10 @@ namespace GL
     glViewport(0, 0, screen->w, screen->h);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
+
     // logical resolution here not real monitor resolution
     glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
+
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     glTranslatef(0, 0, 0);
@@ -475,6 +491,24 @@ namespace GL
     assert_gl("drawing");
     SDL_GL_SwapBuffers();
   }
+
+  void
+  Renderer::resize(int w, int h)
+  {
+    SDL_SetVideoMode(w, h, 0, SDL_OPENGL | SDL_RESIZABLE);
+    
+    config->window_width  = w;
+    config->window_height = h;
+
+    // FIXME: Add aspect handling
+    SCREEN_WIDTH  = w;
+    SCREEN_HEIGHT = h;
+
+    glViewport(0, 0, config->window_width, config->window_height);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
+  }
 }
 
 #endif
index 3a45629..a870c57 100644 (file)
@@ -41,6 +41,7 @@ namespace GL
     void draw_inverse_ellipse(const DrawingRequest& request);
     void do_take_screenshot();
     void flip();
+    void resize(int w, int h);
   };
 }
 
diff --git a/src/video/renderer.cpp b/src/video/renderer.cpp
new file mode 100644 (file)
index 0000000..37b4cde
--- /dev/null
@@ -0,0 +1,32 @@
+//  $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.
+
+#include "renderer.hpp"
+
+Renderer* Renderer::instance_ = 0;
+
+Renderer::Renderer()
+{
+}
+
+Renderer::~Renderer()
+{
+}
+
+/* EOF */
index 8e97e37..7d3868a 100644 (file)
@@ -16,6 +16,7 @@
 //  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 SUPERTUX_RENDERER_H
 #define SUPERTUX_RENDERER_H
 
@@ -42,7 +43,8 @@ struct DrawingRequest;
 class Renderer
 {
 public:
-  virtual ~Renderer() {}
+  Renderer();
+  virtual ~Renderer();
 
   virtual void draw_surface(const DrawingRequest& request) = 0;
   virtual void draw_surface_part(const DrawingRequest& request) = 0;
@@ -51,6 +53,12 @@ public:
   virtual void draw_inverse_ellipse(const DrawingRequest& request)= 0;
   virtual void do_take_screenshot() = 0;
   virtual void flip() = 0;
+  virtual void resize(int w, int h) = 0;
+
+  static Renderer* instance() { return instance_; }
+  
+protected:
+  static Renderer* instance_;
 };
 
 #endif
index 8e7c70f..51e13b9 100644 (file)
@@ -48,8 +48,13 @@ namespace SDL
   {
     screen = SDL_GetVideoSurface();
 
-    float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
-    float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
+    //float xfactor = 1.0f; // FIXME: (float) config->screenwidth / SCREEN_WIDTH;
+    //float yfactor = 1.0f; // FIXME: (float) config->screenheight / SCREEN_HEIGHT;
+
+    numerator = 1;
+    denominator = 1;
+
+    /* FIXME:
     if(xfactor < yfactor)
     {
       numerator = config->screenwidth;
@@ -60,6 +65,7 @@ namespace SDL
       numerator = config->screenheight;
       denominator = SCREEN_HEIGHT;
     }
+    */
 
     LIGHTMAP_DIV = 8 * numerator / denominator;
 
index a48d7f9..56cb6b8 100644 (file)
@@ -130,6 +130,8 @@ namespace SDL
 {
   Renderer::Renderer()
   {
+    ::Renderer::instance_ = this;
+
     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;
@@ -143,8 +145,9 @@ namespace SDL
     int flags = SDL_SWSURFACE | SDL_ANYFORMAT;
     if(config->use_fullscreen)
       flags |= SDL_FULLSCREEN;
-    int width = config->screenwidth;
-    int height = config->screenheight;
+    
+    int width  = 800; //FIXME: config->screenwidth;
+    int height = 600; //FIXME: config->screenheight;
 
     screen = SDL_SetVideoMode(width, height, 0, flags);
     if(screen == 0) {
@@ -154,6 +157,9 @@ namespace SDL
       throw std::runtime_error(msg.str());
     }
 
+    numerator   = 1;
+    denominator = 1;
+    /* FIXME: 
     float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
     float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
     if(xfactor < yfactor)
@@ -166,7 +172,7 @@ namespace SDL
       numerator = config->screenheight;
       denominator = SCREEN_HEIGHT;
     }
-
+    */
     if(texture_manager == 0)
       texture_manager = new TextureManager();
   }
@@ -435,4 +441,10 @@ namespace SDL
   {
     SDL_Flip(screen);
   }
+
+  void
+  Renderer::resize(int, int)
+  {
+    
+  }
 }
index 5a6d31a..572c34e 100644 (file)
@@ -39,6 +39,7 @@ namespace SDL
     void draw_inverse_ellipse(const DrawingRequest& request);
     void do_take_screenshot();
     void flip();
+    void resize(int w, int h);
   private:
     SDL_Surface *screen;
     int numerator, denominator;
index 1e46e68..e4650da 100644 (file)
@@ -38,9 +38,12 @@ namespace SDL
     SurfaceData(const Surface &surface) :
       surface(surface)
     {
-      int numerator, denominator;
-      float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
-      float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
+      int numerator   = 1;
+      int denominator = 1;
+      //float xfactor = 1.0f; // FIXME: (float) config->screenwidth  / SCREEN_WIDTH;
+      //float yfactor = 1.0f; // FIXME: (float) config->screenheight / SCREEN_HEIGHT;
+
+      /* FIXME: 
       if(xfactor < yfactor)
       {
         numerator = config->screenwidth;
@@ -51,6 +54,7 @@ namespace SDL
         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;
index 2164550..05bf5a2 100644 (file)
@@ -611,9 +611,11 @@ namespace SDL
     texture = optimize(image);
     //width = texture->w;
     //height = texture->h;
-    int numerator, denominator;
-    float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
-    float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
+    int numerator   = 1;
+    int denominator = 1;
+    //FIXME: float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
+    //FIXME: float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
+    /* FIXME: 
     if(xfactor < yfactor)
     {
       numerator = config->screenwidth;
@@ -624,6 +626,7 @@ namespace SDL
       numerator = config->screenheight;
       denominator = SCREEN_HEIGHT;
     }
+    */
     cache[NO_EFFECT][Color::WHITE] = scale(texture, numerator, denominator);
   }