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 {};