Skip to content

Commit fa99fa4

Browse files
committed
Add Android support
1 parent 65a8050 commit fa99fa4

38 files changed

+17260
-1
lines changed

.github/workflows/build.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ jobs:
4747
- runner: ubuntu-latest
4848
preset: linux-cross-arm64
4949
name: Linux-cross-arm64
50+
- runner: ubuntu-latest
51+
name: android
5052
build_type:
5153
- Debug
5254
- Release
@@ -100,24 +102,38 @@ jobs:
100102
with:
101103
vcpkgJsonGlob: vcpkg.json
102104

105+
- uses: actions/setup-java@v4
106+
if: ${{ matrix.os.name == 'android' }}
107+
with:
108+
java-version: '17'
109+
distribution: 'temurin'
110+
111+
- name: Build APK
112+
if: ${{ matrix.os.name == 'android' }}
113+
run: ./gradlew build
114+
103115
- name: Configure CMake
116+
if: ${{ matrix.os.name != 'android' }}
104117
env:
105118
CC: ${{ matrix.os.cc }}
106119
CXX: ${{ matrix.os.cxx }}
107120
run: cmake --preset ${{ matrix.os.preset }} -DENABLE_LOGGER=ON -DFORCE_PORTABLE_INSTALL=ON -DUSE_EXTERNAL_PLOG=ON -DBUILD_EDITOR=${{ matrix.os.preset == 'linux-cross-arm64' && 'OFF' || 'ON' }} -DBUILD_TESTING=${{ matrix.os.preset == 'linux-cross-arm64' && 'OFF' || 'ON' }}
108121

109122
- name: Build ${{ matrix.build_type }}
123+
if: ${{ matrix.os.name != 'android' }}
110124
run: cmake --build --preset ${{ matrix.os.preset }} --config ${{ matrix.build_type }} --verbose
111125

112126
- name: Run ${{ matrix.build_type }} Unittests
113-
if: ${{ matrix.os.preset != 'linux-cross-arm64' }}
127+
if: ${{ matrix.os.preset != 'linux-cross-arm64' && matrix.os.name != 'android' }}
114128
run: ctest --preset ${{ matrix.os.preset }} -C ${{ matrix.build_type }}
115129

116130
- name: Local install
131+
if: ${{ matrix.os.name != 'android' }}
117132
# There no cmake install presets so install in traditional way
118133
run: cmake --install builds/${{ matrix.os.preset }}/ --config ${{ matrix.build_type }}
119134

120135
- name: Upload Artifacts
136+
if: ${{ matrix.os.name != 'android' }}
121137
uses: actions/upload-artifact@v4
122138
with:
123139
name: Descent3_${{ matrix.build_type }}_${{ matrix.os.name }}

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,3 +408,10 @@ build[s]
408408

409409
# Ignore autogenerated git-hash.txt file, generated for packaging purposes
410410
git-hash.txt
411+
412+
# Android build bits
413+
.gradle/*
414+
android/.cxx/*
415+
android/build/*
416+
build/*
417+
local.properties

CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,22 @@ endif()
99
set(USE_VCPKG "DEFAULT" CACHE STRING "Use vcpkg for dependency management. DEFAULT defers to existence of $VCPKG_ROOT environment variable.")
1010
set_property(CACHE USE_VCPKG PROPERTY STRINGS "DEFAULT" "ON" "OFF")
1111

12+
if (CMAKE_SYSTEM_NAME STREQUAL "Android")
13+
if (ANDROID_ABI MATCHES "arm64-v8a")
14+
set(VCPKG_TARGET_TRIPLET "arm64-android" CACHE STRING "" FORCE)
15+
elseif(ANDROID_ABI MATCHES "armeabi-v7a")
16+
set(VCPKG_TARGET_TRIPLET "arm-android" CACHE STRING "" FORCE)
17+
elseif(ANDROID_ABI MATCHES "x86_64")
18+
set(VCPKG_TARGET_TRIPLET "x64-android" CACHE STRING "" FORCE)
19+
elseif(ANDROID_ABI MATCHES "x86")
20+
set(VCPKG_TARGET_TRIPLET "x86-android" CACHE STRING "" FORCE)
21+
else()
22+
message(FATAL_ERROR "ANDROID_ABI not set or not recognized")
23+
endif()
24+
25+
set(ENV{ANDROID_NDK_HOME} ${CMAKE_ANDROID_NDK})
26+
endif()
27+
1228
if(USE_VCPKG)
1329
if(DEFINED ENV{VCPKG_ROOT})
1430
if (CMAKE_TOOLCHAIN_FILE)

android/build.gradle

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
apply plugin: 'com.android.application'
2+
3+
repositories {
4+
mavenCentral()
5+
}
6+
7+
android {
8+
namespace "com.descent3.droid"
9+
compileSdk 34
10+
defaultConfig {
11+
minSdkVersion 32
12+
targetSdkVersion 34
13+
versionCode 1
14+
versionName "1.0"
15+
externalNativeBuild {
16+
cmake {
17+
arguments "-DANDROID_APP_PLATFORM=android-19", "-DANDROID_STL=c++_static", "-DENABLE_LOGGER=ON"
18+
// abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
19+
abiFilters 'arm64-v8a'
20+
}
21+
}
22+
}
23+
buildTypes {
24+
release {
25+
minifyEnabled false
26+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
27+
}
28+
}
29+
applicationVariants.all { variant ->
30+
tasks["merge${variant.name.capitalize()}Assets"]
31+
.dependsOn("externalNativeBuild${variant.name.capitalize()}")
32+
}
33+
sourceSets {
34+
main {
35+
jniLibs.srcDir 'libs'
36+
java.srcDirs = ['src/main/java']
37+
}
38+
}
39+
externalNativeBuild {
40+
cmake {
41+
path '../CMakeLists.txt'
42+
}
43+
}
44+
lint {
45+
abortOnError false
46+
}
47+
}
48+
49+
dependencies {
50+
implementation fileTree(include: ['*.jar'], dir: 'libs')
51+
implementation 'org.nanohttpd:nanohttpd:2.2.0'
52+
}

android/proguard-rules.pro

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Add project specific ProGuard rules here.
2+
# By default, the flags in this file are appended to flags specified
3+
# in [sdk]/tools/proguard/proguard-android.txt
4+
# You can edit the include path and order by changing the proguardFiles
5+
# directive in build.gradle.
6+
#
7+
# For more details, see
8+
# http://developer.android.com/guide/developing/tools/proguard.html
9+
10+
# Add any project specific keep options here:
11+
12+
# If your project uses WebView with JS, uncomment the following
13+
# and specify the fully qualified class name to the JavaScript interface
14+
# class:
15+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16+
# public *;
17+
#}

android/src/main/AndroidManifest.xml

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?xml version="1.0" encoding="utf-8"?><!-- Replace com.test.game with the identifier of your game below, e.g.
2+
com.gamemaker.game
3+
-->
4+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
5+
android:installLocation="auto"
6+
android:versionCode="1"
7+
android:versionName="devel">
8+
9+
<!-- OpenGL ES 3.2 -->
10+
<uses-feature
11+
android:glEsVersion="0x00030002"
12+
android:required="true" />
13+
14+
<!-- Touchscreen support -->
15+
<uses-feature
16+
android:name="android.hardware.touchscreen"
17+
android:required="false" />
18+
19+
<!-- Game controller support -->
20+
<uses-feature
21+
android:name="android.hardware.bluetooth"
22+
android:required="false" />
23+
<uses-feature
24+
android:name="android.hardware.gamepad"
25+
android:required="false" />
26+
<uses-feature
27+
android:name="android.hardware.usb.host"
28+
android:required="false" />
29+
30+
<!-- External mouse input events -->
31+
<uses-feature
32+
android:name="android.hardware.type.pc"
33+
android:required="false" />
34+
35+
<!-- Audio recording support -->
36+
<!-- if you want to capture audio, uncomment this. -->
37+
<!-- <uses-feature
38+
android:name="android.hardware.microphone"
39+
android:required="false" /> -->
40+
<!-- <uses-permission android:name="android.permission.RECORD_AUDIO" /> -->
41+
42+
<!-- Allow access to Bluetooth devices -->
43+
<!-- Currently this is just for Steam Controller support and requires setting SDL_HINT_JOYSTICK_HIDAPI_STEAM -->
44+
<!-- <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> -->
45+
<!-- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> -->
46+
47+
<!-- Allow access to the vibrator -->
48+
<uses-permission android:name="android.permission.VIBRATE" />
49+
<uses-permission android:name="android.permission.INTERNET" />
50+
51+
<!-- Create a Java class extending SDLActivity and place it in a
52+
directory under app/src/main/java matching the package, e.g. app/src/main/java/com/gamemaker/game/MyGame.java
53+
54+
then replace "SDLActivity" with the name of your class (e.g. "MyGame")
55+
in the XML below.
56+
57+
An example Java class can be found in README-android.md
58+
-->
59+
<application
60+
android:allowBackup="true"
61+
android:hardwareAccelerated="true"
62+
android:icon="@mipmap/ic_launcher"
63+
android:label="@string/app_name"
64+
android:theme="@style/AppTheme">
65+
66+
<!-- Example of setting SDL hints from AndroidManifest.xml:
67+
<meta-data android:name="SDL_ENV.SDL_ACCELEROMETER_AS_JOYSTICK" android:value="0"/>
68+
-->
69+
70+
<activity
71+
android:name="MainActivity"
72+
android:alwaysRetainTaskState="true"
73+
android:configChanges="layoutDirection|locale|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
74+
android:exported="true"
75+
android:label="@string/app_name"
76+
android:launchMode="singleInstance"
77+
android:preferMinimalPostProcessing="true">
78+
79+
<!-- Let Android know that we can handle some USB devices and should receive this event -->
80+
<intent-filter>
81+
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
82+
</intent-filter>
83+
<intent-filter>
84+
<action android:name="android.intent.action.MAIN" />
85+
<category android:name="android.intent.category.LAUNCHER" />
86+
</intent-filter>
87+
</activity>
88+
<activity
89+
android:name="com.descent3.droid.GameDataUploadActivity"
90+
android:exported="true" />
91+
</application>
92+
93+
</manifest>

android/src/main/assets/css/style.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.title {
2+
font-size: 24pt;
3+
text-align: center;
4+
}
5+
.dir_select {
6+
margin: 12pt;
7+
border: 2pt solid black;
8+
padding: 12pt;
9+
text-align: center;
10+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<html>
2+
<head><title>Not Found</title></head>
3+
<body>
4+
<h1 style="text-align: center;">Bad Request</h1>
5+
<h3 style="text-align: center;">d3.hog not found in upload</h3>
6+
</body>
7+
</html>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<html>
2+
<head><title>Not Found</title></head>
3+
<body>
4+
<h1 style="text-align: center;">Not Found</h1>
5+
</body>
6+
</html>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<html>
2+
<head><title>Method Not Allowed</title></head>
3+
<body>
4+
<h1 style="text-align: center;">Method Not Allowed</h1>
5+
</body>
6+
</html>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<html>
2+
<head><title>Not Implemented</title></head>
3+
<body>
4+
<h1 style="text-align: center;">Not Implemented</h1>
5+
</body>
6+
</html>

android/src/main/assets/index.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<html>
2+
<head>
3+
<link href="css/style.css" rel="stylesheet"/>
4+
<script src="js/jquery-3.7.1.js" type="text/javascript"></script>
5+
<script src="js/main.js" type="text/javascript"></script>
6+
<title>Upload Game Data</title>
7+
</head>
8+
<body>
9+
<div class="title">Upload Game Data</div>
10+
<form action="" class="dir_select" enctype="multipart/form-data" method="post">
11+
Upload Descent 3 Game Data:
12+
<input id="file" mozdirectory name="file" type="file" webkitdirectory/>
13+
<input id="submit" type="submit"/>
14+
</form>
15+
</body>
16+
</html>

0 commit comments

Comments
 (0)