diff --git a/Android/.idea/misc.xml b/Android/.idea/misc.xml
index 8b7ac1cd..cd0c3b68 100644
--- a/Android/.idea/misc.xml
+++ b/Android/.idea/misc.xml
@@ -6,25 +6,6 @@
-
-
-
-
-
-
-
-
- Spelling
-
-
-
-
- Spelling
-
-
-
-
-
diff --git a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Activity.java b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Activity.java
index 6e9cf793..effd5d98 100644
--- a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Activity.java
+++ b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Activity.java
@@ -14,12 +14,12 @@ package org.deadc0de.apple2ix;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
+import android.view.MotionEvent;
import java.io.File;
import java.io.InputStream;
@@ -35,15 +35,17 @@ public class Apple2Activity extends Activity {
private final static String PREFS_CONFIGURED = "prefs_configured";
private Apple2View mView = null;
+ private int mWidth = 0;
+ private int mHeight = 0;
static {
System.loadLibrary("apple2ix");
}
private native void nativeOnCreate(String dataDir);
- private native void nativeOnResume();
- private native void nativeOnPause();
- public native void nativeGraphicsInitialized(int width, int height);
+ public native void nativeOnResume();
+ public native void nativeOnPause();
+ private native void nativeGraphicsInitialized(int width, int height);
public native void nativeRender();
private native void nativeOnKeyDown(int keyCode, int metaState);
private native void nativeOnKeyUp(int keyCode, int metaState);
@@ -87,7 +89,7 @@ public class Apple2Activity extends Activity {
Log.d(TAG, "Saving default preferences");
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean(PREFS_CONFIGURED, true);
- editor.commit();
+ editor.apply();
return dataDir;
}
@@ -100,16 +102,9 @@ public class Apple2Activity extends Activity {
new File(outputPath).mkdirs();
InputStream is = getAssets().open(subdir+File.separator+assetName);
- if (is == null) {
- Log.e(TAG, "inputstream is null");
- }
File file = new File(outputPath+File.separator+assetName);
file.setWritable(true);
-
FileOutputStream os = new FileOutputStream(file);
- if (os == null) {
- Log.e(TAG, "outputstream is null");
- }
byte[] buf = new byte[BUF_SZ];
while (true) {
@@ -161,4 +156,23 @@ public class Apple2Activity extends Activity {
return true;
}
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ Log.d(TAG, "onTouchEvent...");
+ return true;
+ }
+
+ public void graphicsInitialized(int width, int height) {
+ mWidth = width;
+ mHeight = height;
+ nativeGraphicsInitialized(width, height);
+ }
+
+ public int getWidth() {
+ return mWidth;
+ }
+
+ public int getHeight() {
+ return mHeight;
+ }
}
diff --git a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2MainMenu.java b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2MainMenu.java
new file mode 100644
index 00000000..396a4b37
--- /dev/null
+++ b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2MainMenu.java
@@ -0,0 +1,128 @@
+/*
+ * Apple // emulator for *nix
+ *
+ * This software package is subject to the GNU General Public License
+ * version 2 or later (your choice) as published by the Free Software
+ * Foundation.
+ *
+ * THERE ARE NO WARRANTIES WHATSOEVER.
+ *
+ */
+
+package org.deadc0de.apple2ix;
+
+import android.content.Context;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.PopupWindow;
+
+public class Apple2MainMenu {
+
+ public final static int MENU_INSET = 20;
+
+ private final static String TAG = "Apple2MainMenu";
+
+ private Apple2Activity mActivity = null;
+ private Apple2View mParentView = null;
+ private PopupWindow mMainMenuPopup = null;
+
+ public Apple2MainMenu(Apple2Activity activity, Apple2View parent) {
+ mActivity = activity;
+ mParentView = parent;
+ init();
+ }
+
+ private void init() {
+
+ LayoutInflater inflater = (LayoutInflater)mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View listLayout=inflater.inflate(R.layout.activity_main_menu, null, false);
+ ListView mainMenuView = (ListView)listLayout.findViewById(R.id.main_popup_menu);
+ mainMenuView.setEnabled(true);
+ LinearLayout mainPopupContainer = (LinearLayout)listLayout.findViewById(R.id.main_popup_container);
+ String[] values = new String[] {
+ "Emulation Settings...",
+ "Load Disk Image...",
+ "Resume...",
+ };
+
+ ArrayAdapter> adapter = new ArrayAdapter(mActivity, android.R.layout.simple_list_item_1, android.R.id.text1, values);
+ mainMenuView.setAdapter(adapter);
+ mainMenuView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ switch (position) {
+ case 0:
+ Apple2MainMenu.this.showSettings();
+ break;
+ case 1:
+ Apple2MainMenu.this.showDisksMenu();
+ break;
+ default:
+ Apple2MainMenu.this.dismiss();
+ break;
+ }
+ }
+ });
+
+ // WTF ... is there an easier way to dynamically calculate these dimensions?
+ int totalHeight = 0;
+ int maxWidth = 0;
+ for (int i=0; i maxWidth) {
+ maxWidth = width;
+ }
+ }
+
+ mMainMenuPopup = new PopupWindow(mainPopupContainer, maxWidth+MENU_INSET, totalHeight+MENU_INSET, true);
+ }
+
+ public void showDisksMenu() {
+ Log.d(TAG, "showDisksMenu...");
+ }
+
+ public void showSettings() {
+ Log.d(TAG, "showSettings...");
+ }
+
+ public void quitEmulator() {
+
+ }
+
+ public void show() {
+ if (mMainMenuPopup.isShowing()) {
+ return;
+ }
+
+ mActivity.nativeOnPause();
+
+ int x = (mActivity.getWidth()-mMainMenuPopup.getWidth())/2;
+ int y = (mActivity.getHeight()-mMainMenuPopup.getHeight())/2;
+
+ mMainMenuPopup.showAtLocation(mParentView, Gravity.NO_GRAVITY, x, y);
+ }
+
+ public void dismiss() {
+ if (mMainMenuPopup.isShowing()) {
+ mActivity.nativeOnResume();
+ mMainMenuPopup.dismiss();
+ }
+ }
+
+ public void androidBackButton() {
+ dismiss();
+ }
+
+ public boolean isShowing() {
+ return mMainMenuPopup.isShowing();
+ }
+}
diff --git a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2View.java b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2View.java
index a2f8751e..8dd15d9f 100644
--- a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2View.java
+++ b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2View.java
@@ -15,12 +15,9 @@
package org.deadc0de.apple2ix;
-import android.content.Context;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
-import android.util.AttributeSet;
import android.util.Log;
-import android.view.KeyEvent;
import android.view.MotionEvent;
import javax.microedition.khronos.egl.EGL10;
@@ -50,8 +47,17 @@ import javax.microedition.khronos.opengles.GL10;
class Apple2View extends GLSurfaceView {
private final static String TAG = "Apple2View";
private final static boolean DEBUG = false;
+ private final static int MENU_CANCEL_MOVE_THRESHOLD = 20;
private Apple2Activity mActivity = null;
+ private Apple2MainMenu mMainMenu = null;
+
+ private boolean mUltiTapEventBegin = false;
+ private boolean mTapEventBegin = false;
+ private float mSingleX = 0;
+ private float mSingleY = 0;
+ private float mUltiX = 0;
+ private float mUltiY = 0;
private boolean inefficient8888 = true; // HACK FIXME TODO : rewrite GL code to accommodate 565 rendering ...
@@ -96,6 +102,84 @@ class Apple2View extends GLSurfaceView {
setRenderer(new Renderer());
}
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (mMainMenu == null) {
+ return false;
+ }
+
+ Log.d(TAG, "VIEW onTouchEvent : " + event.toString());
+
+ int action = event.getActionMasked();
+
+ if (mMainMenu.isShowing()) {
+ mMainMenu.dismiss();
+ return true;
+ }
+
+ // TODO : native GL touch joystick ...
+
+ switch (action) {
+ case (MotionEvent.ACTION_DOWN):
+ mSingleX = event.getX();
+ mSingleY = event.getY();
+ mTapEventBegin = true;
+ mUltiTapEventBegin = false;
+ return true;
+
+ case (MotionEvent.ACTION_MOVE):
+ if (mTapEventBegin) {
+ float thresholdX = Math.abs(event.getX() - mSingleX);
+ float thresholdY = Math.abs(event.getY() - mSingleY);
+ if (thresholdX > MENU_CANCEL_MOVE_THRESHOLD || thresholdY > MENU_CANCEL_MOVE_THRESHOLD) {
+ mTapEventBegin = false;
+ }
+ } else if (mUltiTapEventBegin) {
+ float thresholdX = Math.abs(event.getX() - mUltiX);
+ float thresholdY = Math.abs(event.getY() - mUltiY);
+ if (thresholdX > MENU_CANCEL_MOVE_THRESHOLD || thresholdY > MENU_CANCEL_MOVE_THRESHOLD) {
+ mUltiTapEventBegin = false;
+ }
+ }
+ return true;
+
+ case (MotionEvent.ACTION_POINTER_DOWN):
+ mUltiX = event.getX();
+ mUltiY = event.getY();
+ mTapEventBegin = false;
+ mUltiTapEventBegin = true;
+ return true;
+
+ case (MotionEvent.ACTION_POINTER_UP):
+ if (mUltiTapEventBegin) {
+ showMultiTapMenu();
+ }
+ mTapEventBegin = false;
+ mUltiTapEventBegin = false;
+ return true;
+
+ case (MotionEvent.ACTION_UP):
+ if (mTapEventBegin) {
+ showMainMenu();
+ }
+ mTapEventBegin = false;
+ mUltiTapEventBegin = false;
+ return true;
+ }
+
+ return super.onTouchEvent(event);
+ }
+
+ public void showMainMenu() {
+ if (mMainMenu != null) {
+ mMainMenu.show();
+ }
+ }
+
+ public void showMultiTapMenu() {
+ Log.d(TAG, "showMultiTapMenu...");
+ }
+
private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
@@ -310,7 +394,8 @@ class Apple2View extends GLSurfaceView {
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
- Apple2View.this.mActivity.nativeGraphicsInitialized(width, height);
+ Apple2View.this.mActivity.graphicsInitialized(width, height);
+ Apple2View.this.mMainMenu = new Apple2MainMenu(Apple2View.this.mActivity, Apple2View.this);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
diff --git a/Android/app/src/main/res/layout/activity_main_menu.xml b/Android/app/src/main/res/layout/activity_main_menu.xml
new file mode 100644
index 00000000..d3f1ac28
--- /dev/null
+++ b/Android/app/src/main/res/layout/activity_main_menu.xml
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/Android/app/src/main/res/values/strings.xml b/Android/app/src/main/res/values/strings.xml
index 23ac1524..a7bf5b49 100644
--- a/Android/app/src/main/res/values/strings.xml
+++ b/Android/app/src/main/res/values/strings.xml
@@ -1,3 +1,4 @@
Apple2ix
+ #000000
diff --git a/Android/jni/jnihooks.c b/Android/jni/jnihooks.c
index 5222c7cd..fe4297cc 100644
--- a/Android/jni/jnihooks.c
+++ b/Android/jni/jnihooks.c
@@ -56,10 +56,12 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeGraphicsInitialized(JNIEnv
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnResume(JNIEnv *env, jobject obj) {
LOG("%s", "native onResume...");
+ pthread_mutex_unlock(&interface_mutex);
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnPause(JNIEnv *env, jobject obj) {
LOG("%s", "native onPause...");
+ pthread_mutex_lock(&interface_mutex);
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeRender(JNIEnv *env, jobject obj) {