Merge branch 'feature/sdl2'
authorIngo Ruhnke <grumbel@gmail.com>
Sun, 3 Aug 2014 03:44:02 +0000 (05:44 +0200)
committerIngo Ruhnke <grumbel@gmail.com>
Sun, 3 Aug 2014 03:44:02 +0000 (05:44 +0200)
Conflicts:
.gitignore
WHATSNEW.txt
data/fonts/zh-white-big.stf
data/fonts/zh-white.stf
data/images/engine/fonts/zh/shadow.png
data/images/engine/fonts/zh/white.png
data/images/powerups/egg/egg.sprite
data/images/tiles.strf
data/levels/bonus1/az.po
data/levels/bonus1/ne.po
data/levels/bonus1/sv.po
data/levels/bonus2/az.po
data/levels/bonus2/pt_BR.po
data/levels/incubator/az.po
data/levels/incubator/de.po
data/levels/incubator/nn.po
data/levels/incubator/pt_BR.po
data/levels/incubator/ru.po
data/levels/incubator/sv.po
data/levels/incubator/worldmap.stwm
data/levels/world1/ar.po
data/levels/world1/az.po
data/levels/world1/be.po
data/levels/world1/ca.po
data/levels/world1/cmn.po
data/levels/world1/cs.po
data/levels/world1/da.po
data/levels/world1/de.po
data/levels/world1/el.po
data/levels/world1/eo.po
data/levels/world1/es.po
data/levels/world1/et.po
data/levels/world1/fi.po
data/levels/world1/fr.po
data/levels/world1/hi_IN.po
data/levels/world1/hr.po
data/levels/world1/hu.po
data/levels/world1/it.po
data/levels/world1/ja.po
data/levels/world1/lt.po
data/levels/world1/nb.po
data/levels/world1/ne.po
data/levels/world1/nl.po
data/levels/world1/nn.po
data/levels/world1/pl.po
data/levels/world1/pt.po
data/levels/world1/pt_BR.po
data/levels/world1/ro.po
data/levels/world1/ru.po
data/levels/world1/sl.po
data/levels/world1/sv.po
data/levels/world1/tr.po
data/levels/world1/uk.po
data/levels/world1/uz.po
data/levels/world1/vi.po
data/levels/world1/zh_CN.po
data/levels/world1/zh_TW.po
data/levels/world2/az.po
data/levels/world2/cs.po
data/levels/world2/de.po
data/levels/world2/hu.po
data/levels/world2/nn.po
data/levels/world2/pt_BR.po
data/levels/world2/sv.po
data/locale/ar.po
data/locale/az.po
data/locale/be.po
data/locale/ca.po
data/locale/cmn.po
data/locale/cs.po
data/locale/da.po
data/locale/de.po
data/locale/el.po
data/locale/eo.po
data/locale/es.po
data/locale/et.po
data/locale/fi.po
data/locale/fr.po
data/locale/hi_IN.po
data/locale/hr.po
data/locale/hu.po
data/locale/it.po
data/locale/ja.po
data/locale/lt.po
data/locale/nb.po
data/locale/ne.po
data/locale/nl.po
data/locale/nn.po
data/locale/pl.po
data/locale/pt.po
data/locale/pt_BR.po
data/locale/ro.po
data/locale/ru.po
data/locale/sl.po
data/locale/sv.po
data/locale/tr.po
data/locale/uk.po
data/locale/uz.po
data/locale/vi.po
data/locale/zh_CN.po
data/locale/zh_TW.po
external/squirrel/squirrel/sqdebug.cpp
src/object/bonus_block.cpp
src/object/explosion.cpp
src/object/player.cpp
src/supertux/game_session.cpp
src/supertux/level.cpp
src/supertux/main.cpp
src/supertux/resources.cpp
src/video/sdl/sdl_renderer.cpp
src/worldmap/worldmap.cpp

1  2 
CMakeLists.txt
data/images/powerups/egg/egg-0.png
src/object/bonus_block.cpp
src/object/explosion.cpp
src/object/growup.cpp
src/supertux/level.cpp
src/supertux/main.cpp
src/video/gl/gl_renderer.cpp
src/video/gl/gl_texture.cpp
src/video/texture_manager.cpp
src/worldmap/worldmap.cpp

diff --combined CMakeLists.txt
@@@ -66,12 -66,18 +66,18 @@@ FIND_PACKAGE(Boost REQUIRED
  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)
@@@ -234,7 -240,7 +240,7 @@@ IF(CMAKE_COMPILER_IS_GNUCC
    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)
@@@ -395,7 -401,7 +401,7 @@@ ENDIF(WIN32 AND NOT UNIX
  
  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})
  
@@@ -431,7 -437,7 +437,7 @@@ SET(CPACK_RPM_PACKAGE_GROUP "Amusements
  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")
index 0000000,6f63e35..8d6105f
mode 000000,100644..100644
Binary files differ
@@@ -41,7 -41,7 +41,7 @@@
  #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),
@@@ -55,8 -55,8 +55,8 @@@
      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;
@@@ -66,7 -66,7 +66,7 @@@
        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;
@@@ -352,8 -352,6 +352,8 @@@ BonusBlock::try_drop(Player *player
  
    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
    }
  }
  
diff --combined src/object/explosion.cpp
@@@ -65,11 -65,13 +65,10 @@@ Explosion::explode(
      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
diff --combined src/object/growup.cpp
@@@ -14,8 -14,6 +14,8 @@@
  //  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"
@@@ -26,17 -24,16 +26,19 @@@ GrowUp::GrowUp(Direction direction) 
    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
@@@ -47,12 -44,8 +49,12 @@@ GrowUp::update(float elapsed_time
  
  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){
@@@ -70,8 -63,15 +72,15 @@@ GrowUp::collision_solid(const Collision
      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
diff --combined src/supertux/level.cpp
@@@ -69,7 -69,7 +69,7 @@@ Level::load(const std::string& filepath
      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;
@@@ -83,7 -83,7 +83,7 @@@
      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;
diff --combined src/supertux/main.cpp
  #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"
@@@ -147,7 -143,10 +143,10 @@@ Main::init_physfs(const char* argv0
    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));
@@@ -317,6 -278,7 +278,7 @@@ Main::parse_commandline(int argc, char*
        
        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;
      }
    }
  
@@@ -435,7 -399,9 +398,9 @@@ Main::init_sdl(
    // 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...
@@@ -459,41 -425,24 +424,24 @@@ Main::init_rand(
  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;
  }
  
@@@ -598,7 -547,9 +546,9 @@@ Main::run(int argc, char** argv
        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);
  
@@@ -1,5 -1,6 +1,6 @@@
  //  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
@@@ -187,7 -191,7 +191,7 @@@ GLRenderer::draw_surface_part(const Dra
  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;
@@@ -231,7 -235,7 +235,7 @@@ GLRenderer::draw_filled_rect(const Draw
    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
@@@ -309,7 -313,7 +313,7 @@@ GLRenderer::draw_inverse_ellipse(const 
    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;
@@@ -454,16 -458,12 +458,12 @@@ voi
  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 */
@@@ -93,11 -93,11 +93,11 @@@ GLTexture::GLTexture(SDL_Surface* image
    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))
@@@ -158,10 -158,10 +158,10 @@@ TextureManager::create_image_texture_ra
      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());
  }
@@@ -192,9 -192,7 +192,9 @@@ TextureManager::create_image_texture_ra
    }
    else
    {
 -    return VideoSystem::new_texture(image.get());
 +    TexturePtr texture = VideoSystem::new_texture(image.get());
 +    image.reset(NULL);
 +    return texture;
    }
  }
  
@@@ -221,9 -219,7 +221,9 @@@ TextureManager::create_dummy_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;
      }
    }
  }
@@@ -80,7 -80,7 +80,7 @@@ WorldMap* WorldMap::current_ = NULL
  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);
  }
@@@ -367,11 -367,6 +367,11 @@@ WorldMap::get_level_title(LevelTile& le
  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;
@@@ -677,8 -669,6 +678,8 @@@ WorldMap::update(float delta
      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())
@@@ -813,7 -803,7 +814,7 @@@ WorldMap::draw(DrawingContext& context
    /*
    // 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++) {