Ticket #2996: 0002-A-small-step-for-wildfiregames-one-giant-leap-for-An.4.patch

File 0002-A-small-step-for-wildfiregames-one-giant-leap-for-An.4.patch, 182.1 KB (added by BogDan, 9 years ago)
  • .gitignore

    From f6b4d2a600a1eb838cac1cc41f369a5096a99647 Mon Sep 17 00:00:00 2001
    From: BogDan Vatra <bogdan@kde.org>
    Date: Tue, 27 Jan 2015 13:44:49 +0200
    Subject: [PATCH 2/6] A small step for wildfiregames one giant leap for
     Android!
    
    - Add QtCreator projects
    - Add SDL activity.
    - Fix compile for Android
    - Say hello to apitrace for 0 A.D.
      Apitrace can be used to trace GL call on Android.
      To enable it add "CONFIG+=apitrace" to qmake parameters.
    ---
     .gitignore                                         |    8 +
     .../android/qtcreator/android/AndroidManifest.xml  |   41 +
     build/android/qtcreator/android/build.gradle       |   51 +
     .../android/gradle/wrapper/gradle-wrapper.jar      |  Bin 0 -> 49896 bytes
     .../gradle/wrapper/gradle-wrapper.properties       |    6 +
     build/android/qtcreator/android/gradlew            |  164 +++
     build/android/qtcreator/android/gradlew.bat        |   90 ++
     .../qtcreator/android/res/drawable/zeroad.png      |  Bin 0 -> 65896 bytes
     .../android/qtcreator/android/res/values/libs.xml  |   25 +
     .../qtcreator/android/res/values/strings.xml       |    4 +
     .../android/src/com/play0ad/Activity.java          |  113 ++
     .../qtcreator/android/src/com/play0ad/Native.java  |    5 +
     .../android/src/com/play0ad/QtCreatorDebugger.java |  242 +++++
     .../android/src/org/libsdl/app/SDLActivity.java    | 1074 ++++++++++++++++++++
     build/android/qtcreator/android_support.pro        |  121 +++
     build/android/qtcreator/atlas.pro                  |    8 +
     build/android/qtcreator/common.pri                 |   25 +
     build/android/qtcreator/engine.pro                 |   38 +
     build/android/qtcreator/graphics.pro               |   11 +
     build/android/qtcreator/gui.pro                    |    2 +
     build/android/qtcreator/lobby.pro                  |    8 +
     build/android/qtcreator/lowlevel.pro               |   60 ++
     build/android/qtcreator/main.pro                   |   42 +
     build/android/qtcreator/mongoose.pro               |    5 +
     build/android/qtcreator/network.pro                |    2 +
     build/android/qtcreator/qtcreator.pro              |   29 +
     build/android/qtcreator/scriptinterface.pro        |    3 +
     build/android/qtcreator/sdl.pro                    |   36 +
     build/android/qtcreator/simulation2.pro            |   14 +
     build/android/qtcreator/staticlib.pri              |   16 +
     build/android/qtcreator/tinygettext.pro            |    7 +
     source/lib/sysdep/os/android/android.cpp           |    7 +-
     source/lib/sysdep/os/linux/lcpu.cpp                |    6 +-
     .../sysdep/os/unix/unix_executable_pathname.cpp    |   10 +-
     source/main.cpp                                    |   20 +-
     source/ps/TouchInput.cpp                           |    3 +
     source/scriptinterface/ScriptInterface.cpp         |    4 +-
     37 files changed, 2284 insertions(+), 16 deletions(-)
     create mode 100644 build/android/qtcreator/android/AndroidManifest.xml
     create mode 100644 build/android/qtcreator/android/build.gradle
     create mode 100644 build/android/qtcreator/android/gradle/wrapper/gradle-wrapper.jar
     create mode 100644 build/android/qtcreator/android/gradle/wrapper/gradle-wrapper.properties
     create mode 100755 build/android/qtcreator/android/gradlew
     create mode 100644 build/android/qtcreator/android/gradlew.bat
     create mode 100644 build/android/qtcreator/android/res/drawable/zeroad.png
     create mode 100644 build/android/qtcreator/android/res/values/libs.xml
     create mode 100644 build/android/qtcreator/android/res/values/strings.xml
     create mode 100644 build/android/qtcreator/android/src/com/play0ad/Activity.java
     create mode 100644 build/android/qtcreator/android/src/com/play0ad/Native.java
     create mode 100644 build/android/qtcreator/android/src/com/play0ad/QtCreatorDebugger.java
     create mode 100644 build/android/qtcreator/android/src/org/libsdl/app/SDLActivity.java
     create mode 100644 build/android/qtcreator/android_support.pro
     create mode 100644 build/android/qtcreator/atlas.pro
     create mode 100644 build/android/qtcreator/common.pri
     create mode 100644 build/android/qtcreator/engine.pro
     create mode 100644 build/android/qtcreator/graphics.pro
     create mode 100644 build/android/qtcreator/gui.pro
     create mode 100644 build/android/qtcreator/lobby.pro
     create mode 100644 build/android/qtcreator/lowlevel.pro
     create mode 100644 build/android/qtcreator/main.pro
     create mode 100644 build/android/qtcreator/mongoose.pro
     create mode 100644 build/android/qtcreator/network.pro
     create mode 100644 build/android/qtcreator/qtcreator.pro
     create mode 100644 build/android/qtcreator/scriptinterface.pro
     create mode 100644 build/android/qtcreator/sdl.pro
     create mode 100644 build/android/qtcreator/simulation2.pro
     create mode 100644 build/android/qtcreator/staticlib.pri
     create mode 100644 build/android/qtcreator/tinygettext.pro
    
    diff --git a/.gitignore b/.gitignore
    index 26a1bcc..3c78870 100644
    a b build/premake/premake4/build/gmake.unix/obj/  
    2626build/premake/.gccmachine.tmp
    2727build/premake/.gccver.tmp
    2828
     29# Exclude android generated files
     30build/android/qtcreator/android/.build
     31build/android/qtcreator/android/.gradle
     32build/android/qtcreator/android/.idea
     33build/android/qtcreator/android/android.iml
     34build/android/qtcreator/android/gradle.properties
     35build/android/qtcreator/android/local.properties
     36
    2937# Exclude test .cpp files (generated during the build)
    3038test_*.cpp
    3139source/ps/tests/stub_impl_hack.cpp
  • new file uild/android/qtcreator/android/AndroidManifest.xml

    diff --git a/build/android/qtcreator/android/AndroidManifest.xml b/build/android/qtcreator/android/AndroidManifest.xml
    new file mode 100644
    index 0000000..59a3137
    - +  
     1<?xml version="1.0"?>
     2<manifest package="com.play0ad" xmlns:android="http://schemas.android.com/apk/res/android"
     3          android:versionCode="1"
     4          android:versionName="1.0"
     5          android:installLocation="auto">
     6    <application android:hardwareAccelerated="true"
     7                 android:label="@string/app_name"
     8                 android:icon="@drawable/zeroad">
     9
     10        <activity android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
     11                  android:name="com.play0ad.Activity" android:icon="@drawable/zeroad" android:label="@string/app_name"
     12                  android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation"
     13                  android:screenOrientation="landscape"
     14                  android:launchMode="singleTop">
     15            <intent-filter>
     16                <action android:name="android.intent.action.MAIN"/>
     17                <category android:name="android.intent.category.LAUNCHER"/>
     18            </intent-filter>
     19            <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
     20            <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
     21            <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
     22        </activity>
     23
     24    </application>
     25    <uses-sdk android:minSdkVersion="12" android:targetSdkVersion="14"/>
     26    <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
     27
     28    <!-- OpenGL ES 2.0 -->
     29    <uses-feature android:glEsVersion="0x00020000"/>
     30
     31    <!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
     32         Remove the comment if you do not require these default permissions. -->
     33    <!-- %%INSERT_PERMISSIONS -->
     34
     35    <!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
     36         Remove the comment if you do not require these default features. -->
     37    <!-- %%INSERT_FEATURES -->
     38
     39    <uses-permission android:name="android.permission.INTERNET"/>
     40    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
     41</manifest>
  • new file uild/android/qtcreator/android/build.gradle

    diff --git a/build/android/qtcreator/android/build.gradle b/build/android/qtcreator/android/build.gradle
    new file mode 100644
    index 0000000..bf3b243
    - +  
     1buildscript {
     2    repositories {
     3        mavenCentral()
     4    }
     5
     6    dependencies {
     7        classpath 'com.android.tools.build:gradle:1.0.0'
     8    }
     9}
     10
     11apply plugin: 'android'
     12
     13dependencies {
     14    compile fileTree(dir: 'libs', include: ['*.jar'])
     15}
     16
     17android {
     18    /*******************************************************
     19     * The following variables:
     20     * - androidBuildToolsVersion,
     21     * - androidCompileSdkVersion
     22     * - qt5AndroidDir - holds the path to qt android files
     23     *                   needed to build any Qt application
     24     *                   on Android.
     25     *
     26     * are defined in gradle.properties file. This file is
     27     * updated by QtCreator and androiddeployqt tools.
     28     * Changing them manually might break the compilation!
     29     *******************************************************/
     30
     31    compileSdkVersion androidCompileSdkVersion.toInteger()
     32
     33    buildToolsVersion androidBuildToolsVersion
     34
     35    sourceSets {
     36        main {
     37            manifest.srcFile 'AndroidManifest.xml'
     38            java.srcDirs = ['src']
     39            aidl.srcDirs = ['src']
     40            res.srcDirs = ['res']
     41            resources.srcDirs = ['src']
     42            renderscript.srcDirs = ['src']
     43            assets.srcDirs = ['assets']
     44            jniLibs.srcDirs = ['libs']
     45       }
     46    }
     47
     48    lintOptions {
     49        abortOnError false
     50    }
     51}
  • new file uild/android/qtcreator/android/gradle/wrapper/gradle-wrapper.jar

    diff --git a/build/android/qtcreator/android/gradle/wrapper/gradle-wrapper.jar b/build/android/qtcreator/android/gradle/wrapper/gradle-wrapper.jar
    new file mode 100644
    index 0000000000000000000000000000000000000000..8c0fb64a8698b08ecc4158d828ca593c4928e9dd
    GIT binary patch
    literal 49896
    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
    N6sQqkUiJO2{|C|0X_No}
  • new file uild/android/qtcreator/android/gradle/wrapper/gradle-wrapper.properties

    literal 0
    HcmV?d00001
    
    diff --git a/build/android/qtcreator/android/gradle/wrapper/gradle-wrapper.properties b/build/android/qtcreator/android/gradle/wrapper/gradle-wrapper.properties
    new file mode 100644
    index 0000000..5714cd1
    - +  
     1#Sat Dec 27 09:55:37 EET 2014
     2distributionBase=GRADLE_USER_HOME
     3distributionPath=wrapper/dists
     4zipStoreBase=GRADLE_USER_HOME
     5zipStorePath=wrapper/dists
     6distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
  • new file uild/android/qtcreator/android/gradlew

    diff --git a/build/android/qtcreator/android/gradlew b/build/android/qtcreator/android/gradlew
    new file mode 100755
    index 0000000..91a7e26
    - +  
     1#!/usr/bin/env bash
     2
     3##############################################################################
     4##
     5##  Gradle start up script for UN*X
     6##
     7##############################################################################
     8
     9# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
     10DEFAULT_JVM_OPTS=""
     11
     12APP_NAME="Gradle"
     13APP_BASE_NAME=`basename "$0"`
     14
     15# Use the maximum available, or set MAX_FD != -1 to use that value.
     16MAX_FD="maximum"
     17
     18warn ( ) {
     19    echo "$*"
     20}
     21
     22die ( ) {
     23    echo
     24    echo "$*"
     25    echo
     26    exit 1
     27}
     28
     29# OS specific support (must be 'true' or 'false').
     30cygwin=false
     31msys=false
     32darwin=false
     33case "`uname`" in
     34  CYGWIN* )
     35    cygwin=true
     36    ;;
     37  Darwin* )
     38    darwin=true
     39    ;;
     40  MINGW* )
     41    msys=true
     42    ;;
     43esac
     44
     45# For Cygwin, ensure paths are in UNIX format before anything is touched.
     46if $cygwin ; then
     47    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
     48fi
     49
     50# Attempt to set APP_HOME
     51# Resolve links: $0 may be a link
     52PRG="$0"
     53# Need this for relative symlinks.
     54while [ -h "$PRG" ] ; do
     55    ls=`ls -ld "$PRG"`
     56    link=`expr "$ls" : '.*-> \(.*\)$'`
     57    if expr "$link" : '/.*' > /dev/null; then
     58        PRG="$link"
     59    else
     60        PRG=`dirname "$PRG"`"/$link"
     61    fi
     62done
     63SAVED="`pwd`"
     64cd "`dirname \"$PRG\"`/" >&-
     65APP_HOME="`pwd -P`"
     66cd "$SAVED" >&-
     67
     68CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
     69
     70# Determine the Java command to use to start the JVM.
     71if [ -n "$JAVA_HOME" ] ; then
     72    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
     73        # IBM's JDK on AIX uses strange locations for the executables
     74        JAVACMD="$JAVA_HOME/jre/sh/java"
     75    else
     76        JAVACMD="$JAVA_HOME/bin/java"
     77    fi
     78    if [ ! -x "$JAVACMD" ] ; then
     79        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
     80
     81Please set the JAVA_HOME variable in your environment to match the
     82location of your Java installation."
     83    fi
     84else
     85    JAVACMD="java"
     86    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
     87
     88Please set the JAVA_HOME variable in your environment to match the
     89location of your Java installation."
     90fi
     91
     92# Increase the maximum file descriptors if we can.
     93if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
     94    MAX_FD_LIMIT=`ulimit -H -n`
     95    if [ $? -eq 0 ] ; then
     96        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
     97            MAX_FD="$MAX_FD_LIMIT"
     98        fi
     99        ulimit -n $MAX_FD
     100        if [ $? -ne 0 ] ; then
     101            warn "Could not set maximum file descriptor limit: $MAX_FD"
     102        fi
     103    else
     104        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
     105    fi
     106fi
     107
     108# For Darwin, add options to specify how the application appears in the dock
     109if $darwin; then
     110    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
     111fi
     112
     113# For Cygwin, switch paths to Windows format before running java
     114if $cygwin ; then
     115    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
     116    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
     117
     118    # We build the pattern for arguments to be converted via cygpath
     119    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
     120    SEP=""
     121    for dir in $ROOTDIRSRAW ; do
     122        ROOTDIRS="$ROOTDIRS$SEP$dir"
     123        SEP="|"
     124    done
     125    OURCYGPATTERN="(^($ROOTDIRS))"
     126    # Add a user-defined pattern to the cygpath arguments
     127    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
     128        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
     129    fi
     130    # Now convert the arguments - kludge to limit ourselves to /bin/sh
     131    i=0
     132    for arg in "$@" ; do
     133        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
     134        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
     135
     136        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
     137            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
     138        else
     139            eval `echo args$i`="\"$arg\""
     140        fi
     141        i=$((i+1))
     142    done
     143    case $i in
     144        (0) set -- ;;
     145        (1) set -- "$args0" ;;
     146        (2) set -- "$args0" "$args1" ;;
     147        (3) set -- "$args0" "$args1" "$args2" ;;
     148        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
     149        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
     150        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
     151        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
     152        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
     153        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
     154    esac
     155fi
     156
     157# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
     158function splitJvmOpts() {
     159    JVM_OPTS=("$@")
     160}
     161eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
     162JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
     163
     164exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
  • new file uild/android/qtcreator/android/gradlew.bat

    diff --git a/build/android/qtcreator/android/gradlew.bat b/build/android/qtcreator/android/gradlew.bat
    new file mode 100644
    index 0000000..8a0b282
    - +  
     1@if "%DEBUG%" == "" @echo off
     2@rem ##########################################################################
     3@rem
     4@rem  Gradle startup script for Windows
     5@rem
     6@rem ##########################################################################
     7
     8@rem Set local scope for the variables with windows NT shell
     9if "%OS%"=="Windows_NT" setlocal
     10
     11@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
     12set DEFAULT_JVM_OPTS=
     13
     14set DIRNAME=%~dp0
     15if "%DIRNAME%" == "" set DIRNAME=.
     16set APP_BASE_NAME=%~n0
     17set APP_HOME=%DIRNAME%
     18
     19@rem Find java.exe
     20if defined JAVA_HOME goto findJavaFromJavaHome
     21
     22set JAVA_EXE=java.exe
     23%JAVA_EXE% -version >NUL 2>&1
     24if "%ERRORLEVEL%" == "0" goto init
     25
     26echo.
     27echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
     28echo.
     29echo Please set the JAVA_HOME variable in your environment to match the
     30echo location of your Java installation.
     31
     32goto fail
     33
     34:findJavaFromJavaHome
     35set JAVA_HOME=%JAVA_HOME:"=%
     36set JAVA_EXE=%JAVA_HOME%/bin/java.exe
     37
     38if exist "%JAVA_EXE%" goto init
     39
     40echo.
     41echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
     42echo.
     43echo Please set the JAVA_HOME variable in your environment to match the
     44echo location of your Java installation.
     45
     46goto fail
     47
     48:init
     49@rem Get command-line arguments, handling Windowz variants
     50
     51if not "%OS%" == "Windows_NT" goto win9xME_args
     52if "%@eval[2+2]" == "4" goto 4NT_args
     53
     54:win9xME_args
     55@rem Slurp the command line arguments.
     56set CMD_LINE_ARGS=
     57set _SKIP=2
     58
     59:win9xME_args_slurp
     60if "x%~1" == "x" goto execute
     61
     62set CMD_LINE_ARGS=%*
     63goto execute
     64
     65:4NT_args
     66@rem Get arguments from the 4NT Shell from JP Software
     67set CMD_LINE_ARGS=%$
     68
     69:execute
     70@rem Setup the command line
     71
     72set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
     73
     74@rem Execute Gradle
     75"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
     76
     77:end
     78@rem End local scope for the variables with windows NT shell
     79if "%ERRORLEVEL%"=="0" goto mainEnd
     80
     81:fail
     82rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
     83rem the _cmd.exe /c_ return code!
     84if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
     85exit /b 1
     86
     87:mainEnd
     88if "%OS%"=="Windows_NT" endlocal
     89
     90:omega
  • new file uild/android/qtcreator/android/res/drawable/zeroad.png

    diff --git a/build/android/qtcreator/android/res/drawable/zeroad.png b/build/android/qtcreator/android/res/drawable/zeroad.png
    new file mode 100644
    index 0000000000000000000000000000000000000000..741352d25a59d8bc6ced9c36037ed705fef2f876
    GIT binary patch
    literal 65896
    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
    J&|&j#{C_29J=6dI
  • new file uild/android/qtcreator/android/res/values/libs.xml

    literal 0
    HcmV?d00001
    
    diff --git a/build/android/qtcreator/android/res/values/libs.xml b/build/android/qtcreator/android/res/values/libs.xml
    new file mode 100644
    index 0000000..4d68673
    - +  
     1<?xml version='1.0' encoding='utf-8'?>
     2<resources>
     3    <array name="qt_sources">
     4        <item>https://download.qt-project.org/ministro/android/qt5/qt-5.4</item>
     5    </array>
     6
     7    <!-- The following is handled automatically by the deployment tool. It should
     8         not be edited manually. -->
     9
     10    <array name="bundled_libs">
     11        <!-- %%INSERT_EXTRA_LIBS%% -->
     12    </array>
     13
     14     <array name="qt_libs">
     15         <!-- %%INSERT_QT_LIBS%% -->
     16     </array>
     17
     18    <array name="bundled_in_lib">
     19        <!-- %%INSERT_BUNDLED_IN_LIB%% -->
     20    </array>
     21    <array name="bundled_in_assets">
     22        <!-- %%INSERT_BUNDLED_IN_ASSETS%% -->
     23    </array>
     24
     25</resources>
  • new file uild/android/qtcreator/android/res/values/strings.xml

    diff --git a/build/android/qtcreator/android/res/values/strings.xml b/build/android/qtcreator/android/res/values/strings.xml
    new file mode 100644
    index 0000000..f73d46d
    - +  
     1<?xml version="1.0" encoding="utf-8"?>
     2<resources>
     3    <string name="app_name">0 A.D.</string>
     4</resources>
  • new file uild/android/qtcreator/android/src/com/play0ad/Activity.java

    diff --git a/build/android/qtcreator/android/src/com/play0ad/Activity.java b/build/android/qtcreator/android/src/com/play0ad/Activity.java
    new file mode 100644
    index 0000000..456a0f6
    - +  
     1package com.play0ad;
     2
     3import android.content.pm.ActivityInfo;
     4import android.content.pm.PackageManager;
     5import android.os.Build;
     6import android.os.Bundle;
     7import android.os.Environment;
     8import android.util.DisplayMetrics;
     9import android.view.Display;
     10import android.view.View;
     11
     12import org.libsdl.app.SDLActivity;
     13
     14import java.io.File;
     15
     16
     17public class Activity extends SDLActivity {
     18
     19    private static final String TAG = "pyrogenesis";
     20    private QtCreatorDebugger m_debugger = new QtCreatorDebugger(TAG);
     21
     22    static String getPath(File f) {
     23        if (!f.exists())
     24            f.mkdirs();
     25        return f.getAbsolutePath();
     26    }
     27
     28    @Override
     29    protected boolean prepareOnCreate(Bundle savedInstanceState) {
     30        hide();
     31        if (null == savedInstanceState) {
     32            try {
     33                ActivityInfo activityInfo = getPackageManager().getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
     34                if (activityInfo.metaData.containsKey("android.app.qt_libs_resource_id")) {
     35                    int resourceId = activityInfo.metaData.getInt("android.app.qt_libs_resource_id");
     36                    for (String library: getResources().getStringArray(resourceId))
     37                        System.loadLibrary(library);
     38                }
     39
     40                if (activityInfo.metaData.containsKey("android.app.bundled_libs_resource_id")) {
     41                    int resourceId = activityInfo.metaData.getInt("android.app.bundled_libs_resource_id");
     42                    for (String library: getResources().getStringArray(resourceId))
     43                        System.loadLibrary(library);
     44                }
     45
     46                if (activityInfo.metaData.containsKey("android.app.bundled_libs_resource_id")) {
     47                    int resourceId = activityInfo.metaData.getInt("android.app.bundled_libs_resource_id");
     48                    for (String library: getResources().getStringArray(resourceId))
     49                        System.loadLibrary(library);
     50                }
     51
     52                if (activityInfo.metaData.containsKey("android.app.lib_name") )
     53                    System.loadLibrary(activityInfo.metaData.getString("android.app.lib_name"));
     54
     55                Native.setenv("TRACE_FILE", "/sdcard/0ad/appdata/logs/pyrogenesis.trace", true);
     56                m_debugger.connect(this);
     57            } catch (Exception e) {
     58                e.printStackTrace();
     59            }
     60        }
     61
     62        int w,h;
     63        if (Build.VERSION.SDK_INT < 13) {
     64            Display d = getWindowManager().getDefaultDisplay();
     65            w = d.getWidth();
     66            h = d.getHeight();
     67        } else {
     68            DisplayMetrics metrics = new DisplayMetrics();
     69            getWindowManager().getDefaultDisplay().getMetrics(metrics);
     70            w = metrics.heightPixels;
     71            h = metrics.widthPixels;
     72        }
     73        Native.setenv("ANDROID_SCREEN_WIDTH", Integer.toString(w), true);
     74        Native.setenv("ANDROID_SCREEN_HEIGHT", Integer.toString(h), true);
     75
     76        Native.setenv("HOME", getPath(getFilesDir()), true);
     77        Native.setenv("CACHE_DIR", getPath(getCacheDir()), true);
     78        Native.setenv("EXTERNAL_DIR", getPath(getExternalFilesDir(null)), true);
     79        Native.setenv("EXTERNAL_CACHE_DIR", getPath(getExternalCacheDir()), true);
     80        Native.setenv("EXTERNAL_STORAGE_DIR", getPath(Environment.getExternalStorageDirectory()), true);
     81
     82        return super.prepareOnCreate(savedInstanceState);
     83    }
     84
     85    public void hide() {
     86        if (Build.VERSION.SDK_INT > 13) {
     87            int systemVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
     88            if (Build.VERSION.SDK_INT > 15) {
     89                systemVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE
     90                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
     91                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
     92                        | View.SYSTEM_UI_FLAG_FULLSCREEN;
     93                if (Build.VERSION.SDK_INT > 18)
     94                    systemVisibility |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
     95            }
     96            getWindow().getDecorView().setSystemUiVisibility(systemVisibility);
     97        }
     98
     99    }
     100
     101    @Override
     102    public void onWindowFocusChanged(boolean hasFocus) {
     103        super.onWindowFocusChanged(hasFocus);
     104        hide();
     105    }
     106
     107    @Override
     108    protected void onDestroy() {
     109        super.onDestroy();
     110        m_debugger.close();
     111        System.exit(0);
     112    }
     113}
  • new file uild/android/qtcreator/android/src/com/play0ad/Native.java

    diff --git a/build/android/qtcreator/android/src/com/play0ad/Native.java b/build/android/qtcreator/android/src/com/play0ad/Native.java
    new file mode 100644
    index 0000000..58ef794
    - +  
     1package com.play0ad;
     2
     3class Native {
     4    public static native int setenv(String key, String value, boolean overwrite);
     5}
  • new file uild/android/qtcreator/android/src/com/play0ad/QtCreatorDebugger.java

    diff --git a/build/android/qtcreator/android/src/com/play0ad/QtCreatorDebugger.java b/build/android/qtcreator/android/src/com/play0ad/QtCreatorDebugger.java
    new file mode 100644
    index 0000000..4964450
    - +  
     1package com.play0ad;
     2
     3import android.app.Activity;
     4import android.net.LocalServerSocket;
     5import android.net.LocalSocket;
     6import android.os.Bundle;
     7import android.util.Log;
     8
     9import java.io.BufferedReader;
     10import java.io.DataOutputStream;
     11import java.io.File;
     12import java.io.FileWriter;
     13import java.io.IOException;
     14import java.io.InputStreamReader;
     15
     16public class QtCreatorDebugger {
     17
     18    QtCreatorDebugger(){}
     19
     20    QtCreatorDebugger(String TAG) {
     21        this.TAG =TAG;
     22    }
     23
     24    private String TAG = "QtCreator";
     25
     26    private Process m_debuggerProcess = null; // debugger process
     27
     28    public boolean connect(Activity activity) {
     29        try {
     30            Bundle extras = activity.getIntent().getExtras();
     31
     32            if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
     33                        &&*/ extras.containsKey("debug_ping")
     34                    && extras.getString("debug_ping").equals("true")) {
     35                try {
     36                    debugLog("extra parameters: " + extras);
     37                    String packageName = activity.getPackageName();
     38                    String pingFile = extras.getString("ping_file");
     39                    String pongFile = extras.getString("pong_file");
     40                    String gdbserverSocket = extras.getString("gdbserver_socket");
     41                    String gdbserverCommand = extras.getString("gdbserver_command");
     42                    String pingSocket = extras.getString("ping_socket");
     43                    boolean usePing = pingFile != null;
     44                    boolean usePong = pongFile != null;
     45                    boolean useSocket = gdbserverSocket != null;
     46                    boolean usePingSocket = pingSocket != null;
     47                    int napTime = 200; // milliseconds between file accesses
     48                    int timeOut = 30000; // ms until we give up on ping and pong
     49                    int maxAttempts = timeOut / napTime;
     50
     51                    if (gdbserverSocket != null) {
     52                        debugLog("removing gdb socket " + gdbserverSocket);
     53                        new File(gdbserverSocket).delete();
     54                    }
     55
     56                    if (usePing) {
     57                        debugLog("removing ping file " + pingFile);
     58                        File ping = new File(pingFile);
     59                        if (ping.exists()) {
     60                            if (!ping.delete())
     61                                debugLog("ping file cannot be deleted");
     62                        }
     63                    }
     64
     65                    if (usePong) {
     66                        debugLog("removing pong file " + pongFile);
     67                        File pong = new File(pongFile);
     68                        if (pong.exists()) {
     69                            if (!pong.delete())
     70                                debugLog("pong file cannot be deleted");
     71                        }
     72                    }
     73
     74                    debugLog("starting " + gdbserverCommand);
     75                    m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand);
     76                    debugLog("gdbserver started");
     77
     78                    if (useSocket) {
     79                        int i;
     80                        for (i = 0; i < maxAttempts; ++i) {
     81                            debugLog("waiting for socket at " + gdbserverSocket + ", attempt " + i);
     82                            File file = new File(gdbserverSocket);
     83                            if (file.exists()) {
     84                                file.setReadable(true, false);
     85                                file.setWritable(true, false);
     86                                file.setExecutable(true, false);
     87                                break;
     88                            }
     89                            Thread.sleep(napTime);
     90                        }
     91
     92                        if (i == maxAttempts) {
     93                            debugLog("time out when waiting for debug socket");
     94                            return false;
     95                        }
     96
     97                        debugLog("socket ok");
     98                    } else {
     99                        debugLog("socket not used");
     100                    }
     101
     102                    if (usePingSocket) {
     103                        DebugWaitRunnable runnable = new DebugWaitRunnable(pingSocket);
     104                        Thread waitThread = new Thread(runnable);
     105                        waitThread.start();
     106
     107                        int i;
     108                        for (i = 0; i < maxAttempts && waitThread.isAlive(); ++i) {
     109                            debugLog("Waiting for debug socket connect");
     110                            debugLog("go to sleep");
     111                            Thread.sleep(napTime);
     112                        }
     113
     114                        if (i == maxAttempts) {
     115                            debugLog("time out when waiting for ping socket");
     116                            runnable.shutdown();
     117                            return false;
     118                        }
     119
     120                        if (runnable.wasFailure) {
     121                            debugLog("Could not connect to debug client");
     122                            return false;
     123                        } else {
     124                            debugLog("Got pid acknowledgment");
     125                        }
     126                    }
     127
     128                    if (usePing) {
     129                        // Tell we are ready.
     130                        debugLog("writing ping at " + pingFile);
     131                        FileWriter writer = new FileWriter(pingFile);
     132                        writer.write("" + android.os.Process.myPid());
     133                        writer.close();
     134                        File file = new File(pingFile);
     135                        file.setReadable(true, false);
     136                        file.setWritable(true, false);
     137                        file.setExecutable(true, false);
     138                        debugLog("wrote ping");
     139                    } else {
     140                        debugLog("ping not requested");
     141                    }
     142
     143                    // Wait until other side is ready.
     144                    if (usePong) {
     145                        int i;
     146                        for (i = 0; i < maxAttempts; ++i) {
     147                            debugLog("waiting for pong at " + pongFile + ", attempt " + i);
     148                            File file = new File(pongFile);
     149                            if (file.exists()) {
     150                                file.delete();
     151                                break;
     152                            }
     153                            debugLog("go to sleep");
     154                            Thread.sleep(napTime);
     155                        }
     156                        debugLog("Removing pingFile " + pingFile);
     157                        new File(pingFile).delete();
     158
     159                        if (i == maxAttempts) {
     160                            debugLog("time out when waiting for pong file");
     161                            return false;
     162                        }
     163
     164                        debugLog("got pong " + pongFile);
     165                    } else {
     166                        debugLog("pong not requested");
     167                    }
     168
     169                } catch (Exception e) {
     170                    debugLog("Can't start debugger" + e.getMessage());
     171                }
     172            }
     173        } catch (Exception e) {
     174            e.printStackTrace();
     175        }
     176        return true;
     177    }
     178
     179    void close()
     180    {
     181        if (m_debuggerProcess != null)
     182            m_debuggerProcess.destroy();
     183    }
     184
     185    private void debugLog(String msg)
     186    {
     187        Log.i(TAG, "DEBUGGER: " + msg);
     188    }
     189
     190    private class DebugWaitRunnable implements Runnable {
     191
     192        public DebugWaitRunnable(String pingPongSocket) throws IOException {
     193            socket = new LocalServerSocket(pingPongSocket);
     194        }
     195
     196        public boolean wasFailure;
     197        private LocalServerSocket socket;
     198
     199        public void run() {
     200            final int napTime = 200; // milliseconds between file accesses
     201            final int timeOut = 30000; // ms until we give up on ping and pong
     202            final int maxAttempts = timeOut / napTime;
     203
     204            try {
     205                LocalSocket connectionFromClient = socket.accept();
     206                debugLog("Debug socket accepted");
     207                BufferedReader inFromClient =
     208                        new BufferedReader(new InputStreamReader(connectionFromClient.getInputStream()));
     209                DataOutputStream outToClient = new DataOutputStream(connectionFromClient.getOutputStream());
     210                outToClient.writeBytes("" + android.os.Process.myPid());
     211
     212                for (int i = 0; i < maxAttempts; i++) {
     213                    String clientData = inFromClient.readLine();
     214                    debugLog("Incoming socket " + clientData);
     215                    if (!clientData.isEmpty())
     216                        break;
     217
     218                    if (connectionFromClient.isClosed()) {
     219                        wasFailure = true;
     220                        break;
     221                    }
     222                    Thread.sleep(napTime);
     223                }
     224            } catch (IOException ioEx) {
     225                ioEx.printStackTrace();
     226                wasFailure = true;
     227                debugLog("Can't start debugger" + ioEx.getMessage());
     228            } catch (InterruptedException interruptEx) {
     229                wasFailure = true;
     230                debugLog("Can't start debugger" + interruptEx.getMessage());
     231            }
     232        }
     233
     234        public void shutdown() throws IOException
     235        {
     236            wasFailure = true;
     237            try {
     238                socket.close();
     239            } catch (IOException ignored) { }
     240        }
     241    };
     242}
  • new file uild/android/qtcreator/android/src/org/libsdl/app/SDLActivity.java

    diff --git a/build/android/qtcreator/android/src/org/libsdl/app/SDLActivity.java b/build/android/qtcreator/android/src/org/libsdl/app/SDLActivity.java
    new file mode 100644
    index 0000000..5c3d342
    - +  
     1package org.libsdl.app;
     2
     3import java.io.*;
     4import java.util.ArrayList;
     5import java.util.Arrays;
     6import java.util.Collections;
     7import java.util.Comparator;
     8import java.util.List;
     9
     10import android.app.*;
     11import android.content.*;
     12import android.view.*;
     13import android.view.inputmethod.BaseInputConnection;
     14import android.view.inputmethod.EditorInfo;
     15import android.view.inputmethod.InputConnection;
     16import android.view.inputmethod.InputMethodManager;
     17import android.widget.AbsoluteLayout;
     18import android.net.*;
     19import android.os.*;
     20import android.util.Log;
     21import android.graphics.*;
     22import android.media.*;
     23import android.hardware.*;
     24
     25
     26/**
     27    SDL Activity
     28*/
     29public class SDLActivity extends Activity {
     30    private static final String TAG = "SDL";
     31
     32    // Keep track of the paused state
     33    public static boolean mIsPaused, mIsSurfaceReady, mHasFocus;
     34    public static boolean mExitCalledFromJava;
     35
     36    // Main components
     37    protected static SDLActivity mSingleton;
     38    protected static SDLSurface mSurface;
     39    protected static View mTextEdit;
     40    protected static ViewGroup mLayout;
     41    protected static SDLJoystickHandler mJoystickHandler;
     42
     43    // This is what SDL runs in. It invokes SDL_main(), eventually
     44    protected static Thread mSDLThread;
     45   
     46    // Audio
     47    protected static AudioTrack mAudioTrack;
     48
     49    public static void initialize() {
     50        // The static nature of the singleton and Android quirkyness force us to initialize everything here
     51        // Otherwise, when exiting the app and returning to it, these variables *keep* their pre exit values
     52        mSingleton = null;
     53        mSurface = null;
     54        mTextEdit = null;
     55        mLayout = null;
     56        mJoystickHandler = null;
     57        mSDLThread = null;
     58        mAudioTrack = null;
     59        mExitCalledFromJava = false;
     60        mIsPaused = false;
     61        mIsSurfaceReady = false;
     62        mHasFocus = true;
     63    }
     64
     65    protected boolean prepareOnCreate(Bundle savedInstanceState)
     66    {
     67        return true;
     68    }
     69
     70    // Setup
     71    @Override
     72    protected void onCreate(Bundle savedInstanceState) {
     73        Log.v("SDL", "onCreate():" + mSingleton);
     74        super.onCreate(savedInstanceState);
     75        if (!prepareOnCreate(savedInstanceState)) {
     76            finish();
     77            return;
     78        }
     79
     80        SDLActivity.initialize();
     81        // So we can call stuff from static callbacks
     82        mSingleton = this;
     83
     84        // Set up the surface
     85        mSurface = new SDLSurface(getApplication());
     86       
     87        if(Build.VERSION.SDK_INT >= 12) {
     88            mJoystickHandler = new SDLJoystickHandler_API12();
     89        }
     90        else {
     91            mJoystickHandler = new SDLJoystickHandler();
     92        }
     93
     94        mLayout = new AbsoluteLayout(this);
     95        mLayout.addView(mSurface);
     96
     97        setContentView(mLayout);
     98    }
     99
     100    // Events
     101    @Override
     102    protected void onPause() {
     103        Log.v("SDL", "onPause()");
     104        super.onPause();
     105        SDLActivity.handlePause();
     106    }
     107
     108    @Override
     109    protected void onResume() {
     110        Log.v("SDL", "onResume()");
     111        super.onResume();
     112        SDLActivity.handleResume();
     113    }
     114
     115
     116    @Override
     117    public void onWindowFocusChanged(boolean hasFocus) {
     118        super.onWindowFocusChanged(hasFocus);
     119        Log.v("SDL", "onWindowFocusChanged(): " + hasFocus);
     120
     121        SDLActivity.mHasFocus = hasFocus;
     122        if (hasFocus) {
     123            SDLActivity.handleResume();
     124        }
     125    }
     126
     127    @Override
     128    public void onLowMemory() {
     129        Log.v("SDL", "onLowMemory()");
     130        super.onLowMemory();
     131        SDLActivity.nativeLowMemory();
     132    }
     133
     134    @Override
     135    protected void onDestroy() {
     136        Log.v("SDL", "onDestroy()");
     137        // Send a quit message to the application
     138        SDLActivity.mExitCalledFromJava = true;
     139        SDLActivity.nativeQuit();
     140
     141        // Now wait for the SDL thread to quit
     142        if (SDLActivity.mSDLThread != null) {
     143            try {
     144                SDLActivity.mSDLThread.join();
     145            } catch(Exception e) {
     146                Log.v("SDL", "Problem stopping thread: " + e);
     147            }
     148            SDLActivity.mSDLThread = null;
     149
     150            //Log.v("SDL", "Finished waiting for SDL thread");
     151        }
     152           
     153        super.onDestroy();
     154        // Reset everything in case the user re opens the app
     155        SDLActivity.initialize();
     156    }
     157
     158    @Override
     159    public boolean dispatchKeyEvent(KeyEvent event) {
     160        int keyCode = event.getKeyCode();
     161        // Ignore certain special keys so they're handled by Android
     162        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
     163            keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
     164            keyCode == KeyEvent.KEYCODE_CAMERA ||
     165            keyCode == 168 || /* API 11: KeyEvent.KEYCODE_ZOOM_IN */
     166            keyCode == 169 /* API 11: KeyEvent.KEYCODE_ZOOM_OUT */
     167            ) {
     168            return false;
     169        }
     170        return super.dispatchKeyEvent(event);
     171    }
     172
     173    /** Called by onPause or surfaceDestroyed. Even if surfaceDestroyed
     174     *  is the first to be called, mIsSurfaceReady should still be set
     175     *  to 'true' during the call to onPause (in a usual scenario).
     176     */
     177    public static void handlePause() {
     178        if (!SDLActivity.mIsPaused && SDLActivity.mIsSurfaceReady) {
     179            SDLActivity.mIsPaused = true;
     180            SDLActivity.nativePause();
     181            mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, false);
     182        }
     183    }
     184
     185    /** Called by onResume or surfaceCreated. An actual resume should be done only when the surface is ready.
     186     * Note: Some Android variants may send multiple surfaceChanged events, so we don't need to resume
     187     * every time we get one of those events, only if it comes after surfaceDestroyed
     188     */
     189    public static void handleResume() {
     190        if (SDLActivity.mIsPaused && SDLActivity.mIsSurfaceReady && SDLActivity.mHasFocus) {
     191            SDLActivity.mIsPaused = false;
     192            SDLActivity.nativeResume();
     193            mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, true);
     194        }
     195    }
     196       
     197    /* The native thread has finished */
     198    public static void handleNativeExit() {
     199        SDLActivity.mSDLThread = null;
     200        mSingleton.finish();
     201    }
     202
     203
     204    // Messages from the SDLMain thread
     205    static final int COMMAND_CHANGE_TITLE = 1;
     206    static final int COMMAND_UNUSED = 2;
     207    static final int COMMAND_TEXTEDIT_HIDE = 3;
     208
     209    protected static final int COMMAND_USER = 0x8000;
     210
     211    /**
     212     * This method is called by SDL if SDL did not handle a message itself.
     213     * This happens if a received message contains an unsupported command.
     214     * Method can be overwritten to handle Messages in a different class.
     215     * @param command the command of the message.
     216     * @param param the parameter of the message. May be null.
     217     * @return if the message was handled in overridden method.
     218     */
     219    protected boolean onUnhandledMessage(int command, Object param) {
     220        return false;
     221    }
     222
     223    /**
     224     * A Handler class for Messages from native SDL applications.
     225     * It uses current Activities as target (e.g. for the title).
     226     * static to prevent implicit references to enclosing object.
     227     */
     228    protected static class SDLCommandHandler extends Handler {
     229        @Override
     230        public void handleMessage(Message msg) {
     231            Context context = getContext();
     232            if (context == null) {
     233                Log.e(TAG, "error handling message, getContext() returned null");
     234                return;
     235            }
     236            switch (msg.arg1) {
     237            case COMMAND_CHANGE_TITLE:
     238                if (context instanceof Activity) {
     239                    ((Activity) context).setTitle((String)msg.obj);
     240                } else {
     241                    Log.e(TAG, "error handling message, getContext() returned no Activity");
     242                }
     243                break;
     244            case COMMAND_TEXTEDIT_HIDE:
     245                if (mTextEdit != null) {
     246                    mTextEdit.setVisibility(View.GONE);
     247
     248                    InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
     249                    imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0);
     250                }
     251                break;
     252
     253            default:
     254                if ((context instanceof SDLActivity) && !((SDLActivity) context).onUnhandledMessage(msg.arg1, msg.obj)) {
     255                    Log.e(TAG, "error handling message, command is " + msg.arg1);
     256                }
     257            }
     258        }
     259    }
     260
     261    // Handler for the messages
     262    Handler commandHandler = new SDLCommandHandler();
     263
     264    // Send a message from the SDLMain thread
     265    boolean sendCommand(int command, Object data) {
     266        Message msg = commandHandler.obtainMessage();
     267        msg.arg1 = command;
     268        msg.obj = data;
     269        return commandHandler.sendMessage(msg);
     270    }
     271
     272    // C functions we call
     273    public static native void nativeInit();
     274    public static native void nativeLowMemory();
     275    public static native void nativeQuit();
     276    public static native void nativePause();
     277    public static native void nativeResume();
     278    public static native void onNativeResize(int x, int y, int format);
     279    public static native int onNativePadDown(int device_id, int keycode);
     280    public static native int onNativePadUp(int device_id, int keycode);
     281    public static native void onNativeJoy(int device_id, int axis,
     282                                          float value);
     283    public static native void onNativeHat(int device_id, int hat_id,
     284                                          int x, int y);
     285    public static native void onNativeKeyDown(int keycode);
     286    public static native void onNativeKeyUp(int keycode);
     287    public static native void onNativeKeyboardFocusLost();
     288    public static native void onNativeTouch(int touchDevId, int pointerFingerId,
     289                                            int action, float x,
     290                                            float y, float p);
     291    public static native void onNativeAccel(float x, float y, float z);
     292    public static native void onNativeSurfaceChanged();
     293    public static native void onNativeSurfaceDestroyed();
     294    public static native void nativeFlipBuffers();
     295    public static native int nativeAddJoystick(int device_id, String name,
     296                                               int is_accelerometer, int nbuttons,
     297                                               int naxes, int nhats, int nballs);
     298    public static native int nativeRemoveJoystick(int device_id);
     299
     300    public static void flipBuffers() {
     301        SDLActivity.nativeFlipBuffers();
     302    }
     303
     304    public static boolean setActivityTitle(String title) {
     305        // Called from SDLMain() thread and can't directly affect the view
     306        return mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title);
     307    }
     308
     309    public static boolean sendMessage(int command, int param) {
     310        return mSingleton.sendCommand(command, Integer.valueOf(param));
     311    }
     312
     313    public static Context getContext() {
     314        return mSingleton;
     315    }
     316
     317    /**
     318     * @return result of getSystemService(name) but executed on UI thread.
     319     */
     320    public Object getSystemServiceFromUiThread(final String name) {
     321        final Object lock = new Object();
     322        final Object[] results = new Object[2]; // array for writable variables
     323        synchronized (lock) {
     324            runOnUiThread(new Runnable() {
     325                @Override
     326                public void run() {
     327                    synchronized (lock) {
     328                        results[0] = getSystemService(name);
     329                        results[1] = Boolean.TRUE;
     330                        lock.notify();
     331                    }
     332                }
     333            });
     334            if (results[1] == null) {
     335                try {
     336                    lock.wait();
     337                } catch (InterruptedException ex) {
     338                    ex.printStackTrace();
     339                }
     340            }
     341        }
     342        return results[0];
     343    }
     344
     345    static class ShowTextInputTask implements Runnable {
     346        /*
     347         * This is used to regulate the pan&scan method to have some offset from
     348         * the bottom edge of the input region and the top edge of an input
     349         * method (soft keyboard)
     350         */
     351        static final int HEIGHT_PADDING = 15;
     352
     353        public int x, y, w, h;
     354
     355        public ShowTextInputTask(int x, int y, int w, int h) {
     356            this.x = x;
     357            this.y = y;
     358            this.w = w;
     359            this.h = h;
     360        }
     361
     362        @Override
     363        public void run() {
     364            AbsoluteLayout.LayoutParams params = new AbsoluteLayout.LayoutParams(
     365                    w, h + HEIGHT_PADDING, x, y);
     366
     367            if (mTextEdit == null) {
     368                mTextEdit = new DummyEdit(getContext());
     369
     370                mLayout.addView(mTextEdit, params);
     371            } else {
     372                mTextEdit.setLayoutParams(params);
     373            }
     374
     375            mTextEdit.setVisibility(View.VISIBLE);
     376            mTextEdit.requestFocus();
     377
     378            InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
     379            imm.showSoftInput(mTextEdit, 0);
     380        }
     381    }
     382
     383    public static boolean showTextInput(int x, int y, int w, int h) {
     384        // Transfer the task to the main thread as a Runnable
     385        return mSingleton.commandHandler.post(new ShowTextInputTask(x, y, w, h));
     386    }
     387           
     388    public static Surface getNativeSurface() {
     389        return SDLActivity.mSurface.getNativeSurface();
     390    }
     391
     392    // Audio
     393    public static int audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
     394        int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
     395        int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
     396        int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
     397       
     398        Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
     399       
     400        // Let the user pick a larger buffer if they really want -- but ye
     401        // gods they probably shouldn't, the minimums are horrifyingly high
     402        // latency already
     403        desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
     404       
     405        if (mAudioTrack == null) {
     406            mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
     407                    channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
     408           
     409            // Instantiating AudioTrack can "succeed" without an exception and the track may still be invalid
     410            // Ref: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java
     411            // Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState()
     412           
     413            if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
     414                Log.e("SDL", "Failed during initialization of Audio Track");
     415                mAudioTrack = null;
     416                return -1;
     417            }
     418           
     419            mAudioTrack.play();
     420        }
     421       
     422        Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
     423       
     424        return 0;
     425    }
     426   
     427    public static void audioWriteShortBuffer(short[] buffer) {
     428        for (int i = 0; i < buffer.length; ) {
     429            int result = mAudioTrack.write(buffer, i, buffer.length - i);
     430            if (result > 0) {
     431                i += result;
     432            } else if (result == 0) {
     433                try {
     434                    Thread.sleep(1);
     435                } catch(InterruptedException e) {
     436                    // Nom nom
     437                }
     438            } else {
     439                Log.w("SDL", "SDL audio: error return from write(short)");
     440                return;
     441            }
     442        }
     443    }
     444   
     445    public static void audioWriteByteBuffer(byte[] buffer) {
     446        for (int i = 0; i < buffer.length; ) {
     447            int result = mAudioTrack.write(buffer, i, buffer.length - i);
     448            if (result > 0) {
     449                i += result;
     450            } else if (result == 0) {
     451                try {
     452                    Thread.sleep(1);
     453                } catch(InterruptedException e) {
     454                    // Nom nom
     455                }
     456            } else {
     457                Log.w("SDL", "SDL audio: error return from write(byte)");
     458                return;
     459            }
     460        }
     461    }
     462
     463    public static void audioQuit() {
     464        if (mAudioTrack != null) {
     465            mAudioTrack.stop();
     466            mAudioTrack = null;
     467        }
     468    }
     469
     470    // Input
     471
     472    /**
     473     * @return an array which may be empty but is never null.
     474     */
     475    public static int[] inputGetInputDeviceIds(int sources) {
     476        int[] ids = InputDevice.getDeviceIds();
     477        int[] filtered = new int[ids.length];
     478        int used = 0;
     479        for (int i = 0; i < ids.length; ++i) {
     480            InputDevice device = InputDevice.getDevice(ids[i]);
     481            if ((device != null) && ((device.getSources() & sources) != 0)) {
     482                filtered[used++] = device.getId();
     483            }
     484        }
     485        return Arrays.copyOf(filtered, used);
     486    }
     487           
     488    // Joystick glue code, just a series of stubs that redirect to the SDLJoystickHandler instance
     489    public static boolean handleJoystickMotionEvent(MotionEvent event) {
     490        return mJoystickHandler.handleMotionEvent(event);
     491    }
     492   
     493    public static void pollInputDevices() {
     494        if (SDLActivity.mSDLThread != null) {
     495            mJoystickHandler.pollInputDevices();
     496        }
     497    }
     498   
     499}
     500
     501/**
     502    Simple nativeInit() runnable
     503*/
     504class SDLMain implements Runnable {
     505    @Override
     506    public void run() {
     507        // Runs SDL_main()
     508        SDLActivity.nativeInit();
     509
     510        //Log.v("SDL", "SDL thread terminated");
     511    }
     512}
     513
     514
     515/**
     516    SDLSurface. This is what we draw on, so we need to know when it's created
     517    in order to do anything useful.
     518
     519    Because of this, that's where we set up the SDL thread
     520*/
     521class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
     522    View.OnKeyListener, View.OnTouchListener, SensorEventListener  {
     523
     524    // Sensors
     525    protected static SensorManager mSensorManager;
     526    protected static Display mDisplay;
     527
     528    // Keep track of the surface size to normalize touch events
     529    protected static float mWidth, mHeight;
     530
     531    // Startup   
     532    public SDLSurface(Context context) {
     533        super(context);
     534        getHolder().addCallback(this);
     535   
     536        setFocusable(true);
     537        setFocusableInTouchMode(true);
     538        requestFocus();
     539        setOnKeyListener(this);
     540        setOnTouchListener(this);   
     541
     542        mDisplay = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
     543        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
     544       
     545        if(Build.VERSION.SDK_INT >= 12) {
     546            setOnGenericMotionListener(new SDLGenericMotionListener_API12());
     547        }
     548
     549        // Some arbitrary defaults to avoid a potential division by zero
     550        mWidth = 1.0f;
     551        mHeight = 1.0f;
     552    }
     553   
     554    public Surface getNativeSurface() {
     555        return getHolder().getSurface();
     556    }
     557
     558    // Called when we have a valid drawing surface
     559    @Override
     560    public void surfaceCreated(SurfaceHolder holder) {
     561        Log.v("SDL", "surfaceCreated()");
     562        holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
     563    }
     564
     565    // Called when we lose the surface
     566    @Override
     567    public void surfaceDestroyed(SurfaceHolder holder) {
     568        Log.v("SDL", "surfaceDestroyed()");
     569        // Call this *before* setting mIsSurfaceReady to 'false'
     570        SDLActivity.handlePause();
     571        SDLActivity.mIsSurfaceReady = false;
     572        SDLActivity.onNativeSurfaceDestroyed();
     573    }
     574
     575    // Called when the surface is resized
     576    @Override
     577    public void surfaceChanged(SurfaceHolder holder,
     578                               int format, int width, int height) {
     579        Log.v("SDL", "surfaceChanged()");
     580
     581        int sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565 by default
     582        switch (format) {
     583        case PixelFormat.A_8:
     584            Log.v("SDL", "pixel format A_8");
     585            break;
     586        case PixelFormat.LA_88:
     587            Log.v("SDL", "pixel format LA_88");
     588            break;
     589        case PixelFormat.L_8:
     590            Log.v("SDL", "pixel format L_8");
     591            break;
     592        case PixelFormat.RGBA_4444:
     593            Log.v("SDL", "pixel format RGBA_4444");
     594            sdlFormat = 0x15421002; // SDL_PIXELFORMAT_RGBA4444
     595            break;
     596        case PixelFormat.RGBA_5551:
     597            Log.v("SDL", "pixel format RGBA_5551");
     598            sdlFormat = 0x15441002; // SDL_PIXELFORMAT_RGBA5551
     599            break;
     600        case PixelFormat.RGBA_8888:
     601            Log.v("SDL", "pixel format RGBA_8888");
     602            sdlFormat = 0x16462004; // SDL_PIXELFORMAT_RGBA8888
     603            break;
     604        case PixelFormat.RGBX_8888:
     605            Log.v("SDL", "pixel format RGBX_8888");
     606            sdlFormat = 0x16261804; // SDL_PIXELFORMAT_RGBX8888
     607            break;
     608        case PixelFormat.RGB_332:
     609            Log.v("SDL", "pixel format RGB_332");
     610            sdlFormat = 0x14110801; // SDL_PIXELFORMAT_RGB332
     611            break;
     612        case PixelFormat.RGB_565:
     613            Log.v("SDL", "pixel format RGB_565");
     614            sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565
     615            break;
     616        case PixelFormat.RGB_888:
     617            Log.v("SDL", "pixel format RGB_888");
     618            // Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead?
     619            sdlFormat = 0x16161804; // SDL_PIXELFORMAT_RGB888
     620            break;
     621        default:
     622            Log.v("SDL", "pixel format unknown " + format);
     623            break;
     624        }
     625
     626        mWidth = width;
     627        mHeight = height;
     628        SDLActivity.onNativeResize(width, height, sdlFormat);
     629        Log.v("SDL", "Window size:" + width + "x"+height);
     630
     631        // Set mIsSurfaceReady to 'true' *before* making a call to handleResume
     632        SDLActivity.mIsSurfaceReady = true;
     633        SDLActivity.onNativeSurfaceChanged();
     634
     635
     636        if (SDLActivity.mSDLThread == null) {
     637            // This is the entry point to the C app.
     638            // Start up the C app thread and enable sensor input for the first time
     639
     640            SDLActivity.mSDLThread = new Thread(new SDLMain(), "SDLThread");
     641            enableSensor(Sensor.TYPE_ACCELEROMETER, true);
     642            SDLActivity.mSDLThread.start();
     643           
     644            // Set up a listener thread to catch when the native thread ends
     645            new Thread(new Runnable(){
     646                @Override
     647                public void run(){
     648                    try {
     649                        SDLActivity.mSDLThread.join();
     650                    }
     651                    catch(Exception e){}
     652                    finally{
     653                        // Native thread has finished
     654                        if (! SDLActivity.mExitCalledFromJava) {
     655                            SDLActivity.handleNativeExit();
     656                        }
     657                    }
     658                }
     659            }).start();
     660        }
     661    }
     662
     663    // unused
     664    @Override
     665    public void onDraw(Canvas canvas) {}
     666
     667
     668    // Key events
     669    @Override
     670    public boolean onKey(View  v, int keyCode, KeyEvent event) {
     671        // Dispatch the different events depending on where they come from
     672        // Some SOURCE_DPAD or SOURCE_GAMEPAD are also SOURCE_KEYBOARD
     673        // So, we try to process them as DPAD or GAMEPAD events first, if that fails we try them as KEYBOARD
     674       
     675        if ( (event.getSource() & 0x00000401) != 0 || /* API 12: SOURCE_GAMEPAD */
     676                   (event.getSource() & InputDevice.SOURCE_DPAD) != 0 ) {
     677            if (event.getAction() == KeyEvent.ACTION_DOWN) {
     678                if (SDLActivity.onNativePadDown(event.getDeviceId(), keyCode) == 0) {
     679                    return true;
     680                }
     681            } else if (event.getAction() == KeyEvent.ACTION_UP) {
     682                if (SDLActivity.onNativePadUp(event.getDeviceId(), keyCode) == 0) {
     683                    return true;
     684                }
     685            }
     686        }
     687       
     688        if( (event.getSource() & InputDevice.SOURCE_KEYBOARD) != 0) {
     689            if (event.getAction() == KeyEvent.ACTION_DOWN) {
     690                //Log.v("SDL", "key down: " + keyCode);
     691                SDLActivity.onNativeKeyDown(keyCode);
     692                return true;
     693            }
     694            else if (event.getAction() == KeyEvent.ACTION_UP) {
     695                //Log.v("SDL", "key up: " + keyCode);
     696                SDLActivity.onNativeKeyUp(keyCode);
     697                return true;
     698            }
     699        }
     700       
     701        return false;
     702    }
     703
     704    // Touch events
     705    @Override
     706    public boolean onTouch(View v, MotionEvent event) {
     707        /* Ref: http://developer.android.com/training/gestures/multi.html */
     708        final int touchDevId = event.getDeviceId();
     709        final int pointerCount = event.getPointerCount();
     710        int action = event.getActionMasked();
     711        int pointerFingerId;
     712        int i = -1;
     713        float x,y,p;
     714       
     715        switch(action) {
     716            case MotionEvent.ACTION_MOVE:
     717                for (i = 0; i < pointerCount; i++) {
     718                    pointerFingerId = event.getPointerId(i);
     719                    x = event.getX(i) / mWidth;
     720                    y = event.getY(i) / mHeight;
     721                    p = event.getPressure(i);
     722                    SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
     723                }
     724                break;
     725           
     726            case MotionEvent.ACTION_UP:
     727            case MotionEvent.ACTION_DOWN:
     728                // Primary pointer up/down, the index is always zero
     729                i = 0;
     730            case MotionEvent.ACTION_POINTER_UP:
     731            case MotionEvent.ACTION_POINTER_DOWN:
     732                // Non primary pointer up/down
     733                if (i == -1) {
     734                    i = event.getActionIndex();
     735                }
     736               
     737                pointerFingerId = event.getPointerId(i);
     738                x = event.getX(i) / mWidth;
     739                y = event.getY(i) / mHeight;
     740                p = event.getPressure(i);
     741                SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
     742                break;
     743           
     744            default:
     745                break;
     746        }
     747
     748        return true;
     749   }
     750
     751    // Sensor events
     752    public void enableSensor(int sensortype, boolean enabled) {
     753        // TODO: This uses getDefaultSensor - what if we have >1 accels?
     754        if (enabled) {
     755            mSensorManager.registerListener(this,
     756                            mSensorManager.getDefaultSensor(sensortype),
     757                            SensorManager.SENSOR_DELAY_GAME, null);
     758        } else {
     759            mSensorManager.unregisterListener(this,
     760                            mSensorManager.getDefaultSensor(sensortype));
     761        }
     762    }
     763   
     764    @Override
     765    public void onAccuracyChanged(Sensor sensor, int accuracy) {
     766        // TODO
     767    }
     768
     769    @Override
     770    public void onSensorChanged(SensorEvent event) {
     771        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
     772            float x, y;
     773            switch (mDisplay.getRotation()) {
     774                case Surface.ROTATION_90:
     775                    x = -event.values[1];
     776                    y = event.values[0];
     777                    break;
     778                case Surface.ROTATION_270:
     779                    x = event.values[1];
     780                    y = -event.values[0];
     781                    break;
     782                case Surface.ROTATION_180:
     783                    x = -event.values[1];
     784                    y = -event.values[0];
     785                    break;
     786                default:
     787                    x = event.values[0];
     788                    y = event.values[1];
     789                    break;
     790            }
     791            SDLActivity.onNativeAccel(-x / SensorManager.GRAVITY_EARTH,
     792                                      y / SensorManager.GRAVITY_EARTH,
     793                                      event.values[2] / SensorManager.GRAVITY_EARTH - 1);
     794        }
     795    }   
     796}
     797
     798/* This is a fake invisible editor view that receives the input and defines the
     799 * pan&scan region
     800 */
     801class DummyEdit extends View implements View.OnKeyListener {
     802    InputConnection ic;
     803
     804    public DummyEdit(Context context) {
     805        super(context);
     806        setFocusableInTouchMode(true);
     807        setFocusable(true);
     808        setOnKeyListener(this);
     809    }
     810
     811    @Override
     812    public boolean onCheckIsTextEditor() {
     813        return true;
     814    }
     815
     816    @Override
     817    public boolean onKey(View v, int keyCode, KeyEvent event) {
     818
     819        // This handles the hardware keyboard input
     820        if (event.isPrintingKey()) {
     821            if (event.getAction() == KeyEvent.ACTION_DOWN) {
     822                ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
     823            }
     824            return true;
     825        }
     826
     827        if (event.getAction() == KeyEvent.ACTION_DOWN) {
     828            SDLActivity.onNativeKeyDown(keyCode);
     829            return true;
     830        } else if (event.getAction() == KeyEvent.ACTION_UP) {
     831            SDLActivity.onNativeKeyUp(keyCode);
     832            return true;
     833        }
     834
     835        return false;
     836    }
     837       
     838    //
     839    @Override
     840    public boolean onKeyPreIme (int keyCode, KeyEvent event) {
     841        // As seen on StackOverflow: http://stackoverflow.com/questions/7634346/keyboard-hide-event
     842        // FIXME: Discussion at http://bugzilla.libsdl.org/show_bug.cgi?id=1639
     843        // FIXME: This is not a 100% effective solution to the problem of detecting if the keyboard is showing or not
     844        // FIXME: A more effective solution would be to change our Layout from AbsoluteLayout to Relative or Linear
     845        // FIXME: And determine the keyboard presence doing this: http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android
     846        // FIXME: An even more effective way would be if Android provided this out of the box, but where would the fun be in that :)
     847        if (event.getAction()==KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
     848            if (SDLActivity.mTextEdit != null && SDLActivity.mTextEdit.getVisibility() == View.VISIBLE) {
     849                SDLActivity.onNativeKeyboardFocusLost();
     850            }
     851        }
     852        return super.onKeyPreIme(keyCode, event);
     853    }
     854
     855    @Override
     856    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
     857        ic = new SDLInputConnection(this, true);
     858
     859        outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
     860                | 33554432 /* API 11: EditorInfo.IME_FLAG_NO_FULLSCREEN */;
     861
     862        return ic;
     863    }
     864}
     865
     866class SDLInputConnection extends BaseInputConnection {
     867
     868    public SDLInputConnection(View targetView, boolean fullEditor) {
     869        super(targetView, fullEditor);
     870
     871    }
     872
     873    @Override
     874    public boolean sendKeyEvent(KeyEvent event) {
     875
     876        /*
     877         * This handles the keycodes from soft keyboard (and IME-translated
     878         * input from hardkeyboard)
     879         */
     880        int keyCode = event.getKeyCode();
     881        if (event.getAction() == KeyEvent.ACTION_DOWN) {
     882            if (event.isPrintingKey()) {
     883                commitText(String.valueOf((char) event.getUnicodeChar()), 1);
     884            }
     885            SDLActivity.onNativeKeyDown(keyCode);
     886            return true;
     887        } else if (event.getAction() == KeyEvent.ACTION_UP) {
     888
     889            SDLActivity.onNativeKeyUp(keyCode);
     890            return true;
     891        }
     892        return super.sendKeyEvent(event);
     893    }
     894
     895    @Override
     896    public boolean commitText(CharSequence text, int newCursorPosition) {
     897
     898        nativeCommitText(text.toString(), newCursorPosition);
     899
     900        return super.commitText(text, newCursorPosition);
     901    }
     902
     903    @Override
     904    public boolean setComposingText(CharSequence text, int newCursorPosition) {
     905
     906        nativeSetComposingText(text.toString(), newCursorPosition);
     907
     908        return super.setComposingText(text, newCursorPosition);
     909    }
     910
     911    public native void nativeCommitText(String text, int newCursorPosition);
     912
     913    public native void nativeSetComposingText(String text, int newCursorPosition);
     914
     915    @Override
     916    public boolean deleteSurroundingText(int beforeLength, int afterLength) {       
     917        // Workaround to capture backspace key. Ref: http://stackoverflow.com/questions/14560344/android-backspace-in-webview-baseinputconnection
     918        if (beforeLength == 1 && afterLength == 0) {
     919            // backspace
     920            return super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
     921                && super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
     922        }
     923
     924        return super.deleteSurroundingText(beforeLength, afterLength);
     925    }
     926}
     927
     928/* A null joystick handler for API level < 12 devices (the accelerometer is handled separately) */
     929class SDLJoystickHandler {
     930   
     931    public boolean handleMotionEvent(MotionEvent event) {
     932        return false;
     933    }
     934   
     935    public void pollInputDevices() {
     936    }
     937}
     938
     939/* Actual joystick functionality available for API >= 12 devices */
     940class SDLJoystickHandler_API12 extends SDLJoystickHandler {
     941 
     942    class SDLJoystick {
     943        public int device_id;
     944        public String name;
     945        public ArrayList<InputDevice.MotionRange> axes;
     946        public ArrayList<InputDevice.MotionRange> hats;
     947    }
     948    class RangeComparator implements Comparator<InputDevice.MotionRange>
     949    {
     950        @Override
     951        public int compare(InputDevice.MotionRange arg0, InputDevice.MotionRange arg1) {
     952            return arg0.getAxis() - arg1.getAxis();
     953        }
     954    }
     955   
     956    private ArrayList<SDLJoystick> mJoysticks;
     957   
     958    public SDLJoystickHandler_API12() {
     959       
     960        mJoysticks = new ArrayList<SDLJoystick>();
     961    }
     962
     963    @Override
     964    public void pollInputDevices() {
     965        int[] deviceIds = InputDevice.getDeviceIds();
     966        // It helps processing the device ids in reverse order
     967        // For example, in the case of the XBox 360 wireless dongle,
     968        // so the first controller seen by SDL matches what the receiver
     969        // considers to be the first controller
     970       
     971        for(int i=deviceIds.length-1; i>-1; i--) {
     972            SDLJoystick joystick = getJoystick(deviceIds[i]);
     973            if (joystick == null) {
     974                joystick = new SDLJoystick();
     975                InputDevice joystickDevice = InputDevice.getDevice(deviceIds[i]);
     976                if( (joystickDevice.getSources() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
     977                    joystick.device_id = deviceIds[i];
     978                    joystick.name = joystickDevice.getName();
     979                    joystick.axes = new ArrayList<InputDevice.MotionRange>();
     980                    joystick.hats = new ArrayList<InputDevice.MotionRange>();
     981                   
     982                    List<InputDevice.MotionRange> ranges = joystickDevice.getMotionRanges();
     983                    Collections.sort(ranges, new RangeComparator());
     984                    for (InputDevice.MotionRange range : ranges ) {
     985                        if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0 ) {
     986                            if (range.getAxis() == MotionEvent.AXIS_HAT_X ||
     987                                range.getAxis() == MotionEvent.AXIS_HAT_Y) {
     988                                joystick.hats.add(range);
     989                            }
     990                            else {
     991                                joystick.axes.add(range);
     992                            }
     993                        }
     994                    }
     995                   
     996                    mJoysticks.add(joystick);
     997                    SDLActivity.nativeAddJoystick(joystick.device_id, joystick.name, 0, -1,
     998                                                  joystick.axes.size(), joystick.hats.size()/2, 0);
     999                }
     1000            }
     1001        }
     1002       
     1003        /* Check removed devices */
     1004        ArrayList<Integer> removedDevices = new ArrayList<Integer>();
     1005        for(int i=0; i < mJoysticks.size(); i++) {
     1006            int device_id = mJoysticks.get(i).device_id;
     1007            int j;
     1008            for (j=0; j < deviceIds.length; j++) {
     1009                if (device_id == deviceIds[j]) break;
     1010            }
     1011            if (j == deviceIds.length) {
     1012                removedDevices.add(device_id);
     1013            }
     1014        }
     1015           
     1016        for(int i=0; i < removedDevices.size(); i++) {
     1017            int device_id = removedDevices.get(i);
     1018            SDLActivity.nativeRemoveJoystick(device_id);
     1019            for (int j=0; j < mJoysticks.size(); j++) {
     1020                if (mJoysticks.get(j).device_id == device_id) {
     1021                    mJoysticks.remove(j);
     1022                    break;
     1023                }
     1024            }
     1025        }       
     1026    }
     1027   
     1028    protected SDLJoystick getJoystick(int device_id) {
     1029        for(int i=0; i < mJoysticks.size(); i++) {
     1030            if (mJoysticks.get(i).device_id == device_id) {
     1031                return mJoysticks.get(i);
     1032            }
     1033        }
     1034        return null;
     1035    }   
     1036   
     1037    @Override       
     1038    public boolean handleMotionEvent(MotionEvent event) {
     1039        if ( (event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) {
     1040            int actionPointerIndex = event.getActionIndex();
     1041            int action = event.getActionMasked();
     1042            switch(action) {
     1043                case MotionEvent.ACTION_MOVE:
     1044                    SDLJoystick joystick = getJoystick(event.getDeviceId());
     1045                    if ( joystick != null ) {
     1046                        for (int i = 0; i < joystick.axes.size(); i++) {
     1047                            InputDevice.MotionRange range = joystick.axes.get(i);
     1048                            /* Normalize the value to -1...1 */
     1049                            float value = ( event.getAxisValue( range.getAxis(), actionPointerIndex) - range.getMin() ) / range.getRange() * 2.0f - 1.0f;
     1050                            SDLActivity.onNativeJoy(joystick.device_id, i, value );
     1051                        }         
     1052                        for (int i = 0; i < joystick.hats.size(); i+=2) {
     1053                            int hatX = Math.round(event.getAxisValue( joystick.hats.get(i).getAxis(), actionPointerIndex ) );
     1054                            int hatY = Math.round(event.getAxisValue( joystick.hats.get(i+1).getAxis(), actionPointerIndex ) );
     1055                            SDLActivity.onNativeHat(joystick.device_id, i/2, hatX, hatY );
     1056                        }
     1057                    }
     1058                    break;
     1059                default:
     1060                    break;
     1061            }
     1062        }
     1063        return true;
     1064    }           
     1065}
     1066
     1067class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener {
     1068    // Generic Motion (mouse hover, joystick...) events go here
     1069    // We only have joysticks yet
     1070    @Override
     1071    public boolean onGenericMotion(View v, MotionEvent event) {
     1072        return SDLActivity.handleJoystickMotionEvent(event);
     1073    }
     1074}
  • new file uild/android/qtcreator/android_support.pro

    diff --git a/build/android/qtcreator/android_support.pro b/build/android/qtcreator/android_support.pro
    new file mode 100644
    index 0000000..eb47835
    - +  
     1TARGET=android_support
     2include(staticlib.pri)
     3
     4DEFINES+= restrict=__restrict__
     5
     6AS_SRCS=$$NDK_ROOT/sources/android/support
     7
     8SOURCES+= \
     9    $$AS_SRCS/src/libdl_support.c \
     10    $$AS_SRCS/src/locale_support.c \
     11    $$AS_SRCS/src/math_support.c \
     12    $$AS_SRCS/src/stdlib_support.c \
     13    $$AS_SRCS/src/wchar_support.c \
     14    $$AS_SRCS/src/locale/duplocale.c \
     15    $$AS_SRCS/src/locale/freelocale.c \
     16    $$AS_SRCS/src/locale/localeconv.c \
     17    $$AS_SRCS/src/locale/newlocale.c \
     18    $$AS_SRCS/src/locale/uselocale.c \
     19    $$AS_SRCS/src/stdio/stdio_impl.c \
     20    $$AS_SRCS/src/stdio/strtod.c \
     21    $$AS_SRCS/src/stdio/vfprintf.c \
     22    $$AS_SRCS/src/stdio/vfwprintf.c \
     23    $$AS_SRCS/src/msun/e_log2.c \
     24    $$AS_SRCS/src/msun/e_log2f.c \
     25    $$AS_SRCS/src/msun/s_nan.c \
     26    $$AS_SRCS/src/musl-ctype/iswalnum.c \
     27    $$AS_SRCS/src/musl-ctype/iswalpha.c \
     28    $$AS_SRCS/src/musl-ctype/iswblank.c \
     29    $$AS_SRCS/src/musl-ctype/iswcntrl.c \
     30    $$AS_SRCS/src/musl-ctype/iswctype.c \
     31    $$AS_SRCS/src/musl-ctype/iswdigit.c \
     32    $$AS_SRCS/src/musl-ctype/iswgraph.c \
     33    $$AS_SRCS/src/musl-ctype/iswlower.c \
     34    $$AS_SRCS/src/musl-ctype/iswprint.c \
     35    $$AS_SRCS/src/musl-ctype/iswpunct.c \
     36    $$AS_SRCS/src/musl-ctype/iswspace.c \
     37    $$AS_SRCS/src/musl-ctype/iswupper.c \
     38    $$AS_SRCS/src/musl-ctype/iswxdigit.c \
     39    $$AS_SRCS/src/musl-ctype/towctrans.c \
     40    $$AS_SRCS/src/musl-ctype/wcswidth.c \
     41    $$AS_SRCS/src/musl-ctype/wctrans.c \
     42    $$AS_SRCS/src/musl-ctype/wcwidth.c \
     43    $$AS_SRCS/src/musl-locale/catclose.c \
     44    $$AS_SRCS/src/musl-locale/catgets.c \
     45    $$AS_SRCS/src/musl-locale/catopen.c \
     46    $$AS_SRCS/src/musl-locale/iconv.c \
     47    $$AS_SRCS/src/musl-locale/intl.c \
     48    $$AS_SRCS/src/musl-locale/isalnum_l.c \
     49    $$AS_SRCS/src/musl-locale/isalpha_l.c \
     50    $$AS_SRCS/src/musl-locale/isblank_l.c \
     51    $$AS_SRCS/src/musl-locale/iscntrl_l.c \
     52    $$AS_SRCS/src/musl-locale/isdigit_l.c \
     53    $$AS_SRCS/src/musl-locale/isgraph_l.c \
     54    $$AS_SRCS/src/musl-locale/islower_l.c \
     55    $$AS_SRCS/src/musl-locale/isprint_l.c \
     56    $$AS_SRCS/src/musl-locale/ispunct_l.c \
     57    $$AS_SRCS/src/musl-locale/isspace_l.c \
     58    $$AS_SRCS/src/musl-locale/isupper_l.c \
     59    $$AS_SRCS/src/musl-locale/iswalnum_l.c \
     60    $$AS_SRCS/src/musl-locale/iswalpha_l.c \
     61    $$AS_SRCS/src/musl-locale/iswblank_l.c \
     62    $$AS_SRCS/src/musl-locale/iswcntrl_l.c \
     63    $$AS_SRCS/src/musl-locale/iswctype_l.c \
     64    $$AS_SRCS/src/musl-locale/iswdigit_l.c \
     65    $$AS_SRCS/src/musl-locale/iswgraph_l.c \
     66    $$AS_SRCS/src/musl-locale/iswlower_l.c \
     67    $$AS_SRCS/src/musl-locale/iswprint_l.c \
     68    $$AS_SRCS/src/musl-locale/iswpunct_l.c \
     69    $$AS_SRCS/src/musl-locale/iswspace_l.c \
     70    $$AS_SRCS/src/musl-locale/iswupper_l.c \
     71    $$AS_SRCS/src/musl-locale/iswxdigit_l.c \
     72    $$AS_SRCS/src/musl-locale/isxdigit_l.c \
     73    $$AS_SRCS/src/musl-locale/langinfo.c \
     74    $$AS_SRCS/src/musl-locale/strcasecmp_l.c \
     75    $$AS_SRCS/src/musl-locale/strcoll.c \
     76    $$AS_SRCS/src/musl-locale/strerror_l.c \
     77    $$AS_SRCS/src/musl-locale/strfmon.c \
     78    $$AS_SRCS/src/musl-locale/strftime_l.c \
     79    $$AS_SRCS/src/musl-locale/strncasecmp_l.c \
     80    $$AS_SRCS/src/musl-locale/strxfrm.c \
     81    $$AS_SRCS/src/musl-locale/tolower_l.c \
     82    $$AS_SRCS/src/musl-locale/toupper_l.c \
     83    $$AS_SRCS/src/musl-locale/towctrans_l.c \
     84    $$AS_SRCS/src/musl-locale/towlower_l.c \
     85    $$AS_SRCS/src/musl-locale/towupper_l.c \
     86    $$AS_SRCS/src/musl-locale/wcscoll.c \
     87    $$AS_SRCS/src/musl-locale/wcsxfrm.c \
     88    $$AS_SRCS/src/musl-locale/wctrans_l.c \
     89    $$AS_SRCS/src/musl-locale/wctype_l.c \
     90    $$AS_SRCS/src/musl-math/frexp.c \
     91    $$AS_SRCS/src/musl-math/frexpf.c \
     92    $$AS_SRCS/src/musl-math/frexpl.c \
     93    $$AS_SRCS/src/musl-multibyte/btowc.c \
     94    $$AS_SRCS/src/musl-multibyte/internal.c \
     95    $$AS_SRCS/src/musl-multibyte/mblen.c \
     96    $$AS_SRCS/src/musl-multibyte/mbrlen.c \
     97    $$AS_SRCS/src/musl-multibyte/mbrtowc.c \
     98    $$AS_SRCS/src/musl-multibyte/mbsinit.c \
     99    $$AS_SRCS/src/musl-multibyte/mbsnrtowcs.c \
     100    $$AS_SRCS/src/musl-multibyte/mbsrtowcs.c \
     101    $$AS_SRCS/src/musl-multibyte/mbstowcs.c \
     102    $$AS_SRCS/src/musl-multibyte/mbtowc.c \
     103    $$AS_SRCS/src/musl-multibyte/wcrtomb.c \
     104    $$AS_SRCS/src/musl-multibyte/wcsnrtombs.c \
     105    $$AS_SRCS/src/musl-multibyte/wcsrtombs.c \
     106    $$AS_SRCS/src/musl-multibyte/wcstombs.c \
     107    $$AS_SRCS/src/musl-multibyte/wctob.c \
     108    $$AS_SRCS/src/musl-multibyte/wctomb.c \
     109    $$AS_SRCS/src/musl-stdio/printf.c \
     110    $$AS_SRCS/src/musl-stdio/snprintf.c \
     111    $$AS_SRCS/src/musl-stdio/sprintf.c \
     112    $$AS_SRCS/src/musl-stdio/vprintf.c \
     113    $$AS_SRCS/src/musl-stdio/vsprintf.c \
     114    $$AS_SRCS/src/musl-stdio/swprintf.c \
     115    $$AS_SRCS/src/musl-stdio/vwprintf.c \
     116    $$AS_SRCS/src/musl-stdio/wprintf.c \
     117    $$AS_SRCS/src/wcstox/floatscan.c \
     118    $$AS_SRCS/src/wcstox/intscan.c \
     119    $$AS_SRCS/src/wcstox/shgetc.c \
     120    $$AS_SRCS/src/wcstox/wcstol.c \
     121    $$AS_SRCS/src/wcstox/wcstod.c
  • new file uild/android/qtcreator/atlas.pro

    diff --git a/build/android/qtcreator/atlas.pro b/build/android/qtcreator/atlas.pro
    new file mode 100644
    index 0000000..97efad0
    - +  
     1TARGET=atlas
     2include(staticlib.pri)
     3
     4SOURCES+=$$SRCS_PATH/tools/atlas/GameInterface/*.cpp
     5HEADERS+=$$SRCS_PATH/tools/atlas/GameInterface/*.h
     6
     7SOURCES+=$$SRCS_PATH/tools/atlas/GameInterface/Handlers/*.cpp
     8HEADERS+=$$SRCS_PATH/tools/atlas/GameInterface/Handlers/*.h
  • new file uild/android/qtcreator/common.pri

    diff --git a/build/android/qtcreator/common.pri b/build/android/qtcreator/common.pri
    new file mode 100644
    index 0000000..3f4cd72
    - +  
     1QT=
     2
     3OBJECTS_DIR =.$$TARGET
     4
     5QMAKE_CFLAGS +=  -Wno-unused-parameter -Wno-parentheses  -Wno-sign-compare
     6QMAKE_CXXFLAGS += -Wno-unused-local-typedefs -Wno-reorder -Wno-unused-parameter -Wno-parentheses -Wno-sign-compare
     7
     8DEPENDENCIES_PATH = $$PWD/../../../libraries/android/$$ANDROID_ARCHITECTURE
     9
     10DEFINES +=  \
     11            U_HAVE_STD_STRING \
     12            CONFIG2_NVTT=0 CONFIG2_MINIUPNPC=1 \
     13            CONFIG2_GLES=1 CONFIG2_AUDIO=1
     14
     15SRCS_PATH=$$PWD/../../../source
     16
     17INCLUDEPATH +=  \
     18            $$NDK_ROOT/sources/android/support/include \
     19            $$DEPENDENCIES_PATH/include $$DEPENDENCIES_PATH/include/SDL2 \
     20            $$DEPENDENCIES_PATH/include/mozjs-31 $$DEPENDENCIES_PATH/include/libxml2 \
     21            $$DEPENDENCIES_PATH/include/miniupnpc $$SRCS_PATH/third_party/tinygettext/include \
     22            $$PWD/../../../source $$PWD/../../../source/pch/$$TARGET
     23
     24PCH_FILE=$$PWD/../../../source/pch/$$TARGET/precompiled.h
     25exists($$PCH_FILE):PRECOMPILED_HEADER = $$PWD/../../../source/pch/$$TARGET/precompiled.h
  • new file uild/android/qtcreator/engine.pro

    diff --git a/build/android/qtcreator/engine.pro b/build/android/qtcreator/engine.pro
    new file mode 100644
    index 0000000..8f3b83f
    - +  
     1TARGET=engine
     2include(staticlib.pri)
     3
     4SOURCES+=$$SRCS_PATH/ps/*.cpp
     5HEADERS+=$$SRCS_PATH/ps/*.h
     6
     7SOURCES+=$$SRCS_PATH/ps/scripting/*.cpp
     8HEADERS+=$$SRCS_PATH/ps/scripting/*.h
     9
     10SOURCES+=$$SRCS_PATH/ps/GameSetup/*.cpp
     11HEADERS+=$$SRCS_PATH/ps/GameSetup/*.h
     12
     13SOURCES+=$$SRCS_PATH/ps/XML/*.cpp
     14HEADERS+=$$SRCS_PATH/ps/XML/*.h
     15
     16SOURCES+=$$SRCS_PATH/soundmanager/*.cpp
     17HEADERS+=$$SRCS_PATH/soundmanager/*.h
     18
     19SOURCES+=$$SRCS_PATH/soundmanager/data/*.cpp
     20HEADERS+=$$SRCS_PATH/soundmanager/data/*.h
     21
     22SOURCES+=$$SRCS_PATH/soundmanager/items/*.cpp
     23HEADERS+=$$SRCS_PATH/soundmanager/items/*.h
     24
     25SOURCES+=$$SRCS_PATH/soundmanager/scripting/*.cpp
     26HEADERS+=$$SRCS_PATH/soundmanager/scripting/*.h
     27
     28SOURCES+=$$SRCS_PATH/maths/*.cpp
     29HEADERS+=$$SRCS_PATH/maths/*.h
     30
     31SOURCES+=$$SRCS_PATH/i18n/*.cpp
     32HEADERS+=$$SRCS_PATH/i18n/*.h
     33
     34SOURCES+=$$SRCS_PATH/i18n/scripting/*.cpp
     35HEADERS+=$$SRCS_PATH/i18n/scripting/*.h
     36
     37SOURCES+=$$SRCS_PATH/third_party/cppformat/*.cpp
     38HEADERS+=$$SRCS_PATH/third_party/cppformat/*.h
  • new file uild/android/qtcreator/graphics.pro

    diff --git a/build/android/qtcreator/graphics.pro b/build/android/qtcreator/graphics.pro
    new file mode 100644
    index 0000000..d3ad694
    - +  
     1TARGET=graphics
     2include(staticlib.pri)
     3
     4SOURCES+=$$SRCS_PATH/renderer/*.cpp
     5HEADERS+=$$SRCS_PATH/renderer/*.h
     6
     7SOURCES+=$$SRCS_PATH/renderer/scripting/*.cpp
     8HEADERS+=$$SRCS_PATH/renderer/scripting/*.h
     9
     10SOURCES+=$$SRCS_PATH/third_party/mikktspace/*.cpp
     11HEADERS+=$$SRCS_PATH/third_party/mikktspace/*.h
  • new file uild/android/qtcreator/gui.pro

    diff --git a/build/android/qtcreator/gui.pro b/build/android/qtcreator/gui.pro
    new file mode 100644
    index 0000000..42f87ad
    - +  
     1TARGET=gui
     2include(staticlib.pri)
  • new file uild/android/qtcreator/lobby.pro

    diff --git a/build/android/qtcreator/lobby.pro b/build/android/qtcreator/lobby.pro
    new file mode 100644
    index 0000000..67c470b
    - +  
     1TARGET=lobby
     2include(staticlib.pri)
     3
     4SOURCES+=$$SRCS_PATH/lobby/glooxwrapper/*.cpp
     5HEADERS+=$$SRCS_PATH/lobby/glooxwrapper/*.h
     6
     7SOURCES+=$$SRCS_PATH/third_party/encryption/*.cpp
     8HEADERS+=$$SRCS_PATH/third_party/encryption/*.h
  • new file uild/android/qtcreator/lowlevel.pro

    diff --git a/build/android/qtcreator/lowlevel.pro b/build/android/qtcreator/lowlevel.pro
    new file mode 100644
    index 0000000..d96612b
    - +  
     1TARGET=lowlevel
     2include(staticlib.pri)
     3
     4SOURCES+=$$SRCS_PATH/lib/*.cpp
     5HEADERS+=$$SRCS_PATH/lib/*.h
     6
     7HEADERS+=$$SRCS_PATH/lib/adts/*.h
     8
     9SOURCES+=$$SRCS_PATH/lib/allocators/*.cpp
     10HEADERS+=$$SRCS_PATH/lib/allocators/*.h
     11
     12SOURCES+=$$SRCS_PATH/lib/external_libraries/*.cpp
     13HEADERS+=$$SRCS_PATH/lib/external_libraries/*.h
     14
     15SOURCES+=$$SRCS_PATH/lib/file/*.cpp
     16HEADERS+=$$SRCS_PATH/lib/file/*.h
     17
     18SOURCES+=$$SRCS_PATH/lib/file/archive/*.cpp
     19HEADERS+=$$SRCS_PATH/lib/file/archive/*.h
     20
     21SOURCES+=$$SRCS_PATH/lib/file/common/*.cpp
     22HEADERS+=$$SRCS_PATH/lib/file/common/*.h
     23
     24SOURCES+=$$SRCS_PATH/lib/file/io/*.cpp
     25HEADERS+=$$SRCS_PATH/lib/file/io/*.h
     26
     27SOURCES+=$$SRCS_PATH/lib/file/vfs/*.cpp
     28HEADERS+=$$SRCS_PATH/lib/file/vfs/*.h
     29
     30HEADERS+=$$SRCS_PATH/lib/pch/*.h
     31
     32SOURCES+=$$SRCS_PATH/lib/posix/*.cpp
     33HEADERS+=$$SRCS_PATH/lib/posix/*.h
     34
     35SOURCES+=$$SRCS_PATH/lib/res/*.cpp
     36HEADERS+=$$SRCS_PATH/lib/res/*.h
     37
     38SOURCES+=$$SRCS_PATH/lib/res/graphics/*.cpp
     39HEADERS+=$$SRCS_PATH/lib/res/graphics/*.h
     40
     41SOURCES+=$$SRCS_PATH/lib/tex/*.cpp
     42HEADERS+=$$SRCS_PATH/lib/tex/*.h
     43
     44SOURCES+=$$SRCS_PATH/lib/sysdep/*.cpp
     45HEADERS+=$$SRCS_PATH/lib/sysdep/*.h
     46
     47SOURCES+=$$SRCS_PATH/lib/sysdep/arch/arm/*.cpp
     48HEADERS+=$$SRCS_PATH/lib/sysdep/arch/arm/*.h
     49
     50SOURCES+=$$SRCS_PATH/lib/sysdep/os/unix/*.cpp
     51HEADERS+=$$SRCS_PATH/lib/sysdep/os/unix/*.h
     52
     53SOURCES+=$$SRCS_PATH/lib/sysdep/os/linux/*.cpp
     54HEADERS+=$$SRCS_PATH/lib/sysdep/os/linux/*.h
     55
     56SOURCES+=$$SRCS_PATH/lib/sysdep/os/android/*.cpp
     57HEADERS+=$$SRCS_PATH/lib/sysdep/os/android/*.h
     58
     59SOURCES+=$$SRCS_PATH/lib/sysdep/rtl/gcc/*.cpp
     60HEADERS+=$$SRCS_PATH/lib/sysdep/rtl/gcc/*.h
  • new file uild/android/qtcreator/main.pro

    diff --git a/build/android/qtcreator/main.pro b/build/android/qtcreator/main.pro
    new file mode 100644
    index 0000000..6c94037
    - +  
     1TARGET=main
     2include(common.pri)
     3
     4SDL_SRCS=$$DEPENDENCIES_PATH/SDL2/src
     5
     6SOURCES += $$PWD/../../../source/main.cpp \
     7       $$SDL_SRCS/main/android/SDL_android_main.c
     8
     9LIBS += -L$$OUT_PWD -Wl,--start-group \
     10        -lgui -lsimulation2 -lgraphics -latlas -lengine -lnetwork \
     11        -lscriptinterface -ltinygettext -lmongoose -llowlevel \
     12        -llobby -Wl,--end-group -lSDL  -landroid_support\
     13        -L$$DEPENDENCIES_PATH/lib -lpng -ljpeg -lxml2 -lmozjs-31 \
     14        -lgloox -lopenal -lcommon -lvorbisfile -lvorbis -logg \
     15        -lminiupnpc -licui18n -licuio -licule -liculx -licuuc -licudata \
     16        -lenet -lboost_filesystem -lboost_system -lcurl -lssl -lcrypto -lm
     17
     18apitrace: exists($$DEPENDENCIES_PATH/lib/apitrace/wrappers/libegltrace.so) {
     19        ANDROID_EXTRA_LIBS += $$DEPENDENCIES_PATH/lib/apitrace/wrappers/libegltrace.so
     20        LIBS += -L$$DEPENDENCIES_PATH/lib/apitrace/wrappers -legltrace
     21} else {
     22        LIBS += -lGLESv2 -lGLESv1_CM
     23}
     24
     25LIBS += -lOpenSLES -landroid
     26
     27DISTFILES += \
     28    android/gradle/wrapper/gradle-wrapper.jar \
     29    android/AndroidManifest.xml \
     30    android/gradlew.bat \
     31    android/res/values/libs.xml \
     32    android/build.gradle \
     33    android/gradle/wrapper/gradle-wrapper.properties \
     34    android/gradlew \
     35    android/src/org/libsdl/app/SDLActivity.java \
     36    android/res/drawable/zeroad.png \
     37    android/res/values/strings.xml \
     38    android/src/com/play0ad/Activity.java \
     39    android/src/com/play0ad/Native.java \
     40    android/src/com/play0ad/QtCreatorDebugger.java
     41
     42ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
  • new file uild/android/qtcreator/mongoose.pro

    diff --git a/build/android/qtcreator/mongoose.pro b/build/android/qtcreator/mongoose.pro
    new file mode 100644
    index 0000000..be18009
    - +  
     1TARGET=mongoose
     2include(staticlib.pri)
     3
     4SOURCES+=$$SRCS_PATH/third_party/mongoose/*.cpp
     5HEADERS+=$$SRCS_PATH/third_party/mongoose/*.h
  • new file uild/android/qtcreator/network.pro

    diff --git a/build/android/qtcreator/network.pro b/build/android/qtcreator/network.pro
    new file mode 100644
    index 0000000..3a087db
    - +  
     1TARGET=network
     2include(staticlib.pri)
  • new file uild/android/qtcreator/qtcreator.pro

    diff --git a/build/android/qtcreator/qtcreator.pro b/build/android/qtcreator/qtcreator.pro
    new file mode 100644
    index 0000000..ed4a82f
    - +  
     1TEMPLATE = subdirs
     2CONFIG += ordered
     3
     4!android: error("Use only on Android");
     5
     6DEPENDENCIES_PATH = $$PWD/../../../libraries/android/$$ANDROID_ARCHITECTURE
     7
     8!exists($$DEPENDENCIES_PATH/SDL2): {
     9    warning("Dependencies $$DEPENDENCIES_PATH are not setup.\nRunning setup-libs.sh, please be patient ...")
     10    system($$PWD/../setup-libs.sh -n $$NDK_ROOT -a $$ANDROID_ARCHITECTURE)
     11    !exists($$DEPENDENCIES_PATH/SDL2): error("setup-libs.sh failed, please run it manually and check the oputput")
     12                                 else: warning("Dependencies compiled, please reload the project!")
     13}
     14
     15SUBDIRS += \
     16    android_support.pro \
     17    sdl.pro \
     18    mongoose.pro \
     19    tinygettext.pro \
     20    lowlevel.pro \
     21    network.pro \
     22    lobby.pro \
     23    simulation2.pro\
     24    scriptinterface.pro \
     25    graphics.pro \
     26    gui.pro \
     27    atlas.pro \
     28    engine.pro \
     29    main.pro
  • new file uild/android/qtcreator/scriptinterface.pro

    diff --git a/build/android/qtcreator/scriptinterface.pro b/build/android/qtcreator/scriptinterface.pro
    new file mode 100644
    index 0000000..1104c7e
    - +  
     1TARGET=scriptinterface
     2include(staticlib.pri)
     3
  • new file uild/android/qtcreator/sdl.pro

    diff --git a/build/android/qtcreator/sdl.pro b/build/android/qtcreator/sdl.pro
    new file mode 100644
    index 0000000..a30c97c
    - +  
     1TARGET = SDL
     2include(staticlib.pri)
     3
     4# ADD SDL SRCS
     5SDL_SRCS=$$DEPENDENCIES_PATH/SDL2/src
     6DEFINES += GL_GLEXT_PROTOTYPES
     7SOURCES += \
     8    $$files($$SDL_SRCS/*.c) \
     9    $$files($$SDL_SRCS/audio/*.c) \
     10    $$files($$SDL_SRCS/audio/android/*.c) \
     11    $$files($$SDL_SRCS/audio/dummy/*.c) \
     12    $$files($$SDL_SRCS/atomic/*.c) \
     13    $$files($$SDL_SRCS/core/android/*.c) \
     14    $$files($$SDL_SRCS/cpuinfo/*.c) \
     15    $$files($$SDL_SRCS/dynapi/*.c) \
     16    $$files($$SDL_SRCS/events/*.c) \
     17    $$files($$SDL_SRCS/file/*.c) \
     18    $$files($$SDL_SRCS/haptic/*.c) \
     19    $$files($$SDL_SRCS/haptic/dummy/*.c) \
     20    $$files($$SDL_SRCS/joystick/*.c) \
     21    $$files($$SDL_SRCS/joystick/android/*.c) \
     22    $$files($$SDL_SRCS/loadso/dlopen/*.c) \
     23    $$files($$SDL_SRCS/power/*.c) \
     24    $$files($$SDL_SRCS/power/android/*.c) \
     25    $$files($$SDL_SRCS/filesystem/dummy/*.c) \
     26    $$files($$SDL_SRCS/render/*.c) \
     27    $$files($$SDL_SRCS/render/software/*.c) \
     28    $$files($$SDL_SRCS/render/opengles/*.c) \
     29    $$files($$SDL_SRCS/render/opengles2/*.c) \
     30    $$files($$SDL_SRCS/stdlib/*.c) \
     31    $$files($$SDL_SRCS/thread/*.c) \
     32    $$files($$SDL_SRCS/thread/pthread/*.c) \
     33    $$files($$SDL_SRCS/timer/*.c) \
     34    $$files($$SDL_SRCS/timer/unix/*.c) \
     35    $$files($$SDL_SRCS/video/*.c) \
     36    $$files($$SDL_SRCS/video/android/*.c)
  • new file uild/android/qtcreator/simulation2.pro

    diff --git a/build/android/qtcreator/simulation2.pro b/build/android/qtcreator/simulation2.pro
    new file mode 100644
    index 0000000..1fcced4
    - +  
     1TARGET=simulation2
     2include(staticlib.pri)
     3
     4SOURCES+=$$SRCS_PATH/$$TARGET/components/*.cpp
     5HEADERS+=$$SRCS_PATH/$$TARGET/components/*.h
     6
     7SOURCES+=$$SRCS_PATH/$$TARGET/helpers/*.cpp
     8HEADERS+=$$SRCS_PATH/$$TARGET/helpers/*.h
     9
     10SOURCES+=$$SRCS_PATH/$$TARGET/serialization/*.cpp
     11HEADERS+=$$SRCS_PATH/$$TARGET/serialization/*.h
     12
     13SOURCES+=$$SRCS_PATH/$$TARGET/system/*.cpp
     14HEADERS+=$$SRCS_PATH/$$TARGET/system/*.h
  • new file uild/android/qtcreator/staticlib.pri

    diff --git a/build/android/qtcreator/staticlib.pri b/build/android/qtcreator/staticlib.pri
    new file mode 100644
    index 0000000..5e4a03d
    - +  
     1TEMPLATE = lib
     2CONFIG += staticlib
     3
     4include(common.pri)
     5
     6exists($$SRCS_PATH/$$TARGET): {
     7    SOURCES+=$$SRCS_PATH/$$TARGET/*.cpp
     8    HEADERS+=$$SRCS_PATH/$$TARGET/*.h
     9}
     10
     11exists($$SRCS_PATH/$$TARGET/scripting): {
     12    SOURCES+=$$SRCS_PATH/$$TARGET/scripting/*.cpp
     13    HEADERS+=$$SRCS_PATH/$$TARGET/scripting/*.h
     14}
     15
     16QMAKE_POST_LINK += $$QMAKE_DEL_FILE $$OUT_PWD/*.so
  • new file uild/android/qtcreator/tinygettext.pro

    diff --git a/build/android/qtcreator/tinygettext.pro b/build/android/qtcreator/tinygettext.pro
    new file mode 100644
    index 0000000..4552511
    - +  
     1TARGET=tinygettext
     2include(staticlib.pri)
     3
     4INCLUDEPATH += $$PWD/../../../source/third_party/$$TARGET/include/$$TARGET
     5
     6SOURCES+=$$SRCS_PATH/third_party/$$TARGET/src/*.c*
     7HEADERS+=$$PWD/../../../source/third_party/$$TARGET/include/$$TARGET/*.h*
  • source/lib/sysdep/os/android/android.cpp

    diff --git a/source/lib/sysdep/os/android/android.cpp b/source/lib/sysdep/os/android/android.cpp
    index 105068a..5ec8871 100644
    a b namespace gfx {  
    4646
    4747Status GetVideoMode(int* xres, int* yres, int* bpp, int* freq)
    4848{
    49 #warning TODO: implement gfx::GetVideoMode properly for Android
    50 
    5149    if(xres)
    52         *xres = 800;
     50        *xres = atoi(getenv("ANDROID_SCREEN_WIDTH"));
    5351
    5452    if(yres)
    55         *yres = 480;
     53        *yres = atoi(getenv("ANDROID_SCREEN_HEIGHT"));
    5654
    5755    if(bpp)
    5856        *bpp = 32;
    Status sys_cursor_reset()  
    117115{
    118116    return INFO::OK;
    119117}
    120 
  • source/lib/sysdep/os/linux/lcpu.cpp

    diff --git a/source/lib/sysdep/os/linux/lcpu.cpp b/source/lib/sysdep/os/linux/lcpu.cpp
    index 79fa566..e47c20b 100644
    a b  
    2727#include "lib/bits.h"
    2828#include "lib/module_init.h"
    2929
    30 #if OS_LINUX
    31 #include "valgrind.h"
     30#if OS_LINUX && !OS_ANDROID
     31# include "valgrind.h"
    3232#endif
    3333
    3434
    size_t os_cpu_NumProcessors()  
    4141        // Valgrind reports the number of real CPUs, but only emulates a single CPU.
    4242        // That causes problems when we expect all those CPUs to be distinct, so
    4343        // just pretend there's only one CPU
     44#if !OS_ANDROID
    4445        if (RUNNING_ON_VALGRIND)
    4546            numProcessors = 1;
    4647        else
     48#endif
    4749        {
    4850            long res = sysconf(_SC_NPROCESSORS_CONF);
    4951            ENSURE(res != -1);
  • source/lib/sysdep/os/unix/unix_executable_pathname.cpp

    diff --git a/source/lib/sysdep/os/unix/unix_executable_pathname.cpp b/source/lib/sysdep/os/unix/unix_executable_pathname.cpp
    index ae7b989..dcb4019 100644
    a b  
    2525#include "lib/sysdep/sysdep.h"
    2626
    2727#define GNU_SOURCE
    28 #include "mocks/dlfcn.h"
    29 #include "mocks/unistd.h"
     28#if OS_ANDROID
     29# include <dlfcn.h>
     30# include <unistd.h>
     31#define T
     32#else
     33# include "mocks/dlfcn.h"
     34# include "mocks/unistd.h"
     35#endif
    3036
    3137#include <cstdio>
    3238
  • source/main.cpp

    diff --git a/source/main.cpp b/source/main.cpp
    index 051e2f9..32dde39 100644
    a b static void RunGameOrAtlas(int argc, const char* argv[])  
    525525}
    526526
    527527#if OS_ANDROID
    528 // In Android we compile the engine as a shared library, not an executable,
    529 // so rename main() to a different symbol that the wrapper library can load
    530 #undef main
    531 #define main pyrogenesis_main
    532 extern "C" __attribute__((visibility ("default"))) int main(int argc, char* argv[]);
    533 #endif
     528#include <jni.h>
     529extern"C" JNIEXPORT jint JNICALL Java_com_play0ad_Native_setenv
     530  (JNIEnv* env, jclass /*clazz*/, jstring key, jstring value, jboolean overwrite)
     531{
     532    const char *k = env->GetStringUTFChars(key, NULL);
     533    const char *v = env->GetStringUTFChars(value, NULL);
     534    int err = setenv(k, v, overwrite);
     535    env->ReleaseStringUTFChars(key, k);
     536    env->ReleaseStringUTFChars(value, v);
     537    return err;
     538}
    534539
     540extern "C" __attribute__((visibility ("default"))) int SDL_main(int argc, char* argv[])
     541#else
    535542extern "C" int main(int argc, char* argv[])
     543#endif
    536544{
    537545#if OS_UNIX
    538546    // Don't allow people to run the game with root permissions,
  • source/ps/TouchInput.cpp

    diff --git a/source/ps/TouchInput.cpp b/source/ps/TouchInput.cpp
    index 390f11b..372b934 100644
    a b void CTouchInput::OnFingerUp(int id, int x, int y)  
    113113
    114114void CTouchInput::OnFingerMotion(int id, int x, int y)
    115115{
     116    if (!g_Game)
     117        return;
     118
    116119    debug_printf(L"finger motion %d %d %d; state %d\n", id, x, y, m_State);
    117120
    118121    CVector2D pos(x, y);
  • source/scriptinterface/ScriptInterface.cpp

    diff --git a/source/scriptinterface/ScriptInterface.cpp b/source/scriptinterface/ScriptInterface.cpp
    index 15873b2..a237211 100644
    a b  
    4141#include <boost/flyweight/no_locking.hpp>
    4242#include <boost/flyweight/no_tracking.hpp>
    4343
    44 #include "valgrind.h"
     44#if !OS_ANDROID
     45# include "valgrind.h"
     46#endif
    4547
    4648#include "scriptinterface/ScriptExtraHeaders.h"
    4749