CAGE on Android¶
Pre-requisites¶
Before we begin building our SDL2 and libcage project,
make sure you have the Android SDK and NDK
environment properly set up. You should be able
to run ndk-build
and adb
,
and you should also have the latest Android SDK
installed using the android
application. [1]
If you want to use a real device to test your game (you probably should),
make sure you can see it using adb devices
.
This tutorial also assumes you’re running in Linux (Mac OS should
work similar) and optionally, that you can edit and build C files
using make
gcc
or clang
. We will create a Linux build
of our game as well.
Setting up the project¶
Begin by creating your project folders:
mkdir my-game && cd my-game; mkdir src deps res build build/android build/linux
Note build/android
and build/linux
. You can use the Linux build for
on-going development and the Android build when you want to test the game
on a real device.
Now we will get SDL2, SDL2_image, SDL2_mixer and CAGE. We need everything in its source form to build it using the NDK.
hg clone http://hg.libsdl.org/SDL deps/SDL2
hg clone http://hg.libsdl.org/SDL_image deps/SDL2_image
hg clone http://hg.libsdl.org/SDL_mixer deps/SDL2_mixer
git clone https://github.com/rlofc/cage deps/cage
Coding a basic game¶
Create and edit src/game.c
#include "cage.h"
static void* create_game(void)
{
screen_color(color_from_RGB(255, 255, 255));
return create_font("res/font.png", 32, 4);
}
static void update_game(void* data, float elapsed_ms)
{
draw_text(data, "hello, world", 10, 10);
UNUSED(elapsed_ms);
}
static void destroy_game(void* data)
{
destroy_font(data);
}
int main(int argc, char* argv[])
{
return game_loop(create_game, update_game, destroy_game);
}
You will also need to put this bitmap font in your game
resources folder, my-game/res/
.
(Use right-click and save link as to download and save the bitmap file)
Building for Android¶
Bootstrapping the build project¶
SDL2 come with a handy build script that we can use to bootstrap
our Android project, but before we can use it, we need to let it know
which Android SDK version to target. This should be the same API version
you chose to install using the android
command and you can run it again
just to make sure.
Now, edit deps/SDL2/build-scripts/androidbuild.sh
and change
$ANDROID update project --path $BUILDPATH
to:
$ANDROID update project --path $BUILDPATH --target android-{API version}
To keep things clean, let’s also change the BUILDPATH
to our project’s build folder:
BUILDPATH="$SDLPATH/build/$APP"
to
BUILDPATH="$SDLPATH/../../build/android/$APP"
The script is now ready to bootstrap your build environment using the SDL2 Android project template files:
cd deps/SDL2/build-scripts/
./androidbuild.sh com.your.game /dev/null
cd -
Your game’s build project is now in my-game/build/android/com.your.game
and we can now inject the rest of the dependencies into it.
Injecting the dependencies¶
To inject the rest of our build project dependencies, create symbolic files links for SDL2_image, SDL2_mixer, CAGE, your source file and your game resources folder:
ln -s $(pwd)/deps/SDL2_image build/android/com.your.game/jni/
ln -s $(pwd)/deps/SDL2_mixer build/android/com.your.game/jni/
ln -s $(pwd)/deps/cage build/android/com.your.game/jni/
ln -s $(pwd)/src/game.c build/android/com.your.game/jni/src/
mkdir build/android/com.your.game/assets
ln -s $(pwd)/res build/android/com.your.game/assets
This will allow NDK to build everything we need, but we will still need to tweak the build files.
Tweaking the NDK build files¶
Just a few required tweaks before we can run a succesful build.
Edit build/android/com.your.game/jni/Android.mk
and add the following
lines to the beginning of the file:
SUPPORT_MOD_MODPLUG := false
SUPPORT_MOD_MIKMOD := false
SUPPORT_MP3_SMPEG := false
SUPPORT_WEBP := false
include $(call all-subdir-makefiles)
Now edit build/android/com.your.game/jni/src/Android.mk
and make sure
you have the needed LOCAL_C_INCLUDES
added:
LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include \
$(LOCAL_PATH)/../SDL2_image \
$(LOCAL_PATH)/../SDL2_mixer \
$(LOCAL_PATH)/../cage/src
Your game.c files added to LOCAL_SRC_FILES
:
# Add your application source files here...
LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \
game.c
And the needed libraries added to LOCAL_SHARED_LIBRARIES
:
LOCAL_SHARED_LIBRARIES := SDL2 SDL2_image SDL2_mixer cage
Build and Run¶
Here we go! time to build and install your game on your Android device:
cd build/android/com.your.game/jni
ndk-build -j$(nproc)
cd ..
ant debug install
Optional - Build your game for Linux¶
To have a smoother workflow, you will probably want to use your Linux build for on-going development.
Begin by building and installing your project’s SDL2 SDL2_image and SDL2_mixer. Note: this will replace any previously installed SDL in your system. If you already have SDL2, SDL2_image and SDL2_mixer installed and you do not want to change these, you may skip this step. You will still need the source files for the Android build though.
for lib in SDL2 SDL2_mixer SDL2_image; do \
cd deps/$lib; ./autogen.sh && ./configure && \
make && sudo make install; cd -; done;
Running autotools will change some files in the SDL2 include folder. This has to be reverted before you try to build for Android again, otherwise the NDK build will fail.
Run:
cd deps/SDL2
hg revert deps/SDL2/include/**
cd -
Build CAGE:
cd deps/cage; make; cd -
If everything went well, you should now have SDL2 and CAGE ready for Linux game development.
Let’s create a simple Makefile:
GAME_BUILD_PATH = build/linux
GAME_BINARY = game
include deps/cage/linux.mk
Now make
and try your shiny new game:
make && cd build/linux; ./game; cd -
Footnotes
[1] | You can follow the Pre-requisites instructions in https://wiki.libsdl.org/Android or your platform specific guidelines. |