From: Ingo Ruhnke Date: Wed, 14 May 2008 16:39:43 +0000 (+0000) Subject: Added experimental and unfinished window resize more fixes will follow later, might... X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=403276e51afda11d0738be756025411d9103a6ed;p=supertux.git Added experimental and unfinished window resize more fixes will follow later, might have broken SDL renderer in the progress SVN-Revision: 5475 --- diff --git a/src/gameconfig.cpp b/src/gameconfig.cpp index c717af56b..d3c589678 100644 --- a/src/gameconfig.cpp +++ b/src/gameconfig.cpp @@ -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"); diff --git a/src/gameconfig.hpp b/src/gameconfig.hpp index 775e45132..6c3df206d 100644 --- a/src/gameconfig.hpp +++ b/src/gameconfig.hpp @@ -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; diff --git a/src/main.cpp b/src/main.cpp index 500688253..c05f57992 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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(config->aspect_width) / - static_cast(config->aspect_height); - - // use aspect ratio to calculate logical resolution - if (aspect_ratio > 1) { - config->aspect_width = static_cast (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 (600 * 1/aspect_ratio + 0.5); + float aspect_ratio = static_cast(config->aspect_width) / + static_cast(config->aspect_height); + + // use aspect ratio to calculate logical resolution + if (aspect_ratio > 1) { + config->aspect_width = static_cast (600 * aspect_ratio + 0.5); + config->aspect_height = 600; + } else { + config->aspect_width = 600; + config->aspect_height = static_cast (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; } diff --git a/src/main.hpp b/src/main.hpp index e64b01fea..4a79a807c 100644 --- a/src/main.hpp +++ b/src/main.hpp @@ -23,13 +23,18 @@ 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 diff --git a/src/mainloop.cpp b/src/mainloop.cpp index 4d32e54ff..6ea17aaee 100644 --- a/src/mainloop.cpp +++ b/src/mainloop.cpp @@ -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 diff --git a/src/options_menu.cpp b/src/options_menu.cpp index 000592a71..778f77cd4 100644 --- a/src/options_menu.cpp +++ b/src/options_menu.cpp @@ -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")); diff --git a/src/video/gl_renderer.cpp b/src/video/gl_renderer.cpp index 7b6d0e05f..8f4fbedb6 100644 --- a/src/video/gl_renderer.cpp +++ b/src/video/gl_renderer.cpp @@ -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 diff --git a/src/video/gl_renderer.hpp b/src/video/gl_renderer.hpp index 3a45629f4..a870c5752 100644 --- a/src/video/gl_renderer.hpp +++ b/src/video/gl_renderer.hpp @@ -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 index 000000000..37b4cde32 --- /dev/null +++ b/src/video/renderer.cpp @@ -0,0 +1,32 @@ +// $Id$ +// +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// 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 */ diff --git a/src/video/renderer.hpp b/src/video/renderer.hpp index 8e97e377f..7d3868aa8 100644 --- a/src/video/renderer.hpp +++ b/src/video/renderer.hpp @@ -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 diff --git a/src/video/sdl_lightmap.cpp b/src/video/sdl_lightmap.cpp index 8e7c70fac..51e13b937 100644 --- a/src/video/sdl_lightmap.cpp +++ b/src/video/sdl_lightmap.cpp @@ -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; diff --git a/src/video/sdl_renderer.cpp b/src/video/sdl_renderer.cpp index a48d7f914..56cb6b899 100644 --- a/src/video/sdl_renderer.cpp +++ b/src/video/sdl_renderer.cpp @@ -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) + { + + } } diff --git a/src/video/sdl_renderer.hpp b/src/video/sdl_renderer.hpp index 5a6d31add..572c34ee7 100644 --- a/src/video/sdl_renderer.hpp +++ b/src/video/sdl_renderer.hpp @@ -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; diff --git a/src/video/sdl_surface_data.hpp b/src/video/sdl_surface_data.hpp index 1e46e683a..e4650da37 100644 --- a/src/video/sdl_surface_data.hpp +++ b/src/video/sdl_surface_data.hpp @@ -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; diff --git a/src/video/sdl_texture.cpp b/src/video/sdl_texture.cpp index 21645507e..05bf5a229 100644 --- a/src/video/sdl_texture.cpp +++ b/src/video/sdl_texture.cpp @@ -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); }