SuperTuxKart 1.5 upstream source (from official release tarball)

This commit is contained in:
Benjamin
2026-06-11 20:04:02 +02:00
commit 2957e51aaa
8551 changed files with 1801800 additions and 0 deletions
+401
View File
@@ -0,0 +1,401 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# OpenAL
LOCAL_MODULE := openal
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/openal/libopenal.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# OGG
LOCAL_MODULE := ogg
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/libogg/libogg.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# Vorbis
LOCAL_MODULE := vorbis
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/libvorbis/lib/libvorbis.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# Vorbisfile
LOCAL_MODULE := vorbisfile
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/libvorbis/lib/libvorbisfile.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# CURL
LOCAL_MODULE := curl
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/curl/lib/libcurl.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# libmbedtls
LOCAL_MODULE := libmbedtls
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/mbedtls/library/libmbedtls.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# libmbedcrypto
LOCAL_MODULE := libmbedcrypto
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/mbedtls/library/libmbedcrypto.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# libmbedx509
LOCAL_MODULE := libmbedx509
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/mbedtls/library/libmbedx509.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# JPEG
LOCAL_MODULE := libjpeg
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/libjpeg/libjpeg.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# zlib
LOCAL_MODULE := zlib
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/zlib/libz.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# PNG
LOCAL_MODULE := png
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/libpng/libpng.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# Freetype
LOCAL_MODULE := freetype
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/freetype/build/libfreetype.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# Harfbuzz
LOCAL_MODULE := harfbuzz
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/harfbuzz/build/libharfbuzz.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# shaderc
LOCAL_MODULE := shaderc
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/shaderc/libshaderc/libshaderc_combined.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# libsquish
LOCAL_MODULE := libsquish
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/libsquish/libsquish.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# astc-encoder
LOCAL_MODULE := libastcenc
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/astc-encoder/Source/libastcenc.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# libadrenotools
ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
LOCAL_MODULE := libadrenotools
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/libadrenotools/libadrenotools.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
endif
# liblinkernsbypass
ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
LOCAL_MODULE := liblinkernsbypass
LOCAL_SRC_FILES := deps-$(TARGET_ARCH_ABI)/libadrenotools/lib/linkernsbypass/liblinkernsbypass.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
endif
# ifaddrs
LOCAL_MODULE := ifaddrs
LOCAL_PATH := .
LOCAL_SRC_FILES := ../lib/ifaddrs/ifaddrs.c
LOCAL_CFLAGS := -I../lib/ifaddrs
# Starting NDK21 it enables NEON by default on 32-bit ARM target
# Disable it to support more phones
#ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
#LOCAL_ARM_NEON := false
#endif
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
# AngelScript
LOCAL_MODULE := angelscript
LOCAL_PATH := .
LOCAL_CPP_FEATURES += rtti exceptions
LOCAL_SRC_FILES := $(wildcard ../lib/angelscript/source/*.S) \
$(wildcard ../lib/angelscript/source/*.cpp)
LOCAL_CFLAGS := -I../lib/angelscript/source/
#ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
#LOCAL_ARM_NEON := false
#endif
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
# ENET
LOCAL_MODULE := enet
LOCAL_PATH := .
LOCAL_CPP_FEATURES += rtti
LOCAL_SRC_FILES := $(wildcard ../lib/enet/*.c)
LOCAL_CFLAGS := -I../lib/enet/include/ -DHAS_SOCKLEN_T -DENABLE_IPV6
#ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
#LOCAL_ARM_NEON := false
#endif
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
# Bullet
LOCAL_MODULE := bullet
LOCAL_PATH := .
LOCAL_CPP_FEATURES += rtti
LOCAL_SRC_FILES := $(wildcard ../lib/bullet/src/*/*.cpp) \
$(wildcard ../lib/bullet/src/*/*/*.cpp)
LOCAL_CFLAGS := -I../lib/bullet/src/
#ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
#LOCAL_ARM_NEON := false
#endif
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
# Graphics utils
LOCAL_MODULE := graphics_utils
LOCAL_PATH := .
LOCAL_CPP_FEATURES += rtti
LOCAL_SRC_FILES := $(wildcard ../lib/graphics_utils/mipmap/*.c)
LOCAL_CFLAGS := -I../lib/graphics_utils/mipmap \
-I../lib/simd_wrapper
#ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
#LOCAL_ARM_NEON := false
#endif
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
# Graphics engine
LOCAL_MODULE := graphics_engine
LOCAL_PATH := .
LOCAL_CPP_FEATURES += rtti exceptions
LOCAL_SRC_FILES := $(wildcard ../lib/graphics_engine/src/*.c) \
$(wildcard ../lib/graphics_engine/src/*.cpp)
LOCAL_CFLAGS := -DENABLE_LIBASTCENC \
-I../lib/graphics_engine/include \
-I../lib/graphics_utils \
-I../lib/sdl2/include/ \
-I../lib/bullet/src/ \
-I../lib/irrlicht/include/ \
-I../lib/shaderc/libshaderc/include \
-I../lib/libsquish \
-Ideps-$(TARGET_ARCH_ABI)/astc-encoder/Source
#ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
#LOCAL_ARM_NEON := false
#endif
LOCAL_STATIC_LIBRARIES := shaderc libsquish libastcenc
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
# MCPP
LOCAL_MODULE := mcpp
LOCAL_PATH := .
LOCAL_CPP_FEATURES += rtti
LOCAL_SRC_FILES := $(wildcard ../lib/mcpp/*.c)
LOCAL_CFLAGS := -DMCPP_LIB -DHAVE_CONFIG_H
#ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
#LOCAL_ARM_NEON := false
#endif
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
# SheenBidi
LOCAL_MODULE := sheenbidi
LOCAL_PATH := .
LOCAL_CPP_FEATURES += rtti
LOCAL_SRC_FILES := $(wildcard ../lib/sheenbidi/Source/*.c)
LOCAL_CFLAGS := -I../lib/sheenbidi/Headers
#ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
#LOCAL_ARM_NEON := false
#endif
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
# tinygettext
LOCAL_MODULE := tinygettext
LOCAL_PATH := .
LOCAL_CPP_FEATURES += rtti exceptions
LOCAL_SRC_FILES := $(wildcard ../lib/tinygettext/src/*.cpp)
LOCAL_CFLAGS := -I../lib/tinygettext/include -DDISABLE_ICONV
#ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
#LOCAL_ARM_NEON := false
#endif
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
# Irrlicht
LOCAL_MODULE := irrlicht
LOCAL_PATH := .
LOCAL_CPP_FEATURES += rtti exceptions
LOCAL_SRC_FILES := $(wildcard ../lib/irrlicht/source/Irrlicht/*.cpp)
LOCAL_CFLAGS := -I../lib/irrlicht/source/Irrlicht/ \
-I../lib/irrlicht/include/ \
-I../src \
-Ideps-$(TARGET_ARCH_ABI)/libjpeg/ \
-Ideps-$(TARGET_ARCH_ABI)/libpng/ \
-Ideps-$(TARGET_ARCH_ABI)/zlib/ \
-I../lib/sdl2/include/ \
-I../lib/graphics_engine/include \
-DMOBILE_STK \
-DANDROID_PACKAGE_CALLBACK_NAME=$(PACKAGE_CALLBACK_NAME)
LOCAL_CPPFLAGS := -std=gnu++0x
LOCAL_STATIC_LIBRARIES := libjpeg png zlib
#ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
#LOCAL_ARM_NEON := false
#endif
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
# SDL2
LOCAL_MODULE := SDL2
LOCAL_PATH := .
LOCAL_SRC_FILES := $(wildcard ../lib/sdl2/src/*.c) \
$(wildcard ../lib/sdl2/src/audio/*.c) \
$(wildcard ../lib/sdl2/src/audio/android/*.c) \
$(wildcard ../lib/sdl2/src/audio/dummy/*.c) \
$(wildcard ../lib/sdl2/src/audio/aaudio/*.c) \
$(wildcard ../lib/sdl2/src/audio/openslES/*.c) \
../lib/sdl2/src/atomic/SDL_atomic.c.arm \
../lib/sdl2/src/atomic/SDL_spinlock.c.arm \
$(wildcard ../lib/sdl2/src/core/android/*.c) \
$(wildcard ../lib/sdl2/src/cpuinfo/*.c) \
$(wildcard ../lib/sdl2/src/dynapi/*.c) \
$(wildcard ../lib/sdl2/src/events/*.c) \
$(wildcard ../lib/sdl2/src/file/*.c) \
$(wildcard ../lib/sdl2/src/haptic/*.c) \
$(wildcard ../lib/sdl2/src/haptic/android/*.c) \
$(wildcard ../lib/sdl2/src/hidapi/*.c) \
$(wildcard ../lib/sdl2/src/hidapi/android/*.cpp) \
$(wildcard ../lib/sdl2/src/joystick/*.c) \
$(wildcard ../lib/sdl2/src/joystick/android/*.c) \
$(wildcard ../lib/sdl2/src/joystick/hidapi/*.c) \
$(wildcard ../lib/sdl2/src/joystick/virtual/*.c) \
$(wildcard ../lib/sdl2/src/loadso/dlopen/*.c) \
$(wildcard ../lib/sdl2/src/locale/android/*.c) \
$(wildcard ../lib/sdl2/src/locale/*.c) \
$(wildcard ../lib/sdl2/src/misc/*.c) \
$(wildcard ../lib/sdl2/src/misc/android/*.c) \
$(wildcard ../lib/sdl2/src/power/*.c) \
$(wildcard ../lib/sdl2/src/power/android/*.c) \
$(wildcard ../lib/sdl2/src/filesystem/android/*.c) \
$(wildcard ../lib/sdl2/src/sensor/*.c) \
$(wildcard ../lib/sdl2/src/sensor/android/*.c) \
$(wildcard ../lib/sdl2/src/render/*.c) \
$(wildcard ../lib/sdl2/src/render/*/*.c) \
$(wildcard ../lib/sdl2/src/stdlib/*.c) \
$(wildcard ../lib/sdl2/src/thread/*.c) \
$(wildcard ../lib/sdl2/src/thread/pthread/*.c) \
$(wildcard ../lib/sdl2/src/timer/*.c) \
$(wildcard ../lib/sdl2/src/timer/unix/*.c) \
$(wildcard ../lib/sdl2/src/video/*.c) \
$(wildcard ../lib/sdl2/src/video/android/*.c) \
$(wildcard ../lib/sdl2/src/video/yuv2rgb/*.c)
LOCAL_CFLAGS := -I../lib/sdl2/include/ -DGL_GLEXT_PROTOTYPES \
-I../lib/libadrenotools/include
LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -lOpenSLES -llog -landroid
LOCAL_STATIC_LIBRARIES := cpufeatures
ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
LOCAL_STATIC_LIBRARIES += libadrenotools liblinkernsbypass
endif
#ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
#LOCAL_ARM_NEON := false
#endif
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
# STK
LOCAL_MODULE := main
LOCAL_PATH := .
LOCAL_CPP_FEATURES += rtti exceptions
LOCAL_SRC_FILES := $(wildcard ../src/*.cpp) \
$(wildcard ../src/*/*.cpp) \
$(wildcard ../src/*/*/*.cpp)
LOCAL_LDLIBS := -llog -lm -lOpenSLES
LOCAL_CFLAGS := -I../lib/angelscript/include \
-I../lib/bullet/src \
-I../lib/sheenbidi/Headers \
-I../lib/enet/include \
-I../lib/ifaddrs \
-I../lib/irrlicht/include \
-I../lib/irrlicht/source/Irrlicht \
-I../lib/graphics_utils \
-I../lib/graphics_engine/include \
-I../lib/mcpp \
-I../lib/sdl2/include \
-I../lib/tinygettext/include \
-I../lib/libsquish \
-I../src \
-Ideps-$(TARGET_ARCH_ABI)/curl/include \
-Ideps-$(TARGET_ARCH_ABI)/freetype/include \
-Ideps-$(TARGET_ARCH_ABI)/harfbuzz/include \
-Ideps-$(TARGET_ARCH_ABI)/libogg/include \
-Ideps-$(TARGET_ARCH_ABI)/libvorbis/include \
-Ideps-$(TARGET_ARCH_ABI)/openal/include \
-Ideps-$(TARGET_ARCH_ABI)/mbedtls/include \
-DUSE_GLES2 \
-DMOBILE_STK \
-DENABLE_SOUND \
-DENABLE_IPV6 \
-DENABLE_CRYPTO_MBEDTLS \
-DNDEBUG \
-DDISABLE_ICONV \
-DANDROID_PACKAGE_NAME=\"$(PACKAGE_NAME)\" \
-DANDROID_APP_DIR_NAME=\"$(APP_DIR_NAME)\" \
-DSUPERTUXKART_VERSION=\"$(PROJECT_VERSION)\" \
-DANDROID_PACKAGE_CLASS_NAME=\"$(PACKAGE_CLASS_NAME)\"
LOCAL_CPPFLAGS := -std=gnu++0x
LOCAL_STATIC_LIBRARIES := irrlicht bullet enet ifaddrs angelscript mcpp SDL2 \
vorbisfile vorbis ogg openal curl libmbedtls \
libmbedcrypto libmbedx509 sheenbidi \
harfbuzz freetype tinygettext graphics_utils \
graphics_engine
#ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
#LOCAL_ARM_NEON := false
#endif
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
$(call import-module, android/cpufeatures)
+70
View File
@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="auto">
<application android:label="@string/app_name"
android:icon="@drawable/icon"
android:allowBackup="true"
android:appCategory="game"
android:banner="@drawable/banner"
android:hasCode="true"
android:isGame="true"
android:theme="@style/Theme.STKSplashScreen"
android:hardwareAccelerated="true"
android:resizeableActivity="true">
<activity android:name=".SuperTuxKartActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|uiMode|layoutDirection|grammaticalGender|fontWeightAdjustment|smallestScreenSize"
android:screenOrientation="sensorLandscape"
android:preferMinimalPostProcessing="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
<!-- Let Android know that we can handle some USB devices and should receive this event -->
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
</activity>
</application>
<uses-feature android:glEsVersion="0x00020000" />
<uses-feature android:name="android.software.leanback" android:required="false" />
<uses-feature android:name="android.software.input_methods" android:required="false" />
<!-- Touchscreen support -->
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<!-- Game controller support -->
<uses-feature
android:name="android.hardware.bluetooth"
android:required="false" />
<uses-feature
android:name="android.hardware.gamepad"
android:required="false" />
<uses-feature
android:name="android.hardware.usb.host"
android:required="false" />
<!-- External mouse input events -->
<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- Allow writing to external storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Allow access to Bluetooth devices -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<!-- Allow access to the vibrator -->
<uses-permission android:name="android.permission.VIBRATE" />
</manifest>
+166
View File
@@ -0,0 +1,166 @@
================================================================================
SUPERTUXKART
================================================================================
--------------------------------------------------------------------------------
SYSTEM REQUIREMENTS
--------------------------------------------------------------------------------
To run SuperTuxKart on Android, you need a device that meets following
requirements:
- Android 4.1 or later
- Processor compatible with armv7 or x86
- GPU that supports OpenGL ES 2.0
- 1 GB RAM (STK uses ~150 MB in minimal configuration)
- 300 MB of free space on internal storage
- Touch screen or external keyboard
--------------------------------------------------------------------------------
COMPILATION
--------------------------------------------------------------------------------
The build scripts are designed to run under linux. They may work under cygwin
after some tweaks, but atm. only linux is supported.
Dependencies list (may be incomplete):
autoconf, automake, make, python, gradle, imagemagick, cmake,
vorbis-tools, pngquant
Additionally some dependencies for optimize_data script:
advancecomp, libjpeg-progs, optipng
Before compilation you must download dependencies-android-src.tar.xz from:
https://github.com/supertuxkart/dependencies/releases
Choose the corresponding STK version you are compiling, use "preview" for git.
It contains sources of libraries that are used in STK, but are not available
in stk-code repository (curl, freetype, openal...).
These libraries are compiled and then statically linked with STK by the Android
build script.
You need to extract that packed file to stk-code/lib directory, so that the
directory will have following structure:
> stk-code
> build
> data
> lib
> angelscript
> bullet
> curl
> enet
> freetype
> ...
> src
> ...
You also need Android SDK for android-26 platform or later (SDL2 requirement) and
Android NDK. Version r23 is recommended, because it's known that it works
without issues. r24 or later is not compatible because it removes Android 4.1
support (https://github.com/android/ndk/wiki/Changelog-r23#announcements)
You need to create proper "android-sdk" and "android-ndk" symlinks in the
directory with Android project, so that the compilation script will have access
to the SDK and NDK.
Before running the compilation, run the generate_assets script, so that
selected assets will be copied to "assets" directory, and then included in the
apk file.
You can select different karts and tracks by setting KARTS and TRACKS variables
in the generate_assets.sh script at the beginning of file.
When you are creating the assets directory manually, note that the
directories.txt file is urgently needed and it is used by the application for
extracting assets.
If the assets directory is already prepared, you can run "./make.sh" command to
build the project and create an apk file. Note that all arguments are passed to
the make command, so that you can run "./make.sh -j5" for multi-threaded build.
Basically if all dependencies are installed in the system, it should be enough
to just run:
export SDK_PATH=/path/to/your/android/sdk
export NDK_PATH=/path/to/your/android/ndk
# Optional for STK_MIN_ANDROID_SDK, STK_TARGET_ANDROID_SDK and STK_NDK_VERSION
# If unset it will use the below values
export STK_MIN_ANDROID_SDK=16
export STK_TARGET_ANDROID_SDK=30
export STK_NDK_VERSION=23.1.7779620
./generate_assets.sh
./make_deps.sh
./make.sh
You may need to add org.gradle.jvmargs=-XX:MaxHeapSize=2048m -Xmx2048m to
.gradle/gradle.properties if you see java.lang.OutOfMemoryError / Java heap
space execption error.
--------------------------------------------------------------------------------
ENVIRONMENT VARIABLES
--------------------------------------------------------------------------------
COMPILE_ARCH - Allows one to choose CPU architecture for which the package will
be compiled.
Possible values: all, armv7, aarch64, x86, x86_64.
Default is: all.
BUILD_TYPE - Allows one to set build type.
Possible values: debug, release, beta.
Default is: debug.
BUILD_TOOLS_VER - Allows to override the SDK build-tools version.
SDK_PATH - Path to SDK directory
NDK_PATH - Path to NDK directory, it should include a list of installed
NDK version folders
PROJECT_VERSION - Set Supertuxkart version number, for example "0.9.3" or
"git20170409" or whatever. The version must match with file
assets/data/supertuxkart.$PROJECT_VERSION
and that file must exist, because it is used for extracting
and loading game data.
Default is: git.
PROJECT_CODE - Set Supertuxkart version code that is used in the manifest
file.
Default is: 1.
--------------------------------------------------------------------------------
RELEASE BUILD
--------------------------------------------------------------------------------
Making a release build is similar to typical compilation, but there are few
additional things to do.
You have to set PROJECT_VERSION variable. This is important, because assets
manager in STK checks that value and detects if already extracted data files are
up to date. So that when you will install new STK version, this will force new
data extraction automatically.
The PROJECT_CODE variable typically should be set to a value higher than for
previous release, so that users will receive the upgrade.
Before compilation you have to set:
export BUILD_TYPE=release
It's also needed to set STK_STOREPASS, STK_KEYSTORE and STK_ALIAS environment
variables, so that the apk files can be signed.
and then you make standard compilation with:
./generate_assets.sh
./make_deps.sh
./make.sh
Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

+167
View File
@@ -0,0 +1,167 @@
buildscript
{
repositories
{
mavenCentral()
google()
}
dependencies
{
// 4.1.2 is the minimum version to support native debug symbols file
// https://developer.android.com/studio/build/shrink-code#android_gradle_plugin_version_41_or_later
// 7.0.0 to fix https://stackoverflow.com/questions/68387270/android-studio-error-installed-build-tools-revision-31-0-0-is-corrupted
classpath 'com.android.tools.build:gradle:8.7.3'
}
}
allprojects
{
repositories
{
mavenCentral()
google()
}
}
apply plugin: 'com.android.application'
android
{
// Setting the namespace via a source AndroidManifest.xml's package attribute is deprecated.
namespace project.getProperty('package_name')
// buildToolsVersion is no longer needed https://developer.android.com/studio/releases/gradle-plugin.html#behavior_changes_1
// Quote:
// Build Tools 27.0.3 or higher. Keep in mind, you no longer need to specify a version for the build tools using the android.buildToolsVersion property—the plugin uses the minimum required version by default.
compileSdkVersion compile_sdk_version.toInteger()
ndkVersion ndk_version
externalNativeBuild
{
ndkBuild
{
path 'Android.mk'
}
}
packagingOptions
{
jniLibs.useLegacyPackaging = true
}
defaultConfig
{
versionCode project.getProperty('version_code').toInteger()
versionName project.getProperty('version_name')
minSdkVersion min_sdk_version.toInteger()
compileSdkVersion compile_sdk_version.toInteger()
targetSdkVersion target_sdk_version.toInteger()
externalNativeBuild
{
ndkBuild
{
def app_platform = "APP_PLATFORM=android-${min_sdk_version}"
arguments app_platform, 'APP_STL=c++_static', cpu_core
if (project.getProperty('compile_arch') == 'all')
{
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
else
{
abiFilters project.getProperty('compile_arch')
}
}
}
def runTasks = gradle.startParameter.taskNames
if ('bundleRelease' in runTasks)
{
// use SYMBOL_TABLE if too large later (max limit on google play is 300MB)
ndk.debugSymbolLevel 'FULL'
}
}
signingConfigs
{
release
{
storeFile file(keystore)
storePassword storepass
keyAlias alias
keyPassword storepass
}
}
buildTypes
{
debug
{
debuggable true
jniDebuggable true
minifyEnabled false
shrinkResources false
multiDexEnabled true
externalNativeBuild
{
ndkBuild
{
arguments 'NDK_DEBUG=1'
cFlags '-O0'
cppFlags '-O0'
}
}
ndk
{
if (project.getProperty('compile_arch') == 'all')
{
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
else
{
abiFilters project.getProperty('compile_arch')
}
}
}
release
{
externalNativeBuild
{
ndkBuild
{
cFlags '-O3'
cppFlags '-O3'
}
}
signingConfig signingConfigs.release
ndk
{
if (project.getProperty('compile_arch') == 'all')
{
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
else
{
abiFilters project.getProperty('compile_arch')
}
}
}
}
sourceSets
{
main
{
manifest.srcFile 'AndroidManifest.xml'
res.srcDirs = ['res']
assets.srcDirs = ['assets']
if (project.getProperty('compile_arch') == 'all' ||
project.getProperty('compile_arch') == 'arm64-v8a')
{
jniLibs.srcDirs = ['mesa']
}
}
}
}
dependencies
{
implementation 'org.minidns:minidns-hla:0.3.3'
}
+723
View File
@@ -0,0 +1,723 @@
#!/bin/bash
#
# (C) 2016-2017 Dawid Gan, under the GPLv3
#
# A script that generates data files for Android apk
# Below you can find some simple configuration variables.
# It's allowed to set "all" for KARTS and TRACKS if it's intended to create
# package with full data.
# The karts and tracks directories shouldn't exist in ASSETS_DIRS variable
# because they are handled separately.
# The TEXTURE_SIZE and SOUND_QUALITY take effect only if DECREASE_QUALITY has
# value greater than 0.
# The CONVERT_TO_JPG variable enables converting all images that are safe to
# convert and keeps other images untouched.
# The script needs imagemagick, pngquant and ogg utils installed in order to
# use DECREASE_QUALITY feature
################################################################################
export KARTS_DEFAULT="all"
export TRACKS_DEFAULT="all"
export TEXTURE_SIZE_DEFAULT=256
export JPEG_QUALITY_DEFAULT=85
export PNG_QUALITY_DEFAULT=95
export PNGQUANT_QUALITY_DEFAULT=90
export SOUND_QUALITY_DEFAULT=42
export SOUND_MONO_DEFAULT=1
export SOUND_SAMPLE_DEFAULT=32000
export RUN_OPTIMIZE_SCRIPT_DEFAULT=0
export DECREASE_QUALITY_DEFAULT=1
export CONVERT_TO_JPG_DEFAULT=1
export ONLY_ASSETS_DEFAULT=0
export ASSETS_PATHS_DEFAULT="../data \
../../stk-assets \
../../supertuxkart-assets"
export OUTPUT_PATH_DEFAULT="assets"
export ASSETS_DIRS="library models music sfx textures"
export CONVERT_TO_JPG_BLACKLIST="data/models/traffic_light.png"
export BLACKLIST_FILES="data/supertuxkart.icns \
data/supertuxkart_1024.png \
data/supertuxkart_128.png \
data/supertuxkart_16.png \
data/supertuxkart_256.png \
data/supertuxkart_32.png \
data/supertuxkart_48.png \
data/supertuxkart_512.png \
data/supertuxkart_64.png"
################################################################################
export OS_NAME="`uname -s`"
export LANG=C
cd "`dirname "$0"`"
# Set default configuration if not changed outside of the script
if [ -z "$KARTS" ]; then
export KARTS="$KARTS_DEFAULT"
fi
if [ -z "$TRACKS" ]; then
export TRACKS="$TRACKS_DEFAULT"
fi
if [ -z "$TEXTURE_SIZE" ]; then
export TEXTURE_SIZE="$TEXTURE_SIZE_DEFAULT"
fi
if [ -z "$JPEG_QUALITY" ]; then
export JPEG_QUALITY="$JPEG_QUALITY_DEFAULT"
fi
if [ -z "$PNG_QUALITY" ]; then
export PNG_QUALITY="$PNG_QUALITY_DEFAULT"
fi
if [ -z "$PNGQUANT_QUALITY" ]; then
export PNGQUANT_QUALITY="$PNGQUANT_QUALITY_DEFAULT"
fi
if [ -z "$SOUND_QUALITY" ]; then
export SOUND_QUALITY="$SOUND_QUALITY_DEFAULT"
fi
if [ -z "$SOUND_MONO" ]; then
export SOUND_MONO="$SOUND_MONO_DEFAULT"
fi
if [ -z "$SOUND_SAMPLE" ]; then
export SOUND_SAMPLE="$SOUND_SAMPLE_DEFAULT"
fi
if [ -z "$RUN_OPTIMIZE_SCRIPT" ]; then
export RUN_OPTIMIZE_SCRIPT="$RUN_OPTIMIZE_SCRIPT_DEFAULT"
fi
if [ -z "$DECREASE_QUALITY" ]; then
export DECREASE_QUALITY="$DECREASE_QUALITY_DEFAULT"
fi
if [ -z "$CONVERT_TO_JPG" ]; then
export CONVERT_TO_JPG="$CONVERT_TO_JPG_DEFAULT"
fi
if [ -z "$ONLY_ASSETS" ]; then
export ONLY_ASSETS="$ONLY_ASSETS_DEFAULT"
fi
if [ -z "$ASSETS_PATHS" ]; then
export ASSETS_PATHS="$ASSETS_PATHS_DEFAULT"
fi
if [ -z "$OUTPUT_PATH" ]; then
export OUTPUT_PATH="$OUTPUT_PATH_DEFAULT"
fi
# Find assets path
for ASSETS_PATH in $ASSETS_PATHS; do
if [ -d $ASSETS_PATH ] && [ `ls $ASSETS_PATH | grep -c tracks` -gt 0 ]; then
echo "Assets found in $ASSETS_PATH"
ASSETS_PATH_FOUND=1
break
fi
done
if [ -z $ASSETS_PATH_FOUND ]; then
echo "Couldn't find assets path"
exit 1
fi
if [ ! -d "../data" ]; then
echo "Couldn't find data directory"
exit 1
fi
# Use `magick` when it's available
if command -v magick > /dev/null; then
MAGICK='magick'
else
MAGICK='convert'
fi
# Clear previous assets directory
echo "Clear previous assets directory"
rm -rf "$OUTPUT_PATH"
# Copy all assets
echo "Copy all assets"
mkdir -p "$OUTPUT_PATH/data"
for DIR in `ls $ASSETS_PATH`; do
CAN_BE_COPIED=0
for ASSETS_DIR in $ASSETS_DIRS; do
if [ $DIR = $ASSETS_DIR ]; then
CAN_BE_COPIED=1
break
fi
done;
# Don't copy karts and tracks. It will be handled later
BLACKLIST_ASSETS="karts tracks"
for ASSETS_DIR in $BLACKLIST_ASSETS; do
if [ $DIR = $ASSETS_DIR ]; then
CAN_BE_COPIED=0
break
fi
done;
if [ $CAN_BE_COPIED -gt 0 ]; then
cp -a "$ASSETS_PATH/$DIR" "$OUTPUT_PATH/data/"
fi
done;
# Copy selected tracks
echo "Copy selected tracks"
mkdir -p "$OUTPUT_PATH/data/tracks"
for DIR in `ls $ASSETS_PATH/tracks`; do
CAN_BE_COPIED=0
if [ "$TRACKS" != "all" ]; then
for TRACK in $TRACKS; do
if [ $DIR = $TRACK ]; then
CAN_BE_COPIED=1
break
fi
done;
else
CAN_BE_COPIED=1
fi
if [ $CAN_BE_COPIED -gt 0 ]; then
cp -a "$ASSETS_PATH/tracks/$DIR" "$OUTPUT_PATH/data/tracks/"
fi
done
# Copy selected karts
echo "Copy selected karts"
mkdir -p "$OUTPUT_PATH/data/karts"
for DIR in `ls $ASSETS_PATH/karts`; do
CAN_BE_COPIED=0
if [ "$KARTS" != "all" ]; then
for KART in $KARTS; do
if [ $DIR = $KART ]; then
CAN_BE_COPIED=1
break
fi
done;
else
CAN_BE_COPIED=1
fi
if [ $CAN_BE_COPIED -gt 0 ]; then
cp -a "$ASSETS_PATH/karts/$DIR" "$OUTPUT_PATH/data/karts/"
fi
done
# Decrease assets quality in order to save some disk space and RAM
echo "Decrease assets quality"
convert_image()
{
FILE="$1"
FILE_TYPE="$2"
echo "Convert file: $FILE"
if [ ! -f "$FILE" ]; then
echo " File doesn't exist."
return
fi
W=`identify -format "%[fx:w]" "$FILE"`
H=`identify -format "%[fx:h]" "$FILE"`
if [ -z $W ] || [ -z $H ]; then
echo "Couldn't convert $FILE file"
return
fi
SCALE_CMD=""
QUALITY_CMD=""
if [ $W -gt $TEXTURE_SIZE ] || [ $H -gt $TEXTURE_SIZE ]; then
if [ $W -gt $H ]; then
SCALED_W=$TEXTURE_SIZE
SCALED_H=$(($TEXTURE_SIZE * $H / $W))
else
SCALED_W=$(($TEXTURE_SIZE * $W / $H))
SCALED_H=$TEXTURE_SIZE
fi
SCALE_CMD="-scale ${SCALED_W}x${SCALED_H}"
fi
if [ "$FILE_TYPE" = "jpg" ]; then
QUALITY_CMD="-quality $JPEG_QUALITY"
elif [ "$FILE_TYPE" = "png" ]; then
QUALITY_CMD="-quality $PNG_QUALITY"
fi
$MAGICK "$FILE" $SCALE_CMD $QUALITY_CMD "tmp.$FILE_TYPE"
if [ -s "tmp.$FILE_TYPE" ]; then
SIZE_OLD=`du -k "$FILE" | cut -f1`
SIZE_NEW=`du -k "tmp.$FILE_TYPE" | cut -f1`
if [ $SIZE_NEW -lt $SIZE_OLD ]; then
mv "tmp.$FILE_TYPE" "$FILE"
fi
fi
rm -f "tmp.$FILE_TYPE"
}
convert_sound()
{
FILE="$1"
echo "Convert file: $FILE"
if [ ! -f "$FILE" ]; then
echo " File doesn't exist."
return
fi
oggdec "$FILE" -o tmp.wav
if [ -s tmp.wav ]; then
OGGENC_CMD=""
if [ "$SOUND_MONO" -gt 0 ]; then
OGGENC_CMD="$OGGENC_CMD --downmix"
fi
OGG_RATE=`ogginfo "$FILE" | grep "Rate: " | cut -f 2 -d " " \
| grep -o '[0-9]*'`
if [ ! -z "$OGG_RATE" ] && [ "$OGG_RATE" -gt "$SOUND_SAMPLE" ]; then
OGGENC_CMD="$OGGENC_CMD --resample $SOUND_SAMPLE"
fi
OGGENC_CMD="$OGGENC_CMD -b $SOUND_QUALITY"
oggenc $OGGENC_CMD tmp.wav -o tmp.ogg
fi
if [ -s tmp.ogg ]; then
SIZE_OLD=`du -k "$FILE" | cut -f1`
SIZE_NEW=`du -k "tmp.ogg" | cut -f1`
if [ $SIZE_NEW -lt $SIZE_OLD ]; then
mv tmp.ogg "$FILE"
fi
fi
rm -f tmp.wav tmp.ogg
}
optimize_png()
{
FILE="$1"
echo "Optimize file: $FILE"
if [ ! -f "$FILE" ]; then
echo " File doesn't exist."
return
fi
pngquant --force --skip-if-larger --quality 0-$PNGQUANT_QUALITY --output "$FILE" -- "$FILE"
}
convert_to_jpg()
{
FILE="$1"
echo "Convert file to jpg: $FILE"
if [ ! -f "$FILE" ]; then
echo " File doesn't exist."
return
fi
ALREADY_CONVERTED=0
if [ -s "./converted_textures" ]; then
while read -r CONVERTED_TEXTURE; do
if [ "$FILE" = "$CONVERTED_TEXTURE" ]; then
ALREADY_CONVERTED=1
break
fi
done < "./converted_textures"
fi
if [ $ALREADY_CONVERTED -eq 1 ]; then
return
fi
BLACKLISTED=0
for BLACKLIST_FILE in $CONVERT_TO_JPG_BLACKLIST; do
if [ "$FILE" = "$OUTPUT_PATH/$BLACKLIST_FILE" ]; then
BLACKLISTED=1
break
fi
done
if [ $BLACKLISTED -eq 1 ]; then
#echo " File is blacklisted. Ignore..."
return
fi
FILE_EXTENSION=`echo "$FILE" | tail -c 5`
if [ `echo "$FILE_EXTENSION" | head -c 1` != "." ]; then
#echo " Unsupported file extension. Ignore..."
return
fi
FILE_FORMAT=`identify -format %m "$FILE"`
if [ "$FILE_FORMAT" = "JPEG" ]; then
#echo " File is already JPEG. Ignore..."
return
fi
IS_OPAQUE=`identify -format '%[opaque]' "$FILE"`
#HAS_ALPHA=`identify -format '%A' "$FILE"`
if [ "$IS_OPAQUE" = "False" ] || [ "$IS_OPAQUE" = "false" ]; then
#echo " File has alpha channel. Ignore..."
return
fi
DIRNAME="`dirname "$FILE"`"
BASENAME="`basename "$FILE"`"
IS_GLOSS_MAP=`find "$DIRNAME" -iname "*.xml" -exec cat {} \; \
| grep -c "gloss-map=\"$BASENAME\""`
if [ $IS_GLOSS_MAP -gt 0 ]; then
#echo " File is a gloss-map. Ignore..."
return
fi
NEW_FILE="`echo $FILE | rev | cut -c 5- | rev`.jpg"
if [ -f "$NEW_FILE" ]; then
#echo " There is already a file with .jpg extension. Ignore..."
return
fi
# We can check if new file is smaller
$MAGICK "$FILE" -quality $JPEG_QUALITY "$NEW_FILE"
rm -f "$FILE"
echo "$FILE" >> "./converted_textures"
}
convert_to_jpg_extract_b3dz()
{
FILE="$1"
echo "Extract b3dz file: $FILE"
if [ ! -f "$FILE" ]; then
echo " File doesn't exist."
return
fi
DIRNAME="`dirname "$FILE"`"
unzip "$FILE" -d "$DIRNAME"
rm -f "$FILE"
TEXNAME="`basename "$FILE"`"
NEWNAME="`echo $TEXNAME | rev | cut -c 6- | rev`.b3d"
if [ "$OS_NAME" = "Darwin" ]; then
sed -i "" "s/\"$TEXNAME\"/\"$NEWNAME\"/g" "$DIRNAME/kart.xml"
else
sed -i "s/\"$TEXNAME\"/\"$NEWNAME\"/g" "$DIRNAME/kart.xml"
fi
}
convert_to_jpg_update_b3d()
{
FILE="$1"
echo "Update b3d file: $FILE"
if [ ! -f "$1" ]; then
echo " File doesn't exist."
return
fi
HEX_FILE=`hexdump -ve '1/1 "%.2x"' "$FILE"`
TEXS_CHUNK="54455853"
TEXS_CHUNK_POS=24
FOUND_CHUNK=`echo $HEX_FILE | head -c $(($TEXS_CHUNK_POS + 8)) \
| tail -c +$(($TEXS_CHUNK_POS + 1))`
if [ -z "$FOUND_CHUNK" ] || [ "$FOUND_CHUNK" != "$TEXS_CHUNK" ]; then
echo " File has no textures."
return
fi
TEXS_SIZE=`echo $HEX_FILE | head -c $(($TEXS_CHUNK_POS + 16)) | tail -c 8`
TEXS_SIZE_CONVERTED=`echo $TEXS_SIZE | cut -c7-8`
TEXS_SIZE_CONVERTED=$TEXS_SIZE_CONVERTED`echo $TEXS_SIZE | cut -c5-6`
TEXS_SIZE_CONVERTED=$TEXS_SIZE_CONVERTED`echo $TEXS_SIZE | cut -c3-4`
TEXS_SIZE_CONVERTED=$TEXS_SIZE_CONVERTED`echo $TEXS_SIZE | cut -c1-2`
TEXS_SIZE_CONVERTED=`echo $((0x$TEXS_SIZE_CONVERTED))`
if [ $TEXS_SIZE_CONVERTED -le 0 ]; then
echo " Invalid TEXS size value."
return
fi
TEXS_BEGIN=$(($TEXS_CHUNK_POS + 16))
TEXS_END=$(($TEXS_BEGIN + $TEXS_SIZE_CONVERTED * 2))
HEX_TEXS=`echo $HEX_FILE | head -c $TEXS_END | tail -c +$(($TEXS_BEGIN+1))`
CURR_POS=0
while [ $CURR_POS -lt $TEXS_END ]; do
NULL_POS=`echo $HEX_TEXS | tail -c +$(($CURR_POS+1)) | grep -b -o "00" \
| head -n 1 | cut -f1 -d":"`
if [ -z $NULL_POS ]; then
#echo " Done."
break
fi
if [ $NULL_POS -lt 4 ]; then
echo " Something went wrong..."
break
fi
TEXNAME_BEGIN=$((($TEXS_BEGIN + $CURR_POS) / 2))
TEXNAME_END=$((($TEXS_BEGIN + $CURR_POS + $NULL_POS) / 2))
CURR_POS=$(($CURR_POS + $NULL_POS + 58))
TEXTURE_NAME=`dd if="$FILE" bs=1 skip=$TEXNAME_BEGIN \
count=$(($TEXNAME_END - $TEXNAME_BEGIN)) 2> /dev/null`
DIRNAME="`dirname "$FILE"`"
TEXTURE_PATH="$DIRNAME/$TEXTURE_NAME"
IS_CONVERTED=0
while read -r CONVERTED_TEXTURE; do
if [ "$TEXTURE_PATH" = "$CONVERTED_TEXTURE" ]; then
IS_CONVERTED=1
break
fi
done < "./converted_textures"
if [ $IS_CONVERTED -eq 1 ]; then
echo -n ".jpg" | dd of="$FILE" bs=1 seek=$(($TEXNAME_END - 4)) \
conv=notrunc 2> /dev/null
fi;
done
}
convert_to_jpg_update_spm()
{
FILE="$1"
echo "Update spm file: $FILE"
if [ ! -f "$1" ]; then
echo " File doesn't exist."
return
fi
HEX_FILE=`hexdump -ve '1/1 "%.2x"' "$FILE"`
SP_HEADER="5350"
SP_FOUND=`echo $HEX_FILE | head -c 4`
if [ -z "$SP_FOUND" ] || [ "$SP_FOUND" != "$SP_HEADER" ]; then
echo " Unsupported format."
return
fi
TEXS_BEGIN=60
TEXS_COUNT=`echo $HEX_FILE | head -c $TEXS_BEGIN | tail -c 4`
TEXS_COUNT_CONVERTED=`echo $TEXS_COUNT | cut -c3-4`
TEXS_COUNT_CONVERTED=$TEXS_COUNT_CONVERTED`echo $TEXS_COUNT | cut -c1-2`
TEXS_COUNT_CONVERTED=`echo $((0x$TEXS_COUNT_CONVERTED))`
TEXS_COUNT_CONVERTED=$(($TEXS_COUNT_CONVERTED * 2))
if [ $TEXS_COUNT_CONVERTED -le 0 ]; then
echo " Invalid textures count value."
return
fi
CURR_POS=$(($TEXS_BEGIN + 2))
while [ $TEXS_COUNT_CONVERTED -gt 0 ]; do
TEXS_COUNT_CONVERTED=$(($TEXS_COUNT_CONVERTED - 1))
TEX_LEN=`echo $HEX_FILE | head -c $(($CURR_POS)) | tail -c 2`
TEX_LEN=`echo $((0x$TEX_LEN))`
TEXNAME_BEGIN=$(($CURR_POS / 2))
TEXNAME_END=$(($CURR_POS / 2 + $TEX_LEN))
CURR_POS=$(($CURR_POS + 2 + $TEX_LEN * 2))
if [ $TEX_LEN -eq 0 ]; then
#echo " Empty texture name, ignore..."
continue
fi
TEXTURE_NAME=`dd if="$FILE" bs=1 skip=$TEXNAME_BEGIN \
count=$(($TEXNAME_END - $TEXNAME_BEGIN)) 2> /dev/null`
DIRNAME="`dirname "$FILE"`"
TEXTURE_PATH="$DIRNAME/$TEXTURE_NAME"
IS_CONVERTED=0
while read -r CONVERTED_TEXTURE; do
if [ "$TEXTURE_PATH" = "$CONVERTED_TEXTURE" ]; then
IS_CONVERTED=1
break
fi
done < "./converted_textures"
if [ $IS_CONVERTED -eq 1 ]; then
echo -n ".jpg" | dd of="$FILE" bs=1 seek=$(($TEXNAME_END - 4)) \
conv=notrunc 2> /dev/null
fi
done
}
convert_to_jpg_update_xml()
{
FILE="$1"
echo "Update xml file: $FILE"
if [ ! -f "$FILE" ]; then
echo " File doesn't exist."
return
fi
DIRNAME="`dirname "$FILE"`"
while read -r CONVERTED_TEXTURE; do
DIRNAME_TEX="`dirname "$CONVERTED_TEXTURE"`"
if [ "$DIRNAME_TEX" != "$DIRNAME" ]; then
continue;
fi
TEXNAME="`basename "$CONVERTED_TEXTURE" | rev | cut -c 5- | rev`"
if [ "$OS_NAME" = "Darwin" ]; then
sed -i "" "s/\"$TEXNAME.[pP][nN][gG]/\"$TEXNAME.jpg/g" "$FILE"
sed -i "" "s/ $TEXNAME.[pP][nN][gG]/ $TEXNAME.jpg/g" "$FILE"
else
sed -i "s/\"$TEXNAME.[pP][nN][gG]/\"$TEXNAME.jpg/g" "$FILE"
sed -i "s/ $TEXNAME.[pP][nN][gG]/ $TEXNAME.jpg/g" "$FILE"
fi
done < "./converted_textures"
}
if [ $DECREASE_QUALITY -gt 0 ]; then
find "$OUTPUT_PATH/data" -iname "*.png" | while read f; do convert_image "$f" "png"; done
find "$OUTPUT_PATH/data" -iname "*.jpg" | while read f; do convert_image "$f" "jpg"; done
find "$OUTPUT_PATH/data" -iname "*.ogg" | while read f; do convert_sound "$f"; done
fi
if [ $CONVERT_TO_JPG -gt 0 ]; then
rm -f "./converted_textures"
find "$OUTPUT_PATH/data" -not -path "$OUTPUT_PATH/data/textures/*" \
-not -path "$OUTPUT_PATH/data/karts/*" \
-iname "*.png" | while read f; do convert_to_jpg "$f"; done
find "$OUTPUT_PATH/data" -iname "*.b3dz" | while read f; do convert_to_jpg_extract_b3dz "$f"; done
find "$OUTPUT_PATH/data" -iname "*.b3d" | while read f; do convert_to_jpg_update_b3d "$f"; done
find "$OUTPUT_PATH/data" -iname "*.spm" | while read f; do convert_to_jpg_update_spm "$f"; done
find "$OUTPUT_PATH/data" -iname "*.xml" | while read f; do convert_to_jpg_update_xml "$f"; done
if [ -s "./converted_textures" ]; then
echo "Converted textures:"
cat "./converted_textures"
rm -f "./converted_textures"
fi
fi
if [ $DECREASE_QUALITY -gt 0 ]; then
find "$OUTPUT_PATH/data" -iname "*.png" | while read f; do optimize_png "$f" "png"; done
fi
# Copy data directory
if [ $ONLY_ASSETS -eq 0 ]; then
echo "Copy data directory"
cp -a ../data/* "$OUTPUT_PATH/data"
fi
# Remove unused files
for BLACKLIST_FILE in $BLACKLIST_FILES; do
rm -f "$OUTPUT_PATH/$BLACKLIST_FILE"
done
# Run optimize_data.sh script
if [ $RUN_OPTIMIZE_SCRIPT -gt 0 ]; then
echo "Run optimize_data.sh script"
sh -c "cd "$OUTPUT_PATH/data"; ../../../data/optimize_data.sh"
fi
# Generate files list
echo "Generate files list"
find "$OUTPUT_PATH"/* -type d| sort > tmp1.txt
if [ "$OS_NAME" = "Darwin" ]; then
sed -i "" 's/$/\//' tmp1.txt
else
sed -i 's/$/\//' tmp1.txt
fi
find "$OUTPUT_PATH"/* -type f| sort > tmp2.txt
cat tmp1.txt tmp2.txt | sort > "$OUTPUT_PATH/files.txt"
rm tmp1.txt tmp2.txt
if [ "$OS_NAME" = "Darwin" ]; then
sed -i "" s/".\/$OUTPUT_PATH\/"// "$OUTPUT_PATH/files.txt"
sed -i "" s/"$OUTPUT_PATH\/"// "$OUTPUT_PATH/files.txt"
else
sed -i s/".\/$OUTPUT_PATH\/"// "$OUTPUT_PATH/files.txt"
sed -i s/"$OUTPUT_PATH\/"// "$OUTPUT_PATH/files.txt"
fi
# A file that can be used to check if apk has assets
echo "has_assets" > "$OUTPUT_PATH/has_assets.txt"
# It will be probably ignored by ant, but create it anyway...
touch "$OUTPUT_PATH/.nomedia"
echo "Done."
exit 0
+1
View File
@@ -0,0 +1 @@
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
Binary file not shown.
+7
View File
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored Executable
+249
View File
@@ -0,0 +1,249 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

+475
View File
@@ -0,0 +1,475 @@
#!/bin/bash
#
# (C) 2016-2017 Dawid Gan, under the GPLv3
#
# A script that creates the apk build
export DIRNAME=$(realpath "$(dirname "$0")")
export NDK_PATH_DEFAULT="$DIRNAME/android-ndk"
export SDK_PATH_DEFAULT="$DIRNAME/android-sdk"
export NDK_BUILD_SCRIPT="$DIRNAME/Android.mk"
#export NDK_CCACHE=ccache
export CPU_CORE="-j$(($(nproc) + 1))"
if [ -z "$STK_MIN_ANDROID_SDK" ]; then
export STK_MIN_ANDROID_SDK=21
fi
if [ -z "$STK_TARGET_ANDROID_SDK" ]; then
export STK_TARGET_ANDROID_SDK=35
fi
if [ -z "$STK_NDK_VERSION" ]; then
export STK_NDK_VERSION="28.1.13356709"
fi
export APP_NAME_RELEASE="SuperTuxKart"
export PACKAGE_NAME_RELEASE="org.supertuxkart.stk"
export PACKAGE_CLASS_NAME_RELEASE="org/supertuxkart/stk"
export APP_DIR_NAME_RELEASE="supertuxkart"
export APP_ICON_RELEASE="$DIRNAME/icon.png"
export APP_ICON_ADAPTIVE_BG_RELEASE="$DIRNAME/icon_adaptive_bg.png"
export APP_ICON_ADAPTIVE_FG_RELEASE="$DIRNAME/icon_adaptive_fg.png"
export APP_NAME_BETA="SuperTuxKart Beta"
export PACKAGE_NAME_BETA="org.supertuxkart.stk_beta"
export PACKAGE_CLASS_NAME_BETA="org/supertuxkart/stk_beta"
export APP_DIR_NAME_BETA="supertuxkart-beta"
export APP_ICON_BETA="$DIRNAME/icon-dbg.png"
export APP_ICON_ADAPTIVE_BG_BETA="$DIRNAME/icon_adaptive_bg-dbg.png"
export APP_ICON_ADAPTIVE_FG_BETA="$DIRNAME/icon_adaptive_fg-dbg.png"
export APP_NAME_DEBUG="SuperTuxKart Debug"
export PACKAGE_NAME_DEBUG="org.supertuxkart.stk_dbg"
export PACKAGE_CLASS_NAME_DEBUG="org/supertuxkart/stk_dbg"
export APP_DIR_NAME_DEBUG="supertuxkart-dbg"
export APP_ICON_DEBUG="$DIRNAME/icon-dbg.png"
export APP_ICON_ADAPTIVE_BG_DEBUG="$DIRNAME/icon_adaptive_bg-dbg.png"
export APP_ICON_ADAPTIVE_FG_DEBUG="$DIRNAME/icon_adaptive_fg-dbg.png"
# A helper function that checks if error ocurred
check_error()
{
if [ $? -gt 0 ]; then
echo "Error ocurred."
exit
fi
}
# Handle clean command
if [ ! -z "$1" ] && [ "$1" = "clean" ]; then
rm -rf "$DIRNAME/bin"
rm -rf "$DIRNAME/build"
rm -rf "$DIRNAME/libs"
rm -rf "$DIRNAME/obj"
rm -rf "$DIRNAME/res"
rm -rf "$DIRNAME/.gradle"
rm -rf "$DIRNAME/.cxx"
exit
fi
# Update variables for selected architecture
if [ -z "$COMPILE_ARCH" ]; then
COMPILE_ARCH="all"
fi
if [ "$COMPILE_ARCH" = "armv7" ]; then
COMPILE_ARCH="armeabi-v7a"
elif [ "$COMPILE_ARCH" = "aarch64" ]; then
COMPILE_ARCH="arm64-v8a"
elif [ "$COMPILE_ARCH" != "x86" ] && [ "$COMPILE_ARCH" != "x86_64" ] && \
[ "$COMPILE_ARCH" != "all" ]; then
echo "Unknown COMPILE_ARCH: $COMPILE_ARCH. Possible values are:" \
"all, armv7, aarch64, x86, x86_64"
exit
fi
# Update variables for selected build type
if [ -z "$BUILD_TYPE" ]; then
BUILD_TYPE="debug"
fi
if [ "$BUILD_TYPE" = "debug" ] || [ "$BUILD_TYPE" = "Debug" ]; then
export GRADLE_BUILD_TYPE="assembleDebug"
export IS_DEBUG_BUILD=1
export APP_NAME="$APP_NAME_DEBUG"
export PACKAGE_NAME="$PACKAGE_NAME_DEBUG"
export PACKAGE_CLASS_NAME="$PACKAGE_CLASS_NAME_DEBUG"
export APP_DIR_NAME="$APP_DIR_NAME_DEBUG"
export APP_ICON="$APP_ICON_DEBUG"
export APP_ICON_ADAPTIVE_BG="$APP_ICON_ADAPTIVE_BG_DEBUG"
export APP_ICON_ADAPTIVE_FG="$APP_ICON_ADAPTIVE_FG_DEBUG"
elif [ "$BUILD_TYPE" = "release" ] || [ "$BUILD_TYPE" = "Release" ]; then
export GRADLE_BUILD_TYPE="assembleRelease"
export IS_DEBUG_BUILD=0
export APP_NAME="$APP_NAME_RELEASE"
export PACKAGE_NAME="$PACKAGE_NAME_RELEASE"
export PACKAGE_CLASS_NAME="$PACKAGE_CLASS_NAME_RELEASE"
export APP_DIR_NAME="$APP_DIR_NAME_RELEASE"
export APP_ICON="$APP_ICON_RELEASE"
export APP_ICON_ADAPTIVE_BG="$APP_ICON_ADAPTIVE_BG_RELEASE"
export APP_ICON_ADAPTIVE_FG="$APP_ICON_ADAPTIVE_FG_RELEASE"
elif [ "$BUILD_TYPE" = "beta" ] || [ "$BUILD_TYPE" = "Beta" ]; then
export GRADLE_BUILD_TYPE="assembleRelease"
export IS_DEBUG_BUILD=0
export APP_NAME="$APP_NAME_BETA"
export PACKAGE_NAME="$PACKAGE_NAME_BETA"
export PACKAGE_CLASS_NAME="$PACKAGE_CLASS_NAME_BETA"
export APP_DIR_NAME="$APP_DIR_NAME_BETA"
export APP_ICON="$APP_ICON_BETA"
export APP_ICON_ADAPTIVE_BG="$APP_ICON_ADAPTIVE_BG_BETA"
export APP_ICON_ADAPTIVE_FG="$APP_ICON_ADAPTIVE_FG_BETA"
else
echo "Unsupported BUILD_TYPE: $BUILD_TYPE. Possible values are: " \
"debug, release"
exit
fi
# Check if we have access to the Android NDK and SDK
if [ -z "$NDK_PATH" ]; then
export NDK_PATH="$NDK_PATH_DEFAULT"
fi
if [ -z "$SDK_PATH" ]; then
export SDK_PATH="$SDK_PATH_DEFAULT"
fi
NDK_PATH="$(realpath "$NDK_PATH")/${STK_NDK_VERSION}"
SDK_PATH=$(realpath "$SDK_PATH")
if [ ! -d "$NDK_PATH" ]; then
echo "Error: Couldn't find $NDK_PATH directory. Please create a symlink" \
"to your Android NDK installation in the $NDK_PATH_DEFAULT or set" \
"proper path in the NDK_PATH variable"
exit
fi
if [ ! -d "$SDK_PATH" ]; then
echo "Error: Couldn't find $SDK_PATH directory. Please create a symlink" \
"to your Android SDK installation in the $SDK_PATH_DEFAULT or set" \
"proper path in the SDK_PATH variable"
exit
fi
# Check if we have key for signing in release build
if [ "$GRADLE_BUILD_TYPE" = "assembleRelease" ]; then
if [ -z "$STK_KEYSTORE" ]; then
echo "Error: STK_KEYSTORE variable is empty."
exit
fi
if [ ! -f "$STK_KEYSTORE" ]; then
echo "Error: Couldn't find $STK_KEYSTORE file."
exit
fi
if [ -z "$STK_STOREPASS" ]; then
echo "Error: STK_STOREPASS variable is empty"
exit
fi
if [ -z "$STK_ALIAS" ]; then
echo "Error: STK_ALIAS variable is empty."
exit
fi
else
STK_KEYSTORE="empty"
STK_STOREPASS="empty"
STK_ALIAS="empty"
fi
# Find newest build-tools version
if [ -z "$BUILD_TOOLS_VER" ]; then
BUILD_TOOLS_DIRS=`ls -1 "$SDK_PATH/build-tools" | sort -V -r`
for DIR in $BUILD_TOOLS_DIRS; do
if [ "$DIR" = "`echo $DIR | sed 's/[^0-9,.]//g'`" ]; then
BUILD_TOOLS_VER="$DIR"
break
fi
done
fi
if [ -z "$BUILD_TOOLS_VER" ] || [ ! -d "$SDK_PATH/build-tools/$BUILD_TOOLS_VER" ]; then
echo "Error: Couldn't detect build-tools version."
exit
fi
BUILD_TOOLS_FULL=(${BUILD_TOOLS_VER//./ })
export COMPILE_SDK_VERSION="${BUILD_TOOLS_FULL[0]}"
# Set project version and code
if [ -f "$DIRNAME/obj/project_version" ]; then
PROJECT_VERSION_PREV=$(cat "$DIRNAME/obj/project_version")
if [ -z "$PROJECT_VERSION" ]; then
export PROJECT_VERSION="$PROJECT_VERSION_PREV"
elif [ "$PROJECT_VERSION" != "$PROJECT_VERSION_PREV" ]; then
echo "Different project version has been set. Forcing recompilation..."
touch -c "$DIRNAME/Android.mk"
fi
fi
if [ -z "$PROJECT_VERSION" ]; then
if [ $IS_DEBUG_BUILD -ne 0 ]; then
export PROJECT_VERSION="git"
else
echo "Error: Variable PROJECT_VERSION is not set. It must have unique" \
"value for release build."
exit
fi
fi
if [ -z "$PROJECT_CODE" ]; then
if [ $IS_DEBUG_BUILD -ne 0 ]; then
PROJECT_CODE="1"
else
echo "Error: Variable PROJECT_CODE is not set."
exit
fi
fi
if [ -d "$DIRNAME/assets/data" ]; then
if [ ! -f "$DIRNAME/assets/data/supertuxkart.$PROJECT_VERSION" ]; then
echo "Error: supertuxkart.$PROJECT_VERSION doesn't exist in" \
"assets/data directory."
exit
fi
fi
# Use `magick` when it's available
if command -v magick > /dev/null; then
MAGICK='magick'
else
MAGICK='convert'
fi
# Standalone toolchain
if [ ! -f "$DIRNAME/obj/make_standalone_toolchain.stamp" ]; then
echo "Creating standalone toolchain"
rm -rf "$DIRNAME/obj"
mkdir "$DIRNAME/obj"
touch "$DIRNAME/obj/make_standalone_toolchain.stamp"
fi
echo "$PROJECT_VERSION" > "$DIRNAME/obj/project_version"
# Build apk
echo "Building APK"
mkdir -p "$DIRNAME/res/drawable/"
mkdir -p "$DIRNAME/res/drawable-anydpi-v26/"
mkdir -p "$DIRNAME/res/drawable-mdpi/"
mkdir -p "$DIRNAME/res/drawable-hdpi/"
mkdir -p "$DIRNAME/res/drawable-xhdpi/"
mkdir -p "$DIRNAME/res/drawable-xxhdpi/"
mkdir -p "$DIRNAME/res/drawable-xxxhdpi/"
rm -rf "$DIRNAME/res/values*"
mkdir -p "$DIRNAME/res/values/"
STYLES_FILE="$DIRNAME/res/values/styles.xml"
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>" > "$STYLES_FILE"
echo "<!--Generated by make.sh-->" >> "$STYLES_FILE"
echo "<resources>" >> "$STYLES_FILE"
echo " <style name=\"Theme.STKSplashScreen\" parent=\"android:style/Theme.Holo\">" >> "$STYLES_FILE"
echo " <item name=\"android:windowBackground\">#A8A8A8</item>" >> "$STYLES_FILE"
echo " <item name=\"android:windowFullscreen\">true</item>" >> "$STYLES_FILE"
echo " <item name=\"android:windowNoTitle\">true</item>" >> "$STYLES_FILE"
echo " <item name=\"android:windowLayoutInDisplayCutoutMode\">shortEdges</item>" >> "$STYLES_FILE"
echo " <item name=\"android:windowContentOverlay\">@null</item>" >> "$STYLES_FILE"
echo " </style>" >> "$STYLES_FILE"
echo "</resources>" >> "$STYLES_FILE"
STRINGS_FILE="$DIRNAME/res/values/strings.xml"
# Strings used in stk android ui (when extracting game data first time)
PO_EXTRACT_GAME_DATA="po_extract_game_data"
PO_EXTRACT_GAME_DATA_STR="Extracting game data..."
PO_EXTRACT_ERROR="po_extract_error"
PO_EXTRACT_ERROR_STR="Game data extraction error"
PO_EXTRACT_ERROR_MSG="po_extract_error_msg"
PO_EXTRACT_ERROR_MSG_STR="Check remaining device space or reinstall SuperTuxKart."
PO_QUIT="po_quit"
PO_QUIT_STR="Quit"
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>" > "$STRINGS_FILE"
echo "<!--Generated by make.sh-->" >> "$STRINGS_FILE"
echo "<resources>" >> "$STRINGS_FILE"
echo " <string name=\"app_name\">$APP_NAME</string>" >> "$STRINGS_FILE"
echo " <string name=\"$PO_EXTRACT_GAME_DATA\">$PO_EXTRACT_GAME_DATA_STR</string>" >> "$STRINGS_FILE"
echo " <string name=\"$PO_EXTRACT_ERROR\">$PO_EXTRACT_ERROR_STR</string>" >> "$STRINGS_FILE"
echo " <string name=\"$PO_EXTRACT_ERROR_MSG\">$PO_EXTRACT_ERROR_MSG_STR</string>" >> "$STRINGS_FILE"
echo " <string name=\"$PO_QUIT\">$PO_QUIT_STR</string>" >> "$STRINGS_FILE"
echo "</resources>" >> "$STRINGS_FILE"
translate_str()
{
echo $(grep -A 1 -e "msgid \"$1\"" "$2" \
| sed -n 's/msgstr "\(.*\)"/\1/p' | sed "s/'/\\\'/g")
}
create_translation()
{
PO="$1"
CUR_LANG=$(basename -- "$PO" | cut -f 1 -d '.')
# Skip english po file
if [ "$CUR_LANG" = "en" ]; then
return
fi
# Fix some difference in language code
if [ "$CUR_LANG" = "he" ]; then
# Hebrew
CUR_LANG="iw"
fi
if [ "$CUR_LANG" = "id" ]; then
# Indonesian
CUR_LANG="in"
fi
if [ "$CUR_LANG" = "yi" ]; then
# Yiddish
CUR_LANG="ji"
fi
CUR_LANG=$(echo "$CUR_LANG" | sed 's/_/-r/g')
EXTRACT_GAME_DATA_STR=$(translate_str "$PO_EXTRACT_GAME_DATA_STR" "$PO")
EXTRACT_ERROR_STR=$(translate_str "$PO_EXTRACT_ERROR_STR" "$PO")
EXTRACT_ERROR_MSG_STR=$(translate_str "$PO_EXTRACT_ERROR_MSG_STR" "$PO")
QUIT_STR=$(translate_str "$PO_QUIT_STR" "$PO")
if [ -n "$EXTRACT_GAME_DATA_STR" ] \
|| [ -n "$EXTRACT_ERROR_STR" ] \
|| [ -n "$EXTRACT_ERROR_MSG_STR" ] \
|| [ -n "$QUIT_STR" ]; then
mkdir -p "$DIRNAME/res/values-$CUR_LANG"
TRANSLATION="$DIRNAME/res/values-$CUR_LANG/strings.xml"
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>" > "$TRANSLATION"
echo "<!--Generated by make.sh-->" >> "$TRANSLATION"
echo "<resources>" >> "$TRANSLATION"
if [ -n "$EXTRACT_GAME_DATA_STR" ] ; then
echo " <string name=\"$PO_EXTRACT_GAME_DATA\">$EXTRACT_GAME_DATA_STR</string>" >> "$TRANSLATION"
fi
if [ -n "$EXTRACT_ERROR_STR" ] ; then
echo " <string name=\"$PO_EXTRACT_ERROR\">$EXTRACT_ERROR_STR</string>" >> "$TRANSLATION"
fi
if [ -n "$EXTRACT_ERROR_MSG_STR" ] ; then
echo " <string name=\"$PO_EXTRACT_ERROR_MSG\">$EXTRACT_ERROR_MSG_STR</string>" >> "$TRANSLATION"
fi
if [ -n "$QUIT_STR" ] ; then
echo " <string name=\"$PO_QUIT\">$QUIT_STR</string>" >> "$TRANSLATION"
fi
echo "</resources>" >> "$TRANSLATION"
fi
}
find "$DIRNAME/assets/data/po" -type f -name '*.po' | while read -r f; do create_translation "$f"; done
ADAPTIVE_ICON_FILE="$DIRNAME/res/drawable-anydpi-v26/icon.xml"
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>" > "$ADAPTIVE_ICON_FILE"
echo "<adaptive-icon" >> "$ADAPTIVE_ICON_FILE"
echo " xmlns:android=\"http://schemas.android.com/apk/res/android\">" >> "$ADAPTIVE_ICON_FILE"
echo " <background android:drawable=\"@drawable/icon_bg\" />" >> "$ADAPTIVE_ICON_FILE"
echo " <foreground android:drawable=\"@drawable/icon_fg\" />" >> "$ADAPTIVE_ICON_FILE"
echo "</adaptive-icon>" >> "$ADAPTIVE_ICON_FILE"
sed -i "s/package org.supertuxkart.*/package $PACKAGE_NAME;/g" \
"$DIRNAME/src/main/java/STKEditText.java"
sed -i "s/import org.supertuxkart.*/import $PACKAGE_NAME.STKInputConnection;/g" \
"$DIRNAME/src/main/java/STKEditText.java"
sed -i "s/package org.supertuxkart.*/package $PACKAGE_NAME;/g" \
"$DIRNAME/src/main/java/STKInputConnection.java"
sed -i "s/import org.supertuxkart.*.STKEditText;/import $PACKAGE_NAME.STKEditText;/g" \
"$DIRNAME/src/main/java/STKInputConnection.java"
sed -i "s/package org.supertuxkart.*/package $PACKAGE_NAME;/g" \
"$DIRNAME/src/main/java/SuperTuxKartActivity.java"
sed -i "s/import org.supertuxkart.*/import $PACKAGE_NAME.STKEditText;/g" \
"$DIRNAME/src/main/java/SuperTuxKartActivity.java"
cp -f "$DIRNAME/../lib/sdl2/android-project/app/src/main/java/org/libsdl/app/HIDDevice.java" \
"$DIRNAME/src/main/java/"
cp -f "$DIRNAME/../lib/sdl2/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java" \
"$DIRNAME/src/main/java/"
cp -f "$DIRNAME/../lib/sdl2/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java" \
"$DIRNAME/src/main/java/"
cp -f "$DIRNAME/../lib/sdl2/android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java" \
"$DIRNAME/src/main/java/"
cp -f "$DIRNAME/../lib/sdl2/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java" \
"$DIRNAME/src/main/java/"
cp -f "$DIRNAME/../lib/sdl2/android-project/app/src/main/java/org/libsdl/app/SDLAudioManager.java" \
"$DIRNAME/src/main/java/"
cp -f "$DIRNAME/../lib/sdl2/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java" \
"$DIRNAME/src/main/java/"
cp -f "$DIRNAME/../lib/sdl2/android-project/app/src/main/java/org/libsdl/app/SDL.java" \
"$DIRNAME/src/main/java/"
cp -f "$DIRNAME/../lib/sdl2/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java" \
"$DIRNAME/src/main/java/"
cp "banner.png" "$DIRNAME/res/drawable/banner.png"
cp "$APP_ICON" "$DIRNAME/res/drawable/icon.png"
$MAGICK "$APP_ICON" -scale 48x48 "$DIRNAME/res/drawable-mdpi/icon.png"
$MAGICK "$APP_ICON" -scale 72x72 "$DIRNAME/res/drawable-hdpi/icon.png"
$MAGICK "$APP_ICON" -scale 96x96 "$DIRNAME/res/drawable-xhdpi/icon.png"
$MAGICK "$APP_ICON" -scale 144x144 "$DIRNAME/res/drawable-xxhdpi/icon.png"
$MAGICK "$APP_ICON" -scale 192x192 "$DIRNAME/res/drawable-xxxhdpi/icon.png"
#$MAGICK "$APP_ICON_ADAPTIVE_BG" -scale 108x108 "$DIRNAME/res/drawable-mdpi/icon_bg.png"
#$MAGICK "$APP_ICON_ADAPTIVE_BG" -scale 162x162 "$DIRNAME/res/drawable-hdpi/icon_bg.png"
#$MAGICK "$APP_ICON_ADAPTIVE_BG" -scale 216x216 "$DIRNAME/res/drawable-xhdpi/icon_bg.png"
#$MAGICK "$APP_ICON_ADAPTIVE_BG" -scale 324x324 "$DIRNAME/res/drawable-xxhdpi/icon_bg.png"
#$MAGICK "$APP_ICON_ADAPTIVE_BG" -scale 432x432 "$DIRNAME/res/drawable-xxxhdpi/icon_bg.png"
$MAGICK xc:"rgba(255,255,255,255)" -scale 108x108 "$DIRNAME/res/drawable-mdpi/icon_bg.png"
$MAGICK xc:"rgba(255,255,255,255)" -scale 162x162 "$DIRNAME/res/drawable-hdpi/icon_bg.png"
$MAGICK xc:"rgba(255,255,255,255)" -scale 216x216 "$DIRNAME/res/drawable-xhdpi/icon_bg.png"
$MAGICK xc:"rgba(255,255,255,255)" -scale 324x324 "$DIRNAME/res/drawable-xxhdpi/icon_bg.png"
$MAGICK xc:"rgba(255,255,255,255)" -scale 432x432 "$DIRNAME/res/drawable-xxxhdpi/icon_bg.png"
$MAGICK "$APP_ICON_ADAPTIVE_FG" -scale 108x108 "$DIRNAME/res/drawable-mdpi/icon_fg.png"
$MAGICK "$APP_ICON_ADAPTIVE_FG" -scale 162x162 "$DIRNAME/res/drawable-hdpi/icon_fg.png"
$MAGICK "$APP_ICON_ADAPTIVE_FG" -scale 216x216 "$DIRNAME/res/drawable-xhdpi/icon_fg.png"
$MAGICK "$APP_ICON_ADAPTIVE_FG" -scale 324x324 "$DIRNAME/res/drawable-xxhdpi/icon_fg.png"
$MAGICK "$APP_ICON_ADAPTIVE_FG" -scale 432x432 "$DIRNAME/res/drawable-xxxhdpi/icon_fg.png"
export ANDROID_HOME="$SDK_PATH"
./gradlew -Pcompile_sdk_version="$COMPILE_SDK_VERSION" \
-Pmin_sdk_version="$STK_MIN_ANDROID_SDK" \
-Pcompile_sdk_version="$STK_TARGET_ANDROID_SDK"\
-Ptarget_sdk_version="$STK_TARGET_ANDROID_SDK" \
-Pstorepass="$STK_STOREPASS" \
-Pkeystore="$STK_KEYSTORE" \
-Palias="$STK_ALIAS" \
-Pndk_version="$STK_NDK_VERSION" \
-Pcompile_arch="$COMPILE_ARCH" \
-Pcpu_core="$CPU_CORE" \
-Ppackage_name="$PACKAGE_NAME" \
-Pversion_name="$PROJECT_VERSION" \
-Pversion_code="$PROJECT_CODE" \
$GRADLE_BUILD_TYPE
if [ "$GRADLE_BUILD_TYPE" = "assembleRelease" ]; then
./gradlew -Pcompile_sdk_version="$COMPILE_SDK_VERSION" \
-Pmin_sdk_version="$STK_MIN_ANDROID_SDK" \
-Pcompile_sdk_version="$STK_TARGET_ANDROID_SDK"\
-Ptarget_sdk_version="$STK_TARGET_ANDROID_SDK" \
-Pstorepass="$STK_STOREPASS" \
-Pkeystore="$STK_KEYSTORE" \
-Palias="$STK_ALIAS" \
-Pndk_version="$STK_NDK_VERSION" \
-Pcompile_arch="$COMPILE_ARCH" \
-Pcpu_core="$CPU_CORE" \
-Ppackage_name="$PACKAGE_NAME" \
-Pversion_name="$PROJECT_VERSION" \
-Pversion_code="$PROJECT_CODE" \
"bundleRelease"
fi
check_error
+465
View File
@@ -0,0 +1,465 @@
#!/bin/sh
# Tested with NDK 28.1.13356709
export DIRNAME=$(realpath "$(dirname "$0")")
export NDK_PATH_DEFAULT="$DIRNAME/android-ndk"
export ARCH_ARMV7=arm
export HOST_ARMV7=arm-linux-androideabi
export ARCH_AARCH64=arm64
export HOST_AARCH64=aarch64-linux-android
export ARCH_X86=x86
export HOST_X86=i686-linux-android
export ARCH_X86_64=x86_64
export HOST_X86_64=x86_64-linux-android
# For cmake 4.0 until stk dependencies are updated
export CMAKE_POLICY_VERSION_MINIMUM=3.5
# A helper function that checks if error ocurred
check_error()
{
if [ $? -gt 0 ]; then
echo "Error ocurred."
exit
fi
}
# Handle clean command
if [ ! -z "$1" ] && [ "$1" = "clean" ]; then
rm -rf "$DIRNAME/deps-armeabi-v7a"
rm -rf "$DIRNAME/deps-arm64-v8a"
rm -rf "$DIRNAME/deps-x86"
rm -rf "$DIRNAME/deps-x86_64"
exit
fi
if [ -z "$NDK_PATH" ]; then
export NDK_PATH="$NDK_PATH_DEFAULT"
fi
if [ -z "$STK_NDK_VERSION" ]; then
export STK_NDK_VERSION="28.1.13356709"
fi
NDK_PATH="$(realpath "$NDK_PATH")/${STK_NDK_VERSION}"
if [ ! -d "$NDK_PATH" ]; then
echo "Error: Couldn't find $NDK_PATH directory. Please create a symlink" \
"to your Android NDK installation in the $NDK_PATH_DEFAULT or set" \
"proper path in the NDK_PATH variable"
exit
fi
export NDK_TOOLCHAIN_PATH="$NDK_PATH/toolchains/llvm/prebuilt/linux-x86_64/bin"
export NDK_SYSROOT="$NDK_PATH/toolchains/llvm/prebuilt/linux-x86_64/sysroot"
export PATH="$NDK_TOOLCHAIN_PATH:$PATH"
build_deps()
{
export ARCH_OPTION=$1
if [ "$ARCH_OPTION" = "armv7" ]; then
ARCH_OPTION="armeabi-v7a"
export ARCH=$ARCH_ARMV7
# Special case
export HOST=armv7a-linux-androideabi21
export HOST_DIR=$HOST_ARMV7
elif [ "$ARCH_OPTION" = "aarch64" ]; then
ARCH_OPTION="arm64-v8a"
export ARCH=$ARCH_AARCH64
export HOST_DIR=$HOST_AARCH64
export HOST="${HOST_DIR}21"
elif [ "$ARCH_OPTION" = "x86" ]; then
export ARCH=$ARCH_X86
export HOST_DIR=$HOST_X86
export HOST="${HOST_DIR}21"
elif [ "$ARCH_OPTION" = "x86_64" ]; then
export ARCH=$ARCH_X86_64
export HOST_DIR=$HOST_X86_64
export HOST="${HOST_DIR}21"
else
echo "Unknown architecture: $1. Possible values are:"\
"all, armv7, aarch64, x86, x86_64"
exit
fi
# Zlib
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/zlib.stamp" ]; then
echo "Compiling $ARCH_OPTION zlib"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/zlib"
cp -a -f "$DIRNAME/../lib/zlib/"* "$DIRNAME/deps-$ARCH_OPTION/zlib"
cd "$DIRNAME/deps-$ARCH_OPTION/zlib"
cmake . -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH -DCMAKE_C_FLAGS=" -Wl,--undefined-version -fpic -O3 -g" &&
make -j $(($(nproc) + 1))
check_error
touch "$DIRNAME/deps-$ARCH_OPTION/zlib.stamp"
fi
# Libpng
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/libpng.stamp" ]; then
echo "Compiling $ARCH_OPTION libpng"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/libpng"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/libpng/lib"
cp -a -f "$DIRNAME/../lib/libpng/"* "$DIRNAME/deps-$ARCH_OPTION/libpng"
cd "$DIRNAME/deps-$ARCH_OPTION/libpng"
MLIBRARY="$NDK_SYSROOT/usr/lib/$HOST_DIR/libm.a"
cmake . -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH \
-DZLIB_LIBRARY="$DIRNAME/deps-$ARCH_OPTION/zlib/libz.a" \
-DZLIB_INCLUDE_DIR="$DIRNAME/deps-$ARCH_OPTION/zlib/" \
-DM_LIBRARY="$MLIBRARY" \
-DPNG_TESTS=0 -DCMAKE_C_FLAGS="-fpic -O3 -g" &&
make -j $(($(nproc) + 1))
check_error
touch "$DIRNAME/deps-$ARCH_OPTION/libpng.stamp"
fi
# Freetype bootstrap
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/freetype_bootstrap.stamp" ]; then
echo "Compiling $ARCH_OPTION freetype bootstrap"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/freetype/build"
cp -a -f "$DIRNAME/../lib/freetype/"* "$DIRNAME/deps-$ARCH_OPTION/freetype"
cd "$DIRNAME/deps-$ARCH_OPTION/freetype/build"
cmake .. -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH \
-DZLIB_LIBRARY="$DIRNAME/deps-$ARCH_OPTION/zlib/libz.a" \
-DZLIB_INCLUDE_DIR="$DIRNAME/deps-$ARCH_OPTION/zlib/" \
-DPNG_LIBRARY="$DIRNAME/deps-$ARCH_OPTION/libpng/libpng.a" \
-DPNG_PNG_INCLUDE_DIR="$DIRNAME/deps-$ARCH_OPTION/libpng/" \
-DFT_WITH_HARFBUZZ=OFF -DFT_WITH_BZIP2=OFF \
-DFT_WITH_BROTLI=OFF -DFT_WITH_ZLIB=ON -DFT_WITH_PNG=ON \
-DCMAKE_C_FLAGS="-fpic -O3 -g" &&
make -j $(($(nproc) + 1))
check_error
# We need to rebuild freetype after harfbuzz is compiled
touch "$DIRNAME/deps-$ARCH_OPTION/freetype_bootstrap.stamp"
fi
# Harfbuzz
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/harfbuzz.stamp" ]; then
echo "Compiling $ARCH_OPTION harfbuzz"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/harfbuzz/build"
cp -a -f "$DIRNAME/../lib/harfbuzz/"* "$DIRNAME/deps-$ARCH_OPTION/harfbuzz"
cd "$DIRNAME/deps-$ARCH_OPTION/harfbuzz/build"
cmake .. -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH -DBUILD_SHARED_LIBS=OFF \
-DFREETYPE_LIBRARY="$DIRNAME/deps-$ARCH_OPTION/freetype/build/libfreetype.a $DIRNAME/deps-$ARCH_OPTION/libpng/libpng.a $DIRNAME/deps-$ARCH_OPTION/zlib/libz.a" \
-DFREETYPE_INCLUDE_DIRS="$DIRNAME/deps-$ARCH_OPTION/freetype/include/" \
-DHB_HAVE_GLIB=OFF -DHB_HAVE_GOBJECT=OFF -DHB_HAVE_ICU=OFF \
-DHB_HAVE_FREETYPE=ON -DHB_BUILD_SUBSET=OFF \
-DCMAKE_C_FLAGS="-fpic -O3 -g" -DCMAKE_CXX_FLAGS="-std=gnu++0x -fpic -O3 -g" &&
make -j $(($(nproc) + 1))
check_error
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/harfbuzz/include/harfbuzz"
cp $DIRNAME/deps-$ARCH_OPTION/harfbuzz/src/*.h "$DIRNAME/deps-$ARCH_OPTION/harfbuzz/include/harfbuzz"
touch "$DIRNAME/deps-$ARCH_OPTION/harfbuzz.stamp"
fi
# Freetype
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/freetype.stamp" ]; then
echo "Compiling $ARCH_OPTION freetype"
cd "$DIRNAME/deps-$ARCH_OPTION/freetype/build"
rm -rf *
cmake .. -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH \
-DZLIB_LIBRARY="$DIRNAME/deps-$ARCH_OPTION/zlib/libz.a" \
-DZLIB_INCLUDE_DIR="$DIRNAME/deps-$ARCH_OPTION/zlib/" \
-DPNG_LIBRARY="$DIRNAME/deps-$ARCH_OPTION/libpng/libpng.a" \
-DPNG_PNG_INCLUDE_DIR="$DIRNAME/deps-$ARCH_OPTION/libpng/" \
-DHarfBuzz_LIBRARY="$DIRNAME/deps-$ARCH_OPTION/harfbuzz/build/libharfbuzz.a" \
-DHarfBuzz_INCLUDE_DIR="$DIRNAME/deps-$ARCH_OPTION/harfbuzz/src/" \
-DFT_WITH_HARFBUZZ=ON -DFT_WITH_BZIP2=OFF \
-DFT_WITH_BROTLI=OFF -DFT_WITH_ZLIB=ON -DFT_WITH_PNG=ON \
-DCMAKE_C_FLAGS="-fpic -O3 -g" &&
make -j $(($(nproc) + 1))
check_error
touch "$DIRNAME/deps-$ARCH_OPTION/freetype.stamp"
fi
# Openal
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/openal.stamp" ]; then
echo "Compiling $ARCH_OPTION openal"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/openal"
cp -a -f "$DIRNAME/../lib/openal/"* "$DIRNAME/deps-$ARCH_OPTION/openal"
cd "$DIRNAME/deps-$ARCH_OPTION/openal"
cmake . -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH -DALSOFT_UTILS=0 -DALSOFT_EXAMPLES=0 \
-DLIBTYPE=STATIC -DOPENSL_LIBRARY="-lOpenSLES" \
-DOPENSL_INCLUDE_DIR="$NDK_SYSROOT/usr/include/SLES/" \
-DOPENSL_ANDROID_INCLUDE_DIR="$NDK_SYSROOT/usr/include/SLES/" \
-DCMAKE_C_FLAGS="-fpic -O3 -g" -DCMAKE_CXX_FLAGS="-fpic -O3 -g" &&
make -j $(($(nproc) + 1))
check_error
touch "$DIRNAME/deps-$ARCH_OPTION/openal.stamp"
fi
# MbedTLS
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/mbedtls.stamp" ]; then
echo "Compiling $ARCH_OPTION mbedtls"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/mbedtls"
cp -a -f "$DIRNAME/../lib/mbedtls/"* "$DIRNAME/deps-$ARCH_OPTION/mbedtls"
if [ "$ARCH_OPTION" = "x86" ]; then
sed -i 's/#define MBEDTLS_AESNI_C//g' "$DIRNAME/deps-$ARCH_OPTION/mbedtls/include/mbedtls/mbedtls_config.h"
fi
cd "$DIRNAME/deps-$ARCH_OPTION/mbedtls"
cmake . -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH -DBUILD_SHARED_LIBS=OFF \
-DENABLE_TESTING=OFF -DENABLE_PROGRAMS=OFF \
-DCMAKE_C_FLAGS="-fpic -O3 -g" &&
make -j $(($(nproc) + 1))
check_error
touch "$DIRNAME/deps-$ARCH_OPTION/mbedtls.stamp"
fi
# Curl
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/curl.stamp" ]; then
echo "Compiling $ARCH_OPTION curl"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/curl"
cp -a -f "$DIRNAME/../lib/curl/"* "$DIRNAME/deps-$ARCH_OPTION/curl"
cd "$DIRNAME/deps-$ARCH_OPTION/curl"
cmake . -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH -DBUILD_SHARED_LIBS=OFF \
-DZLIB_LIBRARY="$DIRNAME/deps-$ARCH_OPTION/zlib/libz.a" \
-DZLIB_INCLUDE_DIR="$DIRNAME/deps-$ARCH_OPTION/zlib/" \
-DMBEDCRYPTO_LIBRARY="$DIRNAME/deps-$ARCH_OPTION/mbedtls/library/libmbedcrypto.a" \
-DMBEDTLS_LIBRARY="$DIRNAME/deps-$ARCH_OPTION/mbedtls/library/libmbedtls.a" \
-DMBEDX509_LIBRARY="$DIRNAME/deps-$ARCH_OPTION/mbedtls/library/libmbedx509.a" \
-DMBEDTLS_INCLUDE_DIRS="$DIRNAME/deps-$ARCH_OPTION/mbedtls/include/" \
-DBUILD_TESTING=OFF -DBUILD_CURL_EXE=OFF \
-DCURL_USE_MBEDTLS=ON -DUSE_ZLIB=ON -DCURL_USE_OPENSSL=OFF \
-DCURL_USE_LIBSSH=OFF -DCURL_USE_LIBSSH2=OFF \
-DCURL_USE_GSSAPI=OFF -DUSE_NGHTTP2=OFF -DUSE_QUICHE=OFF \
-DHTTP_ONLY=ON -DCURL_CA_BUNDLE=none -DCURL_CA_PATH=none \
-DENABLE_THREADED_RESOLVER=ON -DCMAKE_C_FLAGS="-fpic -O3 -g" &&
make -j $(($(nproc) + 1))
check_error
touch "$DIRNAME/deps-$ARCH_OPTION/curl.stamp"
fi
# Libjpeg
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/libjpeg.stamp" ]; then
echo "Compiling $ARCH_OPTION libjpeg"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/libjpeg"
cp -a -f "$DIRNAME/../lib/libjpeg/"* "$DIRNAME/deps-$ARCH_OPTION/libjpeg"
cd "$DIRNAME/deps-$ARCH_OPTION/libjpeg"
cmake . -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH -DCMAKE_C_FLAGS="-fpic -O3 -g" &&
make -j $(($(nproc) + 1))
check_error
touch "$DIRNAME/deps-$ARCH_OPTION/libjpeg.stamp"
fi
# Libogg
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/libogg.stamp" ]; then
echo "Compiling $ARCH_OPTION libogg"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/libogg"
cp -a -f "$DIRNAME/../lib/libogg/"* "$DIRNAME/deps-$ARCH_OPTION/libogg"
cd "$DIRNAME/deps-$ARCH_OPTION/libogg"
cmake . -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH -DCMAKE_C_FLAGS="-fpic -O3 -g" &&
make -j $(($(nproc) + 1))
check_error
touch "$DIRNAME/deps-$ARCH_OPTION/libogg.stamp"
fi
# Libvorbis
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/libvorbis.stamp" ]; then
echo "Compiling $ARCH_OPTION libvorbis"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/libvorbis"
cp -a -f "$DIRNAME/../lib/libvorbis/"* "$DIRNAME/deps-$ARCH_OPTION/libvorbis"
cd "$DIRNAME/deps-$ARCH_OPTION/libvorbis"
cmake . -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH -DCMAKE_C_FLAGS="-fpic -O3 -g" \
-DOGG_LIBRARY="$DIRNAME/deps-$ARCH_OPTION/libogg/libogg.a" \
-DOGG_INCLUDE_DIR="$DIRNAME/deps-$ARCH_OPTION/libogg/include" &&
make -j $(($(nproc) + 1))
check_error
touch "$DIRNAME/deps-$ARCH_OPTION/libvorbis.stamp"
fi
# Shaderc
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/shaderc.stamp" ]; then
echo "Compiling $ARCH_OPTION shaderc"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/shaderc"
cp -a -f "$DIRNAME/../lib/shaderc/"* "$DIRNAME/deps-$ARCH_OPTION/shaderc"
cd "$DIRNAME/deps-$ARCH_OPTION/shaderc"
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/shaderc-deps.stamp" ]; then
./utils/git-sync-deps
check_error
touch "$DIRNAME/deps-$ARCH_OPTION/shaderc-deps.stamp"
fi
cmake . -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH -DCMAKE_C_FLAGS="-fpic -O3" \
-DCMAKE_CXX_FLAGS="-fpic -O3" -DSHADERC_SKIP_INSTALL=1 \
-DCMAKE_BUILD_TYPE=Release \
-DSHADERC_SKIP_TESTS=1 -DSHADERC_SKIP_EXAMPLES=1 \
-DSPIRV_HEADERS_SKIP_INSTALL=1 -DSPIRV_HEADERS_SKIP_EXAMPLES=1 \
-DSKIP_SPIRV_TOOLS_INSTALL=1 -DSPIRV_SKIP_TESTS=1 \
-DSPIRV_SKIP_EXECUTABLES=1 -DENABLE_GLSLANG_BINARIES=0 \
-DENABLE_CTEST=0 &&
make -j $(($(nproc) + 1))
# Strip debug symbol to make app bundle smaller
llvm-strip --strip-debug "$DIRNAME/deps-$ARCH_OPTION/shaderc/libshaderc/libshaderc_combined.a"
check_error
touch "$DIRNAME/deps-$ARCH_OPTION/shaderc.stamp"
fi
# Libsquish
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/libsquish.stamp" ]; then
echo "Compiling $ARCH_OPTION libsquish"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/libsquish"
cp -a -f "$DIRNAME/../lib/libsquish/"* "$DIRNAME/deps-$ARCH_OPTION/libsquish"
cd "$DIRNAME/deps-$ARCH_OPTION/libsquish"
if [[ "$ARCH_OPTION" = "x86" || "$ARCH_OPTION" = "x86_64" ]]; then
cmake . -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH \
-DCMAKE_C_FLAGS="-fpic -O3 -g -DSQUISH_USE_SSE=2 -msse2" \
-DCMAKE_CXX_FLAGS="-fpic -O3 -g -DSQUISH_USE_SSE=2 -msse2"
else
cmake . -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH -DCMAKE_C_FLAGS="-fpic -O3 -g" \
-DCMAKE_CXX_FLAGS="-fpic -O3 -g"
fi
make -j $(($(nproc) + 1))
check_error
touch "$DIRNAME/deps-$ARCH_OPTION/libsquish.stamp"
fi
# ASTC-encoder
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/astc-encoder.stamp" ]; then
echo "Compiling $ARCH_OPTION astc-encoder"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/astc-encoder"
cp -a -f "$DIRNAME/../lib/astc-encoder/"* "$DIRNAME/deps-$ARCH_OPTION/astc-encoder"
cd "$DIRNAME/deps-$ARCH_OPTION/astc-encoder"
sed -i '/-Werror/d' Source/cmake_core.cmake
sed -i 's|${ASTCENC_TARGET}-static|astcenc|g' Source/cmake_core.cmake
if [ "$ARCH_OPTION" = "armeabi-v7a" ]; then
cmake . -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH -DSTK_ARM_NEON=ON \
-DCMAKE_C_FLAGS="-fpic -O3 -g -mfpu=neon" \
-DCMAKE_CXX_FLAGS="-fpic -O3 -g -mfpu=neon" \
-DASTCENC_INVARIANCE=OFF -DASTCENC_CLI=OFF
elif [ "$ARCH_OPTION" = "arm64-v8a" ]; then
cmake . -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH -DCMAKE_C_FLAGS="-fpic -O3 -g" \
-DCMAKE_CXX_FLAGS="-fpic -O3 -g" \
-DASTCENC_ISA_NEON=ON -DASTCENC_INVARIANCE=OFF -DASTCENC_CLI=OFF
else
if [ "$ARCH_OPTION" = "x86" ]; then
sed -i 's/_mm_popcnt_u64/__builtin_popcountll/g' Source/astcenc_vecmathlib_sse_4.h
fi
cmake . -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH -DCMAKE_C_FLAGS="-fpic -O3 -g" \
-DCMAKE_CXX_FLAGS="-fpic -O3 -g" \
-DASTCENC_ISA_SSE41=ON -DASTCENC_INVARIANCE=OFF -DASTCENC_CLI=OFF
fi
make -j $(($(nproc) + 1))
check_error
touch "$DIRNAME/deps-$ARCH_OPTION/astc-encoder.stamp"
fi
# libadrenotools (for custom vulkan driver(s))
if [ "$ARCH_OPTION" = "arm64-v8a" ]; then
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/libadrenotools.stamp" ]; then
echo "Compiling $ARCH_OPTION libadrenotools"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/libadrenotools"
mkdir -p "$DIRNAME/mesa/arm64-v8a"
git clone "$DIRNAME/../lib/libadrenotools" "$DIRNAME/deps-$ARCH_OPTION/libadrenotools"
cd "$DIRNAME/deps-$ARCH_OPTION/libadrenotools"
git submodule update --init
cmake . -DCMAKE_TOOLCHAIN_FILE=../../../cmake/Toolchain-android.cmake \
-DHOST=$HOST -DARCH=$ARCH -DCMAKE_C_FLAGS="-fpic -O3 -g" \
-DCMAKE_CXX_FLAGS="-fpic -O3 -g" \
-DCMAKE_SHARED_LINKER_FLAGS="-static-libstdc++ -static-libgcc"
make -j $(($(nproc) + 1))
check_error
cp "$DIRNAME/deps-$ARCH_OPTION/libadrenotools/src/hook/libhook_impl.so" "$DIRNAME/mesa/arm64-v8a"
cp "$DIRNAME/deps-$ARCH_OPTION/libadrenotools/src/hook/libmain_hook.so" "$DIRNAME/mesa/arm64-v8a"
touch "$DIRNAME/deps-$ARCH_OPTION/libadrenotools.stamp"
fi
if [ ! -f "$DIRNAME/deps-$ARCH_OPTION/mesa.stamp" ]; then
echo "Compiling $ARCH_OPTION mesa"
mkdir -p "$DIRNAME/deps-$ARCH_OPTION/mesa"
cp -a -f "$DIRNAME/../lib/mesa/"* "$DIRNAME/deps-$ARCH_OPTION/mesa"
cd "$DIRNAME/deps-$ARCH_OPTION/mesa"
cat > crossfile <<EOF
[constants]
ndk_path = '$NDK_PATH'
[binaries]
ar = ndk_path / 'toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar'
c = ['ccache', ndk_path / 'toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android26-clang']
cpp = ['ccache', ndk_path / 'toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android26-clang++', '-fno-exceptions', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-static-libstdc++', '-Wno-c++11-narrowing']
c_ld = 'lld'
cpp_ld = 'lld'
# Android doesn't come with a pkg-config, but we need one for meson to be happy not
# finding all the optional deps it looks for. Use system pkg-config pointing at a
# directory we get to populate with any .pc files we want to add for Android
# Also, include the plain DRM lib we found earlier. Panfrost relies on it rather heavily, especially when
# interacting with the panfrost DRM module and not kbase
pkg-config = ['env', 'PKG_CONFIG_LIBDIR=.:/tmp/drm-static/lib/pkgconfig', '/usr/bin/pkg-config']
strip = [ndk_path / 'toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-strip', '-s']
[host_machine]
system = 'android'
cpu_family = 'aarch64'
cpu = 'armv8'
endian = 'little'
EOF
sed -i 's/dep_libarchive = dependency(.*/dep_libarchive = null_dep/' src/freedreno/meson.build
sed -i 's/dep_libxml2 = dependency(.*/dep_libxml2 = null_dep/' src/freedreno/meson.build
sed -i 's/#elif DETECT_OS_ANDROID && !defined(__cplusplus)/#elif 0/' src/util/perf/cpu_trace.h
meson setup build --cross-file crossfile \
-Dbuildtype=release \
-Dplatforms=android \
-Dplatform-sdk-version=26 \
-Dandroid-stub=true \
-Dgallium-drivers= \
-Dvulkan-drivers=freedreno \
-Dfreedreno-kmds=kgsl \
-Db_lto=true \
-Db_lto_mode=thin \
-Degl=disabled \
-Dvalgrind=disabled \
-Dzstd=disabled \
-Dshader-cache=disabled
meson compile -C build
check_error
cp "$DIRNAME/deps-$ARCH_OPTION/mesa/build/src/freedreno/vulkan/libvulkan_freedreno.so" "$DIRNAME/mesa/arm64-v8a"
touch "$DIRNAME/deps-$ARCH_OPTION/mesa.stamp"
fi
fi
}
if [ -z "$COMPILE_ARCH" ] || [ "$COMPILE_ARCH" = "all" ]; then
build_deps armv7
build_deps aarch64
build_deps x86
build_deps x86_64
else
build_deps "$COMPILE_ARCH"
fi
+298
View File
@@ -0,0 +1,298 @@
package org.supertuxkart.stk_dbg;
import org.libsdl.app.SDLActivity;
import org.supertuxkart.stk_dbg.STKInputConnection;
import android.content.Context;
import android.text.InputType;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
// We need to extend EditText instead of view to allow copying to our STK
// editbox
public class STKEditText extends EditText
{
private int m_composing_start;
private int m_composing_end;
/* Used to prevent copying text to non focused widget in STK. */
private int m_stk_widget_id;
private STKInputConnection m_stk_input_connection;
/* Used to avoid infinite calling updateSTKEditBox if setText currently
* by jni or clearing text when out focus. */
private boolean m_from_stk_editbox;
// ------------------------------------------------------------------------
private native static void editText2STKEditbox(int widget_id,
String full_text, int start,
int end,
int composing_start,
int composing_end);
// ------------------------------------------------------------------------
private native static void handleActionNext(int widget_id);
// ------------------------------------------------------------------------
private native static void handleLeftRight(boolean left, int widget_id);
// ------------------------------------------------------------------------
public STKEditText(Context context)
{
super(context);
setInputType(InputType.TYPE_CLASS_TEXT);
setFocusableInTouchMode(true);
m_composing_start = 0;
m_composing_end = 0;
m_stk_widget_id = -1;
m_from_stk_editbox = false;
m_stk_input_connection = null;
setOnEditorActionListener(new EditText.OnEditorActionListener()
{
@Override
public boolean onEditorAction(TextView v, int action_id,
KeyEvent event)
{
if (action_id == EditorInfo.IME_ACTION_NEXT)
{
handleActionNext(m_stk_widget_id);
// STK will handle the closing of the screen keyboard
return true;
}
return false;
}
});
setOnKeyListener(new EditText.OnKeyListener()
{
@Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
// Up or down pressed, leave focus
if (keyCode == KeyEvent.KEYCODE_DPAD_UP ||
keyCode == KeyEvent.KEYCODE_DPAD_DOWN)
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
{
beforeHideKeyboard(true/*clear_text*/);
SDLActivity.onNativeKeyDown(keyCode);
SDLActivity.onNativeKeyUp(keyCode);
}
return true;
}
// For left or right let STK decides
else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT &&
getSelectionStart() == 0)
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
{
beforeHideKeyboard(true/*clear_text*/);
handleLeftRight(true, m_stk_widget_id);
}
else
updateSTKEditBox();
return true;
}
else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT &&
getSelectionEnd() == getText().length())
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
{
beforeHideKeyboard(true/*clear_text*/);
handleLeftRight(false, m_stk_widget_id);
}
else
updateSTKEditBox();
return true;
}
else if (keyCode == KeyEvent.KEYCODE_ENTER)
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
handleActionNext(m_stk_widget_id);
return true;
}
// Requires for hardware key like "Ctrl-a" so it will select
// all text in stk edit box
updateSTKEditBox();
return false;
}
});
}
// ------------------------------------------------------------------------
@Override
public InputConnection onCreateInputConnection(EditorInfo out_attrs)
{
if (m_stk_input_connection == null)
{
m_stk_input_connection = new STKInputConnection(
super.onCreateInputConnection(out_attrs), this);
}
out_attrs.actionLabel = null;
out_attrs.inputType = getInputType();
out_attrs.imeOptions = EditorInfo.IME_ACTION_NEXT |
EditorInfo.IME_FLAG_NO_FULLSCREEN |
EditorInfo.IME_FLAG_NO_EXTRACT_UI;
return m_stk_input_connection;
}
// ------------------------------------------------------------------------
@Override
public boolean onCheckIsTextEditor() { return true; }
// ------------------------------------------------------------------------
@Override
public boolean onKeyPreIme(int key_code, KeyEvent event)
{
// Always remove the focus on STKEdit when pressing back button in
// phone, which hideSoftInputFromWindow is called by java itself
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK &&
event.getAction() == KeyEvent.ACTION_UP)
beforeHideKeyboard(false/*clear_text*/);
return false;
}
// ------------------------------------------------------------------------
public void setComposingRegion(int start, int end)
{
// From doc of InputConnectionWrapper, it says:
// Editor authors, be ready to accept a start that is greater than end.
if (start != end && start > end)
{
m_composing_end = start;
m_composing_start = end;
}
else
{
m_composing_start = start;
m_composing_end = end;
}
}
// ------------------------------------------------------------------------
public void updateSTKEditBox()
{
if (!isFocused() || m_from_stk_editbox)
return;
editText2STKEditbox(m_stk_widget_id, getText().toString(),
getSelectionStart(), getSelectionEnd(), m_composing_start,
m_composing_end);
}
// ------------------------------------------------------------------------
public void beforeHideKeyboard(final boolean clear_text)
{
try
{
if (clear_text)
{
// No need updating stk editbox on clearing text when out focus
m_from_stk_editbox = true;
{
super.clearComposingText();
super.getText().clear();
}
m_from_stk_editbox = false;
}
clearFocus();
setVisibility(View.GONE);
SDLActivity.reFocusAfterSTKEditText();
}
catch (Exception e)
{
m_from_stk_editbox = false;
}
}
// ------------------------------------------------------------------------
/* Called by STK with JNI to set this view with new text (like user focus
* a new editbox in stk, or change cursor / selection). */
public void setTextFromSTK(int widget_id, final String text,
int selection_start, int selection_end)
{
m_stk_widget_id = widget_id;
// Avoid sending the newly set text back to STK at the same time
m_from_stk_editbox = true;
try
{
String old_text = getText().toString();
boolean text_changed = !text.equals(old_text);
if (text_changed)
{
super.clearComposingText();
super.setText(text);
m_stk_input_connection.setComposingRegion(0, 0);
}
if (selection_start != selection_end &&
selection_start > selection_end)
{
int temp = selection_end;
selection_end = selection_start;
selection_start = temp;
}
if (selection_start < 0)
selection_start = 0;
if (selection_end > length())
selection_end = length();
if (text_changed)
{
InputMethodManager imm = (InputMethodManager)getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null)
{
// From google, You should call this when the text within
// your view changes outside of the normal input method or
// key input flow, such as when an application calls
// TextView.setText().
imm.restartInput(this);
}
}
setSelection(selection_start, selection_end);
}
catch (Exception e)
{
m_from_stk_editbox = false;
}
m_from_stk_editbox = false;
}
// ------------------------------------------------------------------------
public STKInputConnection getSTKInputConnection()
{ return m_stk_input_connection; }
// ------------------------------------------------------------------------
public void configType(final int type)
{
int it = InputType.TYPE_CLASS_TEXT;
// Check text_box_widget.hpp for definition
switch (type)
{
case 0:
{
it = InputType.TYPE_CLASS_TEXT;
break;
}
case 1:
{
it = InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
break;
}
case 2:
{
it = InputType.TYPE_TEXT_VARIATION_PASSWORD;
break;
}
case 3:
{
it = InputType.TYPE_CLASS_NUMBER;
break;
}
case 4:
{
it = InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
break;
}
default:
break;
}
if (it != getInputType())
setInputType(it);
}
}
@@ -0,0 +1,68 @@
package org.supertuxkart.stk_dbg;
import org.supertuxkart.stk_dbg.STKEditText;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputConnectionWrapper;
public class STKInputConnection extends InputConnectionWrapper
{
/* The global edittext which will be "copied" to the current focused STK
* box. */
final private STKEditText m_stk_edittext;
// ------------------------------------------------------------------------
public STKInputConnection(InputConnection target, STKEditText stk_edittext)
{
super(target, true/*mutable*/);
m_stk_edittext = stk_edittext;
}
// ------------------------------------------------------------------------
@Override
public boolean setComposingText(CharSequence text, int new_cursor_position)
{
boolean ret = super.setComposingText(text, new_cursor_position);
String composing_text = text.toString();
String new_text = m_stk_edittext.getText().toString();
int composing_start = 0;
int composing_end = 0;
// Test last char
if (!composing_text.isEmpty() && !new_text.isEmpty() &&
composing_text.charAt(composing_text.length() - 1) ==
new_text.charAt(new_text.length() - 1))
{
composing_start = new_text.length() - composing_text.length();
composing_end = composing_start + composing_text.length();
}
m_stk_edittext.setComposingRegion(composing_start, composing_end);
m_stk_edittext.updateSTKEditBox();
return ret;
}
// ------------------------------------------------------------------------
@Override
public boolean finishComposingText()
{
m_stk_edittext.setComposingRegion(0, 0);
m_stk_edittext.updateSTKEditBox();
return super.finishComposingText();
}
// ------------------------------------------------------------------------
@Override
public boolean setComposingRegion(int start, int end)
{
m_stk_edittext.setComposingRegion(start, end);
m_stk_edittext.updateSTKEditBox();
return super.setComposingRegion(start, end);
}
// ------------------------------------------------------------------------
@Override
public boolean commitText(CharSequence text, int new_cursor_position)
{
// Usually only a single character, so dismiss composing region
boolean ret = super.commitText(text, new_cursor_position);
m_stk_edittext.setComposingRegion(0, 0);
m_stk_edittext.updateSTKEditBox();
return ret;
}
}
@@ -0,0 +1,547 @@
package org.supertuxkart.stk_dbg;
import org.supertuxkart.stk_dbg.STKEditText;
import org.libsdl.app.SDLActivity;
import org.libsdl.app.SDL;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Process;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Display;
import android.view.DisplayCutout;
import android.view.Gravity;
import android.view.inputmethod.InputMethodManager;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.View;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.util.DisplayMetrics;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.Set;
import org.minidns.hla.DnssecResolverApi;
import org.minidns.hla.ResolverResult;
import org.minidns.record.SRV;
import org.minidns.record.TXT;
public class SuperTuxKartActivity extends SDLActivity
{
private AlertDialog m_progress_dialog;
private ProgressBar m_progress_bar;
private ImageView m_splash_screen;
private STKEditText m_stk_edittext;
private int m_bottom_y;
private int m_intial_orientation;
private float m_top_padding;
private float m_bottom_padding;
private float m_left_padding;
private float m_right_padding;
private AtomicInteger m_keyboard_height;
private AtomicInteger m_moved_height;
// ------------------------------------------------------------------------
public native static void debugMsg(String msg);
// ------------------------------------------------------------------------
private native static void handlePadding(boolean val);
// ------------------------------------------------------------------------
private native static void saveKeyboardHeight(int height);
// ------------------------------------------------------------------------
private native static void saveMovedHeight(int height);
// ------------------------------------------------------------------------
private native static void addDNSSrvRecords(String name, int weight);
// ------------------------------------------------------------------------
private native static void pauseRenderingJNI();
// ------------------------------------------------------------------------
private void showExtractProgressPrivate()
{
WindowManager wm =
(WindowManager)getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics display_metrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(display_metrics);
int padding = display_metrics.widthPixels / 64;
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
ll.setPadding(padding, padding, padding, padding);
ll.setGravity(Gravity.CENTER);
LinearLayout.LayoutParams ll_param = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
ll_param.gravity = Gravity.CENTER;
TextView tv = new TextView(this);
// From values strings.xml which is generated by make.sh
tv.setText(getString(R.string.po_extract_game_data));
tv.setLayoutParams(ll_param);
ll_param = new LinearLayout.LayoutParams(
display_metrics.widthPixels,
LinearLayout.LayoutParams.WRAP_CONTENT);
ll_param.gravity = Gravity.CENTER;
ll.setLayoutParams(ll_param);
m_progress_bar = new ProgressBar(this, null,
android.R.attr.progressBarStyleHorizontal);
m_progress_bar.setIndeterminate(false);
m_progress_bar.setPadding(0, padding, 0, padding);
m_progress_bar.setLayoutParams(ll_param);
ll.addView(tv);
ll.addView(m_progress_bar);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(false);
builder.setView(ll);
m_progress_dialog = builder.create();
m_progress_dialog.show();
Window window = m_progress_dialog.getWindow();
if (window != null)
{
WindowManager.LayoutParams layout_params =
new WindowManager.LayoutParams();
layout_params.copyFrom(
m_progress_dialog.getWindow().getAttributes());
layout_params.width = WindowManager.LayoutParams.MATCH_PARENT;
layout_params.height = LinearLayout.LayoutParams.WRAP_CONTENT;
m_progress_dialog.getWindow().setAttributes(layout_params);
}
}
// ------------------------------------------------------------------------
private void hideKeyboardNative(final boolean clear_text)
{
if (m_stk_edittext == null)
return;
m_stk_edittext.beforeHideKeyboard(clear_text);
InputMethodManager imm = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm == null)
return;
imm.hideSoftInputFromWindow(m_stk_edittext.getWindowToken(), 0);
}
// ------------------------------------------------------------------------
private void createSTKEditText()
{
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
// We move the dummy edittext out of the android screen because we draw
// our own manually
params.setMargins(0, -100000, 1, -100010);
m_stk_edittext = new STKEditText(this);
// For some copy-and-paste text are not done by commitText in
// STKInputConnection, so we need an extra watcher
m_stk_edittext.addTextChangedListener(new TextWatcher()
{
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {}
@Override
public void afterTextChanged(Editable edit)
{
if (m_stk_edittext != null)
m_stk_edittext.updateSTKEditBox();
}
});
addContentView(m_stk_edittext, params);
// Only focus it and make visible when soft keybord is opened
m_stk_edittext.setVisibility(View.GONE);
}
// ------------------------------------------------------------------------
@Override
public void onCreate(Bundle instance)
{
super.onCreate(instance);
m_keyboard_height = new AtomicInteger();
m_moved_height = new AtomicInteger();
m_progress_dialog = null;
m_progress_bar = null;
m_splash_screen = null;
m_bottom_y = m_intial_orientation = 0;
m_top_padding = m_bottom_padding = m_left_padding = m_right_padding =
0.0f;
final View root = getWindow().getDecorView().findViewById(
android.R.id.content);
root.getViewTreeObserver().addOnGlobalLayoutListener(new
OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
Rect r = new Rect();
root.getWindowVisibleDisplayFrame(r);
int screen_height = root.getRootView().getHeight();
int keyboard_height = screen_height - (r.bottom);
m_keyboard_height.set(keyboard_height);
int moved_height = 0;
int margin = screen_height - m_bottom_y;
if (keyboard_height > margin)
moved_height = -keyboard_height + margin;
m_moved_height.set(-moved_height);
SDLActivity.moveView(moved_height);
}
});
InputStream istr = null;
try
{
LinearLayout ll = new LinearLayout(this);
LinearLayout.LayoutParams ll_param = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
ll.setLayoutParams(ll_param);
WindowManager wm =
(WindowManager)getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics display_metrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(display_metrics);
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
int w = display_metrics.widthPixels;
int h = display_metrics.heightPixels;
Bitmap scaled = Bitmap.createBitmap(w, h, conf);
Canvas canvas = new Canvas(scaled);
istr = getAssets().open("data/gui/icons/logo.png");
Bitmap logo = BitmapFactory.decodeStream(istr);
Rect src = new Rect(0, 0, logo.getWidth(), logo.getHeight());
// STK logo is a square
int target_size = w;
if (target_size > h)
target_size = h;
target_size /= 2;
Rect dest = new Rect(w / 2 - target_size / 2,
h / 2 - target_size / 2,
w / 2 - target_size / 2 + target_size,
h / 2 - target_size / 2 + target_size);
canvas.drawBitmap(logo, src, dest, null);
m_splash_screen = new ImageView(this);
m_splash_screen.setBackgroundColor(Color.argb(255, 168, 168, 168));
m_splash_screen.setImageDrawable(new BitmapDrawable(getResources(),
scaled));
addContentView(m_splash_screen, ll_param);
}
catch (Exception e) {}
finally
{
try
{
if (istr != null)
istr.close();
}
catch(Exception e) {}
}
}
// ------------------------------------------------------------------------
@Override
public void onStart()
{
super.onStart();
m_keyboard_height.set(0);
m_moved_height.set(0);
}
// ------------------------------------------------------------------------
@Override
public void onPause()
{
super.onPause();
hideKeyboardNative(false/*clear_text*/);
if (SDLActivity.mSDLThread != null)
pauseRenderingJNI();
}
// ------------------------------------------------------------------------
/* SDL manually dlopen main to allow unload after main thread exit. */
protected String[] getLibraries()
{
return new String[]{ "SDL2" };
}
// ------------------------------------------------------------------------
protected String getMainSharedObject()
{
return getContext().getApplicationInfo().nativeLibraryDir + "/libmain.so";
}
// ------------------------------------------------------------------------
public void showKeyboard(final int type, final int y)
{
final Context context = this;
// Need to run in ui thread as it access the view m_stk_edittext
runOnUiThread(new Runnable()
{
@Override
public void run()
{
m_bottom_y = y;
InputMethodManager imm = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm == null)
return;
if (m_stk_edittext == null)
createSTKEditText();
m_stk_edittext.configType(type);
m_stk_edittext.setVisibility(View.VISIBLE);
m_stk_edittext.requestFocus();
imm.showSoftInput(m_stk_edittext,
InputMethodManager.SHOW_FORCED);
}
});
}
// ------------------------------------------------------------------------
/* Called by STK in JNI. */
public void hideKeyboard(final boolean clear_text)
{
runOnUiThread(new Runnable()
{
@Override
public void run()
{
m_bottom_y = 0;
hideKeyboardNative(clear_text);
}
});
}
// ------------------------------------------------------------------------
/* Called by STK in JNI. */
public void fromSTKEditBox(final int widget_id, final String text,
final int selection_start,
final int selection_end, final int type)
{
runOnUiThread(new Runnable()
{
@Override
public void run()
{
if (m_stk_edittext == null)
createSTKEditText();
m_stk_edittext.configType(type);
m_stk_edittext.setTextFromSTK(widget_id, text, selection_start,
selection_end);
}
});
}
// ------------------------------------------------------------------------
public String[] getDNSTxtRecords(String domain)
{
try
{
ResolverResult<TXT> txts =
DnssecResolverApi.INSTANCE.resolve(domain, TXT.class);
Set<TXT> ans = txts.getAnswers();
String[] result = new String[ans.size()];
int i = 0;
for (TXT t : ans)
result[i++] = t.getText();
return result;
}
catch (Exception e)
{
e.printStackTrace();
return new String[0];
}
}
// ------------------------------------------------------------------------
public void getDNSSrvRecords(String domain)
{
try
{
ResolverResult<SRV> srvs =
DnssecResolverApi.INSTANCE.resolve(domain, SRV.class);
Set<SRV> ans = srvs.getAnswers();
for (SRV s : ans)
addDNSSrvRecords(s.target.toString() + ":" + s.port, s.weight);
}
catch (Exception e)
{
e.printStackTrace();
}
}
// ------------------------------------------------------------------------
public boolean isHardwareKeyboardConnected()
{
return getResources().getConfiguration()
.keyboard == Configuration.KEYBOARD_QWERTY;
}
// ------------------------------------------------------------------------
public int getScreenSize()
{
return getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_MASK;
}
// ------------------------------------------------------------------------
public float getTopPadding() { return m_top_padding; }
// ------------------------------------------------------------------------
public float getBottomPadding() { return m_bottom_padding; }
// ------------------------------------------------------------------------
public float getLeftPadding() { return m_left_padding; }
// ------------------------------------------------------------------------
public float getRightPadding() { return m_right_padding; }
// ------------------------------------------------------------------------
public int getInitialOrientation() { return m_intial_orientation; }
// ------------------------------------------------------------------------
public void showExtractProgress(final int progress)
{
runOnUiThread(new Runnable()
{
@Override
public void run()
{
if (progress == -1)
{
if (m_progress_dialog != null)
{
m_progress_dialog.dismiss();
m_progress_dialog = null;
m_progress_bar = null;
}
AlertDialog.Builder error =
new AlertDialog.Builder(SDL.getContext());
error.setMessage(getString(R.string.po_extract_error_msg));
error.setTitle(getString(R.string.po_extract_error));
error.setPositiveButton(getString(R.string.po_quit),
new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog,
int id)
{
android.os.Process.killProcess(
android.os.Process.myPid());
}
});
error.setCancelable(false);
error.create().show();
return;
}
if (progress == 0 && m_progress_dialog == null)
showExtractProgressPrivate();
else if (progress == 100 && m_progress_dialog != null)
{
m_progress_dialog.dismiss();
m_progress_dialog = null;
m_progress_bar = null;
}
else if (m_progress_bar != null &&
m_progress_bar.getProgress() != progress)
{
m_progress_bar.setProgress(progress);
}
}
});
}
// ------------------------------------------------------------------------
public void hideSplashScreen()
{
if (m_splash_screen != null)
{
m_splash_screen.animate().setDuration(200).alpha(0).setListener(
new AnimatorListenerAdapter()
{
@Override
public void onAnimationEnd(Animator animation)
{
if (m_splash_screen.getParent() instanceof ViewGroup)
{
ViewGroup view = (ViewGroup)m_splash_screen.getParent();
view.removeView(m_splash_screen);
m_splash_screen = null;
}
}
});
}
}
// ------------------------------------------------------------------------
@Override
public void onAttachedToWindow()
{
super.onAttachedToWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
DisplayCutout dc = getWindow().getDecorView().getRootWindowInsets()
.getDisplayCutout();
if (dc != null)
{
m_top_padding = (float)dc.getBoundingRectTop().height();
m_bottom_padding = (float)dc.getBoundingRectBottom().height();
m_left_padding = (float)dc.getBoundingRectLeft().width();
m_right_padding = (float)dc.getBoundingRectRight().width();
// Left or right will depend on the device initial orientation
// So save it for dealing with device rotation later
m_intial_orientation = SDLActivity.getCurrentOrientation();
}
}
}
// ------------------------------------------------------------------------
@Override
public void onMultiWindowModeChanged(boolean isInMultiWindowMode,
Configuration newConfig)
{
handlePadding(isInMultiWindowMode);
}
// ------------------------------------------------------------------------
public int getKeyboardHeight() { return m_keyboard_height.get(); }
// ------------------------------------------------------------------------
public int getMovedHeight() { return m_moved_height.get(); }
// ------------------------------------------------------------------------
public String getLocaleString()
{
String language = "";
if (mCurrentLocale != null)
{
language = mCurrentLocale.getLanguage();
if (language == "iw")
language = "he";
else if (language == "in")
language = "id";
else if (language == "ji")
language = "yi";
String country = mCurrentLocale.getCountry();
if (country != "")
language += "_" + country;
}
return language;
}
}