SDL2をAndroidで動かす為のポイント

SDL2アプリをAndroidで動かす為のポイントを紹介します。

 

1 SDL2に含まれるandroid-projectを使う

Android向けのSDL2はJNIありきで動作します。そこでSDL2向けのJNIインターフェースが用意されているandroid-projectを使うことでAndroidへの移植が容易になります。

$ tree SDL2-2.0.3/android-project/
SDL2-2.0.3/android-project/
├── AndroidManifest.xml
├── ant.properties
├── build.properties
├── build.xml
├── default.properties
├── jni
│   ├── Android.mk
│   ├── Application.mk
│   └── src
│       ├── Android.mk
│       └── Android_static.mk
├── proguard-project.txt
├── project.properties
├── res
│   ├── drawable-hdpi
│   │   └── ic_launcher.png
│   ├── drawable-mdpi
│   │   └── ic_launcher.png
│   ├── drawable-xhdpi
│   │   └── ic_launcher.png
│   ├── drawable-xxhdpi
│   │   └── ic_launcher.png
│   ├── layout
│   │   └── main.xml
│   └── values
│       └── strings.xml
└── src
    └── org
        └── libsdl
            └── app
                └── SDLActivity.java

android-project直下でandroid update projectを実行する必要があります。

$ cd android-project
$ android udpate project -t [Your Target] -p .

上記のjni/src配下に自分のコードを配置し(srcという名前である必要はありません)、jni/src/Android.mkでコードをビルド対象にします。Makefileと同様、wildcard関数を用いると楽かもしれません。Android.mkにMakefileの関数を使う方法はこちらを参照してください。

# Add your application source files here...
 LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \
- YourSourceHere.c
+ $(patsubst $(LOCAL_PATH)/%,%,$(wildcard $(LOCAL_PATH)/*.c))

2 SDL_imageやSDL_ttfの追加

android-projectにはSDL_imageやSDL_ttf等の追加が容易になっています。jni配下にディレクトリを追加し、jni/src/Android.mkにライブラリ参照を追加すれば良いです。

$ ls jni/
Android.mk Application.mk src SDL_image SDL_ttf
$ grep "SDL2_image" jni/src/Android.mk
LOCAL_SHARED_LIBRARIES := SDL2 SDL2_image SDL2_ttf

3 リソースはassetsディレクトリへ

SDL2で作成したアプリケーションは絶対パスや相対パスで画像ファイル等のリソースにアクセスしますが、Androidの場合はassetsディレクトリ配下のパスになります。

$ ls android-project/
AndroidManifest.xml  build.properties    jni                   res
ant.properties       build.xml           proguard-project.txt  src
assets               default.properties  project.properties

4 jni配下をantでビルドする

ndk-buildでビルドしても良いのですが、antでビルドできるようにするとant debug install等と対応が取れます。

$ cat custom_rules.xml
<?xml version="1.0" encoding="UTF-8"?>
<project>
  <target name="-pre-build">
    <exec executable="ndk-build" failonerror="true"/>
  </target>
</project>

5 ウィンドウサイズが反映されない

SDL_CreateWindowSDL_CreateWindowAndRendererでウィンドウサイズを指定しても反映されず、フルスクリーン表示になります。

このフルスクリーンのサイズはSurfaceViewを継承したSDLSurfaceというビューのサイズです。

SDLActivity.javaのSDLSurface作成時にビューのサイズを変更することで、フルスクリーンのサイズを変更できます。

diff --git a/src/org/libsdl/app/SDLActivity.java b/src/org/libsdl/app/SDLActivity.java
index 5a46c14..1c164c8 100644
--- a/src/org/libsdl/app/SDLActivity.java
+++ b/src/org/libsdl/app/SDLActivity.java
@@ -93,6 +93,7 @@ public class SDLActivity extends Activity {
             mJoystickHandler = new SDLJoystickHandler();
         }

+        mSurface.setLayoutParams(new android.widget.FrameLayout.LayoutParams(640, 360));
         mLayout = new AbsoluteLayout(this);
         mLayout.addView(mSurface);

6 イベントはタッチイベントで

Androidはタッチイベントで動作します。マウスイベントで動作しているプログラムはタッチイベントに変更する必要があります。

SDL_Event event;
SDL_PollEvent(&event);
/** event.typeでイベントの種類を判別 */
switch (event.type) { /** SDL_MOUSEMOTION, SDL_MOUSEBUTTONUP */
case SDL_MOUSEBUTTONDOWN:
  /** 座標はevent.button.x, event.button.y */
case SDL_FINGERDOWN: /** SDL_FINGERMOTION, SDL_FINGERUP */
  /** 座標はevent.tfinger.x, event.tfionger.y */
  break;
default:
  break;
}

event.button.xは0から画面の幅までの整数値である一方、event.tfingerは0から1(1が右端)までの浮動小数点である点に注意です。

7 AVDでUse Host GPU

Use Host GPUにチェックを入れていないAVDの場合、SDL_Renderer構造体の作成で失敗します。チェックを入れましょう。Use Host GPUが上手く動かない環境の場合はこちらの4.1 SDL_CreateRendererのSDL_RENDERER_SOFTWAREの説明を参照して下さい。