Commit 606b0cda authored by Sam Lantinga's avatar Sam Lantinga

Build the SDL library as a shared object on Android, so it will work correctly...

Build the SDL library as a shared object on Android, so it will work correctly with SDL_image and SDL_ttf.
parent e92a0428
LOCAL_PATH := $(call my-dir)
###########################
#
# SDL shared library
#
###########################
include $(CLEAR_VARS)
LOCAL_MODULE := SDL
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SRC_FILES := src/SDL_android.cpp \
$(subst $(LOCAL_PATH)/,, \
$(wildcard $(LOCAL_PATH)/src/*.c) \
$(wildcard $(LOCAL_PATH)/src/audio/*.c) \
$(wildcard $(LOCAL_PATH)/src/cpuinfo/*.c) \
$(wildcard $(LOCAL_PATH)/src/events/*.c) \
$(wildcard $(LOCAL_PATH)/src/file/*.c) \
$(wildcard $(LOCAL_PATH)/src/joystick/*.c) \
$(wildcard $(LOCAL_PATH)/src/haptic/*.c) \
$(wildcard $(LOCAL_PATH)/src/stdlib/*.c) \
$(wildcard $(LOCAL_PATH)/src/thread/*.c) \
$(wildcard $(LOCAL_PATH)/src/timer/*.c) \
$(wildcard $(LOCAL_PATH)/src/video/*.c) \
$(wildcard $(LOCAL_PATH)/src/power/*.c) \
$(wildcard $(LOCAL_PATH)/src/audio/android/*.c) \
$(wildcard $(LOCAL_PATH)/src/audio/dummy/*.c) \
$(wildcard $(LOCAL_PATH)/src/video/android/*.c) \
$(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \
$(wildcard $(LOCAL_PATH)/src/haptic/dummy/*.c) \
$(wildcard $(LOCAL_PATH)/src/atomic/dummy/*.c) \
$(wildcard $(LOCAL_PATH)/src/thread/pthread/*.c) \
$(wildcard $(LOCAL_PATH)/src/timer/unix/*.c) \
$(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c))
LOCAL_LDLIBS := -ldl -lGLESv1_CM -llog
include $(BUILD_SHARED_LIBRARY)
# Makefile to build the SDL library
include ./android/config.cfg #get ANDROID_NDK, ANDROID_NDK_HOST
# For NDK R4
TOOLS_PATH=$(ANDROID_NDK)/build/prebuilt/$(ANDROID_NDK_HOST)/arm-eabi-4.2.1/bin
ANDROID_INCLUDES = -I$(ANDROID_NDK)/build/platforms/android-4/arch-arm/usr/include
# For NDK R5
#TOOLS_PATH=$(ANDROID_NDK)/toolchains/arm-eabi-4.4.0/prebuilt/$(ANDROID_NDK_HOST)/bin
#ANDROID_INCLUDES = -I$(ANDROID_NDK)/platforms/android-4/arch-arm/usr/include
INCLUDE = -I./include
CFLAGS = -g -O2 -fno-short-enums $(INCLUDE) $(ANDROID_INCLUDES) -DANDROID -DANDROID_NDK -static
AR = $(TOOLS_PATH)/arm-eabi-ar
RANLIB = $(TOOLS_PATH)/arm-eabi-ranlib
CC = $(TOOLS_PATH)/arm-eabi-gcc
CONFIG_H = include/SDL_config.h
TARGET = libSDL.a
SOURCES = \
src/*.c \
src/audio/*.c \
src/cpuinfo/*.c \
src/events/*.c \
src/file/*.c \
src/joystick/*.c \
src/haptic/*.c \
src/stdlib/*.c \
src/thread/*.c \
src/timer/*.c \
src/video/*.c \
src/power/*.c \
src/audio/android/*.c \
src/audio/dummy/*.c \
src/video/android/*.c \
src/joystick/android/*.c \
src/haptic/dummy/*.c \
src/atomic/dummy/*.c \
src/thread/pthread/*.c \
src/timer/unix/*.c \
src/loadso/dummy/*.c \
OBJECTS = $(shell echo $(SOURCES) | sed -e 's,\.c,\.o,g')
all: $(TARGET)
$(TARGET): $(CONFIG_H) $(OBJECTS)
$(AR) crv $@ $^
$(RANLIB) $@
$(CONFIG_H):
cp $(CONFIG_H).default $(CONFIG_H)
clean:
rm -f $(TARGET) $(OBJECTS)
......@@ -2,7 +2,8 @@
Simple DirectMedia Layer for Android
================================================================================
Requirements: Android NDK r4 or later
Requirements: Android SDK and Android NDK r4 or later
http://developer.android.com/
================================================================================
How the port works
......@@ -16,26 +17,44 @@ Java project, along with some C support code that communicates with Java
- This eventually produces a standard Android .apk package
================================================================================
Building an app
================================================================================
Instructions:
1. Copy the android-project directory wherever you want your Android project to go
2. Move this SDL directory into the <project>/jni directory
3. Place your application source files in the <project>/jni/src directory
4. Edit <project>/jni/src/Android.mk to include your source files
5. Run 'ndk-build' (a script provided by the NDK). This compiles the C source
If you want to use the Eclipse IDE, skip to the Eclipse section below.
6. Edit <project>/local.properties to point to the Android SDK directory
7. Run 'ant debug' in android/project. This compiles the .java and eventually
creates a .apk with the native code embedded
8. 'ant install' will push the apk to the device or emulator (if connected)
================================================================================
Building an app
Using Eclipse
================================================================================
Instructions:
1. Edit android/config.cfg to point to the location of the NDK
2. Run 'make -f Makefile.android'. If all goes well, libsdl.a should be created
3. Place your application source files in android/project/jni
4. Edit the Android.mk to include your source files
5. Run 'ndk-build' (a script provided by the NDK). This compiles the C source
6. Edit project/local.properties to point to the SDK directory
6. Run 'ant debug' in android/project. This compiles the .java and eventually
creates a .apk with the C source embedded
7. 'ant install' will push the apk to the device or emulator (if connected)
NEED CONTENT
================================================================================
Loading files
================================================================================
NEED CONTENT
================================================================================
Troubleshooting
================================================================================
NEED CONTENT
================================================================================
......
# This file sets up paths needed to find the NDK build tools.
# Edit it appropriately for your configuration and save it as "config.cfg".
# This should be the full path to the Android NDK
ANDROID_NDK := /Users/hercules/eclipse/android-ndk-r5
# This should be "linux-x86" for linux, "darwin-x86" for mac
ANDROID_NDK_HOST := darwin-x86
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.libsdl.app"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/app_name" android:icon="@drawable/icon">
<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>
</application>
</manifest>
# This file is used to override default values used by the Ant build system.
#
# This file must be checked in Version Control Systems, as it is
# integral to the build system of your project.
# This file is only used by the Ant script.
# You can use this to override default values such as
# 'source.dir' for the location of your java source folder and
# 'out.dir' for the location of your output folder.
# You can also use it define how the release builds are signed by declaring
# the following properties:
# 'key.store' for the location of your keystore and
# 'key.alias' for the name of the key to use.
# The password will be asked during the build when you use the 'release' target.
<?xml version="1.0" encoding="UTF-8"?>
<project name="SDLApp" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked in in Version
Control Systems. -->
<property file="local.properties" />
<!-- The build.properties file can be created by you and is never touched
by the 'android' tool. This is the place to change some of the default property values
used by the Ant rules.
Here are some properties you may want to change/update:
application.package
the name of your application package as defined in the manifest. Used by the
'uninstall' rule.
source.dir
the name of the source directory. Default is 'src'.
out.dir
the name of the output directory. Default is 'bin'.
Properties related to the SDK location or the project target should be updated
using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your application and
should be checked in in Version Control Systems.
-->
<property file="build.properties" />
<!-- The default.properties file is created and updated by the 'android' tool, as well
as ADT.
This file is an integral part of the build system for your application and
should be checked in in Version Control Systems. -->
<property file="default.properties" />
<!-- Custom Android task to deal with the project target, and import the proper rules.
This requires ant 1.6.0 or above. -->
<path id="android.antlibs">
<pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
<pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
<pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
<pathelement path="${sdk.dir}/tools/lib/apkbuilder.jar" />
<pathelement path="${sdk.dir}/tools/lib/jarutils.jar" />
</path>
<taskdef name="setup"
classname="com.android.ant.SetupTask"
classpathref="android.antlibs" />
<!-- Execute the Android Setup task that will setup some properties specific to the target,
and import the build rules files.
The rules file is imported from
<SDK>/platforms/<target_platform>/templates/android_rules.xml
To customize some build steps for your project:
- copy the content of the main node <project> from android_rules.xml
- paste it in this build.xml below the <setup /> task.
- disable the import by changing the setup task below to <setup import="false" />
This will ensure that the properties are setup correctly but that your customized
build steps are used.
-->
<setup />
</project>
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-4
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := sdlapp
SDL := ../../../
LOCAL_CFLAGS := -DANDROID_NDK \
-DDISABLE_IMPORTGL \
-I$(SDL)/include
LOCAL_SRC_FILES := \
android-support.cpp \
lesson05.c \
LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog -lSDL -lgcc -L$(SDL)
include $(BUILD_SHARED_LIBRARY)
This diff is collapsed.
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked in Version Control Systems,
# as it contains information specific to your local configuration.
# location of the SDK. This is only used by Ant
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=/home/paul/Projects/gsoc/sdk/android-sdk-linux_86
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, SDLActivity"
/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">SDLActivity</string>
</resources>
This diff is collapsed.
......@@ -127,7 +127,7 @@ typedef unsigned int size_t;
#define SDL_HAPTIC_DUMMY 1
/* Enable various shared object loading systems */
#define SDL_LOADSO_DUMMY 1
#define SDL_LOADSO_DLOPEN 1
/* Enable various threading systems */
#define SDL_THREAD_PTHREAD 1
......
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/*******************************************************************************
This file links the Java side of Android with libsdl
*******************************************************************************/
#include <jni.h>
#include <sys/time.h>
#include <time.h>
#include <android/log.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#define DEBUG
/*******************************************************************************
Globals
*******************************************************************************/
static long _getTime(void){
struct timeval now;
gettimeofday(&now, NULL);
return (long)(now.tv_sec*1000 + now.tv_usec/1000);
}
JavaVM* mVM = NULL;
JNIEnv* mEnv = NULL;
JNIEnv* mAudioThreadEnv = NULL; //See the note below for why this is necessary
JavaVM* mVM = NULL;
//Main activity
jclass mActivityInstance;
......@@ -36,7 +44,6 @@ jmethodID midFlipBuffers;
jmethodID midEnableFeature;
jmethodID midUpdateAudio;
extern "C" int SDL_main(int argc, char *argv[]);
extern "C" int Android_OnKeyDown(int keycode);
extern "C" int Android_OnKeyUp(int keycode);
extern "C" void Android_SetScreenResolution(int width, int height);
......@@ -59,19 +66,20 @@ float fLastAccelerometer[3];
Functions called by JNI
*******************************************************************************/
//Library init
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved){
// Library init
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
mVM = vm;
JNIEnv* env = NULL;
jint result = -1;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
return result;
}
return JNI_VERSION_1_4;
}
// Called before SDL_main() to initialize JNI bindings
extern "C" void SDL_Android_Init(JNIEnv* env)
{
mEnv = env;
__android_log_print(ANDROID_LOG_INFO, "SDL", "JNI: OnLoad");
__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init()");
jclass cls = mEnv->FindClass ("org/libsdl/app/SDLActivity");
mActivityInstance = cls;
......@@ -81,62 +89,41 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved){
midUpdateAudio = mEnv->GetStaticMethodID(cls,"updateAudio","([B)V");
if(!midCreateGLContext || !midFlipBuffers || !midEnableFeature ||
!midUpdateAudio){
!midUpdateAudio) {
__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Bad mids\n");
}else{
} else {
#ifdef DEBUG
__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Good mids\n");
#endif
}
return JNI_VERSION_1_4;
}
//Start up the SDL app
extern "C" void Java_org_libsdl_app_SDLActivity_nativeInit( JNIEnv* env,
jobject obj ){
__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Native Init");
mEnv = env;
bRenderingEnabled = true;
Android_EnableFeature(FEATURE_ACCEL, true);
char *argv[2];
argv[0] = strdup("SDL_app");
argv[1] = NULL;
SDL_main(1, argv);
}
//Keydown
// Keydown
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyDown(JNIEnv* env,
jobject obj, jint keycode){
jobject obj, jint keycode)
{
int r = Android_OnKeyDown(keycode);
#ifdef DEBUG
__android_log_print(ANDROID_LOG_INFO, "SDL",
"SDL: native key down %d, %d\n", keycode, r);
#endif
}
//Keyup
// Keyup
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyUp(JNIEnv* env,
jobject obj, jint keycode){
jobject obj, jint keycode)
{
int r = Android_OnKeyUp(keycode);
#ifdef DEBUG
__android_log_print(ANDROID_LOG_INFO, "SDL",
"SDL: native key up %d, %d\n", keycode, r);
#endif
}
//Touch
// Touch
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeTouch(JNIEnv* env,
jobject obj, jint action, jfloat x, jfloat y, jfloat p){
jobject obj, jint action, jfloat x, jfloat y, jfloat p)
{
#ifdef DEBUG
__android_log_print(ANDROID_LOG_INFO, "SDL",
"SDL: native touch event %d @ %f/%f, pressure %f\n",
......@@ -144,42 +131,40 @@ extern "C" void Java_org_libsdl_app_SDLActivity_onNativeTouch(JNIEnv* env,
#endif
//TODO: Pass this off to the SDL multitouch stuff
}
//Quit
// Quit
extern "C" void Java_org_libsdl_app_SDLActivity_nativeQuit( JNIEnv* env,
jobject obj ){
//Stop rendering as we're no longer in the foreground
jobject obj )
{
// Stop rendering as we're no longer in the foreground
bRenderingEnabled = false;
//Inject a SDL_QUIT event
int r = SDL_SendQuit();
__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Native quit %d", r);
// Inject a SDL_QUIT event
SDL_SendQuit();
}
//Screen size
// Screen size
extern "C" void Java_org_libsdl_app_SDLActivity_nativeSetScreenSize(
JNIEnv* env, jobject obj, jint width, jint height){
JNIEnv* env, jobject obj, jint width, jint height)
{
__android_log_print(ANDROID_LOG_INFO, "SDL",
"SDL: Set screen size on init: %d/%d\n", width, height);
Android_SetScreenResolution(width, height);
}
//Resize
// Resize
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeResize(
JNIEnv* env, jobject obj, jint width,
jint height, jint format){
jint height, jint format)
{
Android_OnResize(width, height, format);
}
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeAccel(
JNIEnv* env, jobject obj,
jfloat x, jfloat y, jfloat z){
jfloat x, jfloat y, jfloat z)
{
fLastAccelerometer[0] = x;
fLastAccelerometer[1] = y;
fLastAccelerometer[2] = z;
......@@ -190,7 +175,8 @@ extern "C" void Java_org_libsdl_app_SDLActivity_onNativeAccel(
/*******************************************************************************
Functions called by SDL into Java
*******************************************************************************/
extern "C" void Android_CreateContext(){
extern "C" void Android_CreateContext()
{
__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: sdl_create_context()\n");
bRenderingEnabled = true;
......@@ -198,30 +184,30 @@ extern "C" void Android_CreateContext(){
mEnv->CallStaticVoidMethod(mActivityInstance, midCreateGLContext );
}
extern "C" void Android_Render(){
if(!bRenderingEnabled){
extern "C" void Android_Render()
{
if (!bRenderingEnabled) {
return;
}
//When we get here, we've accumulated a full frame
mEnv->CallStaticVoidMethod(mActivityInstance, midFlipBuffers );
// When we get here, we've accumulated a full frame
mEnv->CallStaticVoidMethod(mActivityInstance, midFlipBuffers);
}
extern "C" void Android_EnableFeature(int featureid, bool enabled){
extern "C" void Android_EnableFeature(int featureid, bool enabled)
{
mEnv->CallStaticVoidMethod(mActivityInstance, midEnableFeature,
featureid, (int)enabled);
}
extern "C" void Android_UpdateAudioBuffer(unsigned char *buf, int len){
extern "C" void Android_UpdateAudioBuffer(unsigned char *buf, int len)
{
//Annoyingly we can't just call into Java from any thread. Because the audio
//callback is dispatched from the SDL audio thread (that wasn't made from
//java, we have to do some magic here to let the JVM know about the thread.
//Because everything it touches on the Java side is static anyway, it's
//not a big deal, just annoying.
if(!mAudioThreadEnv){
if(!mAudioThreadEnv) {
__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Need to set up audio thread env\n");
mVM->AttachCurrentThread(&mAudioThreadEnv, NULL);
......
/* Include the SDL main definition header */
#include "SDL_main.h"
/*******************************************************************************
Functions called by JNI
*******************************************************************************/
#include <jni.h>
// Called before SDL_main() to initialize JNI bindings in SDL library
extern "C" void SDL_Android_Init(JNIEnv* env);
// Library init
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
return JNI_VERSION_1_4;
}
// Start up the SDL app
extern "C" void Java_org_libsdl_app_SDLActivity_nativeInit( JNIEnv* env, jobject obj )
{
/* This interface could expand with ABI negotiation, calbacks, etc. */
SDL_Android_Init(env);
/* Run the application code! */
char *argv[2];
argv[0] = strdup("SDL_app");
argv[1] = NULL;
SDL_main(1, argv);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment