diff --git a/.gitmodules b/.gitmodules
index c655bb3cb..db67dc6d5 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -77,3 +77,6 @@
[submodule "project/jni/boringssl/boringssl/jni"]
path = project/jni/boringssl/boringssl/jni
url = https://android.googlesource.com/platform/external/boringssl
+[submodule "project/jni/application/supertux/supertux"]
+ path = project/jni/application/supertux/supertux
+ url = git@github.com:pelya/supertux.git
diff --git a/project/java/Audio.java b/project/java/Audio.java
index 17afa3243..14c2320a3 100644
--- a/project/java/Audio.java
+++ b/project/java/Audio.java
@@ -37,7 +37,8 @@ import android.media.MediaRecorder.AudioSource;
import java.io.*;
import android.util.Log;
import java.util.concurrent.Semaphore;
-
+import android.Manifest;
+import android.content.pm.PackageManager;
class AudioThread
@@ -166,6 +167,16 @@ class AudioThread
private byte[] startRecording(int rate, int channels, int encoding, int bufsize)
{
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M)
+ {
+ int permissionCheck = mParent.checkSelfPermission(Manifest.permission.RECORD_AUDIO);
+ if (permissionCheck != PackageManager.PERMISSION_GRANTED)
+ {
+ mParent.requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO}, 0);
+ return null;
+ }
+ }
+
if( mRecordThread == null )
{
mRecordThread = new RecordingThread();
@@ -199,8 +210,26 @@ class AudioThread
mRecorder = new AudioRecord(AudioSource.VOICE_CALL, rate, channelConfig, encodingConfig, minBufferSize);
mRecorderBufferSize = minBufferSize;
} catch (IllegalArgumentException e) {
- Log.i("SDL", "SDL: error: failed to open recording device!");
- return null;
+ Log.i("SDL", "SDL: error: failed to open VOICE_CALL recording device!");
+ try {
+ mRecorder = new AudioRecord(AudioSource.VOICE_UPLINK, rate, channelConfig, encodingConfig, minBufferSize);
+ mRecorderBufferSize = minBufferSize;
+ } catch (IllegalArgumentException ee) {
+ Log.i("SDL", "SDL: error: failed to open VOICE_UPLINK recording device!");
+ try {
+ mRecorder = new AudioRecord(AudioSource.VOICE_RECOGNITION, rate, channelConfig, encodingConfig, minBufferSize);
+ mRecorderBufferSize = minBufferSize;
+ } catch (IllegalArgumentException eee) {
+ Log.i("SDL", "SDL: error: failed to open VOICE_RECOGNITION recording device!");
+ try {
+ mRecorder = new AudioRecord(AudioSource.DEFAULT, rate, channelConfig, encodingConfig, minBufferSize);
+ mRecorderBufferSize = minBufferSize;
+ } catch (IllegalArgumentException eeee) {
+ Log.i("SDL", "SDL: error: failed to open DEFAULT recording device!");
+ return null;
+ }
+ }
+ }
}
}
else
diff --git a/project/java/MainActivity.java b/project/java/MainActivity.java
index 92c8bf4b2..e2ea55420 100644
--- a/project/java/MainActivity.java
+++ b/project/java/MainActivity.java
@@ -93,6 +93,8 @@ import android.app.Notification;
import android.app.PendingIntent;
import java.util.TreeSet;
import android.app.UiModeManager;
+import android.Manifest;
+
public class MainActivity extends Activity
{
@@ -1490,6 +1492,20 @@ public class MainActivity extends Activity
setRequestedOrientation(Globals.HorizontalOrientation ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
+ {
+ if (permissions.length == 0 || grantResults.length == 0)
+ {
+ Log.i("SDL", "libSDL: Permission request dialog was aborted");
+ return;
+ }
+ if (Manifest.permission.RECORD_AUDIO.equals(permissions[0]))
+ {
+ Log.i("SDL", "libSDL: Record audio permission: " + (grantResults[0] == PackageManager.PERMISSION_GRANTED ? "GRANTED" : "DENIED"));
+ }
+ }
+
public FrameLayout getVideoLayout() { return _videoLayout; }
DemoGLSurfaceView mGLView = null;
diff --git a/project/jni/application/supertux/.gitignore b/project/jni/application/supertux/.gitignore
index 137d334da..e69de29bb 100644
--- a/project/jni/application/supertux/.gitignore
+++ b/project/jni/application/supertux/.gitignore
@@ -1 +0,0 @@
-supertux
diff --git a/project/jni/application/supertux/AndroidAppSettings.cfg b/project/jni/application/supertux/AndroidAppSettings.cfg
index 5f063c3c6..f890be862 100644
--- a/project/jni/application/supertux/AndroidAppSettings.cfg
+++ b/project/jni/application/supertux/AndroidAppSettings.cfg
@@ -7,10 +7,10 @@ AppName="SuperTux"
AppFullName=org.lethargik.supertux2
# Application version code (integer)
-AppVersionCode=04009
+AppVersionCode=04010
# Application user-visible version name (string)
-AppVersionName="0.4.0.09"
+AppVersionName="0.4.0.10"
# Specify path to download application data in zip archive in the form 'Description|URL|MirrorURL^Description2|URL2|MirrorURL2^...'
# If you'll start Description with '!' symbol it will be enabled by default, other downloads should be selected by user from startup config menu
@@ -239,12 +239,12 @@ NDK_TOOLCHAIN_VERSION=4.9
# Specify architectures to compile, 'all' or 'y' to compile for all architectures.
# Available architectures: armeabi armeabi-v7a armeabi-v7a-hard x86 mips
-MultiABI='armeabi-v7a x86'
+MultiABI='armeabi-v7a' # x86
# Optional shared libraries to compile - removing some of them will save space
# MP3 support by libMAD is encumbered by patents and libMAD is GPL-ed
# Available libraries: mad (GPL-ed!) sdl_mixer sdl_image sdl_ttf sdl_net sdl_blitpool sdl_gfx sdl_sound intl xml2 lua jpeg png ogg flac tremor vorbis freetype xerces curl theora fluidsynth lzma lzo2 mikmod openal timidity zzip bzip2 yaml-cpp python boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread glu avcodec avdevice avfilter avformat avresample avutil swscale swresample bzip2
-CompiledLibraries="sdl_image physfs curl openal vorbis ogg"
+CompiledLibraries="sdl_image physfs crypto ssl curl openal vorbis ogg"
# Application uses custom build script AndroidBuild.sh instead of Android.mk (y) or (n)
CustomBuildScript=n
@@ -253,13 +253,13 @@ CustomBuildScript=n
AppCflags='-DGL_VERSION_ES_CM_1_0=1 -Ijni/openal/include/AL -Ijni/boost/include -DHAVE_SDL=1 -frtti -fexceptions -std=gnu++11'
# Additional LDFLAGS for application
-AppLdflags='-frtti -fexceptions -fuse-ld=bfd'
+AppLdflags='-frtti -fexceptions'
# If application has headers with the same name as system headers, this option tries to fix compiler flags to make it compilable
AppOverlapsSystemHeaders=n
# Build only following subdirs (empty will build all dirs, ignored with custom script)
-AppSubdirsBuild='. supertux/src/* supertux/external/tinygettext/src supertux/external/tinygettext/include supertux/external/findlocale supertux/external/obstack supertux/external/squirrel/include supertux/external/squirrel/squirrel supertux/external/squirrel/sqstdlib'
+AppSubdirsBuild='. supertux/src/* supertux/external/findlocale supertux/external/obstack supertux/external/squirrel/include supertux/external/squirrel/squirrel supertux/external/squirrel/sqstdlib supertux/external/tinygettext/include supertux/external/tinygettext/src/*'
# Exclude these files from build
AppBuildExclude='supertux/external/findlocale/example.c supertux/src/video/sdl/sdl_lightmap.cpp supertux/src/video/sdl/sdl_painter.cpp supertux/src/video/sdl/sdl_renderer.cpp supertux/src/video/sdl/sdl_texture.cpp supertux/src/video/sdl/sdl_video_system.cpp supertux/src/control/game_controller_manager.cpp supertux/src/control/joystick_manager.cpp'
diff --git a/project/jni/application/supertux/AndroidPreBuild.sh b/project/jni/application/supertux/AndroidPreBuild.sh
deleted file mode 100755
index c37bf63df..000000000
--- a/project/jni/application/supertux/AndroidPreBuild.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-if [ -e supertux/patched.successfully ]; then
- exit 0
-else
- git clone --depth 1 --branch release/0.4 https://github.com/SuperTux/supertux.git || exit 1
- git -C supertux submodule update --init || exit 1
- patch -p1 -d supertux < android.diff && touch supertux/patched.successfully || exit 1
- ln -sf supertux/data/images/engine/icons/supertux-256x256.png icon.png
- ln -sf ../supertux/data/images/engine/menu/logo.png AndroidData/logo.png
-fi
diff --git a/project/jni/application/supertux/android.diff b/project/jni/application/supertux/android.diff
deleted file mode 100644
index 92ffbe139..000000000
--- a/project/jni/application/supertux/android.diff
+++ /dev/null
@@ -1,1732 +0,0 @@
-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 3925293..7a20971 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(joystick_config.use_game_controller),
-- 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 ff5146c..713af95 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 6f8d88e..86894e8 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 98a910b..0d61a08 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
-diff --git a/src/gui/menu.cpp b/src/gui/menu.cpp
-index 69cecf6..6eda865 100644
---- a/src/gui/menu.cpp
-+++ b/src/gui/menu.cpp
-@@ -383,7 +383,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 c59f763..9d4a237 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();
- }
-
-@@ -534,12 +542,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;
-@@ -732,7 +742,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
-@@ -772,7 +782,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();
-@@ -854,6 +864,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 &&
-@@ -1208,6 +1220,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 = "";
-
-@@ -1784,4 +1803,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 f606e04..cfc6451 100644
---- a/src/object/player.hpp
-+++ b/src/object/player.hpp
-@@ -247,6 +247,7 @@ private:
-
- void handle_horizontal_input();
- void handle_vertical_input();
-+ void handle_jump_helper();
-
- void activate();
- void deactivate();
-@@ -327,6 +328,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 d4b0a69..a296960 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 20d51f1..d801b27 100644
---- a/src/supertux/main.cpp
-+++ b/src/supertux/main.cpp
-@@ -20,6 +20,9 @@
- #include
-
- #include
-+#include
-+#include
-+#include
- #include
- #include
- #include
-@@ -130,7 +133,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
-@@ -145,50 +148,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 subdirs = { "data", "../data" };
--#else
-- const std::array 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;
- }
- }
-
-@@ -254,7 +216,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();
-@@ -273,7 +235,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);
-@@ -283,7 +245,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);
-@@ -399,6 +361,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 0b6ba9b..bd7a493 100644
---- a/src/supertux/menu/joystick_menu.cpp
-+++ b/src/supertux/menu/joystick_menu.cpp
-@@ -56,6 +56,7 @@ JoystickMenu::recreate_menu()
- &m_auto_joystick_cfg)
- ->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;
-@@ -86,13 +87,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(_("No Joysticks found"));
- add_entry(MNID_SCAN_JOYSTICKS, _("Scan for Joysticks"));
- }
-- }
-+// }
-
- add_hl();
- add_back(_("Back"));
-@@ -124,7 +126,7 @@ JoystickMenu::menu_action(MenuItem* item)
- return;
- }
- micf->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_AUTO_JOYSTICK_CFG)
- {
-diff --git a/src/supertux/menu/keyboard_menu.cpp b/src/supertux/menu/keyboard_menu.cpp
-index 2078b9f..bcc6226 100644
---- a/src/supertux/menu/keyboard_menu.cpp
-+++ b/src/supertux/menu/keyboard_menu.cpp
-@@ -83,9 +83,9 @@ KeyboardMenu::get_key_name(SDL_Keycode key) const
- 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 98d84a2..14baf3e 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 26f6d69..b884d2e 100644
---- a/src/supertux/menu/options_menu.cpp
-+++ b/src/supertux/menu/options_menu.cpp
-@@ -126,22 +126,13 @@ OptionsMenu::OptionsMenu(bool complete) :
- }
-
- resolutions.clear();
-- 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
-+ SDL_Rect mode = *(SDL_ListModes(NULL, 0)[i]);
- {
- std::ostringstream out;
- out << mode.w << "x" << mode.h;
-- if(mode.refresh_rate)
-- out << "@" << mode.refresh_rate;
- if(last_display_mode == out.str())
- continue;
- last_display_mode = out.str();
-diff --git a/src/supertux/screen_manager.cpp b/src/supertux/screen_manager.cpp
-index 23f1086..960276b 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();
-@@ -370,7 +356,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 3cd3889..09797d1 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 2ace6de..1e34498 100644
---- a/src/util/log.cpp
-+++ b/src/util/log.cpp
-@@ -18,20 +18,96 @@
- #include "util/log.hpp"
-
- #include
-+#ifdef __ANDROID__
-+#include
-+#endif
-
- #include "math/rectf.hpp"
- #include "supertux/console.hpp"
- #include "supertux/gameconfig.hpp"
- #include "supertux/globals.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 (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/util/log.hpp b/src/util/log.hpp
-index b256a74..1a75474 100644
---- a/src/util/log.hpp
-+++ b/src/util/log.hpp
-@@ -45,6 +45,20 @@ void log_info_callback(const std::string& str);
- void log_error_callback(const std::string& str);
- void log_warning_callback(const std::string& str);
-
-+#ifdef __ANDROID__
-+#include
-+// Where else to put this, eh?
-+namespace std
-+{
-+ template < typename T > std::string to_string( const T& n )
-+ {
-+ std::ostringstream ss;
-+ ss << n ;
-+ return ss.str() ;
-+ }
-+}
-+#endif
-+
- #endif
-
- /* EOF */
-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(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 229db78..a725286 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
-@@ -23,6 +26,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 {
-
-@@ -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(),
-@@ -388,4 +400,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 7ec1a0e..b644490 100644
---- a/src/video/gl/gl_renderer.cpp
-+++ b/src/video/gl/gl_renderer.cpp
-@@ -44,35 +44,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
-
-@@ -108,15 +86,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();
-
-@@ -137,8 +106,8 @@ GLRenderer::GLRenderer() :
-
- GLRenderer::~GLRenderer()
- {
-- SDL_GL_DeleteContext(m_glcontext);
-- SDL_DestroyWindow(m_window);
-+ //SDL_GL_DeleteContext(m_glcontext);
-+ //SDL_DestroyWindow(m_window);
- }
-
- void
-@@ -214,7 +183,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
-@@ -230,9 +206,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))
-@@ -265,9 +249,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);
-@@ -286,102 +270,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
-@@ -434,9 +331,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 3aa37b4..0e3cbe7 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 override { return m_window; }
-+ //SDL_Window* get_window() const override { 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 d93c6cd..b65b0bd 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(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(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 105e427..898dea7 100644
---- a/src/video/video_system.cpp
-+++ b/src/video/video_system.cpp
-@@ -20,7 +20,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"
-@@ -32,33 +32,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 {};
diff --git a/project/jni/application/supertux/supertux b/project/jni/application/supertux/supertux
new file mode 160000
index 000000000..409394183
--- /dev/null
+++ b/project/jni/application/supertux/supertux
@@ -0,0 +1 @@
+Subproject commit 409394183506b4b42517ee51ec5c1d415cf38669
diff --git a/project/jni/application/test-record-audio/AndroidAppSettings.cfg b/project/jni/application/test-record-audio/AndroidAppSettings.cfg
new file mode 100644
index 000000000..568bd6c16
--- /dev/null
+++ b/project/jni/application/test-record-audio/AndroidAppSettings.cfg
@@ -0,0 +1,279 @@
+# The application settings for Android libSDL port
+
+# Specify application name (e.x. My Application)
+AppName="Ballfield"
+
+# Specify reversed site name of application (e.x. com.mysite.myapp)
+AppFullName=net.olofson.ballfield
+
+# Application version code (integer)
+AppVersionCode=101
+
+# Application user-visible version name (string)
+AppVersionName="1.01"
+
+# Specify path to download application data in zip archive in the form 'Description|URL|MirrorURL^Description2|URL2|MirrorURL2^...'
+# If you'll start Description with '!' symbol it will be enabled by default, other downloads should be selected by user from startup config menu
+# If the URL in in the form ':dir/file.dat:http://URL/' it will be downloaded as binary BLOB to the application dir and not unzipped
+# If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir -
+# these files are put inside .apk package by build system
+# You can specify Google Play expansion files in the form 'obb:main.12345' or 'obb:patch.12345' where 12345 is the app version, first associated with the file
+AppDataDownloadUrl="!!Game data is 1 Mb|ballfield3.zip"
+
+# Reset SDL config when updating application to the new version (y) / (n)
+ResetSdlConfigForThisVersion=n
+
+# Delete application data files when upgrading (specify file/dir paths separated by spaces)
+DeleteFilesOnUpgrade="%"
+
+# Here you may type readme text, which will be shown during startup. Format is:
+# Text in English, use \\\\n to separate lines (that's four backslashes)^de:Text in Deutsch^ru:Text in Russian^button:Button that will open some URL:http://url-to-open/
+ReadmeText='^Readme text'
+
+# libSDL version to use (1.2/1.3/2.0)
+LibSdlVersion=1.2
+
+# Specify screen orientation: (v)ertical/(p)ortrait or (h)orizontal/(l)andscape
+ScreenOrientation=h
+
+# Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only
+# with SwVideoMode=y, SDL_OPENGL mode supports everything. (16)/(24)/(32)
+VideoDepthBpp=16
+
+# Enable OpenGL depth buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
+NeedDepthBuffer=n
+
+# Enable OpenGL stencil buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
+NeedStencilBuffer=n
+
+# Try to use GLES 2.x context - will revert to GLES 1.X if unsupported by device
+# you need this option only if you're developing 3-d app (y) or (n)
+NeedGles2=n
+
+# Application uses software video buffer - you're calling SDL_SetVideoMode() without SDL_HWSURFACE and without SDL_OPENGL,
+# this will allow small speed optimization. Enable this even when you're using SDL_HWSURFACE. (y) or (n)
+SwVideoMode=y
+
+# Application video output will be resized to fit into native device screen (y)/(n)
+SdlVideoResize=y
+
+# Application resizing will keep 4:3 aspect ratio, with black bars at sides (y)/(n)
+SdlVideoResizeKeepAspect=n
+
+# Do not allow device to sleep when the application is in foreground, set this for video players or apps which use accelerometer
+InhibitSuspend=n
+
+# Create Android service, so the app is less likely to be killed while in background
+CreateService=
+
+# Application does not call SDL_Flip() or SDL_UpdateRects() appropriately, or draws from non-main thread -
+# enabling the compatibility mode will force screen update every 100 milliseconds, which is laggy and inefficient (y) or (n)
+CompatibilityHacksForceScreenUpdate=n
+
+# Application does not call SDL_Flip() or SDL_UpdateRects() after mouse click (ScummVM and all Amiga emulators do that) -
+# force screen update by moving mouse cursor a little after each click (y) or (n)
+CompatibilityHacksForceScreenUpdateMouseClick=y
+
+# Application initializes SDL audio/video inside static constructors (which is bad, you won't be able to run ndk-gdb) (y)/(n)
+CompatibilityHacksStaticInit=n
+
+# On-screen Android soft text input emulates hardware keyboard, this will only work with Hackers Keyboard app (y)/(n)
+CompatibilityHacksTextInputEmulatesHwKeyboard=n
+
+# Built-in text input keyboards with custom layouts for emulators, requires CompatibilityHacksTextInputEmulatesHwKeyboard=y
+# 0 - standard Android keyboard
+# 1 - Simple QWERTY keyboard, no function keys, no arrow keys
+# 2 - Commodore 64 keyboard
+# 3 - Amiga keyboard
+TextInputKeyboard=3
+
+# Hack for broken devices: prevent audio chopping, by sleeping a bit after pushing each audio chunk (y)/(n)
+CompatibilityHacksPreventAudioChopping=n
+
+# Hack for broken apps: application ignores audio buffer size returned by SDL (y)/(n)
+CompatibilityHacksAppIgnoresAudioBufferSize=n
+
+# Hack for VCMI: preload additional shared libraries before aplication start
+CompatibilityHacksAdditionalPreloadedSharedLibraries=""
+
+# Hack for Free Heroes 2, which redraws the screen inside SDL_PumpEvents(): slow and compatible SDL event queue -
+# do not use it with accelerometer/gyroscope, or your app may freeze at random (y)/(n)
+CompatibilityHacksSlowCompatibleEventQueue=n
+
+# Save and restore OpenGL state when drawing on-screen keyboard for apps that use SDL_OPENGL
+CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState=
+
+# Application uses SDL_UpdateRects() properly, and does not draw in any region outside those rects.
+# This improves drawing speed, but I know only one application that does that, and it's written by me (y)/(n)
+CompatibilityHacksProperUsageOfSDL_UpdateRects=n
+
+# Application uses mouse (y) or (n), this will show mouse emulation dialog to the user
+AppUsesMouse=y
+
+# Application needs two-button mouse, will also enable advanced point-and-click features (y) or (n)
+AppNeedsTwoButtonMouse=y
+
+# Right mouse button can do long-press/drag&drop action, necessary for some games (y) or (n)
+# If you disable it, swiping with two fingers will send mouse wheel events
+RightMouseButtonLongPress=
+
+# Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n)
+ShowMouseCursor=n
+
+# Screen follows mouse cursor, when it's covered by soft keyboard, this works only in software video mode (y) or (n)
+ScreenFollowsMouse=
+
+# Generate more touch events, by default SDL generates one event per one video frame, this is useful for drawing apps (y) or (n)
+GenerateSubframeTouchEvents=n
+
+# Force relative (laptop) mouse movement mode, useful when both on-screen keyboard and mouse are needed (y) or (n)
+ForceRelativeMouseMode=y
+
+# Show on-screen dpad/joystick, that will act as arrow keys (y) or (n)
+AppNeedsArrowKeys=y
+
+# On-screen dpad/joystick will appear under finger when it touches the screen (y) or (n)
+# Joystick always follows finger, so moving mouse requires touching the screen with other finger
+FloatingScreenJoystick=n
+
+# Application needs text input (y) or (n), enables button for text input on screen
+AppNeedsTextInput=y
+
+# Application uses joystick (y) or (n), the on-screen DPAD will be used as joystick 0 axes 0-1
+# This will disable AppNeedsArrowKeys option
+AppUsesJoystick=n
+
+# Application uses second on-screen joystick, as SDL joystick 0 axes 2-3 (y)/(n)
+AppUsesSecondJoystick=n
+
+# Application uses third on-screen joystick, as SDL joystick 0 axes 20-21 (y)/(n)
+AppUsesThirdJoystick=n
+
+# Application uses accelerometer (y) or (n), the accelerometer will be used as joystick 1 axes 0-1 and 5-7
+AppUsesAccelerometer=y
+
+# Application uses gyroscope (y) or (n), the gyroscope will be used as joystick 1 axes 2-4
+AppUsesGyroscope=y
+
+# Application uses orientation sensor (y) or (n), reported as joystick 1 axes 8-10
+AppUsesOrientationSensor=
+
+# Use gyroscope to move mouse cursor (y) or (n), it eats battery, and can be disabled in settings, do not use with AppUsesGyroscope setting
+MoveMouseWithGyroscope=
+
+# Application uses multitouch (y) or (n), multitouch events are passed as SDL_JOYBALLMOTION events for the joystick 0
+AppUsesMultitouch=y
+
+# Application records audio (it will use any available source, such a s microphone)
+# API is defined in file SDL_android.h: int SDL_ANDROID_OpenAudioRecording(SDL_AudioSpec *spec); void SDL_ANDROID_CloseAudioRecording(void);
+# This option will add additional permission to Android manifest (y)/(n)
+AppRecordsAudio=y
+
+# Application needs to access SD card. If your data files are bigger than 5 Mb, enable it. (y) / (n)
+AccessSdCard=
+
+# Application needs Internet access. If you disable it, you'll have to bundle all your data files inside .apk (y) / (n)
+AccessInternet=
+
+# Immersive mode - Android will hide on-screen Home/Back keys. Looks bad if you invoke Android keyboard. (y) / (n)
+ImmersiveMode=y
+
+# Application implements Android-specific routines to put to background, and will not draw anything to screen
+# between SDL_ACTIVEEVENT lost / gained notifications - you should check for them
+# rigth after SDL_Flip(), if (n) then SDL_Flip() will block till app in background (y) or (n)
+# This option is reported to be buggy, sometimes failing to restore video state
+NonBlockingSwapBuffers=n
+
+# Redefine common hardware keys to SDL keysyms
+# BACK hardware key is available on all devices, MENU is available on pre-ICS devices, other keys may be absent
+# SEARCH and CALL by default return same keycode as DPAD_CENTER - one of those keys is available on most devices
+# Use word NO_REMAP if you want to preserve native functionality for certain key (volume keys are 3-rd and 4-th)
+# Keys: TOUCHSCREEN (works only when AppUsesMouse=n), DPAD_CENTER/SEARCH, VOLUMEUP, VOLUMEDOWN, MENU, BACK, CAMERA
+RedefinedKeys="SPACE RETURN NO_REMAP NO_REMAP SPACE ESCAPE"
+
+# Number of virtual keyboard keys (currently 6 is maximum)
+AppTouchscreenKeyboardKeysAmount=6
+
+# Redefine on-screen keyboard keys to SDL keysyms - 6 keyboard keys + 4 multitouch gestures (zoom in/out and rotate left/right)
+RedefinedKeysScreenKb="0 1 2 3 4 5 6 7 8 9"
+
+# Names for on-screen keyboard keys, such as Fire, Jump, Run etc, separated by spaces, they are used in SDL config menu
+RedefinedKeysScreenKbNames="0 1 2 3 4 5 6 7 8 9"
+
+# On-screen keys theme
+# 0 = Ultimate Droid by Sean Stieber (green, with cross joystick)
+# 1 = Simple Theme by Beholder (white, with cross joystick)
+# 2 = Sun by Sirea (yellow, with round joystick)
+# 3 = Keen by Gerstrong (multicolor, with round joystick)
+# 4 = Retro by Santiago Radeff (red/white, with cross joystick)
+TouchscreenKeysTheme=4
+
+# Redefine gamepad keys to SDL keysyms, button order is:
+# A B X Y L1 R1 L2 R2 LThumb RThumb
+RedefinedKeysGamepad="0 1 2 3 4 5 6 7 8 9"
+
+# How long to show startup menu button, in msec, 0 to disable startup menu
+StartupMenuButtonTimeout=3000
+
+# Menu items to hide from startup menu, available menu items:
+# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout SettingsMenuKeyboard.ScreenKeyboardAdvanced
+HiddenMenuOptions=''
+
+# Menu items to show at startup - this is Java code snippet, leave empty for default
+# new SettingsMenuMisc.ShowReadme(), (AppUsesMouse \&\& \! ForceRelativeMouseMode \? new SettingsMenuMouse.DisplaySizeConfig(true) : new SettingsMenu.DummyMenu()), new SettingsMenuMisc.OptionalDownloadConfig(true), new SettingsMenuMisc.GyroscopeCalibration()
+# Available menu items:
+# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout SettingsMenuKeyboard.ScreenKeyboardAdvanced
+FirstStartMenuOptions='SettingsMenu.DummyMenu'
+
+# Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower
+AppMinimumRAM=0
+
+# GCC version, 4.6 (default) or 4.8, CLANG is not supported yet
+NDK_TOOLCHAIN_VERSION=
+
+# Specify architectures to compile, 'all' or 'y' to compile for all architectures.
+# Available architectures: armeabi armeabi-v7a armeabi-v7a-hard x86 mips
+MultiABI='armeabi-v7a x86'
+
+# Optional shared libraries to compile - removing some of them will save space
+# MP3 support by libMAD is encumbered by patents and libMAD is GPL-ed
+# Available libraries: mad (GPL-ed!) sdl_mixer sdl_image sdl_ttf sdl_net sdl_blitpool sdl_gfx sdl_sound intl xml2 lua jpeg png ogg flac tremor vorbis freetype xerces curl theora fluidsynth lzma lzo2 mikmod openal timidity zzip bzip2 yaml-cpp python boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread glu avcodec avdevice avfilter avformat avresample avutil swscale swresample bzip2
+CompiledLibraries="sdl_image"
+
+# Application uses custom build script AndroidBuild.sh instead of Android.mk (y) or (n)
+CustomBuildScript=n
+
+# Aditional CFLAGS for application
+AppCflags='-O2 -finline-functions'
+
+# Additional LDFLAGS for application
+AppLdflags='-fuse-ld=bfd'
+
+# If application has headers with the same name as system headers, this option tries to fix compiler flags to make it compilable
+AppOverlapsSystemHeaders=
+
+# Build only following subdirs (empty will build all dirs, ignored with custom script)
+AppSubdirsBuild=''
+
+# Exclude these files from build
+AppBuildExclude=''
+
+# Application command line parameters, including app name as 0-th param
+AppCmdline=''
+
+# Screen size is used by Google Play to prevent an app to be installed on devices with smaller screens
+# Minimum screen size that application supports: (s)mall / (m)edium / (l)arge
+MinimumScreenSize=s
+
+# Your AdMob Publisher ID, (n) if you don't want advertisements
+AdmobPublisherId=n
+
+# Your AdMob test device ID, to receive a test ad
+AdmobTestDeviceId=
+
+# Your AdMob banner size (BANNER/FULL_BANNER/LEADERBOARD/MEDIUM_RECTANGLE/SMART_BANNER/WIDE_SKYSCRAPER/FULL_WIDTH:Height/Width:AUTO_HEIGHT/Width:Height)
+AdmobBannerSize=
+
+# Google Play Game Services application ID, required for cloud saves to work
+GooglePlayGameServicesId=
+
diff --git a/project/jni/application/test-record-audio/AndroidData/ballfield3.zip b/project/jni/application/test-record-audio/AndroidData/ballfield3.zip
new file mode 100644
index 000000000..463c70ee8
Binary files /dev/null and b/project/jni/application/test-record-audio/AndroidData/ballfield3.zip differ
diff --git a/project/jni/application/test-record-audio/ballfield.cpp b/project/jni/application/test-record-audio/ballfield.cpp
new file mode 100644
index 000000000..7eb987475
--- /dev/null
+++ b/project/jni/application/test-record-audio/ballfield.cpp
@@ -0,0 +1,816 @@
+/*
+ * "Ballfield"
+ *
+ * (C) David Olofson , 2002, 2003
+ *
+ * This software is released under the terms of the GPL.
+ *
+ * Contact author for permission if you want to use this
+ * software, or work derived from it, under other terms.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#define fprintf(X, ...) __android_log_print(ANDROID_LOG_INFO, "Ballfield", __VA_ARGS__)
+#define printf(...) __android_log_print(ANDROID_LOG_INFO, "Ballfield", __VA_ARGS__)
+
+/*----------------------------------------------------------
+ Definitions...
+----------------------------------------------------------*/
+
+#define SCREEN_W 640
+#define SCREEN_H 256
+
+
+#define BALLS 300
+
+#define COLORS 2
+
+typedef struct
+{
+ Sint32 x, y, z; /* Position */
+ Uint32 c; /* Color */
+} point_t;
+
+
+/*
+ * Ballfield
+ */
+typedef struct
+{
+ point_t points[BALLS];
+ SDL_Rect *frames;
+ SDL_Surface *gfx[COLORS];
+ int use_alpha;
+} ballfield_t;
+
+
+/*
+ * Size of the biggest ball image in pixels
+ *
+ * Balls are scaled down and *packed*, one pixel
+ * smaller for each frame down to 1x1. The actual
+ * image width is (obviously...) the same as the
+ * width of the first frame.
+ */
+#define BALL_W 32
+#define BALL_H 32
+
+
+
+
+/*----------------------------------------------------------
+ General tool functions
+----------------------------------------------------------*/
+
+/*
+ * Bump areas of low and high alpha to 0% or 100%
+ * respectively, just in case the graphics contains
+ * "alpha noise".
+ */
+SDL_Surface *clean_alpha(SDL_Surface *s)
+{
+ SDL_Surface *work;
+ SDL_Rect r;
+ Uint32 *pixels;
+ int pp;
+ int x, y;
+
+ work = SDL_CreateRGBSurface(SDL_SWSURFACE, s->w, s->h,
+ 32, 0xff000000, 0x00ff0000, 0x0000ff00,
+ 0x000000ff);
+ if(!work)
+ return NULL;
+
+ r.x = r.y = 0;
+ r.w = s->w;
+ r.h = s->h;
+ if(SDL_BlitSurface(s, &r, work, NULL) < 0)
+ {
+ SDL_FreeSurface(work);
+ return NULL;
+ }
+
+ SDL_LockSurface(work);
+ pixels = (Uint32 *)work->pixels;
+ pp = work->pitch / sizeof(Uint32);
+ for(y = 0; y < work->h; ++y)
+ for(x = 0; x < work->w; ++x)
+ {
+ Uint32 pix = pixels[y*pp + x];
+ switch((pix & 0xff) >> 4)
+ {
+ case 0:
+ pix = 0x00000000;
+ break;
+ default:
+ break;
+ case 15:
+ pix |= 0xff;
+ break;
+ }
+ pixels[y*pp + x] = pix;
+ }
+ SDL_UnlockSurface(work);
+
+ return work;
+}
+
+
+/*
+ * Load and convert an antialiazed, zoomed set of sprites.
+ */
+SDL_Surface *load_zoomed(char *name, int alpha)
+{
+ SDL_Surface *sprites;
+ SDL_Surface *temp = IMG_Load(name);
+ if(!temp)
+ return NULL;
+
+ /*
+ sprites = temp;
+ SDL_SetAlpha(sprites, 0, 255);
+ temp = clean_alpha(sprites);
+ SDL_FreeSurface(sprites);
+ */
+ if(!temp)
+ {
+ fprintf(stderr, "Could not clean alpha!\n");
+ return NULL;
+ }
+
+ if(alpha)
+ {
+ SDL_SetAlpha(temp, 0, SDL_ALPHA_OPAQUE);
+ sprites = SDL_DisplayFormatAlpha(temp);
+ }
+ else
+ {
+ SDL_SetColorKey(temp, SDL_SRCCOLORKEY,
+ SDL_MapRGB(temp->format, 0, 0, 0));
+ sprites = SDL_DisplayFormat(temp);
+ }
+ SDL_FreeSurface(temp);
+
+ return sprites;
+}
+
+
+void print_num(SDL_Surface *dst, SDL_Surface *font, int x, int y, float value)
+{
+ char buf[16];
+ int val = (int)(value * 10.0);
+ int pos, p = 0;
+ SDL_Rect from;
+
+ /* Sign */
+ if(val < 0)
+ {
+ buf[p++] = 10;
+ val = -val;
+ }
+
+ /* Integer part */
+ pos = 10000000;
+ while(pos > 1)
+ {
+ int num = val / pos;
+ val -= num * pos;
+ pos /= 10;
+ if(p || num)
+ buf[p++] = num;
+ }
+
+ /* Decimals */
+ if(val / pos)
+ {
+ buf[p++] = 11;
+ while(pos > 0)
+ {
+ int num = val / pos;
+ val -= num * pos;
+ pos /= 10;
+ buf[p++] = num;
+ }
+ }
+
+ /* Render! */
+ from.y = 0;
+ from.w = 7;
+ from.h = 10;
+ for(pos = 0; pos < p; ++pos)
+ {
+ SDL_Rect to;
+ to.x = x + pos * 7;
+ to.y = y;
+ from.x = buf[pos] * 7;
+ SDL_BlitSurface(font, &from, dst, &to);
+ }
+}
+
+void print_num_hex(SDL_Surface *dst, SDL_Surface *font, int x, int y, unsigned val)
+{
+ char buf[8];
+ int pos, p = 0;
+ SDL_Rect from;
+
+ //val = htonl(val); // Big-endian
+
+ /* Render! */
+ from.y = 0;
+ from.w = 7;
+ from.h = 10;
+ for(pos = 0; pos < 8; ++pos)
+ {
+ SDL_Rect to;
+ to.x = 8 * 7 - (x + pos * 7); // Little-endian number wrapped backwards
+ to.y = y;
+ from.x = ( ( val >> (pos * 4) ) & 0xf ) * 7;
+ SDL_BlitSurface(font, &from, dst, &to);
+ }
+}
+
+/*----------------------------------------------------------
+ ballfield_t functions
+----------------------------------------------------------*/
+
+ballfield_t *ballfield_init(void)
+{
+ int i;
+ ballfield_t *bf = (ballfield_t *)calloc(sizeof(ballfield_t), 1);
+ if(!bf)
+ return NULL;
+ for(i = 0; i < BALLS; ++i)
+ {
+ bf->points[i].x = rand() % 0x20000;
+ bf->points[i].y = rand() % 0x20000;
+ bf->points[i].z = 0x20000 * i / BALLS;
+ if(rand() % 100 > 80)
+ bf->points[i].c = 1;
+ else
+ bf->points[i].c = 0;
+ }
+ return bf;
+}
+
+
+void ballfield_free(ballfield_t *bf)
+{
+ int i;
+ for(i = 0; i < COLORS; ++i)
+ SDL_FreeSurface(bf->gfx[i]);
+}
+
+
+static int ballfield_init_frames(ballfield_t *bf)
+{
+ int i, j;
+ /*
+ * Set up source rects for all frames
+ */
+ bf->frames = (SDL_Rect *)calloc(sizeof(SDL_Rect), bf->gfx[0]->w);
+ if(!bf->frames)
+ {
+ fprintf(stderr, "No memory for frame rects!\n");
+ return -1;
+ }
+ for(j = 0, i = 0; i < bf->gfx[0]->w; ++i)
+ {
+ bf->frames[i].x = 0;
+ bf->frames[i].y = j;
+ bf->frames[i].w = bf->gfx[0]->w - i;
+ bf->frames[i].h = bf->gfx[0]->w - i;
+ j += bf->gfx[0]->w - i;
+ }
+ return 0;
+}
+
+
+int ballfield_load_gfx(ballfield_t *bf, char *name, unsigned int color)
+{
+ if(color >= COLORS)
+ return -1;
+
+ bf->gfx[color] = load_zoomed(name, bf->use_alpha);
+ if(!bf->gfx[color])
+ return -2;
+
+ if(!bf->frames)
+ return ballfield_init_frames(bf);
+
+ return 0;
+}
+
+
+void ballfield_move(ballfield_t *bf, Sint32 dx, Sint32 dy, Sint32 dz)
+{
+ int i;
+ for(i = 0; i < BALLS; ++i)
+ {
+ bf->points[i].x += dx;
+ bf->points[i].x &= 0x1ffff;
+ bf->points[i].y += dy;
+ bf->points[i].y &= 0x1ffff;
+ bf->points[i].z += dz;
+ bf->points[i].z &= 0x1ffff;
+ }
+}
+
+
+void ballfield_render(ballfield_t *bf, SDL_Surface *screen)
+{
+ int i, j, z;
+
+ /*
+ * Find the ball with the highest Z.
+ */
+ z = 0;
+ j = 0;
+ for(i = 0; i < BALLS; ++i)
+ {
+ if(bf->points[i].z > z)
+ {
+ j = i;
+ z = bf->points[i].z;
+ }
+ }
+
+ /*
+ * Render all balls in back->front order.
+ */
+ for(i = 0; i < BALLS; ++i)
+ {
+ SDL_Rect r;
+ int f;
+ z = bf->points[j].z;
+ z += 50;
+ f = ((bf->frames[0].w << 12) + 100000) / z;
+ f = bf->frames[0].w - f;
+ if(f < 0)
+ f = 0;
+ else if(f > bf->frames[0].w - 1)
+ f = bf->frames[0].w - 1;
+ z >>= 7;
+ z += 1;
+ r.x = (bf->points[j].x - 0x10000) / z;
+ r.y = (bf->points[j].y - 0x10000) / z;
+ r.x += (screen->w - bf->frames[f].w) >> 1;
+ r.y += (screen->h - bf->frames[f].h) >> 1;
+ SDL_BlitSurface(bf->gfx[bf->points[j].c],
+ &bf->frames[f], screen, &r);
+ if(--j < 0)
+ j = BALLS - 1;
+ }
+}
+
+
+
+/*----------------------------------------------------------
+ Other rendering functions
+----------------------------------------------------------*/
+
+/*
+ * Draw tiled background image with offset.
+ */
+void tiled_back(SDL_Surface *back, SDL_Surface *screen, int xo, int yo)
+{
+ /*
+ int x, y;
+ SDL_Rect r;
+ if(xo < 0)
+ xo += back->w*(-xo/back->w + 1);
+ if(yo < 0)
+ yo += back->h*(-yo/back->h + 1);
+ xo %= back->w;
+ yo %= back->h;
+ for(y = -yo; y < screen->h; y += back->h)
+ for(x = -xo; x < screen->w; x += back->w)
+ {
+ r.x = x;
+ r.y = y;
+ SDL_BlitSurface(back, NULL, screen, &r);
+ }
+ */
+ SDL_Rect r;
+ xo %= back->w/8;
+ yo %= back->h/8;
+ r.x = xo - back->w/2 + screen->w/2;
+ r.y = yo - back->h/2 + screen->h/2;
+ r.w = back->w;
+ r.h = back->h;
+ SDL_BlitSurface(back, NULL, screen, &r);
+}
+
+enum { REC_BUF_SIZE = SCREEN_W };
+Sint16 rec_buffer[REC_BUF_SIZE];
+int rec_pos = 0;
+
+static void rec_callback(void *userdata, Uint8 *stream, int len)
+{
+ int pos = rec_pos;
+ if( pos + len > REC_BUF_SIZE )
+ pos = 0;
+ //Com_Printf("[skipnotify] rec_callback: memcpy pos %d len %d rec_read %d\n", pos, len, rec_read);
+ memcpy( rec_buffer + pos, stream, len );
+ pos += len;
+ rec_pos = pos;
+}
+
+/*----------------------------------------------------------
+ main()
+----------------------------------------------------------*/
+
+int main(int argc, char* argv[])
+{
+ ballfield_t *balls;
+ SDL_Surface *screen;
+ SDL_Surface *temp_image;
+ SDL_Surface *back, *logo, *font, *font_hex;
+ SDL_Event event;
+ int bpp = 16,
+ flags = SDL_HWSURFACE,
+ alpha = 1;
+ int x_offs = 0, y_offs = 0;
+ long tick,
+ last_tick,
+ last_avg_tick;
+ double t = 0;
+ float dt;
+ int i;
+ float fps = 0.0;
+ int fps_count = 0;
+ int fps_start = 0;
+ float x_speed, y_speed, z_speed;
+ enum { MAX_POINTERS = 16 };
+ // some random colors
+ int colors[MAX_POINTERS] = { 0xaaaaaa, 0xffffff, 0x888888, 0xcccccc, 0x666666, 0x999999, 0xdddddd, 0xeeeeee, 0xaaaaaa, 0xffffff, 0x888888, 0xcccccc, 0x666666, 0x999999, 0xdddddd, 0xeeeeee };
+ struct TouchPointer_t { int x; int y; int pressure; int pressed; } touchPointers[MAX_POINTERS];
+ int accel[5], screenjoy[4], gamepads[4][8];
+ SDL_Surface *mouse[4];
+ int screenKeyboardShown = 0;
+ SDL_AudioSpec spec;
+
+
+ SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
+ SDL_EnableUNICODE(1);
+ SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+ SDL_Joystick * joysticks[6];
+ for( i = 0; i < 6; i++ )
+ joysticks[i] = SDL_JoystickOpen(i);
+
+ atexit(SDL_Quit);
+
+ screen = SDL_SetVideoMode(SCREEN_W, SCREEN_H, bpp, flags);
+ if(!screen)
+ {
+ fprintf(stderr, "Failed to open screen!\n");
+ exit(-1);
+ }
+
+ SDL_WM_SetCaption("Ballfield", "Ballfield");
+ if(flags & SDL_FULLSCREEN)
+ SDL_ShowCursor(0);
+
+ balls = ballfield_init();
+ if(!balls)
+ {
+ fprintf(stderr, "Failed to create ballfield!\n");
+ exit(-1);
+ }
+
+ /*
+ * Load and prepare balls...
+ */
+ balls->use_alpha = alpha;
+ if( ballfield_load_gfx(balls, "blueball.png", 0)
+ ||
+ ballfield_load_gfx(balls, "redball.png", 1) )
+ {
+ fprintf(stderr, "Could not load balls!\n");
+ exit(-1);
+ }
+
+ /*
+ * Load background image
+ */
+ temp_image = IMG_Load("sun.gif");
+ if(!temp_image)
+ {
+ fprintf(stderr, "Could not load background!\n");
+ exit(-1);
+ }
+ back = SDL_DisplayFormat(temp_image);
+ SDL_FreeSurface(temp_image);
+
+ /*
+ * Load logo
+ */
+ temp_image = SDL_LoadBMP("logo.bmp");
+ if(!temp_image)
+ {
+ fprintf(stderr, "Could not load logo!\n");
+ exit(-1);
+ }
+ SDL_SetColorKey(temp_image, SDL_SRCCOLORKEY,
+ SDL_MapRGB(temp_image->format, 255, 0, 255));
+ logo = SDL_DisplayFormat(temp_image);
+ SDL_FreeSurface(temp_image);
+
+ /*
+ * Load font
+ */
+ temp_image = SDL_LoadBMP("font7x10.bmp");
+ if(!temp_image)
+ {
+ fprintf(stderr, "Could not load font!\n");
+ exit(-1);
+ }
+ SDL_SetColorKey(temp_image, SDL_SRCCOLORKEY,
+ SDL_MapRGB(temp_image->format, 255, 0, 255));
+ font = SDL_DisplayFormat(temp_image);
+ SDL_FreeSurface(temp_image);
+
+ temp_image = SDL_LoadBMP("font7x10-hex.bmp");
+ if(!temp_image)
+ {
+ fprintf(stderr, "Could not load hex font!\n");
+ exit(-1);
+ }
+ SDL_SetColorKey(temp_image, SDL_SRCCOLORKEY,
+ SDL_MapRGB(temp_image->format, 255, 0, 255));
+ font_hex = SDL_DisplayFormat(temp_image);
+ SDL_FreeSurface(temp_image);
+
+ for(i = 0; i < 4; i++)
+ {
+ char name[32];
+ sprintf(name, "mouse%d.png", i);
+ temp_image = IMG_Load(name);
+ if(!temp_image)
+ {
+ fprintf(stderr, "Could not load %s!\n", name);
+ exit(-1);
+ }
+ //mouse[i] = SDL_DisplayFormat(temp_image);
+ //SDL_FreeSurface(temp_image);
+ mouse[i] = temp_image; // Keep alpha
+ }
+
+ last_avg_tick = last_tick = SDL_GetTicks();
+
+ memset(touchPointers, 0, sizeof(touchPointers));
+ memset(accel, 0, sizeof(accel));
+ memset(screenjoy, 0, sizeof(screenjoy));
+ memset(gamepads, 0, sizeof(gamepads));
+
+ __android_log_print(ANDROID_LOG_INFO, "Ballfield", "sizeof(int) %d long %d long long %d size_t %d", sizeof(int), sizeof(long), sizeof(long long), sizeof(size_t));
+ /*
+ wchar_t ss[256];
+ const wchar_t *ss2 = L"String 2 ЕНГ ---";
+ swprintf(ss, 256, L"String ЙЦУК --- %ls", ss2);
+ char ss3[512] = "";
+ char ss4[512] = "";
+ for(i = 0; i < wcslen(ss); i++)
+ {
+ char tmp[16];
+ sprintf(tmp, "%04X ", (int)ss[i]);
+ strcat(ss3, tmp);
+ sprintf(ss4, "%ls", ss);
+ }
+ __android_log_print(ANDROID_LOG_VERBOSE, "Ballfield", "swprintf: len %d data %s: %s", wcslen(ss), ss3, ss4);
+ */
+
+ __android_log_print(ANDROID_LOG_VERBOSE, "Ballfield", "On-screen buttons:");
+ for(i = 0; i < SDL_ANDROID_SCREENKEYBOARD_BUTTON_NUM; i++)
+ {
+ SDL_Rect r;
+ SDL_ANDROID_GetScreenKeyboardButtonPos(i, &r);
+ __android_log_print(ANDROID_LOG_VERBOSE, "Ballfield", "{ %d, %d, %d, %d },", r.x, r.y, r.x+r.h, r.y+r.w);
+ }
+ //SDL_ANDROID_SetScreenKeyboardButtonGenerateTouchEvents(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, 1);
+ //SDL_ANDROID_SetScreenKeyboardButtonGenerateTouchEvents(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, 1);
+
+ if( !SDL_WasInit( SDL_INIT_AUDIO ) ) {
+ SDL_InitSubSystem( SDL_INIT_AUDIO );
+ }
+ memset( &spec, 0, sizeof(spec) );
+ spec.freq = 8000;
+ spec.format = AUDIO_S16;
+ spec.channels = 1;
+ spec.size = sizeof(rec_buffer);
+ spec.callback = rec_callback;
+ spec.userdata = NULL;
+ SDL_ANDROID_OpenAudioRecording(&spec);
+
+ while(1)
+ {
+ SDL_Rect r;
+
+ /* Timing */
+ tick = SDL_GetTicks();
+ dt = (tick - last_tick) * 0.001f;
+ last_tick = tick;
+
+ if( bpp == 32 )
+ SDL_FillRect(screen, NULL, 0); // Clear alpha channel
+
+ /* Background image */
+ tiled_back(back, screen, x_offs>>11, y_offs>>11);
+
+ /* Ballfield */
+ ballfield_render(balls, screen);
+
+ /* Logo */
+ r.x = 2;
+ r.y = 2;
+ SDL_BlitSurface(logo, NULL, screen, &r);
+
+ /* FPS counter */
+ if(tick > fps_start + 1000)
+ {
+ fps = (float)fps_count * 1000.0 / (tick - fps_start);
+ fps_count = 0;
+ fps_start = tick;
+ }
+
+ print_num(screen, font, screen->w-37, screen->h-12, fps);
+ ++fps_count;
+
+ for(i=0; iw;
+ r.h = mouse[cursorIdx]->h;
+ r.x -= r.w/2;
+ r.y -= r.h/2;
+
+ for (i = 0; i < SCREEN_W; i++)
+ {
+ int r = SCREEN_H / 2 + (int)rec_buffer[i] * SCREEN_H / 2 / 65536;
+ if (r < 0)
+ r = 0;
+ if (r >= SCREEN_H)
+ r = SCREEN_H - 1;
+ *(Uint16 *)(((Uint8 *)SDL_GetVideoSurface()->pixels) + r * SDL_GetVideoSurface()->pitch + i * 2) = 0xffff;
+ }
+
+ SDL_BlitSurface(mouse[cursorIdx], NULL, screen, &r);
+
+ SDL_Flip(SDL_GetVideoSurface());
+ SDL_Event evt;
+ while( SDL_PollEvent(&evt) )
+ {
+ if(evt.type == SDL_KEYUP || evt.type == SDL_KEYDOWN)
+ {
+ __android_log_print(ANDROID_LOG_INFO, "Ballfield", "SDL key event: evt %s state %s key %4d %12s scancode %4d mod %2d unicode %d", evt.type == SDL_KEYUP ? "UP " : "DOWN" , evt.key.state == SDL_PRESSED ? "PRESSED " : "RELEASED", (int)evt.key.keysym.sym, SDL_GetKeyName(evt.key.keysym.sym), (int)evt.key.keysym.scancode, (int)evt.key.keysym.mod, (int)evt.key.keysym.unicode);
+ if(evt.key.keysym.sym == SDLK_ESCAPE)
+ return 0;
+ if( evt.key.state == SDL_RELEASED )
+ {
+ if(evt.key.keysym.sym == SDLK_0)
+ SDL_ANDROID_OpenAudioRecording(&spec);
+ if(evt.key.keysym.sym == SDLK_1)
+ SDL_ANDROID_CloseAudioRecording();
+ if(evt.key.keysym.sym == SDLK_2)
+ {
+ SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, 1);
+ screen = SDL_SetVideoMode(SCREEN_W, SDL_GetVideoSurface()->h + 1, bpp, flags);
+ }
+ if(evt.key.keysym.sym == SDLK_3)
+ SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, 0);
+ if(evt.key.keysym.sym == SDLK_4)
+ SDL_ToggleScreenKeyboard(NULL);
+ if(evt.key.keysym.sym == SDLK_5)
+ SDL_ANDROID_ToggleScreenKeyboardWithoutTextInput();
+ }
+ }
+ if(evt.type == SDL_MOUSEBUTTONUP || evt.type == SDL_MOUSEBUTTONDOWN)
+ {
+ __android_log_print(ANDROID_LOG_INFO, "Ballfield", "SDL mouse button event: evt %s state %s button %d coords %d:%d", evt.type == SDL_MOUSEBUTTONUP ? "UP " : "DOWN" , evt.button.state == SDL_PRESSED ? "PRESSED " : "RELEASED", (int)evt.button.button, (int)evt.button.x, (int)evt.button.y);
+ }
+ if(evt.type == SDL_VIDEORESIZE)
+ __android_log_print(ANDROID_LOG_INFO, "Ballfield", "SDL resize event: %d x %d", evt.resize.w, evt.resize.h);
+ if(evt.type == SDL_ACTIVEEVENT)
+ __android_log_print(ANDROID_LOG_INFO, "Ballfield", "======= SDL active event: gain %d state %d", evt.active.gain, evt.active.state);
+ // Android-specific events - accelerometer, multitoush, and on-screen joystick
+ if( evt.type == SDL_JOYAXISMOTION )
+ {
+ if(evt.jaxis.which == 0) // Multitouch and on-screen joysticks
+ {
+ if(evt.jaxis.axis < 4)
+ screenjoy[evt.jaxis.axis] = evt.jaxis.value;
+ else
+ touchPointers[evt.jaxis.axis - 4].pressure = evt.jaxis.value;
+ }
+ if(evt.jaxis.which == 1)
+ {
+ accel[evt.jaxis.axis] = evt.jaxis.value; // accelerometer and gyroscope
+ }
+ if(evt.jaxis.which >= 2)
+ {
+ // Each gamepad has 8 axes - two joystick hats, two triggers, and Ouya touchpad
+ gamepads[evt.jaxis.which - 2][evt.jaxis.axis] = evt.jaxis.value;
+ }
+ }
+ if( evt.type == SDL_JOYBUTTONDOWN || evt.type == SDL_JOYBUTTONUP )
+ {
+ if(evt.jbutton.which == 0) // Multitouch and on-screen joystick
+ touchPointers[evt.jbutton.button].pressed = (evt.jbutton.state == SDL_PRESSED);
+ }
+ if( evt.type == SDL_JOYBALLMOTION )
+ {
+ if(evt.jball.which == 0) // Multitouch and on-screen joystick
+ {
+ touchPointers[evt.jball.ball].x = evt.jball.xrel;
+ touchPointers[evt.jball.ball].y = evt.jball.yrel;
+ }
+ }
+ }
+ if( screenKeyboardShown != SDL_IsScreenKeyboardShown(NULL))
+ {
+ __android_log_print(ANDROID_LOG_INFO, "Ballfield", "Screen keyboard shown: %d -> %d", screenKeyboardShown, SDL_IsScreenKeyboardShown(NULL));
+ screenKeyboardShown = SDL_IsScreenKeyboardShown(NULL);
+ }
+
+ /* Animate */
+ x_speed = 500.0 * sin(t * 0.37);
+ y_speed = 500.0 * sin(t * 0.53);
+ z_speed = 400.0 * sin(t * 0.21);
+ if( SDL_GetKeyState(NULL)[SDLK_LEFT] )
+ x_speed -= 100000 * dt;
+ if( SDL_GetKeyState(NULL)[SDLK_RIGHT] )
+ x_speed += 100000 * dt;
+ if( SDL_GetKeyState(NULL)[SDLK_UP] )
+ y_speed -= 100000 * dt;
+ if( SDL_GetKeyState(NULL)[SDLK_DOWN] )
+ y_speed += 100000 * dt;
+
+ ballfield_move(balls, x_speed, y_speed, z_speed);
+ x_offs -= x_speed;
+ y_offs -= y_speed;
+
+ t += dt;
+ }
+
+ ballfield_free(balls);
+ SDL_FreeSurface(back);
+ SDL_FreeSurface(logo);
+ SDL_FreeSurface(font);
+ return 0;
+}
diff --git a/project/jni/application/test-record-audio/banner.png b/project/jni/application/test-record-audio/banner.png
new file mode 100644
index 000000000..bfc20e38c
Binary files /dev/null and b/project/jni/application/test-record-audio/banner.png differ
diff --git a/project/jni/application/test-record-audio/icon.png b/project/jni/application/test-record-audio/icon.png
new file mode 100644
index 000000000..b3614e149
Binary files /dev/null and b/project/jni/application/test-record-audio/icon.png differ