From a60ffb8eb9d828da4c6d2b7d51aa40e2881b5efa Mon Sep 17 00:00:00 2001 From: Aaron Culliney Date: Tue, 21 Jul 2015 21:34:51 -0700 Subject: [PATCH] Beginning of Android persistent settings --- .../org/deadc0de/apple2ix/Apple2Activity.java | 15 +- .../deadc0de/apple2ix/Apple2Preferences.java | 155 ++++++++++++++++++ .../deadc0de/apple2ix/Apple2SettingsMenu.java | 4 +- Android/app/src/main/res/values/strings.xml | 4 + Android/jni/apple2ix.mk | 4 +- Android/jni/jnihooks.c | 16 +- Android/jni/jniprefs.c | 62 +++++++ Android/jni/sources.mk | 2 +- Android/jni/testcpu.mk | 2 +- Android/jni/testdisk.mk | 2 +- Android/jni/testdisplay.mk | 2 +- Android/jni/testvm.mk | 2 +- 12 files changed, 240 insertions(+), 30 deletions(-) create mode 100644 Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Preferences.java create mode 100644 Android/jni/jniprefs.c 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 b031243e..de3d1a93 100644 --- a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Activity.java +++ b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Activity.java @@ -36,7 +36,6 @@ public class Apple2Activity extends Activity { private final static String TAG = "Apple2Activity"; private final static int BUF_SZ = 4096; - private final static String PREFS_CONFIGURED = "prefs_configured"; private final static int SOFTKEYBOARD_THRESHOLD = 50; private final static int MAX_FINGERS = 32;// HACK ... @@ -76,8 +75,6 @@ public class Apple2Activity extends Activity { public native void nativeReboot(); public native void nativeRender(); - public native void nativeEnableTouchJoystick(boolean visibility); - public native void nativeSetColor(int color); public native void nativeChooseDisk(String path, boolean driveA, boolean readOnly); @@ -96,8 +93,7 @@ public class Apple2Activity extends Activity { System.exit(1); } - SharedPreferences settings = getPreferences(Context.MODE_PRIVATE); - if (settings.getBoolean(PREFS_CONFIGURED, false)) { + if (Apple2Preferences.PREFS_CONFIGURED.booleanValue(this)) { return dataDir; } @@ -118,9 +114,7 @@ public class Apple2Activity extends Activity { } Log.d(TAG, "Saving default preferences"); - SharedPreferences.Editor editor = settings.edit(); - editor.putBoolean(PREFS_CONFIGURED, true); - editor.apply(); + Apple2Preferences.PREFS_CONFIGURED.saveBoolean(this, true); return dataDir; } @@ -199,7 +193,7 @@ public class Apple2Activity extends Activity { // now append the actual stack trace traceBuffer.append(t.getClass().getName()); traceBuffer.append("\n"); - final int maxTraceSize = 2048+1024+512; // probably should keep this less than a standard Linux PAGE_SIZE + final int maxTraceSize = 2048 + 1024 + 512; // probably should keep this less than a standard Linux PAGE_SIZE for (StackTraceElement elt : stackTraceElements) { traceBuffer.append(elt.toString()); traceBuffer.append("\n"); @@ -230,6 +224,9 @@ public class Apple2Activity extends Activity { nativeOnCreate(mDataDir, mSampleRate, mMonoBufferSize, mStereoBufferSize); + // NOTE: load preferences after nativeOnCreate + Apple2Preferences.loadPreferences(this); + mView = new Apple2View(this); setContentView(mView); diff --git a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Preferences.java b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Preferences.java new file mode 100644 index 00000000..d0df315a --- /dev/null +++ b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2Preferences.java @@ -0,0 +1,155 @@ +/* + * 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.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; + +public enum Apple2Preferences { + PREFS_CONFIGURED { + @Override public void load(Apple2Activity activity) { + // ... + } + @Override public void saveBoolean(Apple2Activity activity, boolean ignored) { + activity.getPreferences(Context.MODE_PRIVATE).edit().putBoolean(toString(), true).apply(); + } + }, + HIRES_COLOR { + @Override public void load(Apple2Activity activity) { + nativeSetColor(intValue(activity)); + } + @Override public int intValue(Apple2Activity activity) { + return activity.getPreferences(Context.MODE_PRIVATE).getInt(toString(), HiresColor.INTERPOLATED.ordinal()); + } + }, + SPEAKER_ENABLED { + @Override public void load(Apple2Activity activity) { + boolean enabled = booleanValue(activity); + boolean result = nativeSetSpeakerEnabled(enabled); + if (enabled && !result) { + warnError(activity, R.string.speaker_disabled_title, R.string.speaker_disabled_mesg); + activity.getPreferences(Context.MODE_PRIVATE).edit().putBoolean(toString(), false).apply(); + } + } + @Override public boolean booleanValue(Apple2Activity activity) { + return activity.getPreferences(Context.MODE_PRIVATE).getBoolean(toString(), true); + } + }, + SPEAKER_VOLUME { + @Override public void load(Apple2Activity activity) { + nativeSetSpeakerVolume(intValue(activity)); + } + @Override public int intValue(Apple2Activity activity) { + return activity.getPreferences(Context.MODE_PRIVATE).getInt(toString(), Volume.MEDIUM.ordinal()); + } + }, + MOCKINGBOARD_ENABLED { + @Override public void load(Apple2Activity activity) { + boolean enabled = booleanValue(activity); + boolean result = nativeSetMockingboardEnabled(enabled); + if (enabled && !result) { + warnError(activity, R.string.mockingboard_disabled_title, R.string.mockingboard_disabled_mesg); + activity.getPreferences(Context.MODE_PRIVATE).edit().putBoolean(toString(), false).apply(); + } + } + }, + MOCKINGBOARD_VOLUME { + @Override public void load(Apple2Activity activity) { + nativeSetMockingboardVolume(intValue(activity)); + } + @Override public int intValue(Apple2Activity activity) { + return activity.getPreferences(Context.MODE_PRIVATE).getInt(toString(), Volume.MEDIUM.ordinal()); + } + }; + + public enum HiresColor { + BW, + COLOR, + INTERPOLATED + } + + public enum Volume { + OFF(0), + ONE(1), + TWO(2), + THREE(3), + FOUR(4), + MEDIUM(5), + FIVE(5), + SIX(6), + SEVEN(7), + EIGHT(8), + NINE(9), + MAX(10), + ELEVEN(11); + private int vol; + Volume(int vol) { + this.vol = vol; + } + } + + protected abstract void load(Apple2Activity activity); + + protected void warnError(Apple2Activity activity, int titleId, int mesgId) { + AlertDialog dialog = new AlertDialog.Builder(activity).setIcon(R.drawable.ic_launcher).setCancelable(true).setTitle(titleId).setMessage(mesgId).setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }).create(); + dialog.show(); + } + + // set and apply + + public void saveInt(Apple2Activity activity, int value) { + activity.getPreferences(Context.MODE_PRIVATE).edit().putInt(toString(), value).apply(); + load(activity); + } + public void saveBoolean(Apple2Activity activity, boolean value) { + activity.getPreferences(Context.MODE_PRIVATE).edit().putBoolean(toString(), value).apply(); + load(activity); + } + public void saveHiresColor(Apple2Activity activity, HiresColor value) { + activity.getPreferences(Context.MODE_PRIVATE).edit().putInt(toString(), value.ordinal()).apply(); + load(activity); + } + public void saveVolume(Apple2Activity activity, Volume value) { + activity.getPreferences(Context.MODE_PRIVATE).edit().putInt(toString(), value.ordinal()).apply(); + load(activity); + } + + // accessors + + public boolean booleanValue(Apple2Activity activity) { + return activity.getPreferences(Context.MODE_PRIVATE).getBoolean(toString(), false); + } + + public int intValue(Apple2Activity activity) { + return activity.getPreferences(Context.MODE_PRIVATE).getInt(toString(), 0); + } + + public static void loadPreferences(Apple2Activity activity) { + for (Apple2Preferences pref : Apple2Preferences.values()) { + pref.load(activity); + } + } + + private static native void nativeEnableTouchJoystick(boolean enabled); + private static native void nativeEnableTiltJoystick(boolean enabled); + private static native void nativeSetColor(int color); + private static native boolean nativeSetSpeakerEnabled(boolean enabled); + private static native void nativeSetSpeakerVolume(int volume); + private static native boolean nativeSetMockingboardEnabled(boolean enabled); + private static native void nativeSetMockingboardVolume(int volume); +} diff --git a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2SettingsMenu.java b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2SettingsMenu.java index 1d0f4a0e..38a8d4af 100644 --- a/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2SettingsMenu.java +++ b/Android/app/src/main/java/org/deadc0de/apple2ix/Apple2SettingsMenu.java @@ -56,7 +56,7 @@ public class Apple2SettingsMenu { @Override public void handleSelection(Apple2SettingsMenu settingsMenu, boolean selected) { } }, - AUDIO_ENABLE { + AUDIO_CONFIGURE { @Override public String getTitle(Context ctx) { return ctx.getResources().getString(R.string.audio_enabled); } @@ -99,7 +99,7 @@ public class Apple2SettingsMenu { builder.setAdapter(adapter, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int color) { - settingsMenu.mActivity.nativeSetColor(color); + Apple2Preferences.HIRES_COLOR.saveHiresColor(settingsMenu.mActivity, Apple2Preferences.HiresColor.values()[color]); dialog.dismiss(); } }); diff --git a/Android/app/src/main/res/values/strings.xml b/Android/app/src/main/res/values/strings.xml index 8c7132db..ebdc6c99 100644 --- a/Android/app/src/main/res/values/strings.xml +++ b/Android/app/src/main/res/values/strings.xml @@ -33,6 +33,8 @@ Insert a Disk ][ image file Emulator settingsā€¦ General, CPU, Joystick + Mockingboard disabled + Mockingboard could not be enabled No OK Quit emulatorā€¦ @@ -43,6 +45,8 @@ You will lose unsaved progress + Speaker disabled + Speaker could not be enabled Alternate CPU Speed CPU Speed Swipe changes emulation speed diff --git a/Android/jni/apple2ix.mk b/Android/jni/apple2ix.mk index 5ca3ff61..9fbafa0f 100644 --- a/Android/jni/apple2ix.mk +++ b/Android/jni/apple2ix.mk @@ -11,8 +11,8 @@ include $(COMMON_SOURCES_MK) # Android build config LOCAL_MODULE := libapple2ix -LOCAL_SRC_FILES := jnihooks.c androidkeys.c -LOCAL_ARM_MODE := arm +LOCAL_SRC_FILES := jniprefs.c androidkeys.c +#LOCAL_ARM_MODE := arm LOCAL_CFLAGS := $(APPLE2_BASE_CFLAGS) -DHEADLESS=0 LOCAL_LDLIBS := -llog -landroid -lGLESv2 -lz -lOpenSLES diff --git a/Android/jni/jnihooks.c b/Android/jni/jnihooks.c index d4249b8e..4ef6290d 100644 --- a/Android/jni/jnihooks.c +++ b/Android/jni/jnihooks.c @@ -140,6 +140,9 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnCreate(JNIEnv *env, jobje c_initialize_firsttime(); pthread_create(&cpu_thread_id, NULL, (void *) &cpu_thread, (void *)NULL); #endif + + sleep(1); +#warning FIXME TODO instead of problematic sleep ... need to preempt CPU thread by holding interface lock and displaying a splash screen and setting preferences/settings defaults before starting CPU } void Java_org_deadc0de_apple2ix_Apple2Activity_nativeGraphicsChanged(JNIEnv *env, jobject obj, jint width, jint height) { @@ -162,6 +165,7 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeGraphicsInitialized(JNIEnv void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnResume(JNIEnv *env, jobject obj, jboolean isSystemResume) { if (!nativePaused) { +#warning FIXME ... replace nativePaused check with cpu_isPaused() return; } LOG("%s", "native onResume..."); @@ -317,18 +321,6 @@ jboolean Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnTouch(JNIEnv *env, jo return consumed; } -void Java_org_deadc0de_apple2ix_Apple2Activity_nativeSetColor(JNIEnv *env, jobject obj, jint color) { - LOG("native set color : %d", color); - if (color < COLOR_NONE || color > COLOR_INTERP) { - return; - } - color_mode = color; - - video_reset(); - video_setpage(!!(softswitches & SS_SCREEN)); - video_redraw(); -} - void Java_org_deadc0de_apple2ix_Apple2Activity_nativeChooseDisk(JNIEnv *env, jobject obj, jstring jPath, jboolean driveA, jboolean readOnly) { const char *path = (*env)->GetStringUTFChars(env, jPath, NULL); int drive = driveA ? 0 : 1; diff --git a/Android/jni/jniprefs.c b/Android/jni/jniprefs.c new file mode 100644 index 00000000..8487814a --- /dev/null +++ b/Android/jni/jniprefs.c @@ -0,0 +1,62 @@ +/* + * 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. + * + */ + +#include "common.h" + +#include + +void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeEnableTouchJoystick(JNIEnv *env, jclass cls, jboolean enabled) { + LOG("native enable touch joystick : %d", enabled); +} + +void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeEnableTiltJoystick(JNIEnv *env, jclass cls, jboolean enabled) { + LOG("native enable tilt joystick : %d", enabled); +} + +void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetColor(JNIEnv *env, jclass cls, jint color) { + LOG("native set hires color : %d", color); + if (color < COLOR_NONE || color > COLOR_INTERP) { + return; + } + color_mode = color; + + video_reset(); + video_setpage(!!(softswitches & SS_SCREEN)); + video_redraw(); +} + +jboolean Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetSpeakerEnabled(JNIEnv *env, jclass cls, jboolean enabled) { + // NO-OP ... speaker should always be enabled (but volume could be zero) + return true; +} + +void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetSpeakerVolume(JNIEnv *env, jclass cls, jint goesToTen) { + LOG("native set speaker volume : %d", goesToTen); + assert(goesToTen >= 0); + speaker_setVolumeZeroToTen(goesToTen); +} + +jboolean Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetMockingboardEnabled(JNIEnv *env, jclass cls, jboolean enabled) { + LOG("native set set mockingboard enabled : %d", enabled); + //assert(cpu_isPaused()); +#warning FIXME ^^^ this should be true + MB_Destroy(); + if (enabled) { + MB_Initialize(); + } +} + +void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetMockingboardVolume(JNIEnv *env, jclass cls, jint goesToTen) { + LOG("native set mockingboard volume : %d", goesToTen); + assert(goesToTen >= 0); + MB_SetVolumeZeroToTen(goesToTen); +} + diff --git a/Android/jni/sources.mk b/Android/jni/sources.mk index 79ff39dc..f2f03bd3 100644 --- a/Android/jni/sources.mk +++ b/Android/jni/sources.mk @@ -33,7 +33,7 @@ APPLE2_META_SRC = \ APPLE2_MAIN_SRC = \ $(APPLE2_SRC_PATH)/font.c $(APPLE2_SRC_PATH)/rom.c $(APPLE2_SRC_PATH)/misc.c $(APPLE2_SRC_PATH)/display.c $(APPLE2_SRC_PATH)/vm.c \ $(APPLE2_SRC_PATH)/timing.c $(APPLE2_SRC_PATH)/zlib-helpers.c $(APPLE2_SRC_PATH)/joystick.c $(APPLE2_SRC_PATH)/keys.c \ - $(APPLE2_SRC_PATH)/interface.c $(APPLE2_SRC_PATH)/disk.c $(APPLE2_SRC_PATH)/cpu-supp.c + $(APPLE2_SRC_PATH)/interface.c $(APPLE2_SRC_PATH)/disk.c $(APPLE2_SRC_PATH)/cpu-supp.c jnihooks.c APPLE2_OPTIM_CFLAGS := -g -O2 APPLE2_BASE_CFLAGS := -DAPPLE2IX=1 -DINTERFACE_TOUCH=1 -DMOBILE_DEVICE=1 -DVIDEO_OPENGL=1 -DDEBUGGER=1 -DAUDIO_ENABLED=1 -std=gnu11 $(APPLE2_OPTIM_CFLAGS) -I$(APPLE2_SRC_PATH) diff --git a/Android/jni/testcpu.mk b/Android/jni/testcpu.mk index 557323ca..bd7d5b87 100644 --- a/Android/jni/testcpu.mk +++ b/Android/jni/testcpu.mk @@ -11,7 +11,7 @@ include $(COMMON_SOURCES_MK) # Android build config LOCAL_MODULE := libapple2ix -LOCAL_SRC_FILES := jnihooks.c $(APPLE2_SRC_PATH)/test/testcommon.c $(APPLE2_SRC_PATH)/test/testcpu.c +LOCAL_SRC_FILES := $(APPLE2_SRC_PATH)/test/testcommon.c $(APPLE2_SRC_PATH)/test/testcpu.c LOCAL_CFLAGS := $(APPLE2_BASE_CFLAGS) -DTEST_CPU -DTESTING=1 -DHEADLESS=1 LOCAL_LDLIBS := -llog -landroid -lGLESv2 -lz diff --git a/Android/jni/testdisk.mk b/Android/jni/testdisk.mk index 77b5125d..d70841d8 100644 --- a/Android/jni/testdisk.mk +++ b/Android/jni/testdisk.mk @@ -11,7 +11,7 @@ include $(COMMON_SOURCES_MK) # Android build config LOCAL_MODULE := libapple2ix -LOCAL_SRC_FILES := jnihooks.c $(APPLE2_SRC_PATH)/test/testcommon.c $(APPLE2_SRC_PATH)/test/testdisk.c +LOCAL_SRC_FILES := $(APPLE2_SRC_PATH)/test/testcommon.c $(APPLE2_SRC_PATH)/test/testdisk.c LOCAL_CFLAGS := $(APPLE2_BASE_CFLAGS) -DTEST_DISK -DTESTING=1 -DCPU_TRACING=1 -DDISK_TRACING=1 -DVM_TRACING=1 LOCAL_LDLIBS := -llog -landroid -lGLESv2 -lz diff --git a/Android/jni/testdisplay.mk b/Android/jni/testdisplay.mk index 4c47b552..d9de4d04 100644 --- a/Android/jni/testdisplay.mk +++ b/Android/jni/testdisplay.mk @@ -11,7 +11,7 @@ include $(COMMON_SOURCES_MK) # Android build config LOCAL_MODULE := libapple2ix -LOCAL_SRC_FILES := jnihooks.c $(APPLE2_SRC_PATH)/test/testcommon.c $(APPLE2_SRC_PATH)/test/testdisplay.c +LOCAL_SRC_FILES := $(APPLE2_SRC_PATH)/test/testcommon.c $(APPLE2_SRC_PATH)/test/testdisplay.c LOCAL_CFLAGS := $(APPLE2_BASE_CFLAGS) -DTEST_DISPLAY -DTESTING=1 LOCAL_LDLIBS := -llog -landroid -lGLESv2 -lz diff --git a/Android/jni/testvm.mk b/Android/jni/testvm.mk index 8f5d1807..db897bb8 100644 --- a/Android/jni/testvm.mk +++ b/Android/jni/testvm.mk @@ -11,7 +11,7 @@ include $(COMMON_SOURCES_MK) # Android build config LOCAL_MODULE := libapple2ix -LOCAL_SRC_FILES := jnihooks.c $(APPLE2_SRC_PATH)/test/testcommon.c $(APPLE2_SRC_PATH)/test/testvm.c +LOCAL_SRC_FILES := $(APPLE2_SRC_PATH)/test/testcommon.c $(APPLE2_SRC_PATH)/test/testvm.c LOCAL_CFLAGS := $(APPLE2_BASE_CFLAGS) -DTEST_VM -DTESTING=1 -DCPU_TRACING=1 -DDISK_TRACING=1 -DVM_TRACING=1 LOCAL_LDLIBS := -llog -landroid -lGLESv2 -lz