diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9a9dde2..c7e2aad 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -186,7 +186,9 @@ ENDIF(MSVC)
FILE(GLOB SUPERTUX_SOURCES_C RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} external/obstack/*.c external/findlocale/findlocale.c)
-FILE(GLOB SUPERTUX_SOURCES_CXX RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} src/main.cpp src/*/*.cpp src/supertux/menu/*.cpp src/video/sdl/*.cpp)
+FILE(GLOB SUPERTUX_SOURCES_CXX RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} src/main.cpp src/*/*.cpp src/supertux/menu/*.cpp)
+
+LIST(REMOVE_ITEM SUPERTUX_SOURCES_CXX src/control//game_controller_manager.cpp src/control//joystick_manager.cpp)
FILE(GLOB TINYGETTEXT_SOURCES_CXX RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} external/tinygettext/src/*.cpp)
SET_SOURCE_FILES_PROPERTIES(${TINYGETTEXT_SOURCES_CXX} PROPERTIES COMPILE_DEFINITIONS HAVE_SDL)
diff --git a/configure b/configure
index b728243..75a4bb4 100755
--- a/configure
+++ b/configure
@@ -6,4 +6,4 @@ set -e
mkdir -p build
cd build
cmake .. "$@"
-
+make -j8
diff --git a/src/control/controller.cpp b/src/control/controller.cpp
index 49996e2..6ad4ed8 100644
--- a/src/control/controller.cpp
+++ b/src/control/controller.cpp
@@ -16,6 +16,9 @@
#include "control/controller.hpp"
+#include "video/renderer.hpp"
+#include "video/video_system.hpp"
+
const char* Controller::controlNames[] = {
"left",
"right",
@@ -51,6 +54,8 @@ Controller::reset()
controls[i] = false;
oldControls[i] = false;
}
+ mousePressed = false;
+ mousePos = Vector(0,0);
}
void
@@ -84,4 +89,23 @@ Controller::update()
oldControls[i] = controls[i];
}
+bool
+Controller::mouse_pressed() const
+{
+ return mousePressed;
+}
+
+Vector
+Controller::mouse_pos() const
+{
+ return mousePos;
+}
+
+void
+Controller::set_mouse(int x, int y, bool pressed)
+{
+ mousePressed = pressed;
+ mousePos = VideoSystem::current()->get_renderer().to_logical(x, y);
+}
+
/* EOF */
diff --git a/src/control/controller.hpp b/src/control/controller.hpp
index 210159d..eba103a 100644
--- a/src/control/controller.hpp
+++ b/src/control/controller.hpp
@@ -17,6 +17,8 @@
#ifndef HEADER_SUPERTUX_CONTROL_CONTROLLER_HPP
#define HEADER_SUPERTUX_CONTROL_CONTROLLER_HPP
+#include "math/vector.hpp"
+
class Controller
{
public:
@@ -58,6 +60,10 @@ public:
/** returns true if the control has just been released this frame */
bool released(Control control) const;
+ bool mouse_pressed() const;
+ Vector mouse_pos() const;
+ void set_mouse(int x, int y, bool pressed);
+
virtual void reset();
virtual void update();
@@ -66,6 +72,8 @@ protected:
bool controls[CONTROLCOUNT];
/** control status at last frame */
bool oldControls[CONTROLCOUNT];
+ bool mousePressed;
+ Vector mousePos;
};
#endif
diff --git a/src/control/game_controller_manager.cpp b/src/control/game_controller_manager.cpp
index 6680c04..401eacc 100644
--- a/src/control/game_controller_manager.cpp
+++ b/src/control/game_controller_manager.cpp
@@ -13,7 +13,6 @@
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-
#include "control/game_controller_manager.hpp"
#include
diff --git a/src/control/input_manager.cpp b/src/control/input_manager.cpp
index ce612d4..2ab1d85 100644
--- a/src/control/input_manager.cpp
+++ b/src/control/input_manager.cpp
@@ -19,8 +19,8 @@
#include
-#include "control/game_controller_manager.hpp"
-#include "control/joystick_manager.hpp"
+//#include "control/game_controller_manager.hpp"
+//#include "control/joystick_manager.hpp"
#include "control/keyboard_manager.hpp"
#include "gui/menu_manager.hpp"
#include "lisp/list_iterator.hpp"
@@ -33,9 +33,9 @@ InputManager::InputManager(KeyboardConfig& keyboard_config,
JoystickConfig& joystick_config) :
controller(new Controller),
m_use_game_controller(true),
- keyboard_manager(new KeyboardManager(this, keyboard_config)),
- joystick_manager(new JoystickManager(this, joystick_config)),
- game_controller_manager(new GameControllerManager(this))
+ keyboard_manager(new KeyboardManager(this, keyboard_config))
+ //joystick_manager(new JoystickManager(this, joystick_config)),
+ //game_controller_manager(new GameControllerManager(this))
{
}
@@ -71,15 +71,25 @@ void
InputManager::process_event(const SDL_Event& event)
{
switch(event.type) {
- case SDL_TEXTINPUT:
- keyboard_manager->process_text_input_event(event.text);
- break;
+ //case SDL_TEXTINPUT:
+ // keyboard_manager->process_text_input_event(event.text);
+ // break;
case SDL_KEYUP:
case SDL_KEYDOWN:
keyboard_manager->process_key_event(event.key);
break;
+ case SDL_MOUSEBUTTONDOWN:
+ case SDL_MOUSEBUTTONUP:
+ keyboard_manager->process_mouse_event(event.button);
+ break;
+
+ case SDL_MOUSEMOTION:
+ keyboard_manager->process_mouse_event(event.motion);
+ break;
+
+#if 0
case SDL_JOYAXISMOTION:
if (!m_use_game_controller) joystick_manager->process_axis_event(event.jaxis);
break;
@@ -126,7 +136,7 @@ InputManager::process_event(const SDL_Event& event)
case SDL_CONTROLLERDEVICEREMAPPED:
log_debug << "SDL_CONTROLLERDEVICEREMAPPED" << std::endl;
break;
-
+#endif
default:
break;
}
diff --git a/src/control/input_manager.hpp b/src/control/input_manager.hpp
index d047e53..a87decd 100644
--- a/src/control/input_manager.hpp
+++ b/src/control/input_manager.hpp
@@ -68,8 +68,8 @@ private:
public:
bool m_use_game_controller;
std::unique_ptr keyboard_manager;
- std::unique_ptr joystick_manager;
- std::unique_ptr game_controller_manager;
+ //std::unique_ptr joystick_manager;
+ //std::unique_ptr game_controller_manager;
private:
InputManager(const InputManager&);
diff --git a/src/control/keyboard_config.hpp b/src/control/keyboard_config.hpp
index e848067..fe1b785 100644
--- a/src/control/keyboard_config.hpp
+++ b/src/control/keyboard_config.hpp
@@ -25,6 +25,8 @@
#include "util/writer.hpp"
+typedef SDLKey SDL_Keycode;
+
class KeyboardConfig
{
public:
diff --git a/src/control/keyboard_manager.cpp b/src/control/keyboard_manager.cpp
index ca4e461..cf67877 100644
--- a/src/control/keyboard_manager.cpp
+++ b/src/control/keyboard_manager.cpp
@@ -18,7 +18,7 @@
#include "control/keyboard_manager.hpp"
#include "control/controller.hpp"
-#include "control/joystick_manager.hpp"
+//#include "control/joystick_manager.hpp"
#include "control/keyboard_config.hpp"
#include "gui/menu_manager.hpp"
#include "lisp/list_iterator.hpp"
@@ -81,6 +81,7 @@ KeyboardManager::process_key_event(const SDL_KeyboardEvent& event)
}
}
+#if 0
void
KeyboardManager::process_text_input_event(const SDL_TextInputEvent& event)
{
@@ -91,6 +92,7 @@ KeyboardManager::process_text_input_event(const SDL_TextInputEvent& event)
}
}
}
+#endif
void
KeyboardManager::process_console_key_event(const SDL_KeyboardEvent& event)
@@ -156,6 +158,7 @@ KeyboardManager::process_menu_key_event(const SDL_KeyboardEvent& event)
return;
}
+#if 0
if (m_parent->joystick_manager->wait_for_joystick >= 0)
{
if (event.keysym.sym == SDLK_ESCAPE)
@@ -166,6 +169,7 @@ KeyboardManager::process_menu_key_event(const SDL_KeyboardEvent& event)
}
return;
}
+#endif
Controller::Control control;
/* we use default keys when the menu is open (to avoid problems when
@@ -209,4 +213,18 @@ KeyboardManager::bind_next_event_to(Controller::Control id)
wait_for_key = id;
}
+void
+KeyboardManager::process_mouse_event(const SDL_MouseMotionEvent& event)
+{
+ m_parent->get_controller()->set_mouse(event.x, event.y, event.state & SDL_BUTTON_LMASK);
+}
+
+void
+KeyboardManager::process_mouse_event(const SDL_MouseButtonEvent& event)
+{
+ if (event.button != SDL_BUTTON_LEFT)
+ return;
+ m_parent->get_controller()->set_mouse(event.x, event.y, event.state == SDL_PRESSED);
+}
+
/* EOF */
diff --git a/src/control/keyboard_manager.hpp b/src/control/keyboard_manager.hpp
index 07885f9..ae02e33 100644
--- a/src/control/keyboard_manager.hpp
+++ b/src/control/keyboard_manager.hpp
@@ -41,10 +41,13 @@ public:
~KeyboardManager();
void process_key_event(const SDL_KeyboardEvent& event);
- void process_text_input_event(const SDL_TextInputEvent& event);
+ //void process_text_input_event(const SDL_TextInputEvent& event);
void process_console_key_event(const SDL_KeyboardEvent& event);
void process_menu_key_event(const SDL_KeyboardEvent& event);
+ void process_mouse_event(const SDL_MouseMotionEvent& event);
+ void process_mouse_event(const SDL_MouseButtonEvent& event);
+
void bind_next_event_to(Controller::Control id);
private:
diff --git a/src/gui/dialog.cpp b/src/gui/dialog.cpp
index e536c9c..55602c0 100644
--- a/src/gui/dialog.cpp
+++ b/src/gui/dialog.cpp
@@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+#include
+
#include "gui/dialog.hpp"
#include "control/controller.hpp"
diff --git a/src/gui/menu.cpp b/src/gui/menu.cpp
index fd253e9..adc20ce 100644
--- a/src/gui/menu.cpp
+++ b/src/gui/menu.cpp
@@ -625,7 +625,9 @@ Menu::get_item_by_id(int id)
}
}
- throw std::runtime_error("MenuItem not found: " + std::to_string(id));
+ char c[32];
+ sprintf(c, "%d", id);
+ throw std::runtime_error(std::string("MenuItem not found: ") + c);
}
const MenuItem&
diff --git a/src/object/player.cpp b/src/object/player.cpp
index c2bfb0e..f7ddd22 100644
--- a/src/object/player.cpp
+++ b/src/object/player.cpp
@@ -148,6 +148,7 @@ Player::Player(PlayerStatus* _player_status, const std::string& name_) :
grabbed_object(NULL),
sprite(),
airarrow(),
+ jumparrow(),
floor_normal(),
ghost_mode(false),
edit_mode(false),
@@ -164,6 +165,7 @@ Player::Player(PlayerStatus* _player_status, const std::string& name_) :
// constructor
sprite = SpriteManager::current()->create("images/creatures/tux/tux.sprite");
airarrow = Surface::create("images/engine/hud/airarrow.png");
+ jumparrow = Surface::create("images/engine/menu/scroll-down.png");
idle_timer.start(IDLE_TIME[0]/1000.0f);
SoundManager::current()->preload("sounds/bigjump.wav");
@@ -223,6 +225,12 @@ Player::init()
climbing = 0;
+ jump_helper = false;
+ jump_helper_draw = false;
+ jump_helper_jump = false;
+ jump_helper_move_left = false;
+ jump_helper_move_right = false;
+
physic.reset();
}
@@ -494,12 +502,14 @@ Player::handle_horizontal_input()
float dirsign = 0;
if(!duck || physic.get_velocity_y() != 0) {
- if(controller->hold(Controller::LEFT) && !controller->hold(Controller::RIGHT)) {
+ if((controller->hold(Controller::LEFT) && !controller->hold(Controller::RIGHT))
+ || jump_helper_move_left) {
old_dir = dir;
dir = LEFT;
dirsign = -1;
- } else if(!controller->hold(Controller::LEFT)
- && controller->hold(Controller::RIGHT)) {
+ } else if((!controller->hold(Controller::LEFT)
+ && controller->hold(Controller::RIGHT))
+ || jump_helper_move_right) {
old_dir = dir;
dir = RIGHT;
dirsign = 1;
@@ -691,7 +701,7 @@ Player::handle_vertical_input()
{
// Press jump key
if(controller->pressed(Controller::JUMP)) jump_button_timer.start(JUMP_GRACE_TIME);
- if(controller->hold(Controller::JUMP) && jump_button_timer.started() && can_jump) {
+ if (((controller->hold(Controller::JUMP) && jump_button_timer.started()) || jump_helper_jump) && can_jump) {
jump_button_timer.stop();
if (duck) {
// when running, only jump a little bit; else do a backflip
@@ -711,7 +721,7 @@ Player::handle_vertical_input()
}
}
// Let go of jump key
- else if(!controller->hold(Controller::JUMP)) {
+ else if(!(controller->hold(Controller::JUMP) || jump_helper_jump)) {
if (!backflipping && jumping && physic.get_velocity_y() < 0) {
jumping = false;
early_jump_apex();
@@ -789,6 +799,8 @@ Player::handle_input()
/* Handle vertical movement: */
handle_vertical_input();
+ handle_jump_helper();
+
/* Shoot! */
if (controller->pressed(Controller::ACTION) && (player_status->bonus == FIRE_BONUS || player_status->bonus == ICE_BONUS)) {
if(Sector::current()->add_bullet(
@@ -1068,6 +1080,13 @@ Player::draw(DrawingContext& context)
context.draw_surface(airarrow, Vector(px, py), LAYER_HUD - 1);
}
+ // Show where Tux will land after using jump helper
+ if (jump_helper_draw && Sector::current() && Sector::current()->camera) {
+ float px = jump_helper_x + (get_bbox().p2.x - get_bbox().p1.x) / 2 - jumparrow.get()->get_width() / 2;
+ float py = get_bbox().p2.y - jumparrow.get()->get_height();
+ context.draw_surface(jumparrow, Vector(px, py), LAYER_HUD - 1);
+ }
+
std::string sa_prefix = "";
std::string sa_postfix = "";
@@ -1582,4 +1601,65 @@ Player::handle_input_climbing()
physic.set_acceleration(0, 0);
}
+void
+Player::handle_jump_helper()
+{
+ if (!Sector::current() || !Sector::current()->camera)
+ return;
+
+ if (controller->mouse_pressed() && can_jump && !jump_helper)
+ { // Select a target to jump
+ jump_helper_draw = true;
+ jump_helper_x = controller->mouse_pos().x + Sector::current()->camera->get_translation().x;
+ }
+
+ if (!controller->mouse_pressed() && can_jump && !jump_helper && jump_helper_draw)
+ { // Initiate the jump
+ jump_helper = true;
+ jump_helper_x = controller->mouse_pos().x + Sector::current()->camera->get_translation().x;
+ // Do not use scriptiong controller - we need to be able to cancel jump helper mid-jump
+ jump_helper_move_left = false;
+ jump_helper_move_right = false;
+ if (jump_helper_x > get_pos().x)
+ jump_helper_move_right = true;
+ else
+ jump_helper_move_left = true;
+ }
+
+ if (jump_helper)
+ {
+ float friction = WALK_ACCELERATION_X * (on_ice ? ICE_FRICTION_MULTIPLIER : NORMAL_FRICTION_MULTIPLIER);
+ float frictionDistance = physic.get_velocity_x() * physic.get_velocity_x() / friction / 2.0f;
+ if (!jump_helper_jump)
+ { // Start running before jump for long jumps
+ float gravity = Sector::current()->get_gravity();
+ float jumpSpeed = fabs(physic.get_velocity_x()) > MAX_WALK_XM ? 580 : 520;
+ float jumpTime = jumpSpeed / gravity * 2.0f;
+ float maxRunSpeed = speedlimit > 0 ? speedlimit : MAX_RUN_XM;
+ float actualJumpDistance = fabs(physic.get_velocity_x()) * jumpTime / 100.0f;
+ float maxJumpDistance = maxRunSpeed * jumpTime / 100.0f;
+ // Check if we can jump that far at current speed, compensate a bit for velocity we'll gain in the air
+ // Empirical coefficients, we should use WALK_ACCELERATION_X / RUN_ACCELERATION_X here
+ if (fabs(jump_helper_x - get_pos().x) <= actualJumpDistance * 0.4f + maxJumpDistance * 0.6f)
+ jump_helper_jump = true;
+ // Check if we can jump that far without running first
+ if (fabs(jump_helper_x - get_pos().x) <= maxJumpDistance * 0.75f)
+ jump_helper_jump = true;
+ }
+ if (controller->mouse_pressed() // Cancel a jump if user presses any button
+ || controller->pressed(Controller::JUMP) || controller->pressed(Controller::ACTION)
+ || controller->pressed(Controller::DOWN) || controller->pressed(Controller::UP)
+ || controller->pressed(Controller::LEFT) || controller->pressed(Controller::RIGHT)
+ || (jump_helper_x >= get_pos().x - frictionDistance && jump_helper_move_left) // Reached destination - finish the jump
+ || (jump_helper_x <= get_pos().x + frictionDistance && jump_helper_move_right))
+ {
+ jump_helper = false;
+ jump_helper_draw = false;
+ jump_helper_jump = false;
+ jump_helper_move_left = false;
+ jump_helper_move_right = false;
+ }
+ }
+}
+
/* EOF */
diff --git a/src/object/player.hpp b/src/object/player.hpp
index 3dda1fd..7e57676 100644
--- a/src/object/player.hpp
+++ b/src/object/player.hpp
@@ -244,6 +244,7 @@ private:
void handle_horizontal_input();
void handle_vertical_input();
+ void handle_jump_helper();
void activate();
void deactivate();
@@ -314,6 +315,15 @@ public:
SurfacePtr airarrow; /**< arrow indicating Tux' position when he's above the camera */
+
+ SurfacePtr jumparrow; /**< arrow indicating wherer Tux' will jump */
+ bool jump_helper; /**< Jump helper for touchscreens to perform precise jumps */
+ bool jump_helper_jump;
+ bool jump_helper_move_left;
+ bool jump_helper_move_right;
+ bool jump_helper_draw;
+ float jump_helper_x;
+
Vector floor_normal;
void position_grabbed_object();
void try_grab();
diff --git a/src/physfs/physfs_sdl.cpp b/src/physfs/physfs_sdl.cpp
index 277f993..356dae0 100644
--- a/src/physfs/physfs_sdl.cpp
+++ b/src/physfs/physfs_sdl.cpp
@@ -24,7 +24,7 @@
#include "util/log.hpp"
-static Sint64 funcSeek(struct SDL_RWops* context, Sint64 offset, int whence)
+static int funcSeek(struct SDL_RWops* context, int offset, int whence)
{
PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
int res;
@@ -51,7 +51,7 @@ static Sint64 funcSeek(struct SDL_RWops* context, Sint64 offset, int whence)
return (int) PHYSFS_tell(file);
}
-static size_t funcRead(struct SDL_RWops* context, void* ptr, size_t size, size_t maxnum)
+static int funcRead(struct SDL_RWops* context, void* ptr, int size, int maxnum)
{
PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
diff --git a/src/supertux/gameconfig.cpp b/src/supertux/gameconfig.cpp
index c7d7778..9949e92 100644
--- a/src/supertux/gameconfig.cpp
+++ b/src/supertux/gameconfig.cpp
@@ -34,7 +34,7 @@ Config::Config() :
window_size(1280, 800),
aspect_size(0, 0), // auto detect
magnification(0.0f),
- use_fullscreen(false),
+ use_fullscreen(true),
video(VideoSystem::AUTO_VIDEO),
try_vsync(true),
show_fps(false),
diff --git a/src/supertux/main.cpp b/src/supertux/main.cpp
index 1cfba9c..f453266 100644
--- a/src/supertux/main.cpp
+++ b/src/supertux/main.cpp
@@ -20,6 +20,9 @@
#include
#include
+#include
+#include
+#include
#include
#include
#include
@@ -128,7 +131,7 @@ public:
if (!PHYSFS_init(argv0))
{
std::stringstream msg;
- msg << "Couldn't initialize physfs: " << PHYSFS_getLastError();
+ msg << "Couldn't initialize physfs: " << PHYSFS_getLastError() << " argv0: " << argv0;
throw std::runtime_error(msg.str());
}
else
@@ -143,36 +146,9 @@ public:
void find_datadir()
{
- std::string datadir;
- if (m_forced_datadir)
+ if (!PHYSFS_addToSearchPath("data.zip", 1))
{
- datadir = *m_forced_datadir;
- }
- else if (const char* env_datadir = getenv("SUPERTUX2_DATA_DIR"))
- {
- datadir = env_datadir;
- }
- else
- {
- // check if we run from source dir
- char* basepath_c = SDL_GetBasePath();
- std::string basepath = basepath_c;
- SDL_free(basepath_c);
-
- datadir = FileSystem::join(basepath, "data");
- std::string testfname = FileSystem::join(datadir, "credits.txt");
- if (!FileSystem::exists(testfname))
- {
- // if the game is not run from the source directory, try to find
- // the global install location
- datadir = datadir.substr(0, datadir.rfind(INSTALL_SUBDIR_BIN));
- datadir = FileSystem::join(datadir, INSTALL_SUBDIR_SHARE);
- }
- }
-
- if (!PHYSFS_addToSearchPath(datadir.c_str(), 1))
- {
- log_warning << "Couldn't add '" << datadir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
+ log_warning << "Couldn't add data.zip to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
}
}
@@ -238,7 +214,7 @@ class SDLSubsystem
public:
SDLSubsystem()
{
- if(SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0)
+ if(SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
{
std::stringstream msg;
msg << "Couldn't initialize SDL: " << SDL_GetError();
@@ -257,7 +233,7 @@ public:
void
Main::init_video()
{
- SDL_SetWindowTitle(VideoSystem::current()->get_renderer().get_window(), PACKAGE_NAME " " PACKAGE_VERSION);
+ //SDL_SetWindowTitle(VideoSystem::current()->get_renderer().get_window(), PACKAGE_NAME " " PACKAGE_VERSION);
const char* icon_fname = "images/engine/icons/supertux-256x256.png";
SDL_Surface* icon = IMG_Load_RW(get_physfs_SDLRWops(icon_fname), true);
@@ -267,7 +243,7 @@ Main::init_video()
}
else
{
- SDL_SetWindowIcon(VideoSystem::current()->get_renderer().get_window(), icon);
+ SDL_WM_SetIcon(icon, NULL);
SDL_FreeSurface(icon);
}
SDL_ShowCursor(0);
@@ -383,6 +359,14 @@ Main::run(int argc, char** argv)
{
CommandLineArguments args;
+ // Copy over old savegames
+ struct stat st;
+ if (stat(".supertux2/profile1", &st) != 0)
+ {
+ system("mkdir -p .supertux2/profile1");
+ system("cp $SDCARD/app-data/org.lethargik.supertux2/.supertux2/profile1/* .supertux2/profile1/");
+ }
+
try
{
args.parse_args(argc, argv);
diff --git a/src/supertux/menu/joystick_menu.cpp b/src/supertux/menu/joystick_menu.cpp
index bd11c9a..a2970bf 100644
--- a/src/supertux/menu/joystick_menu.cpp
+++ b/src/supertux/menu/joystick_menu.cpp
@@ -54,6 +54,7 @@ JoystickMenu::recreate_menu()
!m_input_manager.use_game_controller())
->set_help(_("Use manual configuration instead of SDL2's automatic GameController support"));
+#if 0
if (m_input_manager.use_game_controller())
{
m_joysticks_available = false;
@@ -84,13 +85,14 @@ JoystickMenu::recreate_menu()
add_toggle(MNID_JUMP_WITH_UP, _("Jump with Up"), g_config->joystick_config.jump_with_up_joy);
}
else
+#endif
{
m_joysticks_available = false;
add_inactive(-1, _("No Joysticks found"));
add_entry(MNID_SCAN_JOYSTICKS, _("Scan for Joysticks"));
}
- }
+ //}
add_hl();
add_back(_("Back"));
@@ -118,7 +120,7 @@ JoystickMenu::menu_action(MenuItem* item)
if (0 <= item->id && item->id < Controller::CONTROLCOUNT)
{
item->change_input(_("Press Button"));
- m_input_manager.joystick_manager->bind_next_event_to(static_cast(item->id));
+ //m_input_manager.joystick_manager->bind_next_event_to(static_cast(item->id));
}
else if (item->id == MNID_JUMP_WITH_UP)
{
diff --git a/src/supertux/menu/keyboard_menu.cpp b/src/supertux/menu/keyboard_menu.cpp
index 9b25f8c..2c05d16 100644
--- a/src/supertux/menu/keyboard_menu.cpp
+++ b/src/supertux/menu/keyboard_menu.cpp
@@ -82,9 +82,9 @@ KeyboardMenu::get_key_name(SDL_Keycode key)
return _("Right Alt");
case SDLK_LALT:
return _("Left Alt");
- case SDLK_RGUI:
+ case SDLK_RMETA:
return _("Right Command");
- case SDLK_LGUI:
+ case SDLK_LMETA:
return _("Left Command");
default:
return SDL_GetKeyName(static_cast(key));
diff --git a/src/supertux/menu/keyboard_menu.hpp b/src/supertux/menu/keyboard_menu.hpp
index 3230f34..5eedfd8 100644
--- a/src/supertux/menu/keyboard_menu.hpp
+++ b/src/supertux/menu/keyboard_menu.hpp
@@ -21,6 +21,8 @@
#include "control/input_manager.hpp"
#include "gui/menu_item.hpp"
+typedef SDLKey SDL_Keycode;
+
class KeyboardMenu : public Menu
{
private:
diff --git a/src/supertux/menu/options_menu.cpp b/src/supertux/menu/options_menu.cpp
index 8e1ce9d..183c5f0 100644
--- a/src/supertux/menu/options_menu.cpp
+++ b/src/supertux/menu/options_menu.cpp
@@ -103,25 +103,15 @@ OptionsMenu::OptionsMenu(bool complete)
}
}
- int display_mode_count = SDL_GetNumDisplayModes(0);
std::string last_display_mode;
- for(int i = 0; i < display_mode_count; ++i)
+ for(int i = 0; SDL_ListModes(NULL, 0)[i]; ++i)
{
- SDL_DisplayMode mode;
- int ret = SDL_GetDisplayMode(0, i, &mode);
- if (ret != 0)
- {
- log_warning << "failed to get display mode: " << SDL_GetError() << std::endl;
- }
- else
- {
std::ostringstream out;
- out << mode.w << "x" << mode.h << "@" << mode.refresh_rate;
+ out << SDL_ListModes(NULL, 0)[i]->w << "x" << SDL_ListModes(NULL, 0)[i]->h << "@60";
if(last_display_mode == out.str())
continue;
last_display_mode = out.str();
fullscreen_res->list.push_back(out.str());
- }
}
fullscreen_res->list.push_back("Desktop");
diff --git a/src/supertux/screen_manager.cpp b/src/supertux/screen_manager.cpp
index 580d875..3197a75 100644
--- a/src/supertux/screen_manager.cpp
+++ b/src/supertux/screen_manager.cpp
@@ -189,7 +189,7 @@ ScreenManager::update_gamelogic(float elapsed_time)
}
void
-ScreenManager::process_events()
+ScreenManager::process_events(DrawingContext &context)
{
InputManager::current()->update();
SDL_Event event;
@@ -205,15 +205,10 @@ ScreenManager::process_events()
quit();
break;
- case SDL_WINDOWEVENT:
- switch(event.window.event)
- {
- case SDL_WINDOWEVENT_RESIZED:
- VideoSystem::current()->resize(event.window.data1,
- event.window.data2);
+ case SDL_VIDEORESIZE:
+ VideoSystem::current()->resize(event.resize.w,
+ event.resize.h);
m_menu_manager->on_window_resize();
- break;
- }
break;
case SDL_KEYDOWN:
@@ -227,7 +222,7 @@ ScreenManager::process_events()
VideoSystem::current()->apply_config();
m_menu_manager->on_window_resize();
}
- else if (event.key.keysym.sym == SDLK_PRINTSCREEN ||
+ else if (event.key.keysym.sym == SDLK_PRINT ||
event.key.keysym.sym == SDLK_F12)
{
take_screenshot();
@@ -362,7 +357,7 @@ ScreenManager::run(DrawingContext &context)
timestep *= m_speed;
game_time += timestep;
- process_events();
+ process_events(context);
update_gamelogic(timestep);
frames += 1;
}
diff --git a/src/supertux/screen_manager.hpp b/src/supertux/screen_manager.hpp
index 59599c8..dd45acb 100644
--- a/src/supertux/screen_manager.hpp
+++ b/src/supertux/screen_manager.hpp
@@ -64,7 +64,7 @@ private:
void draw_fps(DrawingContext& context, float fps);
void draw(DrawingContext& context);
void update_gamelogic(float elapsed_time);
- void process_events();
+ void process_events(DrawingContext &context);
void handle_screen_switch();
private:
diff --git a/src/util/log.cpp b/src/util/log.cpp
index de4fb3d..2236626 100644
--- a/src/util/log.cpp
+++ b/src/util/log.cpp
@@ -18,18 +18,94 @@
#include "util/log.hpp"
#include
+#ifdef ANDROID
+#include
+#endif
#include "math/rectf.hpp"
#include "supertux/console.hpp"
+#ifdef ANDROID
+class _android_debugbuf: public std::streambuf
+{
+ public:
+ _android_debugbuf()
+ {
+ pos = 0;
+ buf[0] = 0;
+ }
+
+ protected:
+
+
+virtual int overflow(int c = EOF)
+{
+ if (EOF == c)
+ {
+ return '\0'; // returning EOF indicates an error
+ }
+ else
+ {
+ outputchar(c);
+ return c;
+ }
+};
+
+
+// we don’t do input so always return EOF
+virtual int uflow() {return EOF;}
+
+// we don’t do input so always return 0 chars read
+virtual int xsgetn(char *, int) {return 0;}
+
+// Calls outputchar() for each character.
+virtual int xsputn(const char *s, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ outputchar(s[i]);
+ }
+ return n;// we always process all of the chars
+};
+
+private:
+
+// the buffer
+char buf[256];
+int pos;
+
+void outputchar(char c)
+{
+ // TODO: mutex
+ if( pos >= sizeof(buf)-1 || c == '\n' || c == '\r' || c == 0 )
+ {
+ buf[pos] = 0;
+ __android_log_print(ANDROID_LOG_INFO, "SuperTux", "%s", buf);
+ pos = 0;
+ buf[pos] = 0;
+ return;
+ };
+ buf[pos] = c;
+ pos++;
+};
+
+};
+
+static std::ostream android_logcat(new _android_debugbuf());
+#endif
+
LogLevel g_log_level = LOG_WARNING;
static std::ostream& get_logging_instance (void)
{
+#ifdef ANDROID
+ return android_logcat;
+#else
if (ConsoleBuffer::current())
return (ConsoleBuffer::output);
else
return (std::cerr);
+#endif
}
static std::ostream& log_generic_f (const char *prefix, const char* file, int line)
diff --git a/src/video/gl/gl_lightmap.cpp b/src/video/gl/gl_lightmap.cpp
index b5251e0..6248380 100644
--- a/src/video/gl/gl_lightmap.cpp
+++ b/src/video/gl/gl_lightmap.cpp
@@ -67,7 +67,6 @@ GLLightmap::GLLightmap() :
m_lightmap_uv_right = static_cast(m_lightmap_width) / static_cast(width);
m_lightmap_uv_bottom = static_cast(m_lightmap_height) / static_cast(height);
- TextureManager::current()->register_texture(m_lightmap.get());
}
GLLightmap::~GLLightmap()
diff --git a/src/video/gl/gl_painter.cpp b/src/video/gl/gl_painter.cpp
index ecb3cb1..3493ee1 100644
--- a/src/video/gl/gl_painter.cpp
+++ b/src/video/gl/gl_painter.cpp
@@ -14,6 +14,9 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+#include
+#include
+
#include "video/gl/gl_painter.hpp"
#include "video/drawing_request.hpp"
@@ -21,6 +24,8 @@
#include "video/gl/gl_texture.hpp"
GLuint GLPainter::s_last_texture = static_cast(-1);
+GLenum GLPainter::s_blend_sfactor = -1;
+GLenum GLPainter::s_blend_dfactor = -1;
namespace {
@@ -38,7 +43,13 @@ inline void intern_draw(float left, float top, float right, float bottom,
if(effect & VERTICAL_FLIP)
std::swap(uv_top, uv_bottom);
- glBlendFunc(blend.sfactor, blend.dfactor);
+ bool restoreBlendMode = false;
+ if (blend.sfactor != GL_SRC_ALPHA || blend.dfactor != GL_ONE_MINUS_SRC_ALPHA) {
+ glBlendFunc(blend.sfactor, blend.dfactor);
+ restoreBlendMode = true;
+ //s_blend_sfactor = blend.sfactor;
+ //s_blend_dfactor = blend.dfactor;
+ }
glColor4f(color.red, color.green, color.blue, color.alpha * alpha);
// unrotated blit
@@ -95,7 +106,8 @@ inline void intern_draw(float left, float top, float right, float bottom,
// FIXME: find a better way to restore the blend mode
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ if (restoreBlendMode)
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
} // namespace
@@ -125,8 +137,8 @@ GLPainter::draw_surface(const DrawingRequest& request)
glBindTexture(GL_TEXTURE_2D, th);
}
intern_draw(request.pos.x, request.pos.y,
- request.pos.x + surface->get_width(),
- request.pos.y + surface->get_height(),
+ request.pos.x + surface->get_width() * 1.001f, // Avoid seams between background textures
+ request.pos.y + surface->get_height() * 1.001f,
surface_data->get_uv_left(),
surface_data->get_uv_top(),
surface_data->get_uv_right(),
@@ -371,4 +383,11 @@ GLPainter::draw_inverse_ellipse(const DrawingRequest& request)
glColor4f(1, 1, 1, 1);
}
+void GLPainter::reset_last_texture()
+{
+ s_last_texture = static_cast(-1);
+ s_blend_sfactor = -1;
+ s_blend_dfactor = -1;
+}
+
/* EOF */
diff --git a/src/video/gl/gl_painter.hpp b/src/video/gl/gl_painter.hpp
index bb3dd75..6ac8add 100644
--- a/src/video/gl/gl_painter.hpp
+++ b/src/video/gl/gl_painter.hpp
@@ -17,13 +17,18 @@
#ifndef HEADER_SUPERTUX_VIDEO_GL_GL_PAINTER_HPP
#define HEADER_SUPERTUX_VIDEO_GL_GL_PAINTER_HPP
+#ifndef GL_VERSION_ES_CM_1_0
#ifdef USE_GLBINDING
#include
using namespace gl;
#else
#include
-#include "SDL_opengl.h"
+//#include "SDL_opengl.h"
+#endif
+#else
+#include
+#include
#endif
struct DrawingRequest;
@@ -32,6 +37,8 @@ class GLPainter
{
private:
static GLuint s_last_texture;
+ static GLenum s_blend_sfactor;
+ static GLenum s_blend_dfactor;
public:
GLPainter();
@@ -41,6 +48,7 @@ public:
static void draw_gradient(const DrawingRequest& request);
static void draw_filled_rect(const DrawingRequest& request);
static void draw_inverse_ellipse(const DrawingRequest& request);
+ static void reset_last_texture();
private:
GLPainter(const GLPainter&) = delete;
diff --git a/src/video/gl/gl_renderer.cpp b/src/video/gl/gl_renderer.cpp
index 8f4a18ee..aa5670a 100644
--- a/src/video/gl/gl_renderer.cpp
+++ b/src/video/gl/gl_renderer.cpp
@@ -43,35 +43,13 @@
#endif
GLRenderer::GLRenderer() :
- m_window(),
- m_glcontext(),
+ //m_window(),
+ //m_glcontext(),
m_viewport(),
m_desktop_size(0, 0),
m_fullscreen_active(false)
{
- SDL_DisplayMode mode;
- SDL_GetCurrentDisplayMode(0, &mode);
- m_desktop_size = Size(mode.w, mode.h);
-
- if(g_config->try_vsync) {
- /* we want vsync for smooth scrolling */
- 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;
- }
- }
- }
-
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
-
- apply_video_mode();
+ m_desktop_size = Size(SDL_GetVideoInfo()->current_w, SDL_GetVideoInfo()->current_h);
#ifdef USE_GLBINDING
@@ -107,15 +85,6 @@ GLRenderer::GLRenderer() :
#endif
- // setup opengl state and transform
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
// Init the projection matrix, viewport and stuff
apply_config();
@@ -136,8 +105,8 @@ GLRenderer::GLRenderer() :
GLRenderer::~GLRenderer()
{
- SDL_GL_DeleteContext(m_glcontext);
- SDL_DestroyWindow(m_window);
+ //SDL_GL_DeleteContext(m_glcontext);
+ //SDL_DestroyWindow(m_window);
}
void
@@ -213,7 +182,14 @@ void
GLRenderer::flip()
{
assert_gl("drawing");
- SDL_GL_SwapWindow(m_window);
+ SDL_GL_SwapBuffers();
+ GLPainter::reset_last_texture();
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glColor4f(1, 1, 1, 1);
}
void
@@ -229,9 +205,17 @@ GLRenderer::apply_config()
{
apply_video_mode();
- Size target_size = g_config->use_fullscreen ?
- ((g_config->fullscreen_size == Size(0, 0)) ? m_desktop_size : g_config->fullscreen_size) :
- g_config->window_size;
+ // setup opengl state and transform
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+
+ Size target_size = m_desktop_size;
float pixel_aspect_ratio = 1.0f;
if (g_config->aspect_size != Size(0, 0))
@@ -264,9 +248,9 @@ GLRenderer::apply_config()
{
// Clear both buffers so that we get a clean black border without junk
glClear(GL_COLOR_BUFFER_BIT);
- SDL_GL_SwapWindow(m_window);
+ SDL_GL_SwapBuffers();
glClear(GL_COLOR_BUFFER_BIT);
- SDL_GL_SwapWindow(m_window);
+ SDL_GL_SwapBuffers();
}
glViewport(m_viewport.x, m_viewport.y, m_viewport.w, m_viewport.h);
@@ -285,102 +269,15 @@ GLRenderer::apply_config()
void
GLRenderer::apply_video_mode()
{
- if (m_window)
- {
- if (!g_config->use_fullscreen)
- {
- SDL_SetWindowFullscreen(m_window, 0);
- }
- else
- {
- if (g_config->fullscreen_size.width == 0 &&
- g_config->fullscreen_size.height == 0)
- {
- if (SDL_SetWindowFullscreen(m_window, SDL_WINDOW_FULLSCREEN_DESKTOP) != 0)
- {
- log_warning << "failed to switch to desktop fullscreen mode: "
- << SDL_GetError() << std::endl;
- }
- else
- {
- log_info << "switched to desktop fullscreen mode" << std::endl;
- }
- }
- else
- {
- 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(m_window, &mode) != 0)
- {
- log_warning << "failed to set display mode: "
- << mode.w << "x" << mode.h << "@" << mode.refresh_rate << ": "
- << SDL_GetError() << std::endl;
- }
- else
- {
- if (SDL_SetWindowFullscreen(m_window, SDL_WINDOW_FULLSCREEN) != 0)
- {
- log_warning << "failed to switch to fullscreen mode: "
- << mode.w << "x" << mode.h << "@" << mode.refresh_rate << ": "
- << SDL_GetError() << std::endl;
- }
- else
- {
- log_info << "switched to fullscreen mode: "
- << mode.w << "x" << mode.h << "@" << mode.refresh_rate << std::endl;
- }
- }
- }
- }
- }
- else
- {
- int flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
- Size size;
- if (g_config->use_fullscreen)
- {
- if (g_config->fullscreen_size == Size(0, 0))
- {
- flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
- size = m_desktop_size;
- }
- else
- {
- flags |= SDL_WINDOW_FULLSCREEN;
- size.width = g_config->fullscreen_size.width;
- size.height = g_config->fullscreen_size.height;
- }
- }
- else
- {
- size = g_config->window_size;
- }
-
- m_window = SDL_CreateWindow("SuperTux",
- SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
- size.width, size.height,
- flags);
- if (!m_window)
- {
- std::ostringstream msg;
- msg << "Couldn't set video mode " << size.width << "x" << size.height << ": " << SDL_GetError();
- throw std::runtime_error(msg.str());
- }
- else
- {
- m_glcontext = SDL_GL_CreateContext(m_window);
-
- SCREEN_WIDTH = size.width;
- SCREEN_HEIGHT = size.height;
-
- m_fullscreen_active = g_config->use_fullscreen;
- }
- }
+ //SCREEN_WIDTH = SDL_GetVideoInfo()->current_w;
+ //SCREEN_HEIGHT = SDL_GetVideoInfo()->current_h;
+#ifdef ANDROID
+ SDL_SetVideoMode(m_desktop_size.width, m_desktop_size.height, 16, SDL_OPENGL | SDL_DOUBLEBUF | SDL_FULLSCREEN);
+#else
+ m_desktop_size.width = 1280;
+ m_desktop_size.height = 800;
+ SDL_SetVideoMode(m_desktop_size.width, m_desktop_size.height, 16, SDL_OPENGL | SDL_DOUBLEBUF);
+#endif
}
void
@@ -433,9 +330,9 @@ GLRenderer::to_logical(int physical_x, int physical_y)
void
GLRenderer::set_gamma(float gamma)
{
- Uint16 ramp[256];
- SDL_CalculateGammaRamp(gamma, ramp);
- SDL_SetWindowGammaRamp(m_window, ramp, ramp, ramp);
+ //Uint16 ramp[256];
+ //SDL_CalculateGammaRamp(gamma, ramp);
+ //SDL_SetWindowGammaRamp(m_window, ramp, ramp, ramp);
}
/* EOF */
diff --git a/src/video/gl/gl_renderer.hpp b/src/video/gl/gl_renderer.hpp
index 5da04a8..b73eb9d 100644
--- a/src/video/gl/gl_renderer.hpp
+++ b/src/video/gl/gl_renderer.hpp
@@ -27,8 +27,8 @@
class GLRenderer : public Renderer
{
private:
- SDL_Window* m_window;
- SDL_GLContext m_glcontext;
+ //SDL_Window* m_window;
+ //SDL_GLContext m_glcontext;
SDL_Rect m_viewport;
Size m_desktop_size;
bool m_fullscreen_active;
@@ -51,7 +51,7 @@ public:
Vector to_logical(int physical_x, int physical_y) override;
void set_gamma(float gamma) override;
- SDL_Window* get_window() const { return m_window; }
+ //SDL_Window* get_window() const { return m_window; }
private:
void apply_video_mode();
diff --git a/src/video/gl/gl_texture.cpp b/src/video/gl/gl_texture.cpp
index 443fa01..89c9f5e 100644
--- a/src/video/gl/gl_texture.cpp
+++ b/src/video/gl/gl_texture.cpp
@@ -16,6 +16,8 @@
#include "supertux/gameconfig.hpp"
#include "video/gl/gl_texture.hpp"
+#include "video/texture_manager.hpp"
+#include "util/log.hpp"
#ifdef USE_GLBINDING
#include
@@ -45,7 +47,8 @@ GLTexture::GLTexture(unsigned int width, unsigned int height) :
m_texture_width(),
m_texture_height(),
m_image_width(),
- m_image_height()
+ m_image_height(),
+ m_pixels(NULL)
{
#ifdef GL_VERSION_ES_CM_1_0
assert(is_power_of_2(width));
@@ -57,19 +60,9 @@ GLTexture::GLTexture(unsigned int width, unsigned int height) :
m_image_height = height;
assert_gl("before creating texture");
- glGenTextures(1, &m_handle);
-
- try {
- glBindTexture(GL_TEXTURE_2D, m_handle);
-
- glTexImage2D(GL_TEXTURE_2D, 0, static_cast(GL_RGBA), m_texture_width,
- m_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- set_texture_params();
- } catch(...) {
- glDeleteTextures(1, &m_handle);
- throw;
- }
+ reupload();
+ TextureManager::current()->register_texture(this);
}
GLTexture::GLTexture(SDL_Surface* image) :
@@ -77,7 +70,8 @@ GLTexture::GLTexture(SDL_Surface* image) :
m_texture_width(),
m_texture_height(),
m_image_width(),
- m_image_height()
+ m_image_height(),
+ m_pixels(NULL)
{
#ifdef GL_VERSION_ES_CM_1_0
m_texture_width = next_power_of_two(image->w);
@@ -107,80 +101,93 @@ GLTexture::GLTexture(SDL_Surface* image) :
m_image_width = image->w;
m_image_height = image->h;
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- SDL_Surface* convert = SDL_CreateRGBSurface(0,
- m_texture_width, m_texture_height, 32,
- 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
-#else
- SDL_Surface* convert = SDL_CreateRGBSurface(0,
- m_texture_width, m_texture_height, 32,
- 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
-#endif
+ SDL_Surface* convert;
+ if (image->flags & SDL_SRCCOLORKEY) {
+ // Palette image with colorkey transparency - RGBA5551
+ convert = SDL_CreateRGBSurface(0,
+ m_image_width, m_image_height, 16,
+ 0x0000f800, 0x000007c0, 0x0000003e, 0x00000001);
+ } else if (image->format->BitsPerPixel == 32) {
+ // 32-bit image with alpha channel - RGBA4444
+ convert = SDL_CreateRGBSurface(0,
+ m_image_width, m_image_height, 16,
+ 0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f);
+ } else {
+ // 24-bit image or palette without transparency - RGB565
+ convert = SDL_CreateRGBSurface(0,
+ m_image_width, m_image_height, 16,
+ 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000);
+ }
if(convert == 0) {
throw std::runtime_error("Couldn't create texture: out of memory");
}
- SDL_SetSurfaceBlendMode(image, SDL_BLENDMODE_NONE);
+ SDL_FillRect(convert, NULL, 0x00000000);
+ //SDL_SetColorKey(image, 0, 0); // Some images use colorkey transparency
+ SDL_SetAlpha(image, 0, SDL_ALPHA_OPAQUE);
SDL_BlitSurface(image, 0, convert, 0);
+ //SDL_Rect r = {m_image_width / 2, m_image_height / 2, 4, 4};
+ //SDL_FillRect(convert, &r, 0xff000000);
+
+ m_pixels = convert;
+
+ reupload();
+ TextureManager::current()->register_texture(this);
+ assert_gl("creating texture");
+}
+
+void GLTexture::reupload()
+{
assert_gl("before creating texture");
glGenTextures(1, &m_handle);
try {
- GLenum sdl_format;
- if(convert->format->BytesPerPixel == 3)
- sdl_format = GL_RGB;
- else if(convert->format->BytesPerPixel == 4)
- sdl_format = GL_RGBA;
- else {
- sdl_format = GL_RGBA;
- assert(false);
+ GLenum sdl_format = GL_RGBA;
+ GLenum pixel_packing = GL_UNSIGNED_BYTE;
+
+ if (m_pixels) {
+ if (m_pixels->format->Amask == 0)
+ sdl_format = GL_RGB;
+ if (m_pixels->format->Gmask == 0x000007c0)
+ pixel_packing = GL_UNSIGNED_SHORT_5_5_5_1;
+ if (m_pixels->format->Gmask == 0x00000f00)
+ pixel_packing = GL_UNSIGNED_SHORT_4_4_4_4;
+ if (m_pixels->format->Gmask == 0x000007e0)
+ pixel_packing = GL_UNSIGNED_SHORT_5_6_5;
}
glBindTexture(GL_TEXTURE_2D, m_handle);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
#if defined(GL_UNPACK_ROW_LENGTH) || defined(USE_GLBINDING)
- glPixelStorei(GL_UNPACK_ROW_LENGTH, convert->pitch/convert->format->BytesPerPixel);
+ //glPixelStorei(GL_UNPACK_ROW_LENGTH, convert->pitch/convert->format->BytesPerPixel);
#else
/* OpenGL ES doesn't support UNPACK_ROW_LENGTH, let's hope SDL didn't add
* padding bytes, otherwise we need some extra code here... */
- assert(convert->pitch == m_texture_width * convert->format->BytesPerPixel);
+ //assert(convert->pitch == m_texture_width * convert->format->BytesPerPixel);
#endif
- if(SDL_MUSTLOCK(convert))
- {
- SDL_LockSurface(convert);
- }
-
- glTexImage2D(GL_TEXTURE_2D, 0, static_cast(GL_RGBA),
+ glTexImage2D(GL_TEXTURE_2D, 0, sdl_format,
m_texture_width, m_texture_height, 0, sdl_format,
- GL_UNSIGNED_BYTE, convert->pixels);
-
- // no not use mipmaps
- if(false)
- {
- glGenerateMipmap(GL_TEXTURE_2D);
- }
-
- if(SDL_MUSTLOCK(convert))
- {
- SDL_UnlockSurface(convert);
- }
+ pixel_packing, NULL);
- assert_gl("creating texture");
+ if (m_pixels)
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_image_width, m_image_height,
+ sdl_format, pixel_packing, m_pixels->pixels);
set_texture_params();
} catch(...) {
glDeleteTextures(1, &m_handle);
- SDL_FreeSurface(convert);
throw;
}
- SDL_FreeSurface(convert);
}
GLTexture::~GLTexture()
{
+ TextureManager::current()->remove_texture(this);
+ if (m_pixels)
+ SDL_FreeSurface(m_pixels);
glDeleteTextures(1, &m_handle);
}
diff --git a/src/video/gl/gl_texture.hpp b/src/video/gl/gl_texture.hpp
index 7cb634f..787d702 100644
--- a/src/video/gl/gl_texture.hpp
+++ b/src/video/gl/gl_texture.hpp
@@ -32,6 +32,7 @@ protected:
unsigned int m_texture_height;
unsigned int m_image_width;
unsigned int m_image_height;
+ SDL_Surface* m_pixels;
public:
GLTexture(unsigned int width, unsigned int height);
@@ -76,6 +77,8 @@ public:
m_image_height = height;
}
+ void reupload();
+
private:
void set_texture_params();
};
diff --git a/src/video/gl/gl_video_system.cpp b/src/video/gl/gl_video_system.cpp
index 87b0ab7..328a58c 100644
--- a/src/video/gl/gl_video_system.cpp
+++ b/src/video/gl/gl_video_system.cpp
@@ -69,6 +69,7 @@ void
GLVideoSystem::resize(int w, int h)
{
m_renderer->resize(w, h);
+ TextureManager::current()->reload_textures();
m_lightmap.reset(new GLLightmap);
}
diff --git a/src/video/glutil.hpp b/src/video/glutil.hpp
index 4ead32d..d791bb1 100644
--- a/src/video/glutil.hpp
+++ b/src/video/glutil.hpp
@@ -86,7 +86,7 @@ static inline void check_gl_error(const char* message)
msg << "Unknown error (code " << error << ")";
}
- throw std::runtime_error(msg.str());
+ //throw std::runtime_error(msg.str());
}
}
diff --git a/src/video/renderer.hpp b/src/video/renderer.hpp
index b9d4ec3..2532c65 100644
--- a/src/video/renderer.hpp
+++ b/src/video/renderer.hpp
@@ -56,7 +56,7 @@ public:
virtual void apply_config() = 0;
virtual Vector to_logical(int physical_x, int physical_y) = 0;
virtual void set_gamma(float gamma) = 0;
- virtual SDL_Window* get_window() const = 0;
+ //virtual SDL_Window* get_window() const = 0;
};
#endif
diff --git a/src/video/texture.hpp b/src/video/texture.hpp
index 76964a9..86dc631 100644
--- a/src/video/texture.hpp
+++ b/src/video/texture.hpp
@@ -65,6 +65,7 @@ public:
virtual unsigned int get_texture_height() const = 0;
virtual unsigned int get_image_width() const = 0;
virtual unsigned int get_image_height() const = 0;
+ virtual void reupload() = 0;
private:
Texture(const Texture&);
diff --git a/src/video/texture_manager.cpp b/src/video/texture_manager.cpp
index e544909..aac5c63 100644
--- a/src/video/texture_manager.cpp
+++ b/src/video/texture_manager.cpp
@@ -164,12 +164,14 @@ TextureManager::create_image_texture_raw(const std::string& filename, const Rect
throw std::runtime_error("SDL_CreateRGBSurfaceFrom() call failed");
}
-#ifdef OLD_SDL
if (image->format->palette)
{ // copy the image palette to subimage if present
- SDL_SetSurfacePalette(subimage.get(), image->format->palette->colors);
+ SDL_SetColors(subimage.get(), image->format->palette->colors, 0, image->format->palette->ncolors);
+ }
+ if (image->flags & SDL_SRCCOLORKEY)
+ { // Some images use colorkey transparency
+ SDL_SetColorKey(subimage.get(), SDL_SRCCOLORKEY, image->format->colorkey);
}
-#endif
return VideoSystem::current()->new_texture(subimage.get());
}
@@ -240,6 +242,7 @@ TextureManager::create_dummy_texture()
void
TextureManager::save_textures()
{
+#if 0
#if defined(GL_PACK_ROW_LENGTH) || defined(USE_GLBINDING)
/* all this stuff is not support by OpenGL ES */
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
@@ -261,11 +264,13 @@ TextureManager::save_textures()
{
save_texture(dynamic_cast(i->second.lock().get()));
}
+#endif
}
void
TextureManager::save_texture(GLTexture* texture)
{
+#if 0
SavedTexture saved_texture;
saved_texture.texture = texture;
glBindTexture(GL_TEXTURE_2D, texture->get_handle());
@@ -298,13 +303,14 @@ TextureManager::save_texture(GLTexture* texture)
glDeleteTextures(1, &(texture->get_handle()));
texture->set_handle(0);
-
assert_gl("retrieving texture for save");
+#endif
}
void
TextureManager::reload_textures()
{
+#if 0
#if defined(GL_UNPACK_ROW_LENGTH) || defined(USE_GLBINDING)
/* OpenGL ES doesn't support these */
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
@@ -345,6 +351,16 @@ TextureManager::reload_textures()
}
m_saved_textures.clear();
+#endif
+ for(Textures::iterator i = m_textures.begin(); i != m_textures.end(); ++i) {
+ //log_info << "Texture manager: reuploading texture " << *i << std::endl;
+ (*i)->reupload();
+ }
+ for(ImageTextures::iterator i = m_image_textures.begin();
+ i != m_image_textures.end(); ++i)
+ {
+ dynamic_cast(i->second.lock().get())->reupload();
+ }
}
#endif
diff --git a/src/video/util.hpp b/src/video/util.hpp
index 46be85c..72f7cb8 100644
--- a/src/video/util.hpp
+++ b/src/video/util.hpp
@@ -17,7 +17,7 @@
#ifndef HEADER_SUPERTUX_VIDEO_UTIL_HPP
#define HEADER_SUPERTUX_VIDEO_UTIL_HPP
-#include "SDL_rect.h"
+#include "SDL_video.h"
class Size;
class Vector;
diff --git a/src/video/video_system.cpp b/src/video/video_system.cpp
index dd736d0..726c81a 100644
--- a/src/video/video_system.cpp
+++ b/src/video/video_system.cpp
@@ -19,7 +19,7 @@
#include
#include "util/log.hpp"
-#include "video/sdl/sdl_video_system.hpp"
+//#include "video/sdl/sdl_video_system.hpp"
#ifdef HAVE_OPENGL
#include "video/gl/gl_video_system.hpp"
@@ -31,33 +31,15 @@ VideoSystem::create(VideoSystem::Enum video_system)
switch(video_system)
{
case AUTO_VIDEO:
-#ifdef HAVE_OPENGL
- try
- {
- return std::unique_ptr(new GLVideoSystem);
- }
- catch(std::exception& err)
- {
- log_warning << "Error creating GLVideoSystem, using SDL fallback: " << err.what() << std::endl;
- return std::unique_ptr(new SDLVideoSystem);
- }
-#else
- log_info << "new SDL renderer\n";
- return std::unique_ptr(new SDLVideoSystem);
-#endif
-
case OPENGL:
+ case PURE_SDL:
#ifdef HAVE_OPENGL
return std::unique_ptr(new GLVideoSystem);
#else
- log_warning << "OpenGL requested, but missing using SDL fallback" << std::endl;
- return std::unique_ptr(new SDLVideoSystem);
+ //log_warning << "OpenGL requested, but missing using SDL fallback" << std::endl;
+ //return std::unique_ptr(new SDLVideoSystem);
#endif
- case PURE_SDL:
- log_info << "new SDL renderer\n";
- return std::unique_ptr(new SDLVideoSystem);
-
default:
assert(!"invalid video system in config");
return {};