SDL: show Marshmallow permission dialog for recording audio

Updated SuperTux
This commit is contained in:
Sergii Pylypenko
2016-05-27 19:34:34 +03:00
parent 87e9b75d98
commit 22e7f45f6f
13 changed files with 1153 additions and 1753 deletions

3
.gitmodules vendored
View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -1 +0,0 @@
supertux

View File

@@ -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'

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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=

View File

@@ -0,0 +1,816 @@
/*
* "Ballfield"
*
* (C) David Olofson <david@olofson.net>, 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 <stdlib.h>
#include <string.h>
#include <math.h>
#include <android/log.h>
#include <wchar.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_screenkeyboard.h>
#include <SDL/SDL_android.h>
#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; i<MAX_POINTERS; i++)
{
if( !touchPointers[i].pressed )
continue;
r.x = touchPointers[i].x;
r.y = touchPointers[i].y;
r.w = 50 + touchPointers[i].pressure / 5;
r.h = 50 + touchPointers[i].pressure / 5;
r.x -= r.w/2;
r.y -= r.h/2;
SDL_FillRect(screen, &r, colors[i]);
}
int joyInput[][3] = {
{accel[0], accel[1], 10},
{accel[2], accel[3], 10 + abs(accel[4]) * 100 / 32767},
{screenjoy[0], screenjoy[1], 10},
{screenjoy[2], screenjoy[3], 10},
{gamepads[0][0], gamepads[0][1], 10 + gamepads[0][4] * 100 / 32767},
{gamepads[0][2], gamepads[0][3], 10 + gamepads[0][5] * 100 / 32767},
{gamepads[0][6], gamepads[0][7], 10},
{gamepads[1][0], gamepads[1][1], 10 + gamepads[1][4] * 100 / 32767},
{gamepads[1][2], gamepads[1][3], 10 + gamepads[1][5] * 100 / 32767},
{gamepads[1][6], gamepads[1][7], 10},
{gamepads[2][0], gamepads[2][1], 10 + gamepads[2][4] * 100 / 32767},
{gamepads[2][2], gamepads[2][3], 10 + gamepads[2][5] * 100 / 32767},
{gamepads[2][6], gamepads[2][7], 10},
{gamepads[3][0], gamepads[3][1], 10 + gamepads[3][4] * 100 / 32767},
{gamepads[3][2], gamepads[3][3], 10 + gamepads[3][5] * 100 / 32767},
{gamepads[3][6], gamepads[3][7], 10},
};
for( i = 0; i < 15; i++ )
{
r.w = joyInput[i][2];
r.h = joyInput[i][2];
r.x = SCREEN_W/2 + joyInput[i][0] * SCREEN_H / 65536 - r.w/2;
r.y = SCREEN_H/2 + joyInput[i][1] * SCREEN_H / 65536 - r.w/2;
//__android_log_print(ANDROID_LOG_INFO, "Ballfield", "Joy input %d: %d %d %d", i, joyInput[i][0], joyInput[i][1], joyInput[i][2] );
SDL_FillRect(screen, &r, i * 123);
}
int mx, my;
int b = SDL_GetMouseState(&mx, &my);
//__android_log_print(ANDROID_LOG_INFO, "Ballfield", "Mouse: %04d %04d buttons %d", mx, my, b);
int cursorIdx = 0;
if( b & SDL_BUTTON_LMASK )
cursorIdx |= 1;
if( b & SDL_BUTTON_RMASK )
cursorIdx |= 2;
r.x = mx;
r.y = my;
r.w = mouse[cursorIdx]->w;
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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB