INCLUDE_DIRECTORIES(SYSTEM ${Boost_INCLUDE_DIR})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
- FIND_PACKAGE(SDL REQUIRED)
- INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR})
+ INCLUDE(FindPkgConfig)
+ PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
+ INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS})
+ LINK_LIBRARIES(supertux2 ${SDL2_LIBRARIES})
+
+ PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED SDL2_image>=2.0.0)
+ INCLUDE_DIRECTORIES(${SDL2IMAGE_INCLUDE_DIRS})
+ LINK_LIBRARIES(supertux2 ${SDL2IMAGE_LIBRARIES})
SET(HAVE_SDL TRUE)
- FIND_PACKAGE(SDL_image REQUIRED)
- INCLUDE_DIRECTORIES(${SDLIMAGE_INCLUDE_DIR})
+ #FIND_PACKAGE(SDL_image REQUIRED)
+ #INCLUDE_DIRECTORIES(${SDLIMAGE_INCLUDE_DIR})
OPTION(ENABLE_OPENGL "Enable OpenGL support" ON)
IF(ENABLE_OPENGL)
SET(CMAKE_CXX_FLAGS_PROFILE "-pg" CACHE STRING "Profile flags")
SET(CMAKE_C_FLAGS_PROFILE "-pg" CACHE STRING "Profile flags")
SET(CMAKE_LD_FLAGS_PROFILE "-lgmon" CACHE STRING "Profile flags")
- ADD_DEFINITIONS(-Wall -Wextra -funit-at-a-time)
+ ADD_DEFINITIONS(-Wall -Wextra -Wno-unused-parameter -funit-at-a-time)
IF(WERROR)
ADD_DEFINITIONS(-Werror)
ELSE(WERROR)
INSTALL(TARGETS supertux2 DESTINATION ${INSTALL_SUBDIR_BIN})
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/INSTALL ${CMAKE_CURRENT_SOURCE_DIR}/README ${CMAKE_CURRENT_SOURCE_DIR}/COPYING ${CMAKE_CURRENT_SOURCE_DIR}/WHATSNEW.txt DESTINATION ${INSTALL_SUBDIR_DOC})
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/INSTALL.md ${CMAKE_CURRENT_SOURCE_DIR}/README.md ${CMAKE_CURRENT_SOURCE_DIR}/COPYING ${CMAKE_CURRENT_SOURCE_DIR}/WHATSNEW.txt DESTINATION ${INSTALL_SUBDIR_DOC})
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/credits.txt DESTINATION ${INSTALL_SUBDIR_SHARE})
IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# The OS X PackageMaker doesn't seem to like files with no extension
ELSE(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
- SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
+ SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
SET(CPACK_PACKAGE_VERSION_MAJOR "0")
#include <stdexcept>
BonusBlock::BonusBlock(const Vector& pos, int data) :
- Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite")),
+ Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite")),
contents(),
object(0),
hit_counter(1),
case 3: contents = CONTENT_STAR; break;
case 4: contents = CONTENT_1UP; break;
case 5: contents = CONTENT_ICEGROW; break;
- case 6: contents = CONTENT_LIGHT;
- sound_manager->preload("sounds/switch.ogg");
+ case 6: contents = CONTENT_LIGHT;
+ sound_manager->preload("sounds/switch.ogg");
lightsprite=Surface::create("/images/objects/lightmap_light/bonusblock_light.png");
break;
case 7: contents = CONTENT_TRAMPOLINE;
object = new Trampoline(get_pos(), true);
break;
case 9: contents = CONTENT_CUSTOM;
- object = new Rock(get_pos(), "images/objects/rock/rock.sprite");
+ object = new Rock(get_pos(), "images/objects/rock/rock.sprite");
break;
case 10: contents = CONTENT_RAIN; break;
case 11: contents = CONTENT_EXPLODE; break;
Direction direction = (player->get_bbox().get_middle().x > get_bbox().get_middle().x) ? LEFT : RIGHT;
+ bool countdown = false;
+
switch(contents) {
case CONTENT_COIN:
{
{
sector->add_object(new PowerUp(get_pos() + Vector(0, 32), "images/powerups/fireflower/fireflower.sprite"));
sound_manager->play("sounds/upgrade.wav");
+ countdown = true;
break;
}
{
sector->add_object(new PowerUp(get_pos() + Vector(0, 32), "images/powerups/iceflower/iceflower.sprite"));
sound_manager->play("sounds/upgrade.wav");
+ countdown = true;
+ break;
+ }
+
+ case CONTENT_STAR:
+ {
+ sector->add_object(new Star(get_pos() + Vector(0, 32), direction));
+ sound_manager->play("sounds/upgrade.wav");
+ countdown = true;
+ break;
+ }
+
+ case CONTENT_1UP:
+ {
+ sector->add_object(new OneUp(get_pos(), DOWN));
+ sound_manager->play("sounds/upgrade.wav");
+ countdown = true;
+ break;
+ }
+
+ case CONTENT_CUSTOM:
+ {
+ //NOTE: non-portable trampolines could be moved to CONTENT_CUSTOM, but they should not drop
+ object->set_pos(get_pos() + Vector(0, 32));
+ sector->add_object(object);
+ object = 0;
+ sound_manager->play("sounds/upgrade.wav");
+ countdown = true;
+ break;
+ }
+
+ case CONTENT_SCRIPT:
+ { break; } // because scripts always run, this prevents default contents from being assumed
+
+ case CONTENT_LIGHT:
+ {
+ try_open(player);
+ break;
+ }
+ case CONTENT_TRAMPOLINE:
+ {
+ try_open(player);
+ break;
+ }
+ case CONTENT_RAIN:
+ {
+ try_open(player);
break;
}
+
+ case CONTENT_STAR:
+ {
+ sector->add_object(new Star(get_pos() + Vector(0, 32), direction));
+ sound_manager->play("sounds/upgrade.wav");
+ break;
+ }
+
+ case CONTENT_1UP:
+ {
+ sector->add_object(new OneUp(get_pos(), DOWN));
+ sound_manager->play("sounds/upgrade.wav");
+ break;
+ }
+
+ case CONTENT_CUSTOM:
+ {
+ //TODO: non-portable trampolines could be moved to CONTENT_CUSTOM, but they should not drop
+ object->set_pos(get_pos() + Vector(0, 32));
+ sector->add_object(object);
+ object = 0;
+ sound_manager->play("sounds/upgrade.wav");
+ break;
+ }
+
+ case CONTENT_SCRIPT:
+ { break; } // because scripts always run, this prevents default contents from being assumed
+
+ case CONTENT_LIGHT:
+ {
+ try_open(player);
+ break;
+ }
+ case CONTENT_TRAMPOLINE:
+ {
+ try_open(player);
+ break;
+ }
+ case CONTENT_RAIN:
+ {
+ try_open(player);
+ break;
+ }
case CONTENT_EXPLODE:
{
hit_counter = 1; // multiple hits of coin explode is not allowed
Sector::current()->add_object(new CoinExplode(get_pos() + Vector (0, 40)));
sound_manager->play("sounds/upgrade.wav");
+ countdown = true;
break;
}
}
Sector::current()->run_script(stream, "powerup-script");
}
++<<<<<<< HEAD
+ if(countdown){ // only decrease hit counter if try_open was not called
+ if(hit_counter == 1){
+ sprite->set_action("empty");
+ }else{
+ hit_counter--;
+ }
++=======
+ if(hit_counter <= 0 || contents == CONTENT_LIGHT){ //use 0 to allow infinite hits
+ }else if(hit_counter == 1){
+ sprite->set_action("empty");
+ }else{
+ hit_counter--;
++>>>>>>> feature/sdl2
}
}
return;
state = STATE_EXPLODING;
- set_action("default", 1); //TODO: the less-threatening short_fuse explosion should look less-threatening
+ set_action(hurt ? "default" : "pop", 1);
sprite->set_animation_loops(1); //TODO: this is necessary because set_action will not set "loops" when "action" is the default action
- if (hurt)
- sound_manager->play("sounds/explosion.wav", get_pos());
- else
- sound_manager->play("sounds/firecracker.ogg", get_pos());
-
+ sprite->set_angle(graphicsRandom.randf(0, 360)); // a random rotation on the sprite to make explosions appear more random
- sound_manager->play(hurt ? "sounds/explosion.wav" : "sounds/firecracker.ogg", get_pos());
-
++ sound_manager->play(hurt ? "sounds/explosion.wav" : "sounds/firecracker.ogg", get_pos());
#if 0
// spawn some particles
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
+#include <math.h>
+
#include "audio/sound_manager.hpp"
#include "object/growup.hpp"
#include "object/player.hpp"
MovingSprite(Vector(0,0), "images/powerups/egg/egg.sprite", LAYER_OBJECTS, COLGROUP_MOVING),
physic(),
light(0.0f,0.0f,0.0f),
+ shadesprite(sprite_manager->create("images/powerups/egg/egg.sprite")),
lightsprite(sprite_manager->create("images/objects/lightmap_light/lightmap_light-small.sprite"))
{
physic.enable_gravity(true);
physic.set_velocity_x((direction == LEFT)?-100:100);
sound_manager->preload("sounds/grow.ogg");
+ //shadow to remain in place as egg rolls
+ shadesprite->set_action("shadow");
//set light for glow effect
lightsprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
lightsprite->set_color(Color(0.2f, 0.2f, 0.0f));
+
+ sprite->set_action((direction == LEFT) ? "left" : "right");
}
void
void
GrowUp::draw(DrawingContext& context){
+ //Set Sprite rotation angle
+ sprite->set_angle(get_pos().x * 360.0f / (32.0f * M_PI));
//Draw the Sprite.
MovingSprite::draw(context);
+ //Draw shade
+ shadesprite->draw(context, get_pos(), layer+1);
//Draw the light when dark
context.get_light( get_bbox().get_middle(), &light );
if (light.red + light.green < 2.0){
physic.set_velocity_y(0);
if(hit.bottom && physic.get_velocity_y() > 0)
physic.set_velocity_y(0);
- if(hit.left || hit.right)
+ if(hit.left || hit.right) {
physic.set_velocity_x(-physic.get_velocity_x());
+ if(hit.left)
+ sprite->set_action("right");
+ else {
+ sprite->set_action("left");
+ }
+
+ }
}
HitResponse
int version = 1;
level->get("version", version);
if(version == 1) {
- log_info << "level uses old format: version 1" << std::endl;
+ log_info << "[" << filepath << "] level uses old format: version 1" << std::endl;
tileset = tile_manager->get_tileset("images/tiles.strf");
load_old_format(*level);
return;
std::string tileset_name;
if(level->get("tileset", tileset_name)) {
if(tileset != NULL) {
- log_warning << "multiple tilesets specified in level" << std::endl;
+ log_warning << "[" << filepath << "] multiple tilesets specified in level" << std::endl;
} else {
tileset = tile_manager->get_tileset(tileset_name);
}
if(token == "version") {
iter.value()->get(version);
if(version > 2) {
- log_warning << "level format newer than application" << std::endl;
+ log_warning << "[" << filepath << "] level format newer than application" << std::endl;
}
} else if(token == "tileset" || token == "tilesets") {
continue;
} else if(token == "target-time") {
iter.value()->get(target_time);
} else {
- log_warning << "Unknown token '" << token << "' in level file" << std::endl;
+ log_warning << "[" << filepath << "] Unknown token '" << token << "' in level file" << std::endl;
}
}
if (license == "") {
- log_warning << "The level author \"" << author << "\" did not specify a license for this level \"" << name << "\". You might not be allowed to share it." << std::endl;
-
+ log_warning << "[" << filepath << "] The level author \"" << author << "\" did not specify a license for this level \"" << name << "\". You might not be allowed to share it." << std::endl;
-
}
} catch(std::exception& e) {
std::stringstream msg;
#include <binreloc.h>
#include <tinygettext/log.hpp>
#include <boost/format.hpp>
+ #include <stdio.h>
extern "C" {
#include <findlocale.h>
}
+ #include "video/renderer.hpp"
#include "supertux/main.hpp"
- #ifdef MACOSX
- namespace supertux_apple {
- # include <CoreFoundation/CoreFoundation.h>
- } // namespace supertux_apple
- #endif
-
#include "addon/addon_manager.hpp"
#include "audio/sound_manager.hpp"
#include "control/joystickkeyboardcontroller.hpp"
PHYSFS_addToSearchPath(writedir.c_str(), 0);
// when started from source dir...
- std::string dir = PHYSFS_getBaseDir();
+ char* base_path = SDL_GetBasePath();
+ std::string dir = base_path;
+ SDL_free(base_path);
+
if (dir[dir.length() - 1] != '/')
dir += "/";
dir += "data";
}
}
- #ifdef MACOSX
- {
- using namespace supertux_apple;
-
- // when started from Application file on Mac OS X...
- char path[PATH_MAX];
- CFBundleRef mainBundle = CFBundleGetMainBundle();
- if(mainBundle == 0)
- throw "Assertion failed: mainBundle != 0";
- CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
- if(mainBundleURL == 0)
- throw "Assertion failed: mainBundleURL != 0";
- CFStringRef pathStr = CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle);
- if(pathStr == 0)
- throw "Assertion failed: pathStr != 0";
- CFStringGetCString(pathStr, path, PATH_MAX, kCFStringEncodingUTF8);
- CFRelease(mainBundleURL);
- CFRelease(pathStr);
-
- dir = std::string(path) + "/Contents/Resources/data";
- testfname = dir + "/credits.txt";
- sourcedir = false;
- f = fopen(testfname.c_str(), "r");
- if(f) {
- fclose(f);
- if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) {
- log_warning << "Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
- } else {
- sourcedir = true;
- }
- }
- }
- #endif
-
- #ifdef _WIN32
- PHYSFS_addToSearchPath(".\\data", 1);
- #endif
-
if(!sourcedir) {
std::string datadir = PHYSFS_getBaseDir();
datadir = datadir.substr(0, datadir.rfind(INSTALL_SUBDIR_BIN));
g_config->window_size = Size(800, 600);
g_config->fullscreen_size = Size(800, 600);
+ g_config->fullscreen_refresh_rate = 0;
g_config->aspect_size = Size(0, 0); // auto detect
} else if(arg == "--window" || arg == "-w") {
{
g_config->window_size = Size(width, height);
g_config->fullscreen_size = Size(width, height);
+ g_config->fullscreen_refresh_rate = 0;
}
}
} else if(arg == "--aspect" || arg == "-a") {
g_config->start_level = arg;
} else {
log_warning << "Unknown option '" << arg << "'. Use --help to see a list of options" << std::endl;
- return true;
}
}
// just to be sure
atexit(SDL_Quit);
- SDL_EnableUNICODE(1);
+ // SDL_EnableUNICODE(1); //old code, mofif by giby
+ // SDL_JoystickID myID = SDL_JoystickInstanceID(myOpenedStick);
+
// wait 100ms and clear SDL event queue because sometimes we have random
// joystick events in the queue on startup...
void
Main::init_video()
{
- // FIXME: Add something here
- SCREEN_WIDTH = 800;
- SCREEN_HEIGHT = 600;
-
- context_pointer->init_renderer();
- g_screen = SDL_GetVideoSurface();
-
- SDL_WM_SetCaption(PACKAGE_NAME " " PACKAGE_VERSION, 0);
+ SDL_SetWindowTitle(Renderer::instance()->get_window(), PACKAGE_NAME " " PACKAGE_VERSION);
- // set icon
- #ifdef MACOSX
const char* icon_fname = "images/engine/icons/supertux-256x256.png";
- #else
- const char* icon_fname = "images/engine/icons/supertux.xpm";
- #endif
- SDL_Surface* icon;
- try {
- icon = IMG_Load_RW(get_physfs_SDLRWops(icon_fname), true);
- } catch (const std::runtime_error& err) {
- icon = 0;
- log_warning << "Couldn't load icon '" << icon_fname << "': " << err.what() << std::endl;
+ SDL_Surface* icon = IMG_Load_RW(get_physfs_SDLRWops(icon_fname), true);
+ if (!icon)
+ {
+ log_warning << "Couldn't load icon '" << icon_fname << "': " << SDL_GetError() << std::endl;
}
- if(icon != 0) {
- SDL_WM_SetIcon(icon, 0);
+ else
+ {
+ SDL_SetWindowIcon(Renderer::instance()->get_window(), icon);
SDL_FreeSurface(icon);
}
- else {
- log_warning << "Couldn't load icon '" << icon_fname << "'" << std::endl;
- }
-
SDL_ShowCursor(0);
log_info << (g_config->use_fullscreen?"fullscreen ":"window ")
<< " Window: " << g_config->window_size
- << " Fullscreen: " << g_config->fullscreen_size
+ << " Fullscreen: " << g_config->fullscreen_size << "@" << g_config->fullscreen_refresh_rate
<< " Area: " << g_config->aspect_size << std::endl;
}
return 0;
timelog("video");
- DrawingContext context;
+ std::auto_ptr<Renderer> renderer(VideoSystem::new_renderer());
+ std::auto_ptr<Lightmap> lightmap(VideoSystem::new_lightmap());
+ DrawingContext context(*renderer, *lightmap);
context_pointer = &context;
init_video();
// we have a normal path specified at commandline, not a physfs path.
// So we simply mount that path here...
std::string dir = FileSystem::dirname(g_config->start_level);
+ std::string fileProtocol = "file://";
+ int position = dir.find(fileProtocol);
+ if(position != std::string::npos) {
+ dir = dir.replace(position, fileProtocol.length(), "");
+ }
log_debug << "Adding dir: " << dir << std::endl;
PHYSFS_addToSearchPath(dir.c_str(), true);
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+ // Updated by GiBy 2013 for SDL2 <giby_the_kid@yahoo.fr>
//
// 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
#include <iomanip>
#include <iostream>
#include <physfs.h>
+ #include "SDL.h"
#include "supertux/gameconfig.hpp"
#include "supertux/globals.hpp"
#include "video/drawing_request.hpp"
#include "video/gl/gl_surface_data.hpp"
#include "video/gl/gl_texture.hpp"
+ #include "video/util.hpp"
+
#define LIGHTMAP_DIV 5
#ifdef GL_VERSION_ES_CM_1_0
#endif
GLRenderer::GLRenderer() :
- desktop_size(-1, -1),
- screen_size(-1, -1),
+ window(),
+ desktop_size(0, 0),
+ screen_size(0, 0),
fullscreen_active(false),
last_texture(static_cast<GLuint> (-1))
{
Renderer::instance_ = this;
- #if SDL_MAJOR_VERSION > 1 || SDL_MINOR_VERSION > 2 || (SDL_MINOR_VERSION == 2 && SDL_PATCHLEVEL >= 10)
- // unfortunately only newer SDLs have these infos.
- // This must be called before SDL_SetVideoMode() or it will return
- // the window size instead of the desktop size.
- const SDL_VideoInfo *info = SDL_GetVideoInfo();
- if (info)
- {
- desktop_size = Size(info->current_w, info->current_h);
- }
- #endif
+ SDL_DisplayMode mode;
+ SDL_GetCurrentDisplayMode(0, &mode);
+ desktop_size = Size(mode.w, mode.h);
if(texture_manager != 0)
texture_manager->save_textures();
- #ifdef SDL_GL_SWAP_CONTROL
- if(config->try_vsync) {
+ if(g_config->try_vsync) {
/* we want vsync for smooth scrolling */
- SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
+ if (SDL_GL_SetSwapInterval(-1) != 0)
+ {
+ log_info << "no support for late swap tearing vsync: " << SDL_GetError() << std::endl;
+ if (SDL_GL_SetSwapInterval(1))
+ {
+ log_info << "no support for vsync: " << SDL_GetError() << std::endl;
+ }
+ }
}
- #endif
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- // FIXME: 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);
// Init the projection matrix, viewport and stuff
apply_config();
-
+
if(texture_manager == 0)
texture_manager = new TextureManager();
else
texture_manager->reload_textures();
-
+
#ifndef GL_VERSION_ES_CM_1_0
GLenum err = glewInit();
if (GLEW_OK != err)
GLRenderer::~GLRenderer()
{
+ SDL_GL_DeleteContext(glcontext);
+ SDL_DestroyWindow(window);
}
void
void
GLRenderer::draw_gradient(const DrawingRequest& request)
{
- const GradientRequest* gradientrequest
+ const GradientRequest* gradientrequest
= (GradientRequest*) request.request_data;
const Color& top = gradientrequest->top;
const Color& bottom = gradientrequest->bottom;
glColor4f(fillrectrequest->color.red, fillrectrequest->color.green,
fillrectrequest->color.blue, fillrectrequest->color.alpha);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
+
if (fillrectrequest->radius != 0.0f)
{
// draw round rect
glDisable(GL_TEXTURE_2D);
glColor4f(ellipse->color.red, ellipse->color.green,
ellipse->color.blue, ellipse->color.alpha);
-
+
float x = request.pos.x;
float y = request.pos.y;
float w = ellipse->size.x/2.0f;
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
- glColor4f(1, 1, 1, 1);
+ glColor4f(1, 1, 1, 1);
}
- void
+ void
GLRenderer::do_take_screenshot()
{
// [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it?
SDL_Surface *shot_surf;
// create surface to hold screenshot
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0);
+ shot_surf = SDL_CreateRGBSurface(SDL_HWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0);
#else
- shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0);
+ shot_surf = SDL_CreateRGBSurface(SDL_HWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0);
#endif
if (!shot_surf) {
log_warning << "Could not create RGB Surface to contain screenshot" << std::endl;
GLRenderer::flip()
{
assert_gl("drawing");
- SDL_GL_SwapBuffers();
+ SDL_GL_SwapWindow(window);
}
void
GLRenderer::resize(int w, int h)
{
- // This causes the screen to go black, which is annoying, but seems
- // unavoidable with SDL at the moment
- SDL_SetVideoMode(w, h, 0, SDL_OPENGL | SDL_RESIZABLE);
-
g_config->window_size = Size(w, h);
apply_config();
void
GLRenderer::apply_config()
- {
- if (false)
- {
- log_info << "Applying Config:"
- << "\n Desktop: " << desktop_size.width << "x" << desktop_size.height
- << "\n Window: " << g_config->window_size
- << "\n FullRes: " << g_config->fullscreen_size
- << "\n Aspect: " << g_config->aspect_size
- << "\n Magnif: " << g_config->magnification
- << std::endl;
- }
-
- float target_aspect = static_cast<float>(desktop_size.width) / static_cast<float>(desktop_size.height);
- if (g_config->aspect_size != Size(0, 0))
- {
- target_aspect = float(g_config->aspect_size.width) / float(g_config->aspect_size.height);
- }
-
- float desktop_aspect = 4.0f / 3.0f; // random default fallback guess
- if (desktop_size.width != -1 && desktop_size.height != -1)
- {
- desktop_aspect = float(desktop_size.width) / float(desktop_size.height);
- }
-
- Size screen_size;
-
- // Get the screen width
- if (g_config->use_fullscreen)
- {
- screen_size = g_config->fullscreen_size;
- desktop_aspect = float(screen_size.width) / float(screen_size.height);
- }
- else
- {
- screen_size = g_config->window_size;
- }
-
+ {
apply_video_mode(screen_size, g_config->use_fullscreen);
- if (target_aspect > 1.0f)
+ Size target_size = g_config->use_fullscreen ?
+ g_config->fullscreen_size :
+ g_config->window_size;
+
+ float pixel_aspect_ratio = 1.0f;
+ if (g_config->aspect_size != Size(0, 0))
{
- SCREEN_WIDTH = static_cast<int>(screen_size.width * (target_aspect / desktop_aspect));
- SCREEN_HEIGHT = static_cast<int>(screen_size.height);
+ pixel_aspect_ratio = calculate_pixel_aspect_ratio(desktop_size,
+ g_config->aspect_size);
}
- else
+ else if (g_config->use_fullscreen)
{
- SCREEN_WIDTH = static_cast<int>(screen_size.width);
- SCREEN_HEIGHT = static_cast<int>(screen_size.height * (target_aspect / desktop_aspect));
+ pixel_aspect_ratio = calculate_pixel_aspect_ratio(desktop_size,
+ target_size);
}
Size max_size(1280, 800);
Size min_size(640, 480);
- if (g_config->magnification == 0.0f) // Magic value that means 'minfill'
- {
- // This scales SCREEN_WIDTH/SCREEN_HEIGHT so that they never excede
- // max_size.width/max_size.height resp. min_size.width/min_size.height
- if (SCREEN_WIDTH > max_size.width || SCREEN_HEIGHT > max_size.height)
- {
- float scale1 = float(max_size.width)/SCREEN_WIDTH;
- float scale2 = float(max_size.height)/SCREEN_HEIGHT;
- float scale = (scale1 < scale2) ? scale1 : scale2;
- SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH * scale);
- SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT * scale);
- }
- else if (SCREEN_WIDTH < min_size.width || SCREEN_HEIGHT < min_size.height)
- {
- float scale1 = float(min_size.width)/SCREEN_WIDTH;
- float scale2 = float(min_size.height)/SCREEN_HEIGHT;
- float scale = (scale1 < scale2) ? scale1 : scale2;
- SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH * scale);
- SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT * scale);
- }
-
-
- glViewport(0, 0, screen_size.width, screen_size.height);
- }
- else
- {
- SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH / g_config->magnification);
- SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT / g_config->magnification);
-
- // This works by adding black borders around the screen to limit
- // SCREEN_WIDTH/SCREEN_HEIGHT to max_size.width/max_size.height
- Size new_size = screen_size;
-
- if (SCREEN_WIDTH > max_size.width)
- {
- new_size.width = static_cast<int>((float) new_size.width * float(max_size.width)/SCREEN_WIDTH);
- SCREEN_WIDTH = static_cast<int>(max_size.width);
- }
+ Vector scale;
+ Size logical_size;
+ calculate_viewport(min_size, max_size, screen_size,
+ pixel_aspect_ratio,
+ g_config->magnification,
+ scale,
+ logical_size,
+ viewport);
- if (SCREEN_HEIGHT > max_size.height)
- {
- new_size.height = static_cast<int>((float) new_size.height * float(max_size.height)/SCREEN_HEIGHT);
- SCREEN_HEIGHT = static_cast<int>(max_size.height);
- }
+ SCREEN_WIDTH = logical_size.width;
+ SCREEN_HEIGHT = logical_size.height;
+ if (viewport.x != 0 || viewport.y != 0)
+ {
// Clear both buffers so that we get a clean black border without junk
glClear(GL_COLOR_BUFFER_BIT);
- SDL_GL_SwapBuffers();
+ SDL_GL_SwapWindow(window);
glClear(GL_COLOR_BUFFER_BIT);
- SDL_GL_SwapBuffers();
-
- glViewport(std::max(0, (screen_size.width - new_size.width) / 2),
- std::max(0, (screen_size.height - new_size.height) / 2),
- std::min(new_size.width, screen_size.width),
- std::min(new_size.height, screen_size.height));
+ SDL_GL_SwapWindow(window);
}
+ glViewport(viewport.x, viewport.y, viewport.w, viewport.h);
+
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
void
GLRenderer::apply_video_mode(const Size& size, bool fullscreen)
{
- // Only change video mode when its different from the current one
- if (screen_size != size || fullscreen_active != fullscreen)
+ if (window)
{
- int flags = SDL_OPENGL;
+ SDL_SetWindowSize(window, size.width, size.height);
if (fullscreen)
{
- flags |= SDL_FULLSCREEN;
+ SDL_DisplayMode mode;
+ mode.format = SDL_PIXELFORMAT_RGB888;
+ mode.w = g_config->fullscreen_size.width;
+ mode.h = g_config->fullscreen_size.height;
+ mode.refresh_rate = g_config->fullscreen_refresh_rate;
+ mode.driverdata = 0;
+
+ if (SDL_SetWindowDisplayMode(window, &mode) != 0)
+ {
+ log_warning << "failed to set display mode: "
+ << mode.w << "x" << mode.h << "@" << mode.refresh_rate << ": "
+ << SDL_GetError() << std::endl;
+ }
+ else
+ {
+ SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
+ }
}
else
{
- flags |= SDL_RESIZABLE;
+ SDL_SetWindowFullscreen(window, 0);
}
+ }
+ else
+ {
+ int flags = SDL_WINDOW_OPENGL;
- if (SDL_Surface *screen = SDL_SetVideoMode(size.width, size.height, 0, flags))
+ if (fullscreen)
{
- screen_size = Size(screen->w, screen->h);
- fullscreen_active = fullscreen;
+ flags |= SDL_WINDOW_FULLSCREEN;
}
else
{
+ flags |= SDL_WINDOW_RESIZABLE;
+ }
+
+ window = SDL_CreateWindow("SuperTux",
+ SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
+ size.width, size.height,
+ flags);
+ if (!window)
+ {
std::ostringstream msg;
msg << "Couldn't set video mode " << size.width << "x" << size.height << ": " << SDL_GetError();
throw std::runtime_error(msg.str());
}
+ else
+ {
+ glcontext = SDL_GL_CreateContext(window);
+ screen_size = size;
+
+ SCREEN_WIDTH = size.width;
+ SCREEN_HEIGHT = size.height;
+
+ fullscreen_active = fullscreen;
+ }
}
}
+ Vector
+ GLRenderer::to_logical(int physical_x, int physical_y)
+ {
+ return Vector(static_cast<float>(physical_x - viewport.x) * SCREEN_WIDTH / viewport.w,
+ static_cast<float>(physical_y - viewport.y) * SCREEN_HEIGHT / viewport.h);
+ }
+
+ void
+ GLRenderer::set_gamma(float gamma)
+ {
+ Uint16 ramp[256];
+ SDL_CalculateGammaRamp(gamma, ramp);
+ SDL_SetWindowGammaRamp(window, ramp, ramp, ramp);
+ }
+
/* EOF */
image_height = image->h;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- SDL_Surface* convert = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ SDL_Surface* convert = SDL_CreateRGBSurface(SDL_HWSURFACE,
texture_width, texture_height, 32,
0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
#else
- SDL_Surface* convert = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ SDL_Surface* convert = SDL_CreateRGBSurface(SDL_HWSURFACE,
texture_width, texture_height, 32,
0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
#endif
throw std::runtime_error("Couldn't create texture: out of memory");
}
- SDL_SetAlpha(image, 0, 0);
+ SDL_SetSurfaceBlendMode(image, SDL_BLENDMODE_NONE);
SDL_BlitSurface(image, 0, convert, 0);
assert_gl("before creating texture");
SDL_LockSurface(convert);
}
- if (true)
- { // no not use mipmaps
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width,
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width,
texture_height, 0, sdl_format,
GL_UNSIGNED_BYTE, convert->pixels);
- }
- else
- { // build mipmaps
- gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, texture_width,
- texture_height, sdl_format,
- GL_UNSIGNED_BYTE, convert->pixels);
+
+ // no not use mipmaps
+ if(false)
+ {
+ glGenerateMipmap(GL_TEXTURE_2D);
}
if(SDL_MUSTLOCK(convert))
throw std::runtime_error("SDL_CreateRGBSurfaceFrom() call failed");
}
- if (image->format->palette)
+ /* if (image->format->palette)
{ // copy the image palette to subimage if present
- SDL_SetColors(subimage.get(), image->format->palette->colors, 0, image->format->palette->ncolors);
- }
+ SDL_SetSurfacePalette(subimage.get(), image->format->palette->colors); //edited by giby
+ } */
return VideoSystem::new_texture(subimage.get());
}
}
else
{
- return VideoSystem::new_texture(image.get());
+ TexturePtr texture = VideoSystem::new_texture(image.get());
+ image.reset(NULL);
+ return texture;
}
}
else
{
log_warning << "Couldn't load texture '" << dummy_texture_fname << "' (now using empty one): " << err.what() << std::endl;
- return VideoSystem::new_texture(image.get());
+ TexturePtr texture = VideoSystem::new_texture(image.get());
+ image.reset(NULL);
+ return texture;
}
}
}
WorldMap::WorldMap(const std::string& filename, PlayerStatus* player_status, const std::string& force_spawnpoint) :
tux(0),
player_status(player_status),
- tileset(NULL),
+ tileset(NULL),
free_tileset(false),
worldmap_menu(),
camera_offset(),
total_stats(),
worldmap_table(),
scripts(),
- ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ),
+ ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ),
force_spawnpoint(force_spawnpoint),
- in_level(false),
+ in_level(false),
pan_pos(),
panning(false)
{
sq_pop(global_vm, 1);
sound_manager->preload("sounds/warp.wav");
-
+
// load worldmap objects
load(filename);
}
void
WorldMap::get_level_target_time(LevelTile& level)
{
+ if(last_position == tux->get_tile_pos()) {
+ level.target_time = last_target_time;
+ return;
+ }
+
try {
lisp::Parser parser;
const lisp::Lisp* root = parser.parse(levels_path + level.get_name());
return;
level_lisp->get("target-time", level.target_time);
+
+ last_position = level.pos;
+ last_target_time = level.target_time;
++
} catch(std::exception& e) {
log_warning << "Problem when reading level target time: " << e.what() << std::endl;
return;
LevelTile* level = at_level();
if (level && (level->auto_play) && (!level->solved) && (!tux->is_moving())) {
enter_level = true;
+ // automatically mark these levels as solved in case player aborts
+ level->solved = true;
}
if (enter_level && !tux->is_moving())
/*
// FIXME: make this a runtime switch similar to draw_collrects/show_collrects?
// draw visual indication of possible walk directions
- static int flipme = 0;
+ static int flipme = 0;
if (flipme++ & 0x04)
for (int x = 0; x < get_width(); x++) {
for (int y = 0; y < get_height(); y++) {