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