Search
lxdream.org :: lxdream :: r1245:01e0020adf88
lxdream 0.9.1
released Jun 29
Download Now
changeset1245:01e0020adf88
parent1244:6b54ef5ed413
child1246:887f7b0ac7f3
authornkeynes
dateFri Mar 02 23:49:10 2012 +1000 (12 years ago)
Android WIP:
* Rename gui_jni.c to gui_android.c - now quite android specific.
* Implement generic EGL driver with very minimal Java wrapper
* Run emulation in separate thread, and implement simple queue for
inter-thread communication.
* Add menu/action-bar items for start + reset
Makefile.am
Makefile.in
android/AndroidManifest.xml
android/build.xml
android/gen/org/lxdream/R.java
android/res/drawable/tb_cdrom.png
android/res/drawable/tb_preferences.png
android/res/drawable/tb_reset.png
android/res/drawable/tb_run.png
android/res/menu/main.xml
android/res/values/strings.xml
android/src/org/lxdream/Dreamcast.java
android/src/org/lxdream/LxdreamActivity.java
android/src/org/lxdream/LxdreamView.java
configure
configure.in
m4/android.m4
src/Makefile.am
src/Makefile.in
src/display.c
src/display.h
src/drivers/gl_fbo.c
src/drivers/video_egl.c
src/drivers/video_egl.h
src/gui_android.c
src/gui_jni.c
src/pvr2/glutil.c
src/pvr2/glutil.h
src/tools/Makefile.in
src/tqueue.c
src/tqueue.h
1.1 --- a/Makefile.am Tue Feb 28 18:22:52 2012 +1000
1.2 +++ b/Makefile.am Fri Mar 02 23:49:10 2012 +1000
1.3 @@ -100,7 +100,7 @@
1.4 bundle: all
1.5
1.6 if GUI_ANDROID
1.7 -Lxdream-debug.apk: src/liblxdream.so
1.8 +apk: src/liblxdream.so
1.9 $(mkdir_p) android/libs/armeabi
1.10 $(INSTALL) src/liblxdream.so android/libs/armeabi/liblxdream.so
1.11 $(INSTALL) $(ANDROID_GDBSERVER) android/libs/armeabi/gdbserver
1.12 @@ -109,8 +109,9 @@
1.13 $(ANT) -buildfile build.xml -Dsdk.dir=$(ANDROID_SDK_HOME) \
1.14 -Dout.dir="$$TARGETDIR" \
1.15 -Dnative.libs.dir="$$TARGETDIR/libs" \
1.16 + -Dnative.libs.absolute.dir="$$TARGETDIR/libs" \
1.17 -Dtarget=$(ANDROID_SDK_VERSION) debug )
1.18 cp android/Lxdream-debug.apk Lxdream-debug.apk
1.19
1.20 -all-local: Lxdream-debug.apk
1.21 +all-local: apk
1.22 endif
2.1 --- a/Makefile.in Tue Feb 28 18:22:52 2012 +1000
2.2 +++ b/Makefile.in Fri Mar 02 23:49:10 2012 +1000
2.3 @@ -96,6 +96,7 @@
2.4 AMTAR = @AMTAR@
2.5 ANDROID_GDBSERVER = @ANDROID_GDBSERVER@
2.6 ANDROID_NDK_HOME = @ANDROID_NDK_HOME@
2.7 +ANDROID_NDK_VERSION = @ANDROID_NDK_VERSION@
2.8 ANDROID_SDK_HOME = @ANDROID_SDK_HOME@
2.9 ANDROID_SDK_VERSION = @ANDROID_SDK_VERSION@
2.10 ANT = @ANT@
2.11 @@ -889,7 +890,7 @@
2.12
2.13 bundle: all
2.14
2.15 -@GUI_ANDROID_TRUE@Lxdream-debug.apk: src/liblxdream.so
2.16 +@GUI_ANDROID_TRUE@apk: src/liblxdream.so
2.17 @GUI_ANDROID_TRUE@ $(mkdir_p) android/libs/armeabi
2.18 @GUI_ANDROID_TRUE@ $(INSTALL) src/liblxdream.so android/libs/armeabi/liblxdream.so
2.19 @GUI_ANDROID_TRUE@ $(INSTALL) $(ANDROID_GDBSERVER) android/libs/armeabi/gdbserver
2.20 @@ -898,10 +899,11 @@
2.21 @GUI_ANDROID_TRUE@ $(ANT) -buildfile build.xml -Dsdk.dir=$(ANDROID_SDK_HOME) \
2.22 @GUI_ANDROID_TRUE@ -Dout.dir="$$TARGETDIR" \
2.23 @GUI_ANDROID_TRUE@ -Dnative.libs.dir="$$TARGETDIR/libs" \
2.24 +@GUI_ANDROID_TRUE@ -Dnative.libs.absolute.dir="$$TARGETDIR/libs" \
2.25 @GUI_ANDROID_TRUE@ -Dtarget=$(ANDROID_SDK_VERSION) debug )
2.26 @GUI_ANDROID_TRUE@ cp android/Lxdream-debug.apk Lxdream-debug.apk
2.27
2.28 -@GUI_ANDROID_TRUE@all-local: Lxdream-debug.apk
2.29 +@GUI_ANDROID_TRUE@all-local: apk
2.30 # Tell versions [3.59,3.63) of GNU make to not export all variables.
2.31 # Otherwise a system limit (for SysV at least) may be exceeded.
2.32 .NOEXPORT:
3.1 --- a/android/AndroidManifest.xml Tue Feb 28 18:22:52 2012 +1000
3.2 +++ b/android/AndroidManifest.xml Fri Mar 02 23:49:10 2012 +1000
3.3 @@ -2,8 +2,8 @@
3.4 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.lxdream">
3.5 <application android:label="@string/lxdream_activity">
3.6 <activity android:name="LxdreamActivity"
3.7 - android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
3.8 android:launchMode="singleTask"
3.9 + android:theme="@android:style/Theme.Holo"
3.10 android:configChanges="orientation|keyboardHidden">
3.11 <intent-filter>
3.12 <action android:name="android.intent.action.MAIN" />
3.13 @@ -12,5 +12,5 @@
3.14 </activity>
3.15 </application>
3.16 <uses-feature android:glEsVersion="0x00020000"/>
3.17 - <uses-sdk android:minSdkVersion="8"/>
3.18 + <uses-sdk android:minSdkVersion="11"/>
3.19 </manifest>
4.1 --- a/android/build.xml Tue Feb 28 18:22:52 2012 +1000
4.2 +++ b/android/build.xml Fri Mar 02 23:49:10 2012 +1000
4.3 @@ -1,15 +1,14 @@
4.4 <?xml version="1.0" encoding="UTF-8"?>
4.5 <project name="Lxdream" default="help">
4.6
4.7 -<!-- The local.properties file is created and updated by the 'android'
4.8 - tool.
4.9 - It contains the path to the SDK. It should *NOT* be checked into
4.10 - Version Control Systems. -->
4.11 + <!-- The local.properties file is created and updated by the 'android' tool.
4.12 + It contains the path to the SDK. It should *NOT* be checked into
4.13 + Version Control Systems. -->
4.14 <property file="local.properties" />
4.15
4.16 - <!-- The build.properties file can be created by you and is never touched
4.17 - by the 'android' tool. This is the place to change some of the
4.18 - default property values used by the Ant rules.
4.19 + <!-- The ant.properties file can be created by you. It is only edited by the
4.20 + 'android' tool to add properties to it.
4.21 + This is the place to change some Ant specific build properties.
4.22 Here are some properties you may want to change/update:
4.23
4.24 source.dir
4.25 @@ -17,6 +16,9 @@
4.26 out.dir
4.27 The name of the output directory. Default is 'bin'.
4.28
4.29 + For other overridable properties, look at the beginning of the rules
4.30 + files in the SDK, at tools/ant/build.xml
4.31 +
4.32 Properties related to the SDK location or the project target should
4.33 be updated using the 'android' tool with the 'update' action.
4.34
4.35 @@ -24,17 +26,24 @@
4.36 application and should be checked into Version Control Systems.
4.37
4.38 -->
4.39 - <property file="build.properties" />
4.40 + <property file="ant.properties" />
4.41
4.42 - <!-- The default.properties file is created and updated by the 'android'
4.43 + <!-- The project.properties file is created and updated by the 'android'
4.44 tool, as well as ADT.
4.45 +
4.46 + This contains project specific properties such as project target, and library
4.47 + dependencies. Lower level build properties are stored in ant.properties
4.48 + (or in .classpath for Eclipse projects).
4.49 +
4.50 This file is an integral part of the build system for your
4.51 application and should be checked into Version Control Systems. -->
4.52 - <property file="default.properties" />
4.53 + <loadproperties srcFile="project.properties" />
4.54
4.55 -
4.56 - <!-- Required pre-setup import -->
4.57 - <import file="${sdk.dir}/tools/ant/pre_setup.xml" />
4.58 + <!-- quick check on sdk.dir -->
4.59 + <fail
4.60 + message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var"
4.61 + unless="sdk.dir"
4.62 + />
4.63
4.64
4.65 <!-- extension targets. Uncomment the ones where you want to do custom work
4.66 @@ -45,35 +54,32 @@
4.67 <target name="-pre-compile">
4.68 </target>
4.69
4.70 - [This is typically used for code obfuscation.
4.71 - Compiled code location: ${out.classes.absolute.dir}
4.72 - If this is not done in place, override ${out.dex.input.absolute.dir}]
4.73 + /* This is typically used for code obfuscation.
4.74 + Compiled code location: ${out.classes.absolute.dir}
4.75 + If this is not done in place, override ${out.dex.input.absolute.dir} */
4.76 <target name="-post-compile">
4.77 </target>
4.78 -->
4.79
4.80 - <!-- Execute the Android Setup task that will setup some properties
4.81 - specific to the target, and import the build rules files.
4.82 -
4.83 - The rules file is imported from
4.84 - <SDK>/tools/ant/
4.85 - Depending on the project type it can be either:
4.86 - - main_rules.xml
4.87 - - lib_rules.xml
4.88 - - test_rules.xml
4.89 + <!-- Import the actual build file.
4.90
4.91 To customize existing targets, there are two options:
4.92 - Customize only one target:
4.93 - copy/paste the target into this file, *before* the
4.94 - <setup> task.
4.95 + <import> task.
4.96 - customize it to your needs.
4.97 - - Customize the whole script.
4.98 + - Customize the whole content of build.xml
4.99 - copy/paste the content of the rules files (minus the top node)
4.100 - into this file, *after* the <setup> task
4.101 - - disable the import of the rules by changing the setup task
4.102 - below to <setup import="false" />.
4.103 + into this file, replacing the <import> task.
4.104 - customize to your needs.
4.105 +
4.106 + ***********************
4.107 + ****** IMPORTANT ******
4.108 + ***********************
4.109 + In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
4.110 + in order to avoid having your file be overridden by tools such as "android update project"
4.111 -->
4.112 - <setup />
4.113 + <!-- version-tag: 1 -->
4.114 + <import file="${sdk.dir}/tools/ant/build.xml" />
4.115
4.116 </project>
5.1 --- a/android/gen/org/lxdream/R.java Tue Feb 28 18:22:52 2012 +1000
5.2 +++ b/android/gen/org/lxdream/R.java Fri Mar 02 23:49:10 2012 +1000
5.3 @@ -10,7 +10,24 @@
5.4 public final class R {
5.5 public static final class attr {
5.6 }
5.7 + public static final class drawable {
5.8 + public static final int tb_cdrom=0x7f020000;
5.9 + public static final int tb_preferences=0x7f020001;
5.10 + public static final int tb_reset=0x7f020002;
5.11 + public static final int tb_run=0x7f020003;
5.12 + }
5.13 + public static final class id {
5.14 + public static final int menu_reset=0x7f050001;
5.15 + public static final int menu_run=0x7f050000;
5.16 + public static final int menu_settings=0x7f050002;
5.17 + }
5.18 + public static final class menu {
5.19 + public static final int main=0x7f040000;
5.20 + }
5.21 public static final class string {
5.22 - public static final int lxdream_activity=0x7f020000;
5.23 + public static final int lxdream_activity=0x7f030000;
5.24 + public static final int menu_preferences=0x7f030003;
5.25 + public static final int menu_reset=0x7f030002;
5.26 + public static final int menu_run=0x7f030001;
5.27 }
5.28 }
6.1 Binary file android/res/drawable/tb_cdrom.png has changed
7.1 Binary file android/res/drawable/tb_preferences.png has changed
8.1 Binary file android/res/drawable/tb_reset.png has changed
9.1 Binary file android/res/drawable/tb_run.png has changed
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/android/res/menu/main.xml Fri Mar 02 23:49:10 2012 +1000
10.3 @@ -0,0 +1,17 @@
10.4 +<menu xmlns:android="http://schemas.android.com/apk/res/android">
10.5 + <item android:id="@+id/menu_run"
10.6 + android:icon="@drawable/tb_run"
10.7 + android:onClick="onRunClicked"
10.8 + android:title="@string/menu_run"
10.9 + android:showAsAction="always" />
10.10 + <item android:id="@+id/menu_reset"
10.11 + android:icon="@drawable/tb_reset"
10.12 + android:onClick="onResetClicked"
10.13 + android:title="@string/menu_reset"
10.14 + android:showAsAction="always" />
10.15 + <item android:id="@+id/menu_settings"
10.16 + android:icon="@drawable/tb_preferences"
10.17 + android:onClick="onPreferencesClicked"
10.18 + android:title="@string/menu_preferences"
10.19 + android:showAsAction="never" />
10.20 +</menu>
11.1 --- a/android/res/values/strings.xml Tue Feb 28 18:22:52 2012 +1000
11.2 +++ b/android/res/values/strings.xml Fri Mar 02 23:49:10 2012 +1000
11.3 @@ -1,4 +1,7 @@
11.4 <?xml version="1.0" encoding="utf-8"?>
11.5 <resources>
11.6 <string name="lxdream_activity">Lxdream</string>
11.7 + <string name="menu_run">Run</string>
11.8 + <string name="menu_reset">Reset</string>
11.9 + <string name="menu_preferences">Preferences</string>
11.10 </resources>
12.1 --- a/android/src/org/lxdream/Dreamcast.java Tue Feb 28 18:22:52 2012 +1000
12.2 +++ b/android/src/org/lxdream/Dreamcast.java Fri Mar 02 23:49:10 2012 +1000
12.3 @@ -26,14 +26,18 @@
12.4
12.5 /* Core emulation */
12.6 public static native void init( String appHome );
12.7 - public static native void setViewSize(int width, int height);
12.8 public static native void run();
12.9 public static native void stop();
12.10 - /*
12.11 - public static native void start();
12.12 - public static native void run_slice();
12.13 - public static boolean canRun();
12.14 -*/
12.15 + public static native void reset();
12.16 + public static native void toggleRun();
12.17 + public static native boolean isRunnable();
12.18 + public static native boolean isRunning();
12.19 +
12.20 + /* GD-Rom */
12.21 + public static native boolean mount( String filename );
12.22 + public static native void unmount();
12.23 +
12.24 +
12.25 /* Save state management */
12.26 /* public static native boolean saveState( String filename );
12.27 public static native boolean loadState( String filename );
12.28 @@ -41,9 +45,4 @@
12.29 public static native boolean quickLoad();
12.30 public static native void setQuickState(int state);
12.31 */
12.32 - /* GD-Rom */
12.33 -/* public static native boolean mount_disc( String filename );
12.34 - public static native void unmount_disc();
12.35 - */
12.36 - /* ... */
12.37 }
13.1 --- a/android/src/org/lxdream/LxdreamActivity.java Tue Feb 28 18:22:52 2012 +1000
13.2 +++ b/android/src/org/lxdream/LxdreamActivity.java Fri Mar 02 23:49:10 2012 +1000
13.3 @@ -22,6 +22,9 @@
13.4 import android.content.Context;
13.5 import android.os.Bundle;
13.6 import android.util.Log;
13.7 +import android.view.Menu;
13.8 +import android.view.MenuInflater;
13.9 +import android.view.MenuItem;
13.10 import android.view.WindowManager;
13.11
13.12 import java.io.File;
13.13 @@ -34,20 +37,42 @@
13.14 protected void onCreate(Bundle bundle) {
13.15 super.onCreate(bundle);
13.16 Context ctx = getApplication();
13.17 +
13.18 + Log.i("LxdreamActivity", "Calling Dreamcast.init");
13.19 Dreamcast.init( ctx.getFilesDir().toString() );
13.20 + Log.i("LxdreamActivity", "Finished Dreamcast.init");
13.21 view = new LxdreamView(ctx);
13.22 setContentView(view);
13.23 }
13.24 +
13.25 + @Override
13.26 + public boolean onCreateOptionsMenu(Menu menu) {
13.27 + MenuInflater inflater = getMenuInflater();
13.28 + inflater.inflate(R.menu.main, menu);
13.29 + return true;
13.30 + }
13.31 +
13.32
13.33 @Override
13.34 protected void onPause() {
13.35 super.onPause();
13.36 - view.onPause();
13.37 + Dreamcast.stop();
13.38 }
13.39
13.40 @Override
13.41 protected void onResume() {
13.42 super.onResume();
13.43 - view.onResume();
13.44 + }
13.45 +
13.46 + public void onRunClicked( MenuItem item ) {
13.47 + Dreamcast.toggleRun();
13.48 + }
13.49 +
13.50 + public void onResetClicked( MenuItem item ) {
13.51 + Dreamcast.reset();
13.52 + }
13.53 +
13.54 + public void onPreferencesClicked( MenuItem item ) {
13.55 + /* TODO */
13.56 }
13.57 }
14.1 --- a/android/src/org/lxdream/LxdreamView.java Tue Feb 28 18:22:52 2012 +1000
14.2 +++ b/android/src/org/lxdream/LxdreamView.java Fri Mar 02 23:49:10 2012 +1000
14.3 @@ -36,114 +36,39 @@
14.4
14.5 import android.content.Context;
14.6 import android.graphics.PixelFormat;
14.7 -import android.opengl.GLSurfaceView;
14.8 import android.util.AttributeSet;
14.9 import android.util.Log;
14.10 import android.view.KeyEvent;
14.11 import android.view.MotionEvent;
14.12 +import android.view.Surface;
14.13 +import android.view.SurfaceHolder;
14.14 +import android.view.SurfaceView;
14.15
14.16 -import javax.microedition.khronos.egl.EGL10;
14.17 -import javax.microedition.khronos.egl.EGLConfig;
14.18 -import javax.microedition.khronos.egl.EGLContext;
14.19 -import javax.microedition.khronos.egl.EGLDisplay;
14.20 -import javax.microedition.khronos.opengles.GL10;
14.21 -
14.22 -/**
14.23 - * A simple GLSurfaceView sub-class that demonstrate how to perform
14.24 - * OpenGL ES 2.0 rendering into a GL Surface. Note the following important
14.25 - * details:
14.26 - *
14.27 - * - The class must use a custom context factory to enable 2.0 rendering.
14.28 - * See ContextFactory class definition below.
14.29 - *
14.30 - * - The class must use a custom EGLConfigChooser to be able to select
14.31 - * an EGLConfig that supports 2.0. This is done by providing a config
14.32 - * specification to eglChooseConfig() that has the attribute
14.33 - * EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag
14.34 - * set. See ConfigChooser class definition below.
14.35 - *
14.36 - * - The class must select the surface's format, then choose an EGLConfig
14.37 - * that matches it exactly (with regards to red/green/blue/alpha channels
14.38 - * bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
14.39 - */
14.40 -class LxdreamView extends GLSurfaceView {
14.41 +class LxdreamView extends SurfaceView implements SurfaceHolder.Callback {
14.42 private static String TAG = "LxdreamView";
14.43 private static final boolean DEBUG = false;
14.44
14.45 public LxdreamView(Context context) {
14.46 super(context);
14.47 - init(false, 0, 0);
14.48 + getHolder().addCallback(this);
14.49 }
14.50
14.51 - public LxdreamView(Context context, boolean translucent, int depth, int stencil) {
14.52 - super(context);
14.53 - init(translucent, depth, stencil);
14.54 + @Override
14.55 + public void surfaceCreated( SurfaceHolder holder ) {
14.56 + /* Ignore */
14.57 }
14.58 -
14.59 - private void init(boolean translucent, int depth, int stencil) {
14.60 -
14.61 - /* By default, GLSurfaceView() creates a RGB_565 opaque surface.
14.62 - * If we want a translucent one, we should change the surface's
14.63 - * format here, using PixelFormat.TRANSLUCENT for GL Surfaces
14.64 - * is interpreted as any 32-bit surface with alpha by SurfaceFlinger.
14.65 - */
14.66 - if (translucent) {
14.67 - this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
14.68 - }
14.69 -
14.70 - /* Setup the context factory for 2.0 rendering.
14.71 - * See ContextFactory class definition below
14.72 - */
14.73 - setEGLContextFactory(new ContextFactory());
14.74 -
14.75 - /* We need to choose an EGLConfig that matches the format of
14.76 - * our surface exactly. This is going to be done in our
14.77 - * custom config chooser. See ConfigChooser class definition
14.78 - * below.
14.79 - */
14.80 - setEGLConfigChooser( translucent ?
14.81 - new ConfigChooser(8, 8, 8, 8, depth, stencil) :
14.82 - new ConfigChooser(5, 6, 5, 0, depth, stencil) );
14.83 -
14.84 - /* Set the renderer responsible for frame rendering */
14.85 - setRenderer(new Renderer());
14.86 +
14.87 + @Override
14.88 + public void surfaceChanged( SurfaceHolder holder, int format, int width, int height ) {
14.89 + setSurface( holder.getSurface(), width, height );
14.90 }
14.91 -
14.92 - private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
14.93 - private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
14.94 - public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
14.95 - Log.w(TAG, "creating OpenGL ES 2.0 context");
14.96 - checkEglError("Before eglCreateContext", egl);
14.97 - int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
14.98 - EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
14.99 - checkEglError("After eglCreateContext", egl);
14.100 - return context;
14.101 - }
14.102 -
14.103 - public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
14.104 - egl.eglDestroyContext(display, context);
14.105 - }
14.106 +
14.107 + @Override
14.108 + public void surfaceDestroyed( SurfaceHolder holder ) {
14.109 + clearSurface( holder.getSurface() );
14.110 }
14.111 -
14.112 - private static void checkEglError(String prompt, EGL10 egl) {
14.113 - int error;
14.114 - while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
14.115 - Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
14.116 - }
14.117 - }
14.118 -
14.119 -
14.120 - private static class Renderer implements GLSurfaceView.Renderer {
14.121 - public void onDrawFrame(GL10 gl) {
14.122 - Dreamcast.run();
14.123 - }
14.124 -
14.125 - public void onSurfaceChanged(GL10 gl, int width, int height) {
14.126 - Dreamcast.setViewSize(width,height);
14.127 - }
14.128 -
14.129 - public void onSurfaceCreated(GL10 gl, EGLConfig config) {
14.130 - // Do nothing.
14.131 - }
14.132 - }
14.133 +
14.134 + private native void setSurface( Surface surface, int width, int height );
14.135 + private native void clearSurface( Surface surface );
14.136 +
14.137 }
15.1 --- a/configure Tue Feb 28 18:22:52 2012 +1000
15.2 +++ b/configure Fri Mar 02 23:49:10 2012 +1000
15.3 @@ -686,6 +686,7 @@
15.4 ANDROID_SDK_HOME
15.5 ANDROID_NDK_HOME
15.6 ANDROID_SDK_VERSION
15.7 +ANDROID_NDK_VERSION
15.8 ANDROID_GDBSERVER
15.9 GUI_ANDROID_TRUE
15.10 GUI_ANDROID_FALSE
15.11 @@ -1465,6 +1466,7 @@
15.12 --with-android=SDK Specify the location of the Android SDK
15.13 --with-android-ndk=NDK Specify the location of the Android NDK
15.14 --with-android-version Specify target Android SDK version
15.15 + --with-android-version Specify target Android NDK version
15.16 --with-osmesa Build with the osmesa GL library (software
15.17 rendering)
15.18 --with-gtk Build with the GTK UI. Default on X11 systems
15.19 @@ -2543,7 +2545,15 @@
15.20 if test "${with_android_version+set}" = set; then
15.21 withval=$with_android_version;
15.22 else
15.23 - with_android_version="android-8"
15.24 + with_android_version="android-11"
15.25 +fi
15.26 +
15.27 +
15.28 +# Check whether --with-android-ndk-version was given.
15.29 +if test "${with_android_ndk_version+set}" = set; then
15.30 + withval=$with_android_ndk_version;
15.31 +else
15.32 + with_ndk_version="android-9"
15.33 fi
15.34
15.35
15.36 @@ -2562,6 +2572,7 @@
15.37 ANDROID_SDK_HOME="$with_android"
15.38 ANDROID_NDK_HOME="$with_android_ndk"
15.39 ANDROID_SDK_VERSION="$with_android_version"
15.40 + ANDROID_NDK_VERSION="$with_ndk_version"
15.41
15.42 as_ac_File=`echo "ac_cv_file_$ANDROID_SDK_HOME/tools/ant/pre_setup.xml" | $as_tr_sh`
15.43 { echo "$as_me:$LINENO: checking for $ANDROID_SDK_HOME/tools/ant/pre_setup.xml" >&5
15.44 @@ -2653,7 +2664,7 @@
15.45 host_os="linux-androideabi"
15.46 ANDROID_NDK_BIN=`echo $ANDROID_NDK_HOME/toolchains/arm-*/prebuilt/*/bin`
15.47 ANDROID_GDBSERVER=`echo $ANDROID_NDK_HOME/toolchains/arm-*/prebuilt/gdbserver`
15.48 - ANDROID_SYSROOT="$ANDROID_NDK_HOME/platforms/$ANDROID_SDK_VERSION/arch-arm"
15.49 + ANDROID_SYSROOT="$ANDROID_NDK_HOME/platforms/$ANDROID_NDK_VERSION/arch-arm"
15.50 TARGETFLAGS="-ffunction-sections -funwind-tables -fstack-protector -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -DANDROID -Wno-psabi -Wa,--noexecstack"
15.51 TARGETFLAGS="$TARGETFLAGS -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -march=armv5te -mtune=xscale -msoft-float -mthumb -Os"
15.52 ;;
15.53 @@ -2664,7 +2675,7 @@
15.54 host_os="linux"
15.55 ANDROID_NDK_BIN=`echo $ANDROID_NDK_HOME/toolchains/x86-*/prebuilt/*/bin`
15.56 ANDROID_GDBSERVER=`echo $ANDROID_NDK_HOME/toolchains/x86-*/prebuilt/gdbserver`
15.57 - ANDROID_SYSROOT="$ANDROID_NDK_HOME/platforms/$ANDROID_SDK_VERSION/arch-x86"
15.58 + ANDROID_SYSROOT="$ANDROID_NDK_HOME/platforms/$ANDROID_NDK_VERSION/arch-x86"
15.59 TARGETFLAGS=""
15.60 ;;
15.61 *)
15.62 @@ -2725,7 +2736,8 @@
15.63 OBJDUMP="$ANDROID_NDK_BIN/${host_alias}-objdump"
15.64 CPPFLAGS="-fPIC --sysroot=$ANDROID_SYSROOT -I$ANDROID_SYSROOT/usr/include $TARGETFLAGS $CPPFLAGS"
15.65 LDFLAGS="-nostdlib -Wl,--no-undefined -L${ANDROID_SYSROOT}/usr/lib -Wl,-rpath-link,${ANDROID_SYSROOT}/usr/lib -Wl,-allow-shlib-undefined -Wl,-z,noexecstack $LDFLAGS"
15.66 - LIBS="$LIBS -liconv -llog -lgcc -lc"
15.67 + LIBS="$LIBS -liconv -landroid -llog -lgcc -lc -lm"
15.68 +
15.69
15.70
15.71
15.72 @@ -8966,16 +8978,16 @@
15.73
15.74
15.75
15.76 -
15.77 if test "$ANDROID_BUILD" = "yes"; then
15.78 with_gtk=no;
15.79 EXTRA_OUTPUT_FILES="src/android/build.properties"
15.80 - LIBS="-lGLESv2 $LIBS"
15.81 + LIBS="-lEGL -lGLESv2 $LIBS"
15.82
15.83 cat >>confdefs.h <<\_ACEOF
15.84 #define HAVE_GLES2 1
15.85 _ACEOF
15.86
15.87 + UI_DRIVER="Android"
15.88 with_sdl=no
15.89 else
15.90
15.91 @@ -9442,6 +9454,7 @@
15.92 #define APPLE_BUILD 1
15.93 _ACEOF
15.94
15.95 + UI_DRIVER="Cocoa"
15.96 if test "x$with_gtk" = "xx11"; then
15.97 with_gtk=no
15.98 fi
15.99 @@ -11020,6 +11033,7 @@
15.100 #define HAVE_GTK 1
15.101 _ACEOF
15.102
15.103 + UI_DRIVER="GTK"
15.104
15.105 fi
15.106
15.107 @@ -16749,6 +16763,7 @@
15.108 ANDROID_SDK_HOME!$ANDROID_SDK_HOME$ac_delim
15.109 ANDROID_NDK_HOME!$ANDROID_NDK_HOME$ac_delim
15.110 ANDROID_SDK_VERSION!$ANDROID_SDK_VERSION$ac_delim
15.111 +ANDROID_NDK_VERSION!$ANDROID_NDK_VERSION$ac_delim
15.112 ANDROID_GDBSERVER!$ANDROID_GDBSERVER$ac_delim
15.113 GUI_ANDROID_TRUE!$GUI_ANDROID_TRUE$ac_delim
15.114 GUI_ANDROID_FALSE!$GUI_ANDROID_FALSE$ac_delim
15.115 @@ -16772,7 +16787,6 @@
15.116 CC!$CC$ac_delim
15.117 CFLAGS!$CFLAGS$ac_delim
15.118 CPPFLAGS!$CPPFLAGS$ac_delim
15.119 -CC_FOR_BUILD!$CC_FOR_BUILD$ac_delim
15.120 _ACEOF
15.121
15.122 if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
15.123 @@ -16814,6 +16828,7 @@
15.124 ac_delim='%!_!# '
15.125 for ac_last_try in false false false false false :; do
15.126 cat >conf$$subs.sed <<_ACEOF
15.127 +CC_FOR_BUILD!$CC_FOR_BUILD$ac_delim
15.128 ac_ct_CC_FOR_BUILD!$ac_ct_CC_FOR_BUILD$ac_delim
15.129 CC_FOR_BUILDDEPMODE!$CC_FOR_BUILDDEPMODE$ac_delim
15.130 am__fastdepCC_FOR_BUILD_TRUE!$am__fastdepCC_FOR_BUILD_TRUE$ac_delim
15.131 @@ -16910,7 +16925,6 @@
15.132 BUILD_ARMTEST_TRUE!$BUILD_ARMTEST_TRUE$ac_delim
15.133 BUILD_ARMTEST_FALSE!$BUILD_ARMTEST_FALSE$ac_delim
15.134 LXDREAM_LIBS!$LXDREAM_LIBS$ac_delim
15.135 -GETTEXT_PACKAGE!$GETTEXT_PACKAGE$ac_delim
15.136 _ACEOF
15.137
15.138 if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
15.139 @@ -16952,6 +16966,7 @@
15.140 ac_delim='%!_!# '
15.141 for ac_last_try in false false false false false :; do
15.142 cat >conf$$subs.sed <<_ACEOF
15.143 +GETTEXT_PACKAGE!$GETTEXT_PACKAGE$ac_delim
15.144 USE_NLS!$USE_NLS$ac_delim
15.145 MSGFMT!$MSGFMT$ac_delim
15.146 MSGFMT_OPTS!$MSGFMT_OPTS$ac_delim
15.147 @@ -16972,7 +16987,7 @@
15.148 LTLIBOBJS!$LTLIBOBJS$ac_delim
15.149 _ACEOF
15.150
15.151 - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 18; then
15.152 + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 19; then
15.153 break
15.154 elif $ac_last_try; then
15.155 { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
15.156 @@ -17613,18 +17628,14 @@
15.157 echo "Configuration complete"
15.158 echo
15.159
15.160 -if test "x$HAVE_GTK" = x; then
15.161 - if test "x$HAVE_COCOA" = x; then
15.162 - echo " User interface: none"
15.163 - else
15.164 - echo " User interface: Cocoa"
15.165 - fi
15.166 -else
15.167 - echo " User interface: GTK"
15.168 +if test "x$UI_DRIVER" = x; then
15.169 + echo " User interface: none"
15.170 +else
15.171 + echo " User interface: $UI_DRIVER"
15.172 fi
15.173
15.174 if test "x$SH4_TRANSLATOR" = "x"; then
15.175 - echo " SH4 translator: None (emulation core only)"
15.176 + echo " SH4 translator: none (emulation core only)"
15.177 else
15.178 echo " SH4 translator: $SH4_TRANSLATOR"
15.179 fi
16.1 --- a/configure.in Tue Feb 28 18:22:52 2012 +1000
16.2 +++ b/configure.in Fri Mar 02 23:49:10 2012 +1000
16.3 @@ -79,15 +79,15 @@
16.4 AC_ARG_WITH( sdl,
16.5 AS_HELP_STRING( [--with-sdl], [Build with support for SDL audio]) )
16.6
16.7 -
16.8 -dnl ------------ Check if we're building on Darwin --------------
16.9 +dnl ------------ Check if we're building on Darwin or Android --------------
16.10
16.11 dnl For starters, do we have a working objective-c compiler?
16.12 if test "$ANDROID_BUILD" = "yes"; then
16.13 with_gtk=no;
16.14 EXTRA_OUTPUT_FILES="src/android/build.properties"
16.15 - LIBS="-lGLESv2 $LIBS"
16.16 + LIBS="-lEGL -lGLESv2 $LIBS"
16.17 AC_DEFINE(HAVE_GLES2, 1, [Using GLESv2])
16.18 + UI_DRIVER="Android"
16.19 with_sdl=no
16.20 else
16.21 AC_HAVE_OBJC([
16.22 @@ -100,6 +100,7 @@
16.23 LDFLAGS="$LDFLAGS -Wl,-headerpad_max_install_names"
16.24 AC_DEFINE(HAVE_COCOA,[1],[Have Cocoa framework])
16.25 AC_DEFINE(APPLE_BUILD,[1],[Building on an apple platform. Things are different...])
16.26 + UI_DRIVER="Cocoa"
16.27 if test "x$with_gtk" = "xx11"; then
16.28 with_gtk=no
16.29 fi
16.30 @@ -230,6 +231,7 @@
16.31 PKG_CHECK_MODULES(GTK, gtk+-2.0, [
16.32 HAVE_GTK='yes'
16.33 AC_DEFINE([HAVE_GTK],1,[Have GTK libraries])
16.34 + UI_DRIVER="GTK"
16.35 ])
16.36
16.37 dnl Which GTK port do we have?
16.38 @@ -485,18 +487,14 @@
16.39 echo "Configuration complete"
16.40 echo
16.41
16.42 -if test "x$HAVE_GTK" = x; then
16.43 - if test "x$HAVE_COCOA" = x; then
16.44 - echo " User interface: none"
16.45 - else
16.46 - echo " User interface: Cocoa"
16.47 - fi
16.48 +if test "x$UI_DRIVER" = x; then
16.49 + echo " User interface: none"
16.50 else
16.51 - echo " User interface: GTK"
16.52 + echo " User interface: $UI_DRIVER"
16.53 fi
16.54
16.55 if test "x$SH4_TRANSLATOR" = "x"; then
16.56 - echo " SH4 translator: None (emulation core only)"
16.57 + echo " SH4 translator: none (emulation core only)"
16.58 else
16.59 echo " SH4 translator: $SH4_TRANSLATOR"
16.60 fi
17.1 --- a/m4/android.m4 Tue Feb 28 18:22:52 2012 +1000
17.2 +++ b/m4/android.m4 Fri Mar 02 23:49:10 2012 +1000
17.3 @@ -6,7 +6,8 @@
17.4 AC_REQUIRE([AC_CANONICAL_HOST])
17.5 AC_ARG_WITH( android, AS_HELP_STRING( [--with-android=SDK], [Specify the location of the Android SDK] ) )
17.6 AC_ARG_WITH( android-ndk, AS_HELP_STRING( [--with-android-ndk=NDK], [Specify the location of the Android NDK] ) )
17.7 - AC_ARG_WITH( android-version, AS_HELP_STRING( [--with-android-version], [Specify target Android SDK version]), [], [with_android_version="android-8"] )
17.8 + AC_ARG_WITH( android-version, AS_HELP_STRING( [--with-android-version], [Specify target Android SDK version]), [], [with_android_version="android-11"] )
17.9 + AC_ARG_WITH( android-ndk-version, AS_HELP_STRING( [--with-android-version], [Specify target Android NDK version]), [], [with_ndk_version="android-9"] )
17.10
17.11 if test "x$with_android" != "x"; then
17.12 if test "$with_android" = "yes"; then
17.13 @@ -19,6 +20,7 @@
17.14 ANDROID_SDK_HOME="$with_android"
17.15 ANDROID_NDK_HOME="$with_android_ndk"
17.16 ANDROID_SDK_VERSION="$with_android_version"
17.17 + ANDROID_NDK_VERSION="$with_ndk_version"
17.18
17.19 AC_CHECK_FILE( [$ANDROID_SDK_HOME/tools/ant/pre_setup.xml], [], [ AC_MSG_ERROR([Android SDK not found in $ANDROID_SDK_HOME]) ])
17.20 AC_CHECK_FILE( [$ANDROID_SDK_HOME/platforms/$ANDROID_SDK_VERSION/sdk.properties], [], [ AC_MSG_ERROR([Android platform version $ANDROID_SDK_VERSION not found in $ANDROID_SDK_HOME]) ])
17.21 @@ -32,7 +34,7 @@
17.22 host_os="linux-androideabi"
17.23 ANDROID_NDK_BIN=`echo $ANDROID_NDK_HOME/toolchains/arm-*/prebuilt/*/bin`
17.24 ANDROID_GDBSERVER=`echo $ANDROID_NDK_HOME/toolchains/arm-*/prebuilt/gdbserver`
17.25 - ANDROID_SYSROOT="$ANDROID_NDK_HOME/platforms/$ANDROID_SDK_VERSION/arch-arm"
17.26 + ANDROID_SYSROOT="$ANDROID_NDK_HOME/platforms/$ANDROID_NDK_VERSION/arch-arm"
17.27 TARGETFLAGS="-ffunction-sections -funwind-tables -fstack-protector -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -DANDROID -Wno-psabi -Wa,--noexecstack"
17.28 TARGETFLAGS="$TARGETFLAGS -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -march=armv5te -mtune=xscale -msoft-float -mthumb -Os"
17.29 ;;
17.30 @@ -43,7 +45,7 @@
17.31 host_os="linux"
17.32 ANDROID_NDK_BIN=`echo $ANDROID_NDK_HOME/toolchains/x86-*/prebuilt/*/bin`
17.33 ANDROID_GDBSERVER=`echo $ANDROID_NDK_HOME/toolchains/x86-*/prebuilt/gdbserver`
17.34 - ANDROID_SYSROOT="$ANDROID_NDK_HOME/platforms/$ANDROID_SDK_VERSION/arch-x86"
17.35 + ANDROID_SYSROOT="$ANDROID_NDK_HOME/platforms/$ANDROID_NDK_VERSION/arch-x86"
17.36 TARGETFLAGS=""
17.37 ;;
17.38 *)
17.39 @@ -63,11 +65,12 @@
17.40 OBJDUMP="$ANDROID_NDK_BIN/${host_alias}-objdump"
17.41 CPPFLAGS="-fPIC --sysroot=$ANDROID_SYSROOT -I$ANDROID_SYSROOT/usr/include $TARGETFLAGS $CPPFLAGS"
17.42 LDFLAGS="-nostdlib -Wl,--no-undefined -L${ANDROID_SYSROOT}/usr/lib -Wl,-rpath-link,${ANDROID_SYSROOT}/usr/lib -Wl,-allow-shlib-undefined -Wl,-z,noexecstack $LDFLAGS"
17.43 - LIBS="$LIBS -liconv -llog -lgcc -lc"
17.44 + LIBS="$LIBS -liconv -landroid -llog -lgcc -lc -lm"
17.45
17.46 AC_SUBST(ANDROID_SDK_HOME)
17.47 AC_SUBST(ANDROID_NDK_HOME)
17.48 AC_SUBST(ANDROID_SDK_VERSION)
17.49 + AC_SUBST(ANDROID_NDK_VERSION)
17.50 AC_SUBST(ANDROID_GDBSERVER)
17.51
17.52 ANDROID_BUILD=yes
18.1 --- a/src/Makefile.am Tue Feb 28 18:22:52 2012 +1000
18.2 +++ b/src/Makefile.am Fri Mar 02 23:49:10 2012 +1000
18.3 @@ -111,11 +111,11 @@
18.4 endif
18.5
18.6 if GUI_ANDROID
18.7 -lxdream_SOURCES += gui_none.c
18.8 +lxdream_SOURCES += gui_none.c drivers/video_egl.c drivers/video_egl.h
18.9 noinst_PROGRAMS=liblxdream.so
18.10 liblxdream_so_LINK = $(LINK) -Wl,-soname,liblxdream.so -shared
18.11 liblxdream_so_LDADD = liblxdream-core.a @GLIB_LIBS@ @GTK_LIBS@ @LIBPNG_LIBS@ @LIBISOFS_LIBS@ $(INTLLIBS) @LXDREAM_LIBS@ -lm
18.12 -liblxdream_so_SOURCES = gui_jni.c drivers/cdrom/cd_none.c
18.13 +liblxdream_so_SOURCES = gui_android.c drivers/cdrom/cd_none.c drivers/video_egl.c drivers/video_egl.h tqueue.c tqueue.h
18.14 liblxdream_so_LIBS = liblxdream-core.a
18.15 endif
18.16
19.1 --- a/src/Makefile.in Tue Feb 28 18:22:52 2012 +1000
19.2 +++ b/src/Makefile.in Fri Mar 02 23:49:10 2012 +1000
19.3 @@ -58,7 +58,7 @@
19.4 @GUI_GTK_TRUE@ gtkui/gtk_ctrl.c gtkui/gtk_gd.c \
19.5 @GUI_GTK_TRUE@ drivers/video_gtk.c
19.6
19.7 -@GUI_ANDROID_TRUE@am__append_5 = gui_none.c
19.8 +@GUI_ANDROID_TRUE@am__append_5 = gui_none.c drivers/video_egl.c drivers/video_egl.h
19.9 @GUI_ANDROID_TRUE@noinst_PROGRAMS = liblxdream.so$(EXEEXT)
19.10 @GUI_COCOA_TRUE@am__append_6 = cocoaui/paths_osx.m drivers/io_osx.m drivers/mac_keymap.h drivers/mac_keymap.txt
19.11 @GUI_COCOA_TRUE@am__append_7 = cocoaui/cocoaui.m cocoaui/cocoaui.h cocoaui/cocoa_cfg.m \
19.12 @@ -216,9 +216,11 @@
19.13 input_lirc_@SOEXT@_OBJECTS = $(am_input_lirc_@SOEXT@_OBJECTS)
19.14 @BUILD_PLUGINS_TRUE@@INPUT_LIRC_TRUE@input_lirc_@SOEXT@_DEPENDENCIES = \
19.15 @BUILD_PLUGINS_TRUE@@INPUT_LIRC_TRUE@ input_lirc.lo
19.16 -am__liblxdream_so_SOURCES_DIST = gui_jni.c drivers/cdrom/cd_none.c
19.17 -@GUI_ANDROID_TRUE@am_liblxdream_so_OBJECTS = gui_jni.$(OBJEXT) \
19.18 -@GUI_ANDROID_TRUE@ cd_none.$(OBJEXT)
19.19 +am__liblxdream_so_SOURCES_DIST = gui_android.c drivers/cdrom/cd_none.c \
19.20 + drivers/video_egl.c drivers/video_egl.h tqueue.c tqueue.h
19.21 +@GUI_ANDROID_TRUE@am_liblxdream_so_OBJECTS = gui_android.$(OBJEXT) \
19.22 +@GUI_ANDROID_TRUE@ cd_none.$(OBJEXT) video_egl.$(OBJEXT) \
19.23 +@GUI_ANDROID_TRUE@ tqueue.$(OBJEXT)
19.24 liblxdream_so_OBJECTS = $(am_liblxdream_so_OBJECTS)
19.25 am__DEPENDENCIES_1 =
19.26 @GUI_ANDROID_TRUE@liblxdream_so_DEPENDENCIES = liblxdream-core.a \
19.27 @@ -227,14 +229,15 @@
19.28 gtkui/gtkui.h gtkui/gtk_win.c gtkui/gtkcb.c gtkui/gtk_cfg.c \
19.29 gtkui/gtk_mmio.c gtkui/gtk_debug.c gtkui/gtk_dump.c \
19.30 gtkui/gtk_ctrl.c gtkui/gtk_gd.c drivers/video_gtk.c gui_none.c \
19.31 - cocoaui/cocoaui.m cocoaui/cocoaui.h cocoaui/cocoa_cfg.m \
19.32 - cocoaui/cocoa_win.m cocoaui/cocoa_gd.m cocoaui/cocoa_prefs.m \
19.33 - cocoaui/cocoa_ctrl.m drivers/video_osx.m drivers/video_gdk.c \
19.34 - drivers/video_glx.c drivers/video_glx.h drivers/video_nsgl.m \
19.35 - drivers/video_nsgl.h drivers/audio_osx.m drivers/audio_sdl.c \
19.36 - drivers/audio_pulse.c drivers/audio_esd.c drivers/audio_alsa.c \
19.37 - drivers/input_lirc.c drivers/cdrom/cd_linux.c \
19.38 - drivers/cdrom/cd_osx.c drivers/osx_iokit.m drivers/osx_iokit.h \
19.39 + drivers/video_egl.c drivers/video_egl.h cocoaui/cocoaui.m \
19.40 + cocoaui/cocoaui.h cocoaui/cocoa_cfg.m cocoaui/cocoa_win.m \
19.41 + cocoaui/cocoa_gd.m cocoaui/cocoa_prefs.m cocoaui/cocoa_ctrl.m \
19.42 + drivers/video_osx.m drivers/video_gdk.c drivers/video_glx.c \
19.43 + drivers/video_glx.h drivers/video_nsgl.m drivers/video_nsgl.h \
19.44 + drivers/audio_osx.m drivers/audio_sdl.c drivers/audio_pulse.c \
19.45 + drivers/audio_esd.c drivers/audio_alsa.c drivers/input_lirc.c \
19.46 + drivers/cdrom/cd_linux.c drivers/cdrom/cd_osx.c \
19.47 + drivers/osx_iokit.m drivers/osx_iokit.h \
19.48 drivers/cdrom/cd_none.c drivers/joy_linux.c \
19.49 drivers/joy_linux.h
19.50 @BUILD_PLUGINS_TRUE@am__objects_4 = plugin.$(OBJEXT)
19.51 @@ -243,7 +246,8 @@
19.52 @GUI_GTK_TRUE@ gtk_mmio.$(OBJEXT) gtk_debug.$(OBJEXT) \
19.53 @GUI_GTK_TRUE@ gtk_dump.$(OBJEXT) gtk_ctrl.$(OBJEXT) \
19.54 @GUI_GTK_TRUE@ gtk_gd.$(OBJEXT) video_gtk.$(OBJEXT)
19.55 -@GUI_ANDROID_TRUE@am__objects_6 = gui_none.$(OBJEXT)
19.56 +@GUI_ANDROID_TRUE@am__objects_6 = gui_none.$(OBJEXT) \
19.57 +@GUI_ANDROID_TRUE@ video_egl.$(OBJEXT)
19.58 @GUI_COCOA_TRUE@am__objects_7 = cocoaui.$(OBJEXT) cocoa_cfg.$(OBJEXT) \
19.59 @GUI_COCOA_TRUE@ cocoa_win.$(OBJEXT) cocoa_gd.$(OBJEXT) \
19.60 @GUI_COCOA_TRUE@ cocoa_prefs.$(OBJEXT) cocoa_ctrl.$(OBJEXT) \
19.61 @@ -343,6 +347,7 @@
19.62 AMTAR = @AMTAR@
19.63 ANDROID_GDBSERVER = @ANDROID_GDBSERVER@
19.64 ANDROID_NDK_HOME = @ANDROID_NDK_HOME@
19.65 +ANDROID_NDK_VERSION = @ANDROID_NDK_VERSION@
19.66 ANDROID_SDK_HOME = @ANDROID_SDK_HOME@
19.67 ANDROID_SDK_VERSION = @ANDROID_SDK_VERSION@
19.68 ANT = @ANT@
19.69 @@ -624,7 +629,7 @@
19.70
19.71 @GUI_ANDROID_TRUE@liblxdream_so_LINK = $(LINK) -Wl,-soname,liblxdream.so -shared
19.72 @GUI_ANDROID_TRUE@liblxdream_so_LDADD = liblxdream-core.a @GLIB_LIBS@ @GTK_LIBS@ @LIBPNG_LIBS@ @LIBISOFS_LIBS@ $(INTLLIBS) @LXDREAM_LIBS@ -lm
19.73 -@GUI_ANDROID_TRUE@liblxdream_so_SOURCES = gui_jni.c drivers/cdrom/cd_none.c
19.74 +@GUI_ANDROID_TRUE@liblxdream_so_SOURCES = gui_android.c drivers/cdrom/cd_none.c drivers/video_egl.c drivers/video_egl.h tqueue.c tqueue.h
19.75 @GUI_ANDROID_TRUE@liblxdream_so_LIBS = liblxdream-core.a
19.76 @BUILD_PLUGINS_TRUE@lxdream_dummy_@SOEXT@_SOURCES =
19.77 @BUILD_PLUGINS_TRUE@lxdream_dummy_@SOEXT@_LDADD = lxdream_dummy.lo @SDL_LIBS@
19.78 @@ -844,7 +849,7 @@
19.79 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtk_win.Po@am__quote@
19.80 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtkcb.Po@am__quote@
19.81 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtkui.Po@am__quote@
19.82 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_jni.Po@am__quote@
19.83 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_android.Po@am__quote@
19.84 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_none.Po@am__quote@
19.85 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hotkeys.Po@am__quote@
19.86 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386-dis.Po@am__quote@
19.87 @@ -897,8 +902,10 @@
19.88 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testxlt.Po@am__quote@
19.89 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texcache.Po@am__quote@
19.90 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timer.Po@am__quote@
19.91 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tqueue.Po@am__quote@
19.92 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@
19.93 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@
19.94 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_egl.Po@am__quote@
19.95 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_gdk.Po@am__quote@
19.96 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_gl.Po@am__quote@
19.97 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_glx.Po@am__quote@
19.98 @@ -1852,6 +1859,20 @@
19.99 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
19.100 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cd_none.obj `if test -f 'drivers/cdrom/cd_none.c'; then $(CYGPATH_W) 'drivers/cdrom/cd_none.c'; else $(CYGPATH_W) '$(srcdir)/drivers/cdrom/cd_none.c'; fi`
19.101
19.102 +video_egl.o: drivers/video_egl.c
19.103 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT video_egl.o -MD -MP -MF "$(DEPDIR)/video_egl.Tpo" -c -o video_egl.o `test -f 'drivers/video_egl.c' || echo '$(srcdir)/'`drivers/video_egl.c; \
19.104 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/video_egl.Tpo" "$(DEPDIR)/video_egl.Po"; else rm -f "$(DEPDIR)/video_egl.Tpo"; exit 1; fi
19.105 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='drivers/video_egl.c' object='video_egl.o' libtool=no @AMDEPBACKSLASH@
19.106 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
19.107 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o video_egl.o `test -f 'drivers/video_egl.c' || echo '$(srcdir)/'`drivers/video_egl.c
19.108 +
19.109 +video_egl.obj: drivers/video_egl.c
19.110 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT video_egl.obj -MD -MP -MF "$(DEPDIR)/video_egl.Tpo" -c -o video_egl.obj `if test -f 'drivers/video_egl.c'; then $(CYGPATH_W) 'drivers/video_egl.c'; else $(CYGPATH_W) '$(srcdir)/drivers/video_egl.c'; fi`; \
19.111 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/video_egl.Tpo" "$(DEPDIR)/video_egl.Po"; else rm -f "$(DEPDIR)/video_egl.Tpo"; exit 1; fi
19.112 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='drivers/video_egl.c' object='video_egl.obj' libtool=no @AMDEPBACKSLASH@
19.113 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
19.114 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o video_egl.obj `if test -f 'drivers/video_egl.c'; then $(CYGPATH_W) 'drivers/video_egl.c'; else $(CYGPATH_W) '$(srcdir)/drivers/video_egl.c'; fi`
19.115 +
19.116 gtkui.o: gtkui/gtkui.c
19.117 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gtkui.o -MD -MP -MF "$(DEPDIR)/gtkui.Tpo" -c -o gtkui.o `test -f 'gtkui/gtkui.c' || echo '$(srcdir)/'`gtkui/gtkui.c; \
19.118 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gtkui.Tpo" "$(DEPDIR)/gtkui.Po"; else rm -f "$(DEPDIR)/gtkui.Tpo"; exit 1; fi
20.1 --- a/src/display.c Tue Feb 28 18:22:52 2012 +1000
20.2 +++ b/src/display.c Fri Mar 02 23:49:10 2012 +1000
20.3 @@ -23,6 +23,7 @@
20.4 #include "dream.h"
20.5 #include "display.h"
20.6 #include "pvr2/pvr2.h"
20.7 +#include "pvr2/glutil.h"
20.8
20.9 display_driver_t display_driver_list[] = {
20.10 #ifdef HAVE_GTK
20.11 @@ -33,7 +34,7 @@
20.12 #endif
20.13 #endif
20.14 #ifdef __ANDROID__
20.15 - &display_gl_driver,
20.16 + &display_egl_driver,
20.17 #endif
20.18 &display_null_driver,
20.19 NULL };
21.1 --- a/src/display.h Tue Feb 28 18:22:52 2012 +1000
21.2 +++ b/src/display.h Fri Mar 02 23:49:10 2012 +1000
21.3 @@ -282,6 +282,7 @@
21.4 extern struct display_driver display_gtk_driver;
21.5 extern struct display_driver display_osx_driver;
21.6 extern struct display_driver display_gl_driver;
21.7 +extern struct display_driver display_egl_driver;
21.8 extern struct display_driver display_null_driver;
21.9
21.10 /****************** Input methods **********************/
22.1 --- a/src/drivers/gl_fbo.c Tue Feb 28 18:22:52 2012 +1000
22.2 +++ b/src/drivers/gl_fbo.c Fri Mar 02 23:49:10 2012 +1000
22.3 @@ -67,7 +67,7 @@
22.4
22.5 gboolean gl_fbo_is_supported()
22.6 {
22.7 - return isGLExtensionSupported("GL_EXT_framebuffer_object");
22.8 + return isGLExtensionSupported("GL_EXT_framebuffer_object") || isOpenGLES2();
22.9 }
22.10
22.11 /**
22.12 @@ -353,7 +353,8 @@
22.13 glDrawBuffer( GL_FRONT );
22.14 glReadBuffer( GL_FRONT );
22.15 #endif
22.16 - display_driver->swap_buffers();
22.17 + if( display_driver->swap_buffers )
22.18 + display_driver->swap_buffers();
22.19 }
22.20
22.21 static gboolean gl_fbo_read_render_buffer( unsigned char *target, render_buffer_t buffer,
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/src/drivers/video_egl.c Fri Mar 02 23:49:10 2012 +1000
23.3 @@ -0,0 +1,168 @@
23.4 +/**
23.5 + * $Id$
23.6 + *
23.7 + * Window management using EGL.
23.8 + *
23.9 + * Copyright (c) 2012 Nathan Keynes.
23.10 + *
23.11 + * This program is free software; you can redistribute it and/or modify
23.12 + * it under the terms of the GNU General Public License as published by
23.13 + * the Free Software Foundation; either version 2 of the License, or
23.14 + * (at your option) any later version.
23.15 + *
23.16 + * This program is distributed in the hope that it will be useful,
23.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
23.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23.19 + * GNU General Public License for more details.
23.20 + */
23.21 +
23.22 +#include "lxdream.h"
23.23 +#include "display.h"
23.24 +#include "video_egl.h"
23.25 +#include "video_gl.h"
23.26 +#include "pvr2/pvr2.h"
23.27 +#include "pvr2/glutil.h"
23.28 +
23.29 +static const char *getEGLErrorString( EGLint code )
23.30 +{
23.31 + switch( code ) {
23.32 + case EGL_SUCCESS: return "OK";
23.33 + case EGL_NOT_INITIALIZED: return "EGL not initialized";
23.34 + case EGL_BAD_ACCESS: return "Bad access";
23.35 + case EGL_BAD_ALLOC: return "Allocation failed";
23.36 + case EGL_BAD_ATTRIBUTE: return "Bad attribute";
23.37 + case EGL_BAD_CONTEXT: return "Bad context";
23.38 + case EGL_BAD_CONFIG: return "Bad config";
23.39 + case EGL_BAD_CURRENT_SURFACE: return "Bad current surface";
23.40 + case EGL_BAD_DISPLAY: return "Bad display";
23.41 + case EGL_BAD_MATCH: return "Bad match";
23.42 + case EGL_BAD_PARAMETER: return "Bad parameter";
23.43 + case EGL_BAD_NATIVE_PIXMAP: return "Bad native pixmap";
23.44 + case EGL_BAD_NATIVE_WINDOW: return "Bad native window";
23.45 + default: return "Unknown error";
23.46 + }
23.47 +}
23.48 +
23.49 +
23.50 +static void logEGLError(const char *msg)
23.51 +{
23.52 + EGLint error = eglGetError();
23.53 + const char *errorStr = getEGLErrorString(error);
23.54 +
23.55 + ERROR( "%s: %s (%x)", msg, errorStr, error );
23.56 +}
23.57 +
23.58 +static const EGLint RGB888_attributes[] = {
23.59 + EGL_RED_SIZE, 8,
23.60 + EGL_GREEN_SIZE, 8,
23.61 + EGL_BLUE_SIZE, 8,
23.62 + EGL_DEPTH_SIZE, 16,
23.63 + EGL_STENCIL_SIZE, 8,
23.64 + EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
23.65 + EGL_RENDERABLE_TYPE,EGL_OPENGL_ES2_BIT,
23.66 + EGL_NONE, EGL_NONE };
23.67 +
23.68 +static const EGLint RGB565_attributes[] = {
23.69 + EGL_RED_SIZE, 5,
23.70 + EGL_GREEN_SIZE, 6,
23.71 + EGL_BLUE_SIZE, 5,
23.72 + EGL_DEPTH_SIZE, 16,
23.73 + EGL_STENCIL_SIZE, 8,
23.74 + EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
23.75 + EGL_RENDERABLE_TYPE,EGL_OPENGL_ES2_BIT,
23.76 + EGL_NONE, EGL_NONE };
23.77 +
23.78 +static const EGLint context_attributes[] = {
23.79 + EGL_CONTEXT_CLIENT_VERSION, 2,
23.80 + EGL_NONE, EGL_NONE };
23.81 +
23.82 +static EGLDisplay display;
23.83 +static EGLContext context = EGL_NO_CONTEXT;
23.84 +static EGLSurface surface = EGL_NO_SURFACE;
23.85 +static gboolean fbo_created = FALSE;
23.86 +
23.87 +gboolean video_egl_set_window(EGLNativeWindowType window, int width, int height, int format)
23.88 +{
23.89 + EGLConfig config;
23.90 + EGLint num_config, major = 0, minor = 0;
23.91 + const EGLint *attribute_list;
23.92 +
23.93 + display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
23.94 + if( eglInitialize(display, &major, &minor) != EGL_TRUE ) {
23.95 + logEGLError( "Unable to initialise EGL display" );
23.96 + return FALSE;
23.97 + }
23.98 +
23.99 + if( format == COLFMT_RGB565 || format == COLFMT_BGRA1555 ) {
23.100 + attribute_list = RGB565_attributes;
23.101 + } else {
23.102 + attribute_list = RGB888_attributes;
23.103 + }
23.104 +
23.105 +
23.106 + eglChooseConfig(display, attribute_list, &config, 1, &num_config);
23.107 +
23.108 + context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attributes);
23.109 + if( context == EGL_NO_CONTEXT ) {
23.110 + logEGLError( "Unable to create EGL context" );
23.111 + video_egl_clear_window();
23.112 + return FALSE;
23.113 + }
23.114 +
23.115 + surface = eglCreateWindowSurface(display, config, window, NULL);
23.116 + if( surface == EGL_NO_SURFACE ) {
23.117 + logEGLError( "Unable to create EGL surface" );
23.118 + video_egl_clear_window();
23.119 + return FALSE;
23.120 + }
23.121 +
23.122 + if( eglMakeCurrent( display, surface, surface, context ) == EGL_FALSE ) {
23.123 + video_egl_clear_window();
23.124 + return FALSE;
23.125 + }
23.126 +
23.127 + if( gl_fbo_is_supported() ) {
23.128 + display_gl_driver.capabilities.has_gl = TRUE;
23.129 + gl_fbo_init(&display_egl_driver);
23.130 + gl_vbo_init(&display_egl_driver);
23.131 + fbo_created = TRUE;
23.132 + } else {
23.133 + ERROR( "Display does not support FBO" );
23.134 + video_egl_clear_window();
23.135 + return FALSE;
23.136 + }
23.137 + pvr2_setup_gl_context();
23.138 + INFO( "Initialised EGL %d.%d\n", major, minor );
23.139 + return TRUE;
23.140 +}
23.141 +
23.142 +void video_egl_clear_window()
23.143 +{
23.144 + if( fbo_created ) {
23.145 + gl_fbo_shutdown();
23.146 + fbo_created = FALSE;
23.147 + }
23.148 + eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
23.149 + if( surface != EGL_NO_SURFACE ) {
23.150 + eglDestroySurface(display, surface);
23.151 + surface = EGL_NO_SURFACE;
23.152 + }
23.153 + if( context != EGL_NO_CONTEXT ) {
23.154 + eglDestroyContext(display, context);
23.155 + context = EGL_NO_CONTEXT;
23.156 + }
23.157 + eglTerminate(display);
23.158 +}
23.159 +
23.160 +
23.161 +
23.162 +/**
23.163 + * Minimal init and shutdown. The real work is done from set_window
23.164 + */
23.165 +struct display_driver display_egl_driver = {
23.166 + "egl", N_("OpenGLES driver"), NULL, NULL,
23.167 + NULL, NULL, NULL,
23.168 + NULL, NULL, NULL, NULL,
23.169 + gl_load_frame_buffer, gl_display_render_buffer, gl_display_blank,
23.170 + NULL, gl_read_render_buffer, NULL, NULL
23.171 +};
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/src/drivers/video_egl.h Fri Mar 02 23:49:10 2012 +1000
24.3 @@ -0,0 +1,38 @@
24.4 +/**
24.5 + * $Id$
24.6 + *
24.7 + * Window management using EGL.
24.8 + *
24.9 + * Copyright (c) 2012 Nathan Keynes.
24.10 + *
24.11 + * This program is free software; you can redistribute it and/or modify
24.12 + * it under the terms of the GNU General Public License as published by
24.13 + * the Free Software Foundation; either version 2 of the License, or
24.14 + * (at your option) any later version.
24.15 + *
24.16 + * This program is distributed in the hope that it will be useful,
24.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
24.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24.19 + * GNU General Public License for more details.
24.20 + */
24.21 +
24.22 +
24.23 +#ifndef lxdream_video_egl_H
24.24 +#define lxdream_video_egl_H 1
24.25 +
24.26 +#include "glib/gtypes.h"
24.27 +
24.28 +#ifdef __cplusplus
24.29 +extern "C" {
24.30 +#endif
24.31 +
24.32 +#include <EGL/egl.h>
24.33 +
24.34 +gboolean video_egl_set_window(EGLNativeWindowType window, int width, int height, int format);
24.35 +void video_egl_clear_window();
24.36 +
24.37 +#ifdef __cplusplus
24.38 +}
24.39 +#endif
24.40 +
24.41 +#endif /* !lxdream_video_egl_H */
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/src/gui_android.c Fri Mar 02 23:49:10 2012 +1000
25.3 @@ -0,0 +1,331 @@
25.4 +/**
25.5 + * $Id$
25.6 + *
25.7 + * Native shims for the Android front-end (implemented in Java).
25.8 + *
25.9 + * This is complicated by the fact that all the emulation runs in a
25.10 + * separate thread.
25.11 + *
25.12 + * Copyright (c) 2012 Nathan Keynes.
25.13 + *
25.14 + * This program is free software; you can redistribute it and/or modify
25.15 + * it under the terms of the GNU General Public License as published by
25.16 + * the Free Software Foundation; either version 2 of the License, or
25.17 + * (at your option) any later version.
25.18 + *
25.19 + * This program is distributed in the hope that it will be useful,
25.20 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25.21 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25.22 + * GNU General Public License for more details.
25.23 + */
25.24 +
25.25 +#include <jni.h>
25.26 +#include <pthread.h>
25.27 +#include <android/log.h>
25.28 +#include <android/native_window_jni.h>
25.29 +#include <libisofs.h>
25.30 +#include "dream.h"
25.31 +#include "dreamcast.h"
25.32 +#include "gui.h"
25.33 +#include "config.h"
25.34 +#include "lxpaths.h"
25.35 +#include "tqueue.h"
25.36 +#include "display.h"
25.37 +#include "gdlist.h"
25.38 +#include "gdrom/gdrom.h"
25.39 +#include "hotkeys.h"
25.40 +#include "serial.h"
25.41 +#include "aica/audio.h"
25.42 +#include "drivers/video_egl.h"
25.43 +#include "maple/maple.h"
25.44 +#include "vmu/vmulist.h"
25.45 +
25.46 +struct surface_info {
25.47 + ANativeWindow *win;
25.48 + int width, height, format;
25.49 +};
25.50 +
25.51 +static struct surface_info current_surface;
25.52 +static const char *appHome = NULL;
25.53 +
25.54 +/**
25.55 + * Count of running nanoseconds - used to cut back on the GUI runtime
25.56 + */
25.57 +static uint32_t android_gui_nanos = 0;
25.58 +static uint32_t android_gui_ticks = 0;
25.59 +static struct timeval android_gui_lasttv;
25.60 +
25.61 +
25.62 +void android_gui_start( void )
25.63 +{
25.64 + /* Dreamcast starting up hook */
25.65 +}
25.66 +
25.67 +void android_gui_stop( void )
25.68 +{
25.69 + /* Dreamcast stopping hook */
25.70 +}
25.71 +
25.72 +void android_gui_reset( void )
25.73 +{
25.74 + /* Dreamcast reset hook */
25.75 +}
25.76 +
25.77 +/**
25.78 + * The main emulation thread. (as opposed to the UI thread).
25.79 + */
25.80 +void *android_thread_main(void *data)
25.81 +{
25.82 + while(1) {
25.83 + tqueue_process_wait();
25.84 + }
25.85 + return NULL;
25.86 +}
25.87 +
25.88 +int android_set_surface(void *data)
25.89 +{
25.90 + struct surface_info *surface = (struct surface_info *)data;
25.91 + video_egl_set_window(surface->win, surface->width, surface->height, surface->format);
25.92 + return 0;
25.93 +}
25.94 +
25.95 +int android_clear_surface(void *data)
25.96 +{
25.97 + struct surface_info *surface = (struct surface_info *)data;
25.98 +
25.99 + if( dreamcast_is_running() ) {
25.100 + dreamcast_stop();
25.101 + }
25.102 + video_egl_clear_window();
25.103 + ANativeWindow_release(surface->win);
25.104 + surface->win = NULL;
25.105 + return 0;
25.106 +}
25.107 +
25.108 +static pthread_t dreamcast_thread;
25.109 +
25.110 +void android_start_thread()
25.111 +{
25.112 + pthread_attr_t attr;
25.113 +
25.114 + pthread_attr_init(&attr);
25.115 + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
25.116 + int status = pthread_create(&dreamcast_thread, &attr, android_thread_main, NULL);
25.117 + if( status != 0 ) {
25.118 + /* Handle errors */
25.119 + }
25.120 +}
25.121 +
25.122 +/** tqueue callback wrapper to get the right call type for simple events */
25.123 +int android_callback_wrapper( void *fn )
25.124 +{
25.125 + void (*cast_fn)(void) = fn;
25.126 + cast_fn();
25.127 +}
25.128 +
25.129 +int android_mount_disc( void *data )
25.130 +{
25.131 + char *s = (char *)data;
25.132 + ERROR err;
25.133 + gboolean result = gdrom_mount_image( s, &err ); /* TODO: Report error */
25.134 + return result;
25.135 +}
25.136 +
25.137 +int android_toggle_run( void *data )
25.138 +{
25.139 + if( dreamcast_is_running() ) {
25.140 + dreamcast_stop();
25.141 + } else {
25.142 + dreamcast_run();
25.143 + }
25.144 +}
25.145 +
25.146 +uint32_t android_gui_run_slice( uint32_t nanosecs )
25.147 +{
25.148 + android_gui_nanos += nanosecs;
25.149 + if( android_gui_nanos > GUI_TICK_PERIOD ) { /* 10 ms */
25.150 + android_gui_nanos -= GUI_TICK_PERIOD;
25.151 + android_gui_ticks ++;
25.152 + uint32_t current_period = android_gui_ticks * GUI_TICK_PERIOD;
25.153 +
25.154 + // Run the event loop
25.155 + tqueue_process_all();
25.156 +
25.157 + struct timeval tv;
25.158 + gettimeofday(&tv,NULL);
25.159 + uint32_t ns = ((tv.tv_sec - android_gui_lasttv.tv_sec) * 1000000000) +
25.160 + (tv.tv_usec - android_gui_lasttv.tv_usec)*1000;
25.161 + if( (ns * 1.05) < current_period ) {
25.162 + // We've gotten ahead - sleep for a little bit
25.163 + struct timespec tv;
25.164 + tv.tv_sec = 0;
25.165 + tv.tv_nsec = current_period - ns;
25.166 + nanosleep(&tv, &tv);
25.167 + }
25.168 +
25.169 +#if 0
25.170 + /* Update the display every 10 ticks (ie 10 times a second) and
25.171 + * save the current tv value */
25.172 + if( android_gui_ticks > 10 ) {
25.173 + android_gui_ticks -= 10;
25.174 +
25.175 + double speed = (float)( (double)current_period * 100.0 / ns );
25.176 + android_gui_lasttv.tv_sec = tv.tv_sec;
25.177 + android_gui_lasttv.tv_usec = tv.tv_usec;
25.178 + main_window_set_speed( main_win, speed );
25.179 + }
25.180 +#endif
25.181 + }
25.182 + return nanosecs;
25.183 +
25.184 +
25.185 +}
25.186 +
25.187 +struct dreamcast_module android_gui_module = { "gui", NULL,
25.188 + android_gui_reset,
25.189 + android_gui_start,
25.190 + android_gui_run_slice,
25.191 + android_gui_stop,
25.192 + NULL, NULL };
25.193 +
25.194 +gboolean gui_error_dialog( const char *fmt, ... )
25.195 +{
25.196 + return FALSE; /* TODO */
25.197 +}
25.198 +
25.199 +void gui_update_state()
25.200 +{
25.201 + /* TODO */
25.202 +}
25.203 +
25.204 +void gui_set_use_grab( gboolean grab )
25.205 +{
25.206 + /* No implementation - mouse grab doesn't exist */
25.207 +}
25.208 +
25.209 +void gui_update_io_activity( io_activity_type activity, gboolean active )
25.210 +{
25.211 + /* No implementation */
25.212 +}
25.213 +
25.214 +void gui_do_later( do_later_callback_t func )
25.215 +{
25.216 + func(); /* TODO */
25.217 +}
25.218 +
25.219 +static void android_init( const char *appHomeDir )
25.220 +{
25.221 + set_global_log_level("info");
25.222 + appHome = appHomeDir;
25.223 + const char *confFile = g_strdup_printf("%s/lxdreamrc", appHome);
25.224 + set_user_data_path(appHome);
25.225 + lxdream_set_config_filename( confFile );
25.226 + lxdream_make_config_dir( );
25.227 + lxdream_load_config( );
25.228 + iso_init();
25.229 + gdrom_list_init();
25.230 + vmulist_init();
25.231 + dreamcast_init(1);
25.232 +
25.233 + dreamcast_register_module( &android_gui_module );
25.234 + audio_init_driver(NULL);
25.235 + display_driver_t display_driver = get_display_driver_by_name(NULL);
25.236 + display_set_driver(display_driver);
25.237 +
25.238 + hotkeys_init();
25.239 + serial_init();
25.240 + maple_reattach_all();
25.241 + INFO( "%s! ready...", APP_NAME );
25.242 + android_start_thread();
25.243 +}
25.244 +
25.245 +
25.246 +/************************* Dreamcast native entry points **************************/
25.247 +
25.248 +static char *getStringChars( JNIEnv *env, jstring str );
25.249 +
25.250 +/**
25.251 + * Main initialization entry point. We need to do all the setup that main()
25.252 + * would normally do, as well as any UI specific setup.
25.253 + */
25.254 +JNIEXPORT void JNICALL Java_org_lxdream_Dreamcast_init(JNIEnv * env, jclass obj, jstring homeDir )
25.255 +{
25.256 + android_init( getStringChars(env, homeDir) );
25.257 +}
25.258 +
25.259 +JNIEXPORT void JNICALL Java_org_lxdream_Dreamcast_run(JNIEnv * env, jclass obj)
25.260 +{
25.261 + tqueue_post_message( android_callback_wrapper, dreamcast_run );
25.262 +}
25.263 +
25.264 +JNIEXPORT void JNICALL Java_org_lxdream_Dreamcast_toggleRun(JNIEnv * env, jclass obj)
25.265 +{
25.266 + tqueue_post_message( android_toggle_run, NULL );
25.267 +}
25.268 +
25.269 +JNIEXPORT void JNICALL Java_org_lxdream_Dreamcast_reset(JNIEnv * env, jclass obj)
25.270 +{
25.271 + tqueue_post_message( android_callback_wrapper, dreamcast_reset );
25.272 +}
25.273 +
25.274 +JNIEXPORT void JNICALL Java_org_lxdream_Dreamcast_stop(JNIEnv * env, jclass obj)
25.275 +{
25.276 + /* Need to make sure this completely shuts down before we return */
25.277 + tqueue_send_message( android_callback_wrapper, dreamcast_stop );
25.278 +}
25.279 +
25.280 +JNIEXPORT jboolean JNICALL Java_org_lxdream_Dreamcast_isRunning(JNIEnv *env, jclass obj)
25.281 +{
25.282 + return dreamcast_is_running();
25.283 +}
25.284 +
25.285 +JNIEXPORT jboolean JNICALL Java_org_lxdream_Dreamcast_isRunnable(JNIEnv *env, jclass obj)
25.286 +{
25.287 + return dreamcast_can_run();
25.288 +}
25.289 +
25.290 +JNIEXPORT jboolean JNICALL Java_org_lxdream_Dreamcast_mount(JNIEnv *env, jclass obj, jstring str)
25.291 +{
25.292 + char *s = getStringChars(env, str);
25.293 + return tqueue_send_message( android_mount_disc, s );
25.294 +}
25.295 +
25.296 +JNIEXPORT jboolean JNICALL Java_org_lxdream_Dreamcast_unmount(JNIEnv *env, jclass obj)
25.297 +{
25.298 + tqueue_post_message( android_callback_wrapper, gdrom_unmount_disc );
25.299 +}
25.300 +
25.301 +
25.302 +/************************* LxdreamView native entry points **************************/
25.303 +
25.304 +JNIEXPORT void JNICALL Java_org_lxdream_LxdreamView_setSurface(JNIEnv * env, jobject view, jobject surface, jint width, jint height)
25.305 +{
25.306 + current_surface.win = ANativeWindow_fromSurface(env, surface);
25.307 + current_surface.width = width;
25.308 + current_surface.height = height;
25.309 + int fmt = ANativeWindow_getFormat(current_surface.win);
25.310 + if( fmt == WINDOW_FORMAT_RGB_565 ) {
25.311 + current_surface.format = COLFMT_RGB565;
25.312 + } else {
25.313 + current_surface.format = COLFMT_RGB888;
25.314 + }
25.315 + tqueue_post_message( android_set_surface, &current_surface );
25.316 +}
25.317 +
25.318 +JNIEXPORT void JNICALL Java_org_lxdream_LxdreamView_clearSurface(JNIEnv * env, jobject view, jobject surface)
25.319 +{
25.320 + /* Need to make sure this completely shuts down before we return */
25.321 + tqueue_send_message( android_clear_surface, &current_surface );
25.322 +}
25.323 +
25.324 +
25.325 +/************************* JNI Support functions **************************/
25.326 +
25.327 +static char *getStringChars( JNIEnv *env, jstring str )
25.328 +{
25.329 + jboolean iscopy;
25.330 + const char *p = (*env)->GetStringUTFChars(env, str, &iscopy);
25.331 + char *result = strdup(p);
25.332 + (*env)->ReleaseStringUTFChars(env,str,p);
25.333 + return result;
25.334 +}
26.1 --- a/src/gui_jni.c Tue Feb 28 18:22:52 2012 +1000
26.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
26.3 @@ -1,120 +0,0 @@
26.4 -/**
26.5 - * $Id$
26.6 - *
26.7 - * JNI wrappers for operating the emulator from Java.
26.8 - *
26.9 - * Copyright (c) 2012 Nathan Keynes.
26.10 - *
26.11 - * This program is free software; you can redistribute it and/or modify
26.12 - * it under the terms of the GNU General Public License as published by
26.13 - * the Free Software Foundation; either version 2 of the License, or
26.14 - * (at your option) any later version.
26.15 - *
26.16 - * This program is distributed in the hope that it will be useful,
26.17 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
26.18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26.19 - * GNU General Public License for more details.
26.20 - */
26.21 -
26.22 -#include <jni.h>
26.23 -#include <android/log.h>
26.24 -#include <libisofs.h>
26.25 -#include "dreamcast.h"
26.26 -#include "gui.h"
26.27 -#include "config.h"
26.28 -#include "lxpaths.h"
26.29 -#include "display.h"
26.30 -#include "gdlist.h"
26.31 -#include "hotkeys.h"
26.32 -#include "serial.h"
26.33 -#include "aica/audio.h"
26.34 -#include "drivers/video_gl.h"
26.35 -#include "maple/maple.h"
26.36 -#include "vmu/vmulist.h"
26.37 -
26.38 -static char *getStringChars( JNIEnv *env, jstring str )
26.39 -{
26.40 - jboolean iscopy;
26.41 - const char *p = (*env)->GetStringUTFChars(env, str, &iscopy);
26.42 - char *result = strdup(p);
26.43 - (*env)->ReleaseStringUTFChars(env,str,p);
26.44 - return result;
26.45 -}
26.46 -
26.47 -static const char *appHome = NULL;
26.48 -
26.49 -JNIEXPORT void JNICALL Java_org_lxdream_Dreamcast_init(JNIEnv * env, jclass obj, jstring homeDir )
26.50 -{
26.51 - appHome = getStringChars(env, homeDir);
26.52 - const char *confFile = g_strdup_printf("%s/lxdreamrc", appHome);
26.53 - set_user_data_path(appHome);
26.54 - lxdream_set_config_filename( confFile );
26.55 - lxdream_make_config_dir( );
26.56 - lxdream_load_config( );
26.57 - iso_init();
26.58 - gdrom_list_init();
26.59 - vmulist_init();
26.60 - dreamcast_init(1);
26.61 -
26.62 - audio_init_driver(NULL);
26.63 - display_driver_t display_driver = get_display_driver_by_name(NULL);
26.64 - display_set_driver(display_driver);
26.65 -
26.66 - hotkeys_init();
26.67 - serial_init();
26.68 - maple_reattach_all();
26.69 - INFO( "%s! ready...", APP_NAME );
26.70 -}
26.71 -
26.72 -JNIEXPORT void JNICALL Java_org_lxdream_Dreamcast_setViewSize(JNIEnv * env, jclass obj, jint width, jint height)
26.73 -{
26.74 - gl_set_video_size(width, height);
26.75 -}
26.76 -
26.77 -JNIEXPORT void JNICALL Java_org_lxdream_Dreamcast_run(JNIEnv * env, jclass obj)
26.78 -{
26.79 - dreamcast_run();
26.80 -}
26.81 -
26.82 -JNIEXPORT void JNICALL Java_org_lxdream_Dreamcast_stop(JNIEnv * env, jclass obj)
26.83 -{
26.84 - dreamcast_stop();
26.85 -}
26.86 -
26.87 -gboolean gui_parse_cmdline( int *argc, char **argv[] )
26.88 -{
26.89 - return TRUE;
26.90 -}
26.91 -
26.92 -gboolean gui_init( gboolean debug, gboolean fullscreen )
26.93 -{
26.94 - return TRUE;
26.95 -}
26.96 -
26.97 -void gui_main_loop( gboolean run ) {
26.98 - if( run ) {
26.99 - dreamcast_run();
26.100 - }
26.101 -}
26.102 -
26.103 -gboolean gui_error_dialog( const char *fmt, ... )
26.104 -{
26.105 - return TRUE;
26.106 -}
26.107 -
26.108 -void gui_update_state()
26.109 -{
26.110 -}
26.111 -
26.112 -void gui_set_use_grab( gboolean grab )
26.113 -{
26.114 -}
26.115 -
26.116 -void gui_update_io_activity( io_activity_type activity, gboolean active )
26.117 -{
26.118 -}
26.119 -
26.120 -void gui_do_later( do_later_callback_t func )
26.121 -{
26.122 - func();
26.123 -}
27.1 --- a/src/pvr2/glutil.c Tue Feb 28 18:22:52 2012 +1000
27.2 +++ b/src/pvr2/glutil.c Fri Mar 02 23:49:10 2012 +1000
27.3 @@ -41,6 +41,14 @@
27.4 return isGLExtensionSupported("GL_ARB_texture_mirrored_repeat");
27.5 }
27.6
27.7 +gboolean isOpenGLES2()
27.8 +{
27.9 + const char *str = glGetString(GL_VERSION);
27.10 + if( strncmp(str, "OpenGL ES 2.", 12) == 0 ) {
27.11 + return TRUE;
27.12 + }
27.13 +}
27.14 +
27.15 /**
27.16 * Check if there's at least 2 texture units
27.17 */
28.1 --- a/src/pvr2/glutil.h Tue Feb 28 18:22:52 2012 +1000
28.2 +++ b/src/pvr2/glutil.h Fri Mar 02 23:49:10 2012 +1000
28.3 @@ -33,6 +33,8 @@
28.4 */
28.5 gboolean isGLExtensionSupported( const char *extension );
28.6
28.7 +gboolean isOpenGLES2();
28.8 +
28.9 /**
28.10 * Dump GL information to the output stream, usually for debugging purposes
28.11 */
28.12 @@ -106,6 +108,18 @@
28.13 #define GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_EXT
28.14 #endif
28.15
28.16 +#if defined(GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT) && !defined(GL_UNSIGNED_SHORT_1_5_5_5_REV)
28.17 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT
28.18 +#endif
28.19 +
28.20 +#if defined(GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT) && !defined(GL_UNSIGNED_SHORT_4_4_4_4_REV)
28.21 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT
28.22 +#endif
28.23 +
28.24 +#if defined(GL_BGRA_EXT) && !defined(GL_BGRA)
28.25 +#define GL_BGRA GL_BGRA_EXT
28.26 +#endif
28.27 +
28.28 #if defined(HAVE_OPENGL_FBO_EXT) && !defined(HAVE_OPENGL_FBO)
28.29 #define glGenFramebuffers glGenFramebuffersEXT
28.30 #define glGenRenderbuffers glGenRenderbuffersEXT
29.1 --- a/src/tools/Makefile.in Tue Feb 28 18:22:52 2012 +1000
29.2 +++ b/src/tools/Makefile.in Fri Mar 02 23:49:10 2012 +1000
29.3 @@ -80,6 +80,7 @@
29.4 AMTAR = @AMTAR@
29.5 ANDROID_GDBSERVER = @ANDROID_GDBSERVER@
29.6 ANDROID_NDK_HOME = @ANDROID_NDK_HOME@
29.7 +ANDROID_NDK_VERSION = @ANDROID_NDK_VERSION@
29.8 ANDROID_SDK_HOME = @ANDROID_SDK_HOME@
29.9 ANDROID_SDK_VERSION = @ANDROID_SDK_VERSION@
29.10 ANT = @ANT@
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/src/tqueue.c Fri Mar 02 23:49:10 2012 +1000
30.3 @@ -0,0 +1,137 @@
30.4 +/**
30.5 + * $Id$
30.6 + *
30.7 + * Bounded, blocking queue for inter-thread communication.
30.8 + *
30.9 + * Copyright (c) 2012 Nathan Keynes.
30.10 + *
30.11 + * This program is free software; you can redistribute it and/or modify
30.12 + * it under the terms of the GNU General Public License as published by
30.13 + * the Free Software Foundation; either version 2 of the License, or
30.14 + * (at your option) any later version.
30.15 + *
30.16 + * This program is distributed in the hope that it will be useful,
30.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
30.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30.19 + * GNU General Public License for more details.
30.20 + */
30.21 +
30.22 +#include <assert.h>
30.23 +#include <pthread.h>
30.24 +#include "tqueue.h"
30.25 +
30.26 +#define TQUEUE_LENGTH 64
30.27 +
30.28 +typedef struct {
30.29 + tqueue_callback callback;
30.30 + void *data;
30.31 + gboolean synchronous;
30.32 +} tqueue_entry;
30.33 +
30.34 +struct {
30.35 + pthread_mutex_t mutex;
30.36 + pthread_cond_t consumer_wait;
30.37 + pthread_cond_t producer_sync_wait;
30.38 + pthread_cond_t producer_full_wait;
30.39 + int head; /* next item returned by dequeue */
30.40 + int tail; /* next item filled in by enqueue */
30.41 + int last_result; /* Result value of last dequeued callback */
30.42 + tqueue_entry tqueue[TQUEUE_LENGTH];
30.43 +} tqueue = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0, -1};
30.44 +
30.45 +/************** Producer thread **************/
30.46 +#define TQUEUE_EMPTY() (tqueue.head == tqueue.tail)
30.47 +#define TQUEUE_FULL() ((tqueue.head == tqueue.tail+1) || (tqueue.head == 0 && tqueue.tail == TQUEUE_LENGTH))
30.48 +
30.49 +static void tqueue_enqueue( tqueue_callback callback, void *data, gboolean sync )
30.50 +{
30.51 + assert( !TQUEUE_FULL() );
30.52 + tqueue.tqueue[tqueue.tail].callback = callback;
30.53 + tqueue.tqueue[tqueue.tail].data = data;
30.54 + tqueue.tqueue[tqueue.tail].synchronous = sync;
30.55 + tqueue.tail++;
30.56 +}
30.57 +
30.58 +/**
30.59 + * Add a message to the UI queue and return immediately.
30.60 + */
30.61 +void tqueue_post_message( tqueue_callback callback, void *data )
30.62 +{
30.63 + pthread_mutex_lock(&tqueue.mutex);
30.64 + if( TQUEUE_FULL() ) {
30.65 + /* Wait for the queue to clear */
30.66 + pthread_cond_wait(&tqueue.producer_full_wait, &tqueue.mutex);
30.67 + }
30.68 + tqueue_enqueue( callback, data, FALSE );
30.69 + pthread_cond_signal(&tqueue.consumer_wait);
30.70 + pthread_mutex_unlock(&tqueue.mutex);
30.71 +}
30.72 +
30.73 +/**
30.74 + * Add a message to the UI queue and wait for it to be handled.
30.75 + * @return the result from the handler function.
30.76 + */
30.77 +int tqueue_send_message( tqueue_callback callback, void *data )
30.78 +{
30.79 + pthread_mutex_lock(&tqueue.mutex);
30.80 + if( TQUEUE_FULL() ) {
30.81 + /* Wait for the queue to clear */
30.82 + pthread_cond_wait(&tqueue.producer_full_wait, &tqueue.mutex);
30.83 + }
30.84 + tqueue_enqueue( callback, data, TRUE );
30.85 + pthread_cond_signal(&tqueue.consumer_wait);
30.86 + pthread_cond_wait(&tqueue.producer_sync_wait, &tqueue.mutex);
30.87 + return tqueue.last_result;
30.88 + pthread_mutex_unlock(&tqueue.mutex);
30.89 +}
30.90 +
30.91 +/************** Consumer thread **************/
30.92 +
30.93 +/* Note: must be called with mutex locked */
30.94 +static void tqueue_process_loop() {
30.95 + while( !TQUEUE_EMPTY() ) {
30.96 + gboolean wasFull = TQUEUE_FULL();
30.97 + tqueue_callback callback = tqueue.tqueue[tqueue.head].callback;
30.98 + void *data = tqueue.tqueue[tqueue.head].data;
30.99 + gboolean sync = tqueue.tqueue[tqueue.head].synchronous;
30.100 + tqueue.head++;
30.101 +
30.102 + if( wasFull ) {
30.103 + pthread_cond_signal( &tqueue.producer_full_wait );
30.104 + }
30.105 +
30.106 + pthread_mutex_unlock(&tqueue.mutex);
30.107 + int result = callback(data);
30.108 + pthread_mutex_lock(&tqueue.mutex);
30.109 + if( sync ) {
30.110 + tqueue.last_result = result;
30.111 + pthread_cond_signal( &tqueue.producer_sync_wait );
30.112 + }
30.113 + }
30.114 +}
30.115 +
30.116 +/**
30.117 + * Process all messages in the queue, if any.
30.118 + */
30.119 +void tqueue_process_all()
30.120 +{
30.121 + pthread_mutex_lock(&tqueue.mutex);
30.122 + if( !TQUEUE_EMPTY() ) {
30.123 + tqueue_process_loop();
30.124 + }
30.125 + pthread_mutex_unlock(&tqueue.mutex);
30.126 +}
30.127 +
30.128 +/**
30.129 + * Process the first message in the queue. If no messages are on the
30.130 + * queue, waits for the next one to be queued and then processes it.
30.131 + */
30.132 +void tqueue_process_wait()
30.133 +{
30.134 + pthread_mutex_lock(&tqueue.mutex);
30.135 + if( TQUEUE_EMPTY() ) {
30.136 + pthread_cond_wait( &tqueue.consumer_wait, &tqueue.mutex );
30.137 + }
30.138 + tqueue_process_loop();
30.139 + pthread_mutex_unlock(&tqueue.mutex);
30.140 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/src/tqueue.h Fri Mar 02 23:49:10 2012 +1000
31.3 @@ -0,0 +1,62 @@
31.4 +/**
31.5 + * $Id$
31.6 + *
31.7 + * Bounded, blocking queue for inter-thread communication. Note: consumer side is
31.8 + * re-entrant.
31.9 + *
31.10 + * Copyright (c) 2012 Nathan Keynes.
31.11 + *
31.12 + * This program is free software; you can redistribute it and/or modify
31.13 + * it under the terms of the GNU General Public License as published by
31.14 + * the Free Software Foundation; either version 2 of the License, or
31.15 + * (at your option) any later version.
31.16 + *
31.17 + * This program is distributed in the hope that it will be useful,
31.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
31.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31.20 + * GNU General Public License for more details.
31.21 + */
31.22 +
31.23 +#ifndef lxdream_tqueue_H
31.24 +#define lxdream_tqueue_H 1
31.25 +
31.26 +#include "glib/gtypes.h"
31.27 +
31.28 +#ifdef __cplusplus
31.29 +extern "C" {
31.30 +#endif
31.31 +
31.32 +/**
31.33 + * Callback function to be invoked on the consumer side.
31.34 + */
31.35 +typedef int (*tqueue_callback)(void *);
31.36 +
31.37 +/**
31.38 + * Add a message to the UI queue and return immediately.
31.39 + */
31.40 +void tqueue_post_message( tqueue_callback callback, void *data );
31.41 +
31.42 +/**
31.43 + * Add a message to the UI queue and wait for it to be handled.
31.44 + * @return the result from the handler function.
31.45 + */
31.46 +int tqueue_send_message( tqueue_callback callback, void *data );
31.47 +
31.48 +/************** Consumer thread **************/
31.49 +
31.50 +/**
31.51 + * Process all messages in the queue, if any.
31.52 + */
31.53 +void tqueue_process_all();
31.54 +
31.55 +/**
31.56 + * Process the first message in the queue. If no messages are on the
31.57 + * queue, waits for the next one to be queued and then processes it.
31.58 + */
31.59 +void tqueue_process_wait();
31.60 +
31.61 +#ifdef __cplusplus
31.62 +}
31.63 +#endif
31.64 +
31.65 +#endif /* !lxdream_tqueue_H */
.