SDL中文教程

_(:3」∠)_目前一团乱还请各位见谅
总之各位随意~

在Eclipse中配置SDL2.0 for Android

| Comments

首先要有个装好Android SDK的eclipse不是么。因为我现在用的是在Android developer官网上下的ADT bundle,所以就不多说了。

为了编译SDL我们还需要Android NDK,下好之后在Window-preference-android-ndk里指定路径。

然后新建工程,选择”Android Application Project”,然后一路选择下去,其中在Create Activity界面取消选择Create Activity。

将SDL文件夹内/android-project/文件夹内的src和jni文件夹复制到你新建的项目的文件夹内。

在jni下新建SDL文件夹,将(clone来的)SDL目录内的include、src文件夹和Android.mk复制到新建的SDL文件夹内。

测试SDL

在jni/src/下新建main.c(当然其实文件名你可以随意取,也可以是c++文件)

然后将以下代码写进去:

#include "SDL.h"
#include "stdio.h" 
int main(int argc, char *argv[]) {
    printf("hello world....\n");
}

需要注意的是不能写无参的main函数,因为Android ndk里.so库的入口点并不是main,SDL自己声明了一个main函数以调用,这就是我们的main。

然后编辑该文件夹下的Android.mk文件,将YourSourceHere.c改为main.c(就是刚才新建的文件的文件名)

回到eclipse里,刷新文件浏览视图,可以在jni目录下看到我们刚才复制进去的文件。

编辑根目录下的AndroidManifest.xml,将package改为”org.libsdl.app”,在标签中间加入以下代码:

<activity android:name="SDLActivity"
              android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

打开终端,在jni文件夹下执行Android ndk中的ndk-build(如果不想把ndk-build添加到环境变量中直接把那个文件拽过来就可以了),应该可以看到生成了libSDL2.so与libmain.so两个文件。

SDL compiled

扯句题外话,libmain.so这个文件名是SDL自己定的,跟刚才建的main.c无关哟。

这时回到eclipse内,点运行,它会提示你新建一个avd(android模拟器),按照它提示的步骤建就好了,注意你选择的系统版本应该和你所建的项目版本相兼容才对。[这个问题稍后叙述

在模拟器中运行刚才新建的项目,它应该会显示一个黑屏才对。别指望能看到printf的输出。如果程序提示错误或者你eclipse里的logcat里疯狂地刷红字的错误警告,那么八成是因为库没有加载成功。这样的话就回头看看在ndk-build的那一步是否正确地生成了libmain.so和libSDL2.so吧,它们应该被放在了libs/armebi/下面。

这样我们的SDL程序就算是跑起来了。

test SDL_image

但是这样不方便,我们希望刚才的ndk-build的步骤能直接用eclipse执行。否则要eclipse何用。

选择Help-install new software,然后在work with后面选择Android Developer Tools Update Site.在下面的列表里勾选NDK tools,然后取消勾选左下角的 “Contact all update sites during install to find required software”(不然会安装出错),一路选择next accept,最后finnish.它会开始安装,这里我们先点Run in background,去干别的。

installing ndk plugin

我们先来研究一下SDL的几个扩展库的编译。

首先是SDL_image.

我们先把SDL_image整个文件夹复制到jni文件夹内(其实需要的只是几个源文件和Android.mk),SDL_image需要png和jpeg支持,二者分别可以从https://github.com/julienr/libpng-android和https://github.com/folecr/jpeg8d获得。

对libpng:将文件夹jni放到项目目录的jni文件夹内,重命名为png

对libjpeg:将Android.mk中的LOCAL_MODULE := cocos_jpeg_static,改为LOCAL_MODULE := libjpeg,然后将整个文件夹重命名为jpeg,复制到项目的jni文件夹内

LOCAL_MODULE := libjpeg

执行ndk-build,应该可以生成libSDL2_image.so

使用SDL_image:

用IMG_LoadTexture加载Texture,然后把图片放到assets文件夹内。这里需要说两句,IMG_LoadTexture这个函数在android平台上是会自动帮你从assets里读取文件的。IMG_Load也是。

因为我们的main.c并不知道SDL_image的路径,我们需要在Android.mk文件夹里添加。

打开src文件夹里的Android.mk,给 LOCAL_C_INCLUDES 添加$(LOCAL_PATH)/../SDL_image,注意大小写。

LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include \
            $(LOCAL_PATH)/../SDL_image

然后添加SDL_image库:

LOCAL_SHARED_LIBRARIES := SDL2 SDL2_image

最后打开org.libsdl.app包下的SDLActivity.java 把

System.loadLibrary("SDL2_image");

取消注释,不然SDL2_image库不会被加载~

然后我们可以运行了~

然后我们开始尝试使用刚才安装的Android ndk plugin……= =

这个插件是很囧很囧很囧的。你必须通过它的功能新建一个so库,它才能用。但是一旦你新建了一个,它的新建功能就消失了,无论你如何处置,就算直接把库的源代码删除,它那个选项也回不来= =。而且你不建还不能用。

于是我们新建一个,右键单击工程,依次选择Android Tools -> Add Native Support.然后随便填个库名,然后删除自动生成的那个源码文件。[我知道这很囧,但不这样做,IDE就不知道你在用native库,就不能调试native代码。

好吧,这样就好了,直接run,它会自动执行ndk-build.

关于SDL_ttf的编译。

先把SDL_ttf放到我们的jni文件夹里,这就不多说了。

需要freetype库~在http://sourceforge.net/projects/freetype/files/?source=navbar这里下载,解压后重命名为freetype,然后放到SDL_ttf文件夹里。

然后直接在jni文件夹下执行ndk-build,应该不会有任何问题。

然后在程序的Android.mk里修改路径使其识别SDL_ttf的路径。编辑jni/src/Android.mk

LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include \
            $(LOCAL_PATH)/../SDL_image \
            $(LOCAL_PATH)/../SDL_ttf

LOCAL_SHARED_LIBRARIES := SDL2 SDL2_image SDL2_ttf

以及在SDLActivity.java中,将

System.loadLibrary("SDL2_ttf");

取消注释。

OK,那就可以在main.c里用SDL_ttf了。跟SDL_image一样,把图片放到assets文件夹内就好。

老实说,其实Android NDK插件有很囧的bug,它的code analysis很多时候会以为你的代码有错误,但其实你的代码完全正确,就是它不懂。而当code analysis认为你有错误的时候,就算你的代码已经编译成功,你也照样不能运行它。遇到这种情况……请到Properties里面把code analysis的内容都取消勾选吧!

最后是SDL_mixer的编译~ 把SDL_mixer放到jni文件夹内,然后去https://code.google.com/p/libmikmod-android/source/checkout获取mikmod的源码。

把其中的Android.mk文件的最后一行改为

include $(BUILD_STATIC_LIBRARY)

找到其中的jni文件夹,将里面的libmikmod-3.1.11文件夹复制到我们的jni目录,并重命名为mikmod

svn co http://svn.xiph.org/trunk/Tremor获取tremor的源码

然后还要去http://www.xiph.org/downloads/里下载一份libogg

然后把里面的Tremor重命名为tremor后放到jni文件夹下,把libogg的include文件夹下的ogg文件夹也复制到jni文件夹下,把libogg文件夹下src文件夹里的那俩*.c复制到tremor文件夹下。

然后,在tremor里新建Android.mk,这么写:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := tremor

LOCAL_C_INCLUDES := $(LOCAL_PATH)/.. 

LOCAL_CFLAGS := -I$(LOCAL_PATH) -DHAVE_ALLOCA_H

LOCAL_SRC_FILES := $(notdir $(wildcard $(LOCAL_PATH)/*.c))

include $(BUILD_STATIC_LIBRARY)

最后编辑SDL_mixer的Android.mk文件

把其中的:

LOCAL_SHARED_LIBRARIES := SDL2 mikmod
LOCAL_STATIC_LIBRARIES := tremor

改为:

LOCAL_SHARED_LIBRARIES := SDL2
LOCAL_STATIC_LIBRARIES := tremor mikmod

之后是老规矩:

LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include \
            $(LOCAL_PATH)/../SDL_image \
            $(LOCAL_PATH)/../SDL_ttf \
            $(LOCAL_PATH)/../SDL_mixer
...

LOCAL_SHARED_LIBRARIES := SDL2 SDL2_image SDL2_ttf SDL2_mixer

还有把

System.loadLibrary("SDL2_mixer");

取消注释。

然后就该怎么着怎么着了。老规矩,把音乐文件放到assets文件夹里就够了。

PS:这里我遇到了一个很囧的问题,按照默认的编译方式——将mikmod编译为共享库的话,会导致Activity在加载库的时候有一些问题。 如果我加上System.loadLibrary(“mikmod”);的话,程序就卡在这行代码,进行不下去了;如果我去掉这一行代码,在System.loadLibrary(“SDL2_mixer”);的阶段,SDL_mixer就哼哼唧唧加载不上,好像还报一堆找不到库的错误。无奈只有改链接方式,把mikmod库整个链进SDL_mixer.

整个jni目录的结构大概是这样的:

file tree

如果你“去你的!老子编译不过!!!!!”那么你可以尝试clone https://github.com/alanwoolley/CorsixTH-Android的项目……

剩下的我不说了=____,=。同志们该怎么用怎么用吧,用不来的话直接去github上clone人家的代码。

Comments