Files
commandergenius/project/jni/application/supertux/android.diff
Sergii Pylypenko 06fae348e2 SuperTux: updated
2015-12-25 20:50:34 +02:00

1709 lines
52 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 <http://www.gnu.org/licenses/>.
-
#include "control/game_controller_manager.hpp"
#include <algorithm>
diff --git a/src/control/input_manager.cpp b/src/control/input_manager.cpp
index 588e4b7..57884d1 100644
--- a/src/control/input_manager.cpp
+++ b/src/control/input_manager.cpp
@@ -19,8 +19,8 @@
#include <iostream>
-#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 c8e0df6..5dd6c60 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<KeyboardManager> keyboard_manager;
- std::unique_ptr<JoystickManager> joystick_manager;
- std::unique_ptr<GameControllerManager> game_controller_manager;
+ //std::unique_ptr<JoystickManager> joystick_manager;
+ //std::unique_ptr<GameControllerManager> 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 19b6492..b49734e 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
@@ -213,4 +217,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 57d74e4..66bf674 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 <http://www.gnu.org/licenses/>.
+#include <math.h>
+
#include "gui/dialog.hpp"
#include <algorithm>
diff --git a/src/gui/menu.cpp b/src/gui/menu.cpp
index 7d3b52f..a043fb3 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 d48d410..d2cb99c 100644
--- a/src/object/player.cpp
+++ b/src/object/player.cpp
@@ -160,6 +160,7 @@ Player::Player(PlayerStatus* _player_status, const std::string& name_) :
grabbed_object(NULL),
sprite(),
airarrow(),
+ jumparrow(),
floor_normal(),
ghost_mode(false),
edit_mode(false),
@@ -176,6 +177,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");
@@ -240,6 +242,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();
}
@@ -526,12 +534,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;
@@ -724,7 +734,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
@@ -764,7 +774,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();
@@ -846,6 +856,8 @@ Player::handle_input()
/* Handle vertical movement: */
if (!stone) handle_vertical_input();
+ handle_jump_helper();
+
/* Shoot! */
if (controller->pressed(Controller::ACTION) && (player_status->bonus == FIRE_BONUS || player_status->bonus == ICE_BONUS)) {
if((player_status->bonus == FIRE_BONUS &&
@@ -1190,6 +1202,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 = "";
@@ -1766,4 +1785,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 4d178aa..bf42dd5 100644
--- a/src/object/player.hpp
+++ b/src/object/player.hpp
@@ -246,6 +246,7 @@ private:
void handle_horizontal_input();
void handle_vertical_input();
+ void handle_jump_helper();
void activate();
void deactivate();
@@ -322,6 +323,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 8c2635e..fa862a3 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 c5ca4e8..00010c1 100644
--- a/src/supertux/main.cpp
+++ b/src/supertux/main.cpp
@@ -20,6 +20,9 @@
#include <version.h>
#include <SDL_image.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <boost/format.hpp>
#include <boost/optional.hpp>
#include <array>
@@ -129,7 +132,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
@@ -144,50 +147,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);
-
- // If we are on windows, the data directory is one directory above the binary
-#ifdef WIN32
- const std::array<std::string, 2> subdirs = { "data", "../data" };
-#else
- const std::array<std::string, 1> subdirs = { "data" };
-#endif
- bool found = false;
- for (const std::string &subdir : subdirs)
- {
- datadir = FileSystem::join(basepath, subdir);
- if (FileSystem::exists(FileSystem::join(datadir, "credits.txt")))
- {
- found = true;
- break;
- }
- }
- if (!found)
- {
- // 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;
}
}
@@ -253,7 +215,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();
@@ -272,7 +234,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);
@@ -282,7 +244,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);
@@ -398,6 +360,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 adde0c5..b9eeef3 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<Controller::Control>(item->id));
+ //m_input_manager.joystick_manager->bind_next_event_to(static_cast<Controller::Control>(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<SDL_Keycode>(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 f9e4821..b8d3fc0 100644
--- a/src/supertux/menu/options_menu.cpp
+++ b/src/supertux/menu/options_menu.cpp
@@ -104,25 +104,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 85d9f63..15304de 100644
--- a/src/supertux/screen_manager.cpp
+++ b/src/supertux/screen_manager.cpp
@@ -195,7 +195,7 @@ ScreenManager::update_gamelogic(float elapsed_time)
}
void
-ScreenManager::process_events()
+ScreenManager::process_events(DrawingContext &context)
{
InputManager::current()->update();
SDL_Event event;
@@ -211,24 +211,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);
- m_menu_manager->on_window_resize();
- break;
- case SDL_WINDOWEVENT_FOCUS_LOST:
- if(GameSession::current() != NULL &&
- GameSession::current()->is_active())
- {
- GameSession::current()->toggle_pause();
- }
- break;
- }
- break;
+ case SDL_VIDEORESIZE:
+ VideoSystem::current()->resize(event.resize.w,
+ event.resize.h);
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_F10)
@@ -241,7 +227,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();
@@ -376,7 +362,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 20259bf..d3cee66 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 255a427..b788a5e 100644
--- a/src/util/log.cpp
+++ b/src/util/log.cpp
@@ -18,18 +18,94 @@
#include "util/log.hpp"
#include <iostream>
+#ifdef ANDROID
+#include <android/log.h>
+#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 dont do input so always return EOF
+virtual int uflow() {return EOF;}
+
+// we dont 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 (bool use_console_buffer = true)
{
+#ifdef ANDROID
+ return android_logcat;
+#else
if (ConsoleBuffer::current() && use_console_buffer)
return (ConsoleBuffer::output);
else
return (std::cerr);
+#endif
}
static std::ostream& log_generic_f (const char *prefix, const char* file, int line, bool use_console_buffer = true)
diff --git a/src/video/gl/gl_lightmap.cpp b/src/video/gl/gl_lightmap.cpp
index 97cf70a..3b39497 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<float>(m_lightmap_width) / static_cast<float>(width);
m_lightmap_uv_bottom = static_cast<float>(m_lightmap_height) / static_cast<float>(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 12ee0a5..a1a3f8d 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 <http://www.gnu.org/licenses/>.
+#include <math.h>
+#include <SDL_video.h>
+
#include "video/gl/gl_painter.hpp"
#include <algorithm>
@@ -23,6 +26,8 @@
#include "video/gl/gl_texture.hpp"
GLuint GLPainter::s_last_texture = static_cast<GLuint>(-1);
+GLenum GLPainter::s_blend_sfactor = -1;
+GLenum GLPainter::s_blend_dfactor = -1;
namespace {
@@ -40,7 +45,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
@@ -97,7 +108,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
@@ -127,8 +139,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(),
@@ -387,4 +399,11 @@ GLPainter::draw_inverse_ellipse(const DrawingRequest& request)
glColor4f(1, 1, 1, 1);
}
+void GLPainter::reset_last_texture()
+{
+ s_last_texture = static_cast<GLuint>(-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 <glbinding/gl/gl.h>
using namespace gl;
#else
#include <GL/glew.h>
-#include "SDL_opengl.h"
+//#include "SDL_opengl.h"
+#endif
+#else
+#include <GLES/gl.h>
+#include <GLES/glext.h>
#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 <glbinding/ContextInfo.h>
@@ -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<GLint>(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<GLint>(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 dc38be9..a41f83a 100644
--- a/src/video/texture_manager.cpp
+++ b/src/video/texture_manager.cpp
@@ -152,7 +152,8 @@ TextureManager::create_image_texture_raw(const std::string& filename, const Rect
SDL_PixelFormat* format = image->format;
if(format->Rmask == 0 && format->Gmask == 0 && format->Bmask == 0 && format->Amask == 0) {
log_debug << "Wrong surface format for image " << filename << ". Compensating." << std::endl;
- image = SDL_ConvertSurfaceFormat(image, SDL_PIXELFORMAT_RGBA8888, 0);
+ //image = SDL_ConvertSurfaceFormat(image, SDL_PIXELFORMAT_RGBA8888, 0);
+ image = SDL_ConvertSurface(image, SDL_GetVideoSurface()->format, 0);
}
SDLSurfacePtr subimage(SDL_CreateRGBSurfaceFrom(static_cast<uint8_t*>(image->pixels) +
@@ -170,12 +171,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());
}
@@ -246,6 +249,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);
@@ -271,11 +275,13 @@ TextureManager::save_textures()
save_texture(texture);
}
+#endif
}
void
TextureManager::save_texture(GLTexture* texture)
{
+#if 0
SavedTexture saved_texture;
saved_texture.texture = texture;
glBindTexture(GL_TEXTURE_2D, texture->get_handle());
@@ -308,13 +314,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);
@@ -355,6 +362,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<GLTexture*>(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 <config.h>
#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<VideoSystem>(new GLVideoSystem);
- }
- catch(std::exception& err)
- {
- log_warning << "Error creating GLVideoSystem, using SDL fallback: " << err.what() << std::endl;
- return std::unique_ptr<VideoSystem>(new SDLVideoSystem);
- }
-#else
- log_info << "new SDL renderer\n";
- return std::unique_ptr<VideoSystem>(new SDLVideoSystem);
-#endif
-
case OPENGL:
+ case PURE_SDL:
#ifdef HAVE_OPENGL
return std::unique_ptr<VideoSystem>(new GLVideoSystem);
#else
- log_warning << "OpenGL requested, but missing using SDL fallback" << std::endl;
- return std::unique_ptr<VideoSystem>(new SDLVideoSystem);
+ //log_warning << "OpenGL requested, but missing using SDL fallback" << std::endl;
+ //return std::unique_ptr<VideoSystem>(new SDLVideoSystem);
#endif
- case PURE_SDL:
- log_info << "new SDL renderer\n";
- return std::unique_ptr<VideoSystem>(new SDLVideoSystem);
-
default:
assert(!"invalid video system in config");
return {};