Merge branch 'develop' ... latest stable Linux, Android, Mac, iOS work

This commit is contained in:
Aaron Culliney 2016-01-09 14:26:14 -08:00
commit 4eaa7137a0
257 changed files with 17122 additions and 2890 deletions

View File

@ -11,7 +11,6 @@
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
<entry name="!?*.aj" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">

View File

@ -27,6 +27,25 @@
</value>
</option>
</component>
<component name="ProjectInspectionProfilesVisibleTreeState">
<entry key="Project Default">
<profile-state>
<expanded-state>
<State>
<id />
</State>
<State>
<id>Spelling</id>
</State>
</expanded-state>
<selected-state>
<State>
<id>Spelling</id>
</State>
</selected-state>
</profile-state>
</entry>
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
@ -37,10 +56,38 @@
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
<component name="masterDetails">
<states>
<state key="Copyright.UI">
<settings>
<last-edited>deadc0de.org</last-edited>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
<state key="ProjectJDKs.UI">
<settings>
<last-edited>Android API 21 Platform</last-edited>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
</states>
</component>
</project>

View File

@ -27,8 +27,8 @@ android {
applicationId "org.deadc0de.apple2ix.basic"
minSdkVersion 10
targetSdkVersion 23
versionCode 7
versionName "1.0.4"
versionCode 15
versionName "1.1.5"
ndk {
moduleName "apple2ix"
}

View File

@ -0,0 +1,140 @@
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.inputmanagercompat;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.view.InputDevice;
import android.view.MotionEvent;
public interface InputManagerCompat {
/**
* Gets information about the input device with the specified id.
*
* @param id The device id
* @return The input device or null if not found
*/
public InputDevice getInputDevice(int id);
/**
* Gets the ids of all input devices in the system.
*
* @return The input device ids.
*/
public int[] getInputDeviceIds();
/**
* Registers an input device listener to receive notifications about when
* input devices are added, removed or changed.
*
* @param listener The listener to register.
* @param handler The handler on which the listener should be invoked, or
* null if the listener should be invoked on the calling thread's
* looper.
*/
public void registerInputDeviceListener(InputManagerCompat.InputDeviceListener listener,
Handler handler);
/**
* Unregisters an input device listener.
*
* @param listener The listener to unregister.
*/
public void unregisterInputDeviceListener(InputManagerCompat.InputDeviceListener listener);
/*
* The following three calls are to simulate V16 behavior on pre-Jellybean
* devices. If you don't call them, your callback will never be called
* pre-API 16.
*/
/**
* Pass the motion events to the InputManagerCompat. This is used to
* optimize for polling for controllers. If you do not pass these events in,
* polling will cause regular object creation.
*
* @param event the motion event from the app
*/
public void onGenericMotionEvent(MotionEvent event);
/**
* Tell the V9 input manager that it should stop polling for disconnected
* devices. You can call this during onPause in your activity, although you
* might want to call it whenever your game is not active (or whenever you
* don't care about being notified of new input devices)
*/
public void onPause();
/**
* Tell the V9 input manager that it should start polling for disconnected
* devices. You can call this during onResume in your activity, although you
* might want to call it less often (only when the gameplay is actually
* active)
*/
public void onResume();
public interface InputDeviceListener {
/**
* Called whenever the input manager detects that a device has been
* added. This will only be called in the V9 version when a motion event
* is detected.
*
* @param deviceId The id of the input device that was added.
*/
void onInputDeviceAdded(int deviceId);
/**
* Called whenever the properties of an input device have changed since
* they were last queried. This will not be called for the V9 version of
* the API.
*
* @param deviceId The id of the input device that changed.
*/
void onInputDeviceChanged(int deviceId);
/**
* Called whenever the input manager detects that a device has been
* removed. For the V9 version, this can take some time depending on the
* poll rate.
*
* @param deviceId The id of the input device that was removed.
*/
void onInputDeviceRemoved(int deviceId);
}
/**
* Use this to construct a compatible InputManager.
*/
public static class Factory {
/**
* Constructs and returns a compatible InputManger
*
* @param context the Context that will be used to get the system
* service from
* @return a compatible implementation of InputManager
*/
public static InputManagerCompat getInputManager(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
return new InputManagerV16(context);
} else {
return null;
}
}
}
}

View File

@ -0,0 +1,107 @@
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.inputmanagercompat;
import android.annotation.TargetApi;
import android.content.Context;
import android.hardware.input.InputManager;
import android.os.Build;
import android.os.Handler;
import android.view.InputDevice;
import android.view.MotionEvent;
import java.util.HashMap;
import java.util.Map;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public class InputManagerV16 implements InputManagerCompat {
private final InputManager mInputManager;
private final Map<InputManagerCompat.InputDeviceListener, V16InputDeviceListener> mListeners;
public InputManagerV16(Context context) {
mInputManager = (InputManager) context.getSystemService(Context.INPUT_SERVICE);
mListeners = new HashMap<InputManagerCompat.InputDeviceListener, V16InputDeviceListener>();
}
@Override
public InputDevice getInputDevice(int id) {
return mInputManager.getInputDevice(id);
}
@Override
public int[] getInputDeviceIds() {
return mInputManager.getInputDeviceIds();
}
static class V16InputDeviceListener implements InputManager.InputDeviceListener {
final InputManagerCompat.InputDeviceListener mIDL;
public V16InputDeviceListener(InputDeviceListener idl) {
mIDL = idl;
}
@Override
public void onInputDeviceAdded(int deviceId) {
mIDL.onInputDeviceAdded(deviceId);
}
@Override
public void onInputDeviceChanged(int deviceId) {
mIDL.onInputDeviceChanged(deviceId);
}
@Override
public void onInputDeviceRemoved(int deviceId) {
mIDL.onInputDeviceRemoved(deviceId);
}
}
@Override
public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) {
V16InputDeviceListener v16Listener = new V16InputDeviceListener(listener);
mInputManager.registerInputDeviceListener(v16Listener, handler);
mListeners.put(listener, v16Listener);
}
@Override
public void unregisterInputDeviceListener(InputDeviceListener listener) {
V16InputDeviceListener curListener = mListeners.remove(listener);
if (null != curListener)
{
mInputManager.unregisterInputDeviceListener(curListener);
}
}
@Override
public void onGenericMotionEvent(MotionEvent event) {
// unused in V16
}
@Override
public void onPause() {
// unused in V16
}
@Override
public void onResume() {
// unused in V16
}
}

View File

@ -11,17 +11,17 @@
package org.deadc0de.apple2ix;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.AudioManager;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@ -39,7 +39,6 @@ import org.deadc0de.apple2ix.basic.R;
public class Apple2Activity extends Activity {
private final static String TAG = "Apple2Activity";
private final static int MAX_FINGERS = 32;// HACK ...
private static volatile boolean DEBUG_STRICT = false;
private Apple2View mView = null;
@ -54,9 +53,6 @@ public class Apple2Activity extends Activity {
private AtomicBoolean mPausing = new AtomicBoolean(false);
private float[] mXCoords = new float[MAX_FINGERS];
private float[] mYCoords = new float[MAX_FINGERS];
// non-null if we failed to load/link the native code ... likely we are running on some bizarre 'droid variant
private static Throwable sNativeBarfedThrowable = null;
private static boolean sNativeBarfed = false;
@ -70,44 +66,33 @@ public class Apple2Activity extends Activity {
}
}
public final static long NATIVE_TOUCH_HANDLED = (1 << 0);
public final static long NATIVE_TOUCH_REQUEST_SHOW_MENU = (1 << 1);
public final static int REQUEST_PERMISSION_RWSTORE = 42;
public final static long NATIVE_TOUCH_KEY_TAP = (1 << 4);
public final static long NATIVE_TOUCH_KBD = (1 << 5);
public final static long NATIVE_TOUCH_JOY = (1 << 6);
public final static long NATIVE_TOUCH_MENU = (1 << 7);
public final static long NATIVE_TOUCH_JOY_KPAD = (1 << 8);
private static native void nativeOnCreate(String dataDir, int sampleRate, int monoBufferSize, int stereoBufferSize);
public final static long NATIVE_TOUCH_INPUT_DEVICE_CHANGED = (1 << 16);
public final static long NATIVE_TOUCH_CPU_SPEED_DEC = (1 << 17);
public final static long NATIVE_TOUCH_CPU_SPEED_INC = (1 << 18);
private static native void nativeOnKeyDown(int keyCode, int metaState);
public final static long NATIVE_TOUCH_ASCII_SCANCODE_SHIFT = 32;
public final static long NATIVE_TOUCH_ASCII_SCANCODE_MASK = 0xFFFFL;
public final static long NATIVE_TOUCH_ASCII_MASK = 0xFF00L;
public final static long NATIVE_TOUCH_SCANCODE_MASK = 0x00FFL;
private static native void nativeOnKeyUp(int keyCode, int metaState);
private native void nativeOnCreate(String dataDir, int sampleRate, int monoBufferSize, int stereoBufferSize);
private static native void nativeSaveState(String path);
private native void nativeOnKeyDown(int keyCode, int metaState);
private static native String nativeLoadState(String path);
private native void nativeOnKeyUp(int keyCode, int metaState);
private static native void nativeEmulationResume();
public native void nativeEmulationResume();
private static native void nativeEmulationPause();
public native void nativeEmulationPause();
private static native void nativeOnQuit();
public native void nativeOnQuit();
private static native void nativeReboot();
public native long nativeOnTouch(int action, int pointerCount, int pointerIndex, float[] xCoords, float[] yCoords);
private static native void nativeChooseDisk(String path, boolean driveA, boolean readOnly);
public native void nativeReboot();
public native void nativeChooseDisk(String path, boolean driveA, boolean readOnly);
public native void nativeEjectDisk(boolean driveA);
private static native void nativeEjectDisk(boolean driveA);
public final static boolean isNativeBarfed() {
return sNativeBarfed;
}
@Override
public void onCreate(Bundle savedInstanceState) {
@ -148,12 +133,37 @@ public class Apple2Activity extends Activity {
String dataDir = Apple2DisksMenu.getDataDir(this);
nativeOnCreate(dataDir, sampleRate, monoBufferSize, stereoBufferSize);
final boolean firstTime = !Apple2Preferences.FIRST_TIME_CONFIGURED.booleanValue(this);
Apple2Preferences.FIRST_TIME_CONFIGURED.saveBoolean(this, true);
final boolean firstTime = (Apple2Preferences.EMULATOR_VERSION.intValue(this) != BuildConfig.VERSION_CODE);
if (firstTime) {
// allow for primitive migrations as needed
Apple2Preferences.EMULATOR_VERSION.saveInt(this, BuildConfig.VERSION_CODE);
Log.v(TAG, "Triggering migration to Apple2ix version : " + BuildConfig.VERSION_NAME);
}
showSplashScreen(!firstTime);
Apple2CrashHandler.getInstance().checkForCrashes(this);
boolean extperm = true;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// On Marshmallow+ specifically ask for permission to read/write storage
String readPermission = Manifest.permission.READ_EXTERNAL_STORAGE;
String writePermission = Manifest.permission.WRITE_EXTERNAL_STORAGE;
int hasReadPermission = checkSelfPermission(readPermission);
int hasWritePermission = checkSelfPermission(writePermission);
ArrayList<String> permissions = new ArrayList<String>();
if (hasReadPermission != PackageManager.PERMISSION_GRANTED) {
permissions.add(readPermission);
}
if (hasWritePermission != PackageManager.PERMISSION_GRANTED) {
permissions.add(writePermission);
}
if (!permissions.isEmpty()) {
extperm = false;
String[] params = permissions.toArray(new String[permissions.size()]);
requestPermissions(params, REQUEST_PERMISSION_RWSTORE);
}
}
mGraphicsInitializedRunnable = new Runnable() {
@Override
public void run() {
@ -165,11 +175,15 @@ public class Apple2Activity extends Activity {
};
// first-time initializations
final boolean externalStoragePermission = extperm;
if (firstTime) {
new Thread(new Runnable() {
@Override
public void run() {
Apple2DisksMenu.firstTime(Apple2Activity.this);
Apple2DisksMenu.exposeAPKAssets(Apple2Activity.this);
if (externalStoragePermission) {
Apple2DisksMenu.exposeAPKAssetsToExternal(Apple2Activity.this);
}
mSplashScreen.setDismissable(true);
Log.d(TAG, "Finished first time copying...");
}
@ -192,6 +206,26 @@ public class Apple2Activity extends Activity {
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
// We should already be gracefully handling the case where user denies access.
if (requestCode == REQUEST_PERMISSION_RWSTORE) {
boolean grantedPermissions = true;
for (int grant : grantResults) {
if (grant == PackageManager.PERMISSION_DENIED) {
grantedPermissions = false;
break;
}
}
if (grantedPermissions) {
// this will force copying APK files (now that we have permission
Apple2DisksMenu.exposeAPKAssetsToExternal(Apple2Activity.this);
} // else ... we keep nagging on app startup ...
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
@Override
protected void onResume() {
super.onResume();
@ -234,21 +268,23 @@ public class Apple2Activity extends Activity {
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (sNativeBarfed) {
return true;
if (Apple2Activity.isNativeBarfed()) {
return super.onKeyDown(keyCode, event);
}
if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) || (keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) || (keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
return false;
return super.onKeyDown(keyCode, event);
}
nativeOnKeyDown(keyCode, event.getMetaState());
return true;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (sNativeBarfed) {
return true;
if (Apple2Activity.isNativeBarfed()) {
return super.onKeyUp(keyCode, event);
}
if (keyCode == KeyEvent.KEYCODE_BACK) {
Apple2MenuView apple2MenuView = peekApple2View();
if (apple2MenuView == null) {
@ -261,106 +297,11 @@ public class Apple2Activity extends Activity {
showMainMenu();
return true;
} else if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) || (keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) || (keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
return false;
} else {
nativeOnKeyUp(keyCode, event.getMetaState());
return true;
return super.onKeyUp(keyCode, event);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
do {
if (sNativeBarfed) {
break;
}
if (mMainMenu == null) {
break;
}
Apple2MenuView apple2MenuView = peekApple2View();
if ((apple2MenuView != null) && (!apple2MenuView.isCalibrating())) {
break;
}
//printSamples(event);
int action = event.getActionMasked();
int pointerIndex = event.getActionIndex();
int pointerCount = event.getPointerCount();
for (int i = 0; i < pointerCount/* && i < MAX_FINGERS */; i++) {
mXCoords[i] = event.getX(i);
mYCoords[i] = event.getY(i);
}
long nativeFlags = nativeOnTouch(action, pointerCount, pointerIndex, mXCoords, mYCoords);
if ((nativeFlags & NATIVE_TOUCH_HANDLED) == 0) {
break;
}
if ((nativeFlags & NATIVE_TOUCH_REQUEST_SHOW_MENU) != 0) {
mMainMenu.show();
}
if ((nativeFlags & NATIVE_TOUCH_KEY_TAP) != 0) {
if (Apple2Preferences.KEYBOARD_CLICK_ENABLED.booleanValue(this)) {
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
if (am != null) {
am.playSoundEffect(AudioManager.FX_KEY_CLICK);
}
}
if ((apple2MenuView != null) && apple2MenuView.isCalibrating()) {
long asciiScancodeLong = nativeFlags & (NATIVE_TOUCH_ASCII_SCANCODE_MASK << NATIVE_TOUCH_ASCII_SCANCODE_SHIFT);
int asciiInt = (int) (asciiScancodeLong >> (NATIVE_TOUCH_ASCII_SCANCODE_SHIFT + 8));
int scancode = (int) ((asciiScancodeLong >> NATIVE_TOUCH_ASCII_SCANCODE_SHIFT) & 0xFFL);
char ascii = (char) asciiInt;
apple2MenuView.onKeyTapCalibrationEvent(ascii, scancode);
}
}
if ((nativeFlags & NATIVE_TOUCH_MENU) == 0) {
break;
}
// handle menu-specific actions
if ((nativeFlags & NATIVE_TOUCH_INPUT_DEVICE_CHANGED) != 0) {
Apple2Preferences.TouchDeviceVariant nextVariant;
if ((nativeFlags & NATIVE_TOUCH_KBD) != 0) {
nextVariant = Apple2Preferences.TouchDeviceVariant.KEYBOARD;
} else if ((nativeFlags & NATIVE_TOUCH_JOY) != 0) {
nextVariant = Apple2Preferences.TouchDeviceVariant.JOYSTICK;
} else if ((nativeFlags & NATIVE_TOUCH_JOY_KPAD) != 0) {
nextVariant = Apple2Preferences.TouchDeviceVariant.JOYSTICK_KEYPAD;
} else {
int touchDevice = Apple2Preferences.nativeGetCurrentTouchDevice();
nextVariant = Apple2Preferences.TouchDeviceVariant.next(touchDevice);
}
Apple2Preferences.CURRENT_TOUCH_DEVICE.saveTouchDevice(this, nextVariant);
} else if ((nativeFlags & NATIVE_TOUCH_CPU_SPEED_DEC) != 0) {
int percentSpeed = Apple2Preferences.nativeGetCPUSpeed();
if (percentSpeed > 400) { // HACK: max value from native side
percentSpeed = 375;
} else if (percentSpeed > 100) {
percentSpeed -= 25;
} else {
percentSpeed -= 5;
}
Apple2Preferences.CPU_SPEED_PERCENT.saveInt(this, percentSpeed);
} else if ((nativeFlags & NATIVE_TOUCH_CPU_SPEED_INC) != 0) {
int percentSpeed = Apple2Preferences.nativeGetCPUSpeed();
if (percentSpeed >= 100) {
percentSpeed += 25;
} else {
percentSpeed += 5;
}
Apple2Preferences.CPU_SPEED_PERCENT.saveInt(this, percentSpeed);
}
} while (false);
return super.onTouchEvent(event);
nativeOnKeyUp(keyCode, event.getMetaState());
return true;
}
public void showMainMenu() {
@ -410,7 +351,7 @@ public class Apple2Activity extends Activity {
/* ... */
}
File storageDir = Apple2DisksMenu.getExternalStorageDirectory();
File storageDir = Apple2DisksMenu.getExternalStorageDirectory(Apple2Activity.this);
if (storageDir != null) {
String storagePath = storageDir.getAbsolutePath();
if (diskPath.contains(storagePath)) {
@ -472,23 +413,13 @@ public class Apple2Activity extends Activity {
}
public synchronized void pushApple2View(Apple2MenuView apple2MenuView) {
//
mMenuStack.add(apple2MenuView);
View menuView = apple2MenuView.getView();
nativeEmulationPause();
addContentView(menuView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
}
public synchronized Apple2MenuView popApple2View() {
int lastIndex = mMenuStack.size() - 1;
if (lastIndex < 0) {
return null;
}
Apple2MenuView apple2MenuView = mMenuStack.remove(lastIndex);
_disposeApple2View(apple2MenuView);
return apple2MenuView;
}
public synchronized Apple2MenuView peekApple2View() {
int lastIndex = mMenuStack.size() - 1;
if (lastIndex < 0) {
@ -565,44 +496,55 @@ public class Apple2Activity extends Activity {
}
}
public void maybeResumeCPU() {
public boolean isEmulationPaused() {
boolean mainMenuShowing = (mMainMenu != null && mMainMenu.isShowing());
boolean menusShowing = (mMenuStack.size() > 0);
return mainMenuShowing || menusShowing;
}
public void maybeResumeEmulation() {
if (mMenuStack.size() == 0 && !mPausing.get()) {
nativeEmulationResume();
}
}
public void maybeQuitApp() {
public void pauseEmulation() {
nativeEmulationPause();
AlertDialog quitDialog = new AlertDialog.Builder(this).setIcon(R.drawable.ic_launcher).setCancelable(true).setTitle(R.string.quit_really).setMessage(R.string.quit_warning).setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
nativeOnQuit();
Apple2Activity.this.finish();
new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
// ...
}
System.exit(0);
}
}.run();
}
}).setNegativeButton(R.string.no, null).create();
registerAndShowDialog(quitDialog);
}
public void maybeReboot() {
nativeEmulationPause();
AlertDialog rebootDialog = new AlertDialog.Builder(this).setIcon(R.drawable.ic_launcher).setCancelable(true).setTitle(R.string.reboot_really).setMessage(R.string.reboot_warning).setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void rebootEmulation() {
nativeReboot();
}
public void saveState(String stateFile) {
nativeSaveState(stateFile);
}
public String loadState(String stateFile) {
return Apple2Activity.nativeLoadState(stateFile);
}
public void chooseDisk(String path, boolean driveA, boolean readOnly) {
nativeChooseDisk(path, driveA, readOnly);
}
public void ejectDisk(boolean driveA) {
nativeEjectDisk(driveA);
}
public void quitEmulator() {
nativeOnQuit();
finish();
new Runnable() {
@Override
public void onClick(DialogInterface dialog, int which) {
nativeReboot();
Apple2Activity.this.mMainMenu.dismiss();
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
// ...
}
System.exit(0);
}
}).setNegativeButton(R.string.no, null).create();
registerAndShowDialog(rebootDialog);
}.run();
}
}

View File

@ -50,25 +50,6 @@ public class Apple2AudioSettingsMenu extends Apple2AbstractMenu {
}
enum SETTINGS implements Apple2AbstractMenu.IMenuEnum {
SPEAKER_ENABLED {
@Override
public final String getTitle(Apple2Activity activity) {
return activity.getResources().getString(R.string.speaker_enable);
}
@Override
public final String getSummary(Apple2Activity activity) {
return activity.getResources().getString(R.string.speaker_enable_summary);
}
@Override
public View getView(final Apple2Activity activity, View convertView) {
convertView = _basicView(activity, this, convertView);
CheckBox cb = _addCheckbox(activity, this, convertView, true);
cb.setEnabled(false);
return convertView;
}
},
SPEAKER_VOLUME {
@Override
public final String getTitle(Apple2Activity activity) {

View File

@ -14,6 +14,8 @@ package org.deadc0de.apple2ix;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
@ -210,6 +212,7 @@ public class Apple2CrashHandler {
summary.append("MODEL: ").append(Build.MODEL).append("\n");
summary.append("MANUFACTURER: ").append(Build.MANUFACTURER).append("\n");
summary.append("DEVICE: ").append(Build.DEVICE).append("\n");
summary.append("SDK: ").append(Build.VERSION.SDK_INT).append("\n");
summary.append("SAMPLE RATE: ").append(sampleRate).append("\n");
summary.append("MONO BUFSIZE: ").append(monoBufferSize).append("\n");
summary.append("STEREO BUFSIZE: ").append(stereoBufferSize).append("\n");
@ -217,6 +220,13 @@ public class Apple2CrashHandler {
summary.append("GPU RENDERER: ").append(Apple2Preferences.GL_RENDERER.stringValue(activity)).append("\n");
summary.append("GPU VERSION: ").append(Apple2Preferences.GL_VERSION.stringValue(activity)).append("\n");
try {
PackageInfo pInfo = activity.getPackageManager().getPackageInfo(activity.getPackageName(), 0);
summary.append("APP VERSION: ").append(pInfo.versionName).append("\n");
} catch (PackageManager.NameNotFoundException e) {
// ...
}
allCrashData.append(summary);
File[] nativeCrashes = _nativeCrashFiles(activity);

View File

@ -42,8 +42,10 @@ import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.zip.GZIPOutputStream;
import org.deadc0de.apple2ix.basic.R;
@ -75,10 +77,10 @@ public class Apple2DisksMenu implements Apple2MenuView {
}
});
getExternalStorageDirectory();
getExternalStorageDirectory(activity);
}
public static File getExternalStorageDirectory() {
public static File getExternalStorageDirectory(Apple2Activity activity) {
do {
if (sExternalFilesDir != null) {
@ -135,29 +137,27 @@ public class Apple2DisksMenu implements Apple2MenuView {
return sDataDir;
}
public static void firstTime(Apple2Activity activity) {
public static void exposeAPKAssetsToExternal(Apple2Activity activity) {
getExternalStorageDirectory(activity);
if (sExternalFilesDir == null) {
return;
}
final ProgressBar bar = (ProgressBar) activity.findViewById(R.id.crash_progressBar);
try {
bar.setVisibility(View.VISIBLE);
bar.setIndeterminate(true);
} catch (NullPointerException npe) {
Log.v(TAG, "Whoa, avoided NPE in first time #1");
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
bar.setVisibility(View.VISIBLE);
bar.setIndeterminate(true);
} catch (NullPointerException npe) {
Log.v(TAG, "Avoid NPE in exposeAPKAssetsToExternal #1");
}
}
});
getDataDir(activity);
Log.d(TAG, "First time copying stuff-n-things out of APK for ease-of-NDK access...");
getExternalStorageDirectory();
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"disks", /*to location:*/new File(sDataDir, "disks").getAbsolutePath());
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"keyboards", /*to location:*/new File(sDataDir, "keyboards").getAbsolutePath());
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"shaders", /*to location:*/new File(sDataDir, "shaders").getAbsolutePath());
// expose keyboards to modding
if (sExternalFilesDir != null) {
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"keyboards", /*to location:*/sExternalFilesDir.getAbsolutePath());
}
Log.v(TAG, "Overwriting system files in /sdcard/apple2ix/ (external storage) ...");
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"keyboards", /*to location:*/sExternalFilesDir.getAbsolutePath(), false);
activity.runOnUiThread(new Runnable() {
@Override
@ -166,14 +166,57 @@ public class Apple2DisksMenu implements Apple2MenuView {
bar.setVisibility(View.INVISIBLE);
bar.setIndeterminate(false);
} catch (NullPointerException npe) {
Log.v(TAG, "Whoa, avoided NPE in first time #2");
Log.v(TAG, "Avoid NPE in exposeAPKAssetsToExternal #2");
}
}
});
}
public static void exposeAPKAssets(Apple2Activity activity) {
final ProgressBar bar = (ProgressBar) activity.findViewById(R.id.crash_progressBar);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
bar.setVisibility(View.VISIBLE);
bar.setIndeterminate(true);
} catch (NullPointerException npe) {
Log.v(TAG, "Avoid NPE in exposeAPKAssets #1");
}
}
});
getDataDir(activity);
// FIXME TODO : Heavy-handed migration to 1.1.3 ...
recursivelyDelete(new File(new File(sDataDir, "disks").getAbsolutePath(), "blanks"));
recursivelyDelete(new File(new File(sDataDir, "disks").getAbsolutePath(), "demo"));
recursivelyDelete(new File(new File(sDataDir, "disks").getAbsolutePath(), "eamon"));
recursivelyDelete(new File(new File(sDataDir, "disks").getAbsolutePath(), "logo"));
recursivelyDelete(new File(new File(sDataDir, "disks").getAbsolutePath(), "miscgame"));
Log.d(TAG, "First time copying stuff-n-things out of APK for ease-of-NDK access...");
getExternalStorageDirectory(activity);
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"disks", /*to location:*/new File(sDataDir, "disks").getAbsolutePath(), true);
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"keyboards", /*to location:*/new File(sDataDir, "keyboards").getAbsolutePath(), false);
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"shaders", /*to location:*/new File(sDataDir, "shaders").getAbsolutePath(), false);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
bar.setVisibility(View.INVISIBLE);
bar.setIndeterminate(false);
} catch (NullPointerException npe) {
Log.v(TAG, "Avoid NPE in exposeAPKAssets #1");
}
}
});
}
public static void exposeSymbols(Apple2Activity activity) {
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"symbols", /*to location:*/new File(sDataDir, "symbols").getAbsolutePath());
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"symbols", /*to location:*/new File(sDataDir, "symbols").getAbsolutePath(), false);
}
public static void unexposeSymbols(Apple2Activity activity) {
@ -317,6 +360,7 @@ public class Apple2DisksMenu implements Apple2MenuView {
return pathBuffer.toString();
}
// TODO FIXME : WARNING : this is super dangerous if there are symlinks !!!
private static void recursivelyDelete(File file) {
if (file.isDirectory()) {
for (File f : file.listFiles()) {
@ -328,7 +372,7 @@ public class Apple2DisksMenu implements Apple2MenuView {
}
}
private static void recursivelyCopyAPKAssets(Apple2Activity activity, String srcFileOrDir, String dstFileOrDir) {
private static void recursivelyCopyAPKAssets(Apple2Activity activity, String srcFileOrDir, String dstFileOrDir, boolean shouldGzip) {
AssetManager assetManager = activity.getAssets();
final int maxAttempts = 5;
@ -368,19 +412,23 @@ public class Apple2DisksMenu implements Apple2MenuView {
}
for (String filename : files) {
// iterate on files and subdirectories
recursivelyCopyAPKAssets(activity, srcFileOrDir + File.separator + filename, dstFileOrDir + File.separator + filename);
recursivelyCopyAPKAssets(activity, srcFileOrDir + File.separator + filename, dstFileOrDir + File.separator + filename, shouldGzip);
}
return;
}
// presumably this is a file, not a subdirectory
InputStream is = null;
FileOutputStream os = null;
OutputStream os = null;
attempts = 0;
do {
try {
is = assetManager.open(srcFileOrDir);
os = new FileOutputStream(dstFileOrDir);
if (shouldGzip) {
os = new GZIPOutputStream(new FileOutputStream(dstFileOrDir + ".gz"));
} else {
os = new FileOutputStream(dstFileOrDir);
}
copyFile(is, os);
break;
} catch (InterruptedIOException e) {
@ -412,7 +460,7 @@ public class Apple2DisksMenu implements Apple2MenuView {
} while (attempts < maxAttempts);
}
private static void copyFile(InputStream is, FileOutputStream os) throws IOException {
private static void copyFile(InputStream is, OutputStream os) throws IOException {
final int BUF_SZ = 4096;
byte[] buf = new byte[BUF_SZ];
while (true) {
@ -463,7 +511,7 @@ public class Apple2DisksMenu implements Apple2MenuView {
Arrays.sort(files);
getExternalStorageDirectory();
getExternalStorageDirectory(mActivity);
final boolean includeExternalStoragePath = (sExternalFilesDir != null && isRootPath);
final boolean includeDownloadsPath = (sDownloadFilesDir != null && isRootPath);
final int offset = includeExternalStoragePath ? (includeDownloadsPath ? 2 : 1) : (includeDownloadsPath ? 1 : 0);
@ -528,7 +576,7 @@ public class Apple2DisksMenu implements Apple2MenuView {
ejectButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mActivity.nativeEjectDisk(/*driveA:*/true);
mActivity.ejectDisk(/*driveA:*/true);
Apple2Preferences.CURRENT_DISK_A.saveString(mActivity, "");
dynamicSetup();
}
@ -540,7 +588,7 @@ public class Apple2DisksMenu implements Apple2MenuView {
ejectButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mActivity.nativeEjectDisk(/*driveA:*/false);
mActivity.ejectDisk(/*driveA:*/false);
Apple2Preferences.CURRENT_DISK_B.saveString(mActivity, "");
dynamicSetup();
}
@ -582,17 +630,16 @@ public class Apple2DisksMenu implements Apple2MenuView {
final String imageName = str;
if (imageName.equals(Apple2Preferences.CURRENT_DISK_A.stringValue(mActivity))) {
mActivity.nativeEjectDisk(/*driveA:*/true);
mActivity.ejectDisk(/*driveA:*/true);
Apple2Preferences.CURRENT_DISK_A.saveString(mActivity, "");
dynamicSetup();
return;
}
if (imageName.equals(Apple2Preferences.CURRENT_DISK_B.stringValue(mActivity))) {
mActivity.nativeEjectDisk(/*driveA:*/false);
mActivity.ejectDisk(/*driveA:*/false);
Apple2Preferences.CURRENT_DISK_B.saveString(mActivity, "");
dynamicSetup();
return;
}
String title = mActivity.getResources().getString(R.string.header_disks);

View File

@ -329,6 +329,30 @@ public class Apple2JoystickSettingsMenu extends Apple2AbstractMenu {
return convertView;
}
},
JOYSTICK_AZIMUTH_VISIBILITY {
@Override
public final String getTitle(Apple2Activity activity) {
return activity.getResources().getString(R.string.joystick_azimuth_visible);
}
@Override
public final String getSummary(Apple2Activity activity) {
return activity.getResources().getString(R.string.joystick_azimuth_visible_summary);
}
@Override
public View getView(final Apple2Activity activity, View convertView) {
convertView = _basicView(activity, this, convertView);
CheckBox cb = _addCheckbox(activity, this, convertView, Apple2Preferences.JOYSTICK_AZIMUTH_VISIBILITY.booleanValue(activity));
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Apple2Preferences.JOYSTICK_AZIMUTH_VISIBILITY.saveBoolean(activity, isChecked);
}
});
return convertView;
}
},
JOYSTICK_AXIS_ON_LEFT {
@Override
public final String getTitle(Apple2Activity activity) {
@ -415,7 +439,7 @@ public class Apple2JoystickSettingsMenu extends Apple2AbstractMenu {
@Override
public void showValue(int progress, final TextView seekBarValue) {
int threshold = progress * Apple2Preferences.JOYSTICK_BUTTON_THRESHOLD_STEP;
int threshold = progress * Apple2Preferences.getJoystickButtonSwitchThresholdScale(activity);
seekBarValue.setText("" + threshold + " pts");
}
});

View File

@ -91,10 +91,34 @@ public class Apple2KeyboardSettingsMenu extends Apple2AbstractMenu {
if (position < 0 || position >= SETTINGS.size) {
throw new ArrayIndexOutOfBoundsException();
}
return true;
return (position != SETTINGS.KEYBOARD_VISIBILITY_INACTIVE.ordinal() && position != SETTINGS.KEYBOARD_VISIBILITY_ACTIVE.ordinal());
}
protected enum SETTINGS implements Apple2AbstractMenu.IMenuEnum {
TOUCH_MENU_ENABLED {
@Override
public final String getTitle(Apple2Activity activity) {
return activity.getResources().getString(R.string.touch_menu_enable);
}
@Override
public final String getSummary(Apple2Activity activity) {
return activity.getResources().getString(R.string.touch_menu_enable_summary);
}
@Override
public View getView(final Apple2Activity activity, View convertView) {
convertView = _basicView(activity, this, convertView);
CheckBox cb = _addCheckbox(activity, this, convertView, Apple2Preferences.TOUCH_MENU_ENABLED.booleanValue(activity));
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Apple2Preferences.TOUCH_MENU_ENABLED.saveBoolean(activity, isChecked);
}
});
return convertView;
}
},
KEYBOARD_VISIBILITY_INACTIVE {
@Override
public final String getTitle(Apple2Activity activity) {
@ -226,7 +250,7 @@ public class Apple2KeyboardSettingsMenu extends Apple2AbstractMenu {
@Override
public void handleSelection(final Apple2Activity activity, final Apple2AbstractMenu settingsMenu, boolean isChecked) {
File extKeyboardDir = Apple2DisksMenu.getExternalStorageDirectory();
File extKeyboardDir = Apple2DisksMenu.getExternalStorageDirectory(activity);
FilenameFilter kbdJsonFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
@ -289,6 +313,31 @@ public class Apple2KeyboardSettingsMenu extends Apple2AbstractMenu {
}
});
}
},
KEYBOARD_GLYPH_SCALE {
@Override
public final String getTitle(Apple2Activity activity) {
return activity.getResources().getString(R.string.keyboard_glyph_scale);
}
@Override
public final String getSummary(Apple2Activity activity) {
return activity.getResources().getString(R.string.keyboard_glyph_scale_summary);
}
@Override
public View getView(final Apple2Activity activity, View convertView) {
convertView = _basicView(activity, this, convertView);
int glyphScale = Apple2Preferences.KEYBOARD_GLYPH_SCALE.intValue(activity);
CheckBox cb = _addCheckbox(activity, this, convertView, glyphScale > 1);
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Apple2Preferences.KEYBOARD_GLYPH_SCALE.saveInt(activity, isChecked ? 2 : 1);
}
});
return convertView;
}
};
public static final int size = SETTINGS.values().length;

View File

@ -65,18 +65,18 @@ public class Apple2KeypadChooser implements Apple2MenuView {
mCurrentChoicePrompt.setText(getNextChoiceString() + asciiStr);
switch (mChooserState) {
case CHOOSE_TAP:
mActivity.nativeOnTouch(MotionEvent.ACTION_DOWN, 1, 0, new float[]{400.f}, new float[]{400.f});
mActivity.nativeOnTouch(MotionEvent.ACTION_UP, 1, 0, new float[]{400.f}, new float[]{400.f});
Apple2View.nativeOnTouch(MotionEvent.ACTION_DOWN, 1, 0, new float[]{400.f}, new float[]{400.f});
Apple2View.nativeOnTouch(MotionEvent.ACTION_UP, 1, 0, new float[]{400.f}, new float[]{400.f});
break;
case CHOOSE_SWIPEDOWN:
mActivity.nativeOnTouch(MotionEvent.ACTION_DOWN, 1, 0, new float[]{400.f}, new float[]{400.f});
mActivity.nativeOnTouch(MotionEvent.ACTION_MOVE, 1, 0, new float[]{400.f}, new float[]{600.f});
mActivity.nativeOnTouch(MotionEvent.ACTION_UP, 1, 0, new float[]{400.f}, new float[]{600.f});
Apple2View.nativeOnTouch(MotionEvent.ACTION_DOWN, 1, 0, new float[]{400.f}, new float[]{400.f});
Apple2View.nativeOnTouch(MotionEvent.ACTION_MOVE, 1, 0, new float[]{400.f}, new float[]{600.f});
Apple2View.nativeOnTouch(MotionEvent.ACTION_UP, 1, 0, new float[]{400.f}, new float[]{600.f});
break;
case CHOOSE_SWIPEUP:
mActivity.nativeOnTouch(MotionEvent.ACTION_DOWN, 1, 0, new float[]{400.f}, new float[]{400.f});
mActivity.nativeOnTouch(MotionEvent.ACTION_MOVE, 1, 0, new float[]{400.f}, new float[]{200.f});
mActivity.nativeOnTouch(MotionEvent.ACTION_UP, 1, 0, new float[]{400.f}, new float[]{200.f});
Apple2View.nativeOnTouch(MotionEvent.ACTION_DOWN, 1, 0, new float[]{400.f}, new float[]{400.f});
Apple2View.nativeOnTouch(MotionEvent.ACTION_MOVE, 1, 0, new float[]{400.f}, new float[]{200.f});
Apple2View.nativeOnTouch(MotionEvent.ACTION_UP, 1, 0, new float[]{400.f}, new float[]{200.f});
break;
default:
break;

View File

@ -11,7 +11,9 @@
package org.deadc0de.apple2ix;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.util.Log;
@ -27,16 +29,24 @@ import android.widget.PopupWindow;
import android.widget.TextView;
import org.deadc0de.apple2ix.basic.R;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.util.concurrent.atomic.AtomicBoolean;
public class Apple2MainMenu {
private final static int MENU_INSET = 20;
private final static String SAVE_FILE = "emulator.state";
private final static String TAG = "Apple2MainMenu";
private Apple2Activity mActivity = null;
private Apple2View mParentView = null;
private PopupWindow mMainMenuPopup = null;
private AtomicBoolean mShowingRebootQuit = new AtomicBoolean(false);
private AtomicBoolean mShowingSaveRestore = new AtomicBoolean(false);
public Apple2MainMenu(Apple2Activity activity, Apple2View parent) {
mActivity = activity;
mParentView = parent;
@ -45,52 +55,82 @@ public class Apple2MainMenu {
enum SETTINGS {
SHOW_SETTINGS {
@Override public String getTitle(Context ctx) {
@Override
public String getTitle(Context ctx) {
return ctx.getResources().getString(R.string.menu_settings);
}
@Override public String getSummary(Context ctx) {
@Override
public String getSummary(Context ctx) {
return ctx.getResources().getString(R.string.menu_settings_summary);
}
@Override public void handleSelection(Apple2MainMenu mainMenu) {
@Override
public void handleSelection(Apple2MainMenu mainMenu) {
mainMenu.showSettings();
}
},
LOAD_DISK {
@Override public String getTitle(Context ctx) {
@Override
public String getTitle(Context ctx) {
return ctx.getResources().getString(R.string.menu_disks);
}
@Override public String getSummary(Context ctx) {
@Override
public String getSummary(Context ctx) {
return ctx.getResources().getString(R.string.menu_disks_summary);
}
@Override public void handleSelection(Apple2MainMenu mainMenu) {
@Override
public void handleSelection(Apple2MainMenu mainMenu) {
mainMenu.showDisksMenu();
}
},
REBOOT_EMULATOR {
@Override public String getTitle(Context ctx) {
return ctx.getResources().getString(R.string.reboot);
SAVE_RESTORE {
@Override
public String getTitle(Context ctx) {
return ctx.getResources().getString(R.string.saverestore);
}
@Override public String getSummary(Context ctx) {
return ctx.getResources().getString(R.string.reboot_summary);
@Override
public String getSummary(Context ctx) {
return ctx.getResources().getString(R.string.saverestore_summary);
}
@Override public void handleSelection(Apple2MainMenu mainMenu) {
mainMenu.mActivity.maybeReboot();
@Override
public void handleSelection(Apple2MainMenu mainMenu) {
if (!mainMenu.mShowingSaveRestore.compareAndSet(false, true)) {
Log.v(TAG, "OMG, avoiding nasty UI race around save/restore");
return;
}
mainMenu.maybeSaveRestore();
}
},
QUIT_EMULATOR {
@Override public String getTitle(Context ctx) {
return ctx.getResources().getString(R.string.quit);
REBOOT_QUIT_EMULATOR {
@Override
public String getTitle(Context ctx) {
return ctx.getResources().getString(R.string.quit_reboot);
}
@Override public String getSummary(Context ctx) {
return ctx.getResources().getString(R.string.quit_summary);
@Override
public String getSummary(Context ctx) {
return "";
}
@Override public void handleSelection(Apple2MainMenu mainMenu) {
mainMenu.mActivity.maybeQuitApp();
@Override
public void handleSelection(Apple2MainMenu mainMenu) {
if (!mainMenu.mShowingRebootQuit.compareAndSet(false, true)) {
Log.v(TAG, "OMG, avoiding nasty UI race around quit/reboot");
return;
}
mainMenu.maybeRebootQuit();
}
};
public abstract String getTitle(Context ctx);
public abstract String getSummary(Context ctx);
public abstract void handleSelection(Apple2MainMenu mainMenu);
public static String[] titles(Context ctx) {
@ -105,11 +145,11 @@ public class Apple2MainMenu {
private void setup() {
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);
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);
LinearLayout mainPopupContainer = (LinearLayout) listLayout.findViewById(R.id.main_popup_container);
final String[] values = SETTINGS.titles(mActivity);
@ -118,10 +158,11 @@ public class Apple2MainMenu {
public boolean areAllItemsEnabled() {
return true;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView tv = (TextView)view.findViewById(android.R.id.text2);
TextView tv = (TextView) view.findViewById(android.R.id.text2);
SETTINGS setting = SETTINGS.values()[position];
tv.setText(setting.getSummary(mActivity));
return view;
@ -131,7 +172,7 @@ public class Apple2MainMenu {
mainMenuView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d(TAG, "position:"+position+" tapped...");
Log.d(TAG, "position:" + position + " tapped...");
SETTINGS setting = SETTINGS.values()[position];
setting.handleSelection(Apple2MainMenu.this);
}
@ -153,7 +194,7 @@ public class Apple2MainMenu {
maxWidth = width;
}
}
mMainMenuPopup = new PopupWindow(mainPopupContainer, maxWidth+TOTAL_MARGINS, totalHeight, true);
mMainMenuPopup = new PopupWindow(mainPopupContainer, maxWidth + TOTAL_MARGINS, totalHeight, true);
}
// This kludgery allows touching the outside or back-buttoning to dismiss
@ -162,7 +203,7 @@ public class Apple2MainMenu {
mMainMenuPopup.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
Apple2MainMenu.this.mActivity.maybeResumeCPU();
Apple2MainMenu.this.mActivity.maybeResumeEmulation();
}
});
}
@ -184,7 +225,10 @@ public class Apple2MainMenu {
return;
}
mActivity.nativeEmulationPause();
mShowingRebootQuit.set(false);
mShowingSaveRestore.set(false);
mActivity.pauseEmulation();
mMainMenuPopup.showAtLocation(mParentView, Gravity.CENTER, 0, 0);
}
@ -199,4 +243,82 @@ public class Apple2MainMenu {
public boolean isShowing() {
return mMainMenuPopup.isShowing();
}
public void maybeRebootQuit() {
mActivity.pauseEmulation();
final AtomicBoolean selectionAlreadyHandled = new AtomicBoolean(false);
AlertDialog rebootQuitDialog = new AlertDialog.Builder(mActivity).setIcon(R.drawable.ic_launcher).setCancelable(true).setTitle(R.string.quit_reboot).setMessage(R.string.quit_reboot_choice).setPositiveButton(R.string.reboot, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (!selectionAlreadyHandled.compareAndSet(false, true)) {
Log.v(TAG, "OMG, avoiding nasty UI race in reboot/quit onClick()");
return;
}
mActivity.rebootEmulation();
Apple2MainMenu.this.dismiss();
}
}).setNeutralButton(R.string.quit, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (!selectionAlreadyHandled.compareAndSet(false, true)) {
Log.v(TAG, "OMG, avoiding nasty UI race in reboot/quit onClick()");
return;
}
mActivity.quitEmulator();
}
}).setNegativeButton(R.string.cancel, null).create();
mActivity.registerAndShowDialog(rebootQuitDialog);
}
public void maybeSaveRestore() {
mActivity.pauseEmulation();
final String quickSavePath = Apple2DisksMenu.getDataDir(mActivity) + File.separator + SAVE_FILE;
final AtomicBoolean selectionAlreadyHandled = new AtomicBoolean(false);
AlertDialog saveRestoreDialog = new AlertDialog.Builder(mActivity).setIcon(R.drawable.ic_launcher).setCancelable(true).setTitle(R.string.saverestore).setMessage(R.string.saverestore_choice).setPositiveButton(R.string.save, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (!selectionAlreadyHandled.compareAndSet(false, true)) {
Log.v(TAG, "OMG, avoiding nasty UI race in save/restore onClick()");
return;
}
mActivity.saveState(quickSavePath);
Apple2MainMenu.this.dismiss();
}
}).setNeutralButton(R.string.restore, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (!selectionAlreadyHandled.compareAndSet(false, true)) {
Log.v(TAG, "OMG, avoiding nasty UI race in save/restore onClick()");
return;
}
String jsonData = mActivity.loadState(quickSavePath);
try {
JSONObject map = new JSONObject(jsonData);
String diskPath1 = map.getString("disk1");
boolean readOnly1 = map.getBoolean("readOnly1");
Apple2Preferences.CURRENT_DISK_A.setPath(mActivity, diskPath1);
Apple2Preferences.CURRENT_DISK_A_RO.saveBoolean(mActivity, readOnly1);
String diskPath2 = map.getString("disk2");
boolean readOnly2 = map.getBoolean("readOnly2");
Apple2Preferences.CURRENT_DISK_B.setPath(mActivity, diskPath2);
Apple2Preferences.CURRENT_DISK_B_RO.saveBoolean(mActivity, readOnly2);
} catch (JSONException je) {
Log.v(TAG, "OOPS : " + je);
}
Apple2MainMenu.this.dismiss();
}
}).setNegativeButton(R.string.cancel, null).create();
mActivity.registerAndShowDialog(saveRestoreDialog);
}
}

View File

@ -14,6 +14,7 @@ package org.deadc0de.apple2ix;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.util.DisplayMetrics;
import android.util.Log;
import java.io.File;
@ -21,15 +22,15 @@ import java.io.File;
import org.deadc0de.apple2ix.basic.R;
public enum Apple2Preferences {
FIRST_TIME_CONFIGURED {
EMULATOR_VERSION {
@Override
public void load(Apple2Activity activity) {
/* ... */
}
@Override
public void saveBoolean(Apple2Activity activity, boolean ignored) {
activity.getPreferences(Context.MODE_PRIVATE).edit().putBoolean(toString(), true).apply();
public void saveInt(Apple2Activity activity, int version) {
activity.getPreferences(Context.MODE_PRIVATE).edit().putInt(toString(), version).apply();
}
},
CURRENT_DISK_PATH {
@ -99,6 +100,11 @@ public enum Apple2Preferences {
activity.getPreferences(Context.MODE_PRIVATE).edit().putString(toString(), str).apply();
load(activity);
}
@Override
public void setPath(Apple2Activity activity, String str) {
activity.getPreferences(Context.MODE_PRIVATE).edit().putString(toString(), str).apply();
}
},
CURRENT_DISK_A_RO {
@Override
@ -133,6 +139,11 @@ public enum Apple2Preferences {
activity.getPreferences(Context.MODE_PRIVATE).edit().putString(toString(), str).apply();
load(activity);
}
@Override
public void setPath(Apple2Activity activity, String str) {
activity.getPreferences(Context.MODE_PRIVATE).edit().putString(toString(), str).apply();
}
},
CURRENT_DISK_B_RO {
@Override
@ -173,22 +184,6 @@ public enum Apple2Preferences {
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) {
@ -282,17 +277,16 @@ public enum Apple2Preferences {
return activity.getPreferences(Context.MODE_PRIVATE).getBoolean(toString(), true);
}
},
TOUCH_MENU_VISIBILITY {
SHOW_DISK_OPERATIONS {
@Override
public void load(Apple2Activity activity) {
int setting = intValue(activity);
float alpha = (float) setting / AUDIO_LATENCY_NUM_CHOICES;
nativeSetTouchMenuVisibility(alpha);
boolean enabled = booleanValue(activity);
nativeSetShowDiskOperationAnimation(enabled);
}
@Override
public int intValue(Apple2Activity activity) {
return activity.getPreferences(Context.MODE_PRIVATE).getInt(toString(), 5);
public boolean booleanValue(Apple2Activity activity) {
return activity.getPreferences(Context.MODE_PRIVATE).getBoolean(toString(), true);
}
},
JOYSTICK_AXIS_SENSITIVIY {
@ -327,7 +321,8 @@ public enum Apple2Preferences {
@Override
public void load(Apple2Activity activity) {
int tick = intValue(activity);
nativeSetTouchJoystickButtonSwitchThreshold(tick * JOYSTICK_BUTTON_THRESHOLD_STEP);
tick *= getJoystickButtonSwitchThresholdScale(activity);
nativeSetTouchJoystickButtonSwitchThreshold(tick);
}
@Override
@ -355,7 +350,7 @@ public enum Apple2Preferences {
@Override
public int intValue(Apple2Activity activity) {
int defaultLatency = 3; // /TAPDELAY_NUM_CHOICES * TAPDELAY_SCALE -> 0.075f
int defaultLatency = 8; // /TAPDELAY_NUM_CHOICES * TAPDELAY_SCALE -> 0.2f
return activity.getPreferences(Context.MODE_PRIVATE).getInt(toString(), defaultLatency);
}
},
@ -415,6 +410,17 @@ public enum Apple2Preferences {
return activity.getPreferences(Context.MODE_PRIVATE).getBoolean(toString(), true);
}
},
JOYSTICK_AZIMUTH_VISIBILITY {
@Override
public void load(Apple2Activity activity) {
nativeSetTouchJoystickAzimuthVisibility(booleanValue(activity));
}
@Override
public boolean booleanValue(Apple2Activity activity) {
return activity.getPreferences(Context.MODE_PRIVATE).getBoolean(toString(), true);
}
},
KEYPAD_KEYS {
@Override
public void load(Apple2Activity activity) {
@ -582,6 +588,41 @@ public enum Apple2Preferences {
return activity.getPreferences(Context.MODE_PRIVATE).getBoolean(toString(), true);
}
},
KEYBOARD_GLYPH_SCALE {
@Override
public void load(Apple2Activity activity) {
int scale = intValue(activity);
if (scale == 0) {
scale = 1;
}
nativeSetTouchKeyboardGlyphScale(scale);
}
@Override
public int intValue(Apple2Activity activity) {
int scale = activity.getPreferences(Context.MODE_PRIVATE).getInt(toString(), 0);
if (scale == 0) {
scale = 2;
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
/* calculating actual physical diagonal size appears to be problematic -- Samsung Galaxy Y reports 15" with this method
double x = Math.pow(dm.widthPixels / dm.xdpi, 2);
double y = Math.pow(dm.heightPixels / dm.ydpi, 2);
double screenInches = Math.sqrt(x + y);
Log.d(TAG, "Screen inches:" + screenInches + " w:" + dm.widthPixels + " h:" + dm.heightPixels);
*/
if (dm.widthPixels <= 480 || dm.heightPixels <= 480) {
scale = 1;
}
saveInt(activity, scale);
}
return scale;
}
},
CRASH_CHECK {
@Override
public void load(Apple2Activity activity) {
@ -853,7 +894,6 @@ public enum Apple2Preferences {
public final static String TAG = "Apple2Preferences";
public final static int JOYSTICK_BUTTON_THRESHOLD_NUM_CHOICES = DECENT_AMOUNT_OF_CHOICES;
public final static int JOYSTICK_BUTTON_THRESHOLD_STEP = 5;
public final static float JOYSTICK_AXIS_SENSITIVITY_MIN = 0.25f;
public final static float JOYSTICK_AXIS_SENSITIVITY_DEFAULT = 1.f;
@ -911,6 +951,10 @@ public enum Apple2Preferences {
load(activity);
}
public void setPath(Apple2Activity activity, String path) {
/* ... */
}
// accessors
public boolean booleanValue(Apple2Activity activity) {
@ -941,13 +985,13 @@ public enum Apple2Preferences {
for (Apple2Preferences pref : Apple2Preferences.values()) {
pref.load(activity);
}
// HACK FIXME TODO 2015/12/13 : native GLTouchDevice is conflating various things ... forcefully reset the current touch device here for now
Apple2Preferences.CURRENT_TOUCH_DEVICE.load(activity);
}
public static void resetPreferences(Apple2Activity activity) {
activity.getPreferences(Context.MODE_PRIVATE).edit().clear().commit();
FIRST_TIME_CONFIGURED.saveBoolean(activity, true);
KeypadPreset.IJKM_SPACE.apply(activity);
loadPreferences(activity);
activity.quitEmulator();
}
public String asciiString() {
@ -958,6 +1002,18 @@ public enum Apple2Preferences {
return toString() + "_SCAN";
}
public static int getJoystickButtonSwitchThresholdScale(Apple2Activity activity) {
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
int smallScreenAxis = dm.widthPixels < dm.heightPixels ? dm.widthPixels : dm.heightPixels;
int oneThirdScreenAxis = smallScreenAxis/3;
// largest switch threshold value is 1/3 small dimension of screen
return oneThirdScreenAxis/JOYSTICK_BUTTON_THRESHOLD_NUM_CHOICES;
}
// ------------------------------------------------------------------------
// internals ...
@ -1023,7 +1079,7 @@ public enum Apple2Preferences {
file = new File(fullPath);
}
if (file.exists()) {
activity.nativeChooseDisk(fullPath, isDriveA, isReadOnly);
activity.chooseDisk(fullPath, isDriveA, isReadOnly);
} else {
Log.d(TAG, "Cannot insert: " + fullPath);
}
@ -1055,14 +1111,18 @@ public enum Apple2Preferences {
private static native void nativeSetTouchJoystickVisibility(boolean visibility);
private static native void nativeSetTouchJoystickAzimuthVisibility(boolean visibility);
public static native void nativeSetTouchMenuEnabled(boolean enabled);
private static native void nativeSetTouchMenuVisibility(float alpha);
public static native void nativeSetShowDiskOperationAnimation(boolean enabled);
private static native void nativeSetTouchKeyboardVisibility(float inactiveAlpha, float activeAlpha);
private static native void nativeSetTouchKeyboardLowercaseEnabled(boolean enabled);
private static native void nativeSetTouchKeyboardGlyphScale(int scale);
public static native int nativeGetCurrentTouchDevice();
public static native int nativeGetCPUSpeed();

View File

@ -52,7 +52,7 @@ public class Apple2SettingsMenu extends Apple2AbstractMenu {
if (position < 0 || position >= SETTINGS.size) {
throw new ArrayIndexOutOfBoundsException();
}
return position != SETTINGS.TOUCH_MENU_VISIBILITY.ordinal();
return true;
}
enum SETTINGS implements Apple2AbstractMenu.IMenuEnum {
@ -194,61 +194,30 @@ public class Apple2SettingsMenu extends Apple2AbstractMenu {
});
}
},
TOUCH_MENU_ENABLED {
SHOW_DISK_OPERATIONS {
@Override
public final String getTitle(Apple2Activity activity) {
return activity.getResources().getString(R.string.touch_menu_enable);
return activity.getResources().getString(R.string.disk_show_operation);
}
@Override
public final String getSummary(Apple2Activity activity) {
return activity.getResources().getString(R.string.touch_menu_enable_summary);
return activity.getResources().getString(R.string.disk_show_operation_summary);
}
@Override
public View getView(final Apple2Activity activity, View convertView) {
convertView = _basicView(activity, this, convertView);
CheckBox cb = _addCheckbox(activity, this, convertView, Apple2Preferences.TOUCH_MENU_ENABLED.booleanValue(activity));
CheckBox cb = _addCheckbox(activity, this, convertView, Apple2Preferences.SHOW_DISK_OPERATIONS.booleanValue(activity));
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Apple2Preferences.TOUCH_MENU_ENABLED.saveBoolean(activity, isChecked);
Apple2Preferences.SHOW_DISK_OPERATIONS.saveBoolean(activity, isChecked);
}
});
return convertView;
}
},
TOUCH_MENU_VISIBILITY {
@Override
public final String getTitle(Apple2Activity activity) {
return activity.getResources().getString(R.string.touch_menu_visibility);
}
@Override
public final String getSummary(Apple2Activity activity) {
return activity.getResources().getString(R.string.touch_menu_visibility_summary);
}
@Override
public View getView(final Apple2Activity activity, View convertView) {
return _sliderView(activity, this, Apple2Preferences.ALPHA_SLIDER_NUM_CHOICES, new IPreferenceSlider() {
@Override
public void saveInt(int progress) {
Apple2Preferences.TOUCH_MENU_VISIBILITY.saveInt(activity, progress);
}
@Override
public int intValue() {
return Apple2Preferences.TOUCH_MENU_VISIBILITY.intValue(activity);
}
@Override
public void showValue(int progress, final TextView seekBarValue) {
seekBarValue.setText("" + ((float) progress / Apple2Preferences.ALPHA_SLIDER_NUM_CHOICES));
}
});
}
},
ABOUT {
@Override
public final String getTitle(Apple2Activity activity) {

View File

@ -15,43 +15,57 @@
package org.deadc0de.apple2ix;
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.media.AudioManager;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.os.Build;
import android.util.Log;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.ViewTreeObserver;
import com.example.inputmanagercompat.InputManagerCompat;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.GL10;
/**
* A simple GLSurfaceView sub-class that demonstrate how to perform
* OpenGL ES 2.0 rendering into a GL Surface. Note the following important
* details:
*
* - The class must use a custom context factory to enable 2.0 rendering.
* See ContextFactory class definition below.
*
* - The class must use a custom EGLConfigChooser to be able to select
* an EGLConfig that supports 2.0. This is done by providing a config
* specification to eglChooseConfig() that has the attribute
* EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag
* set. See ConfigChooser class definition below.
*
* - The class must select the surface's format, then choose an EGLConfig
* that matches it exactly (with regards to red/green/blue/alpha channels
* bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
*/
class Apple2View extends GLSurfaceView {
class Apple2View extends GLSurfaceView implements InputManagerCompat.InputDeviceListener {
private final static String TAG = "Apple2View";
private final static boolean DEBUG = false;
private final static int MAX_FINGERS = 32;// HACK ...
public final static long NATIVE_TOUCH_HANDLED = (1 << 0);
public final static long NATIVE_TOUCH_REQUEST_SHOW_MENU = (1 << 1);
public final static long NATIVE_TOUCH_KEY_TAP = (1 << 4);
public final static long NATIVE_TOUCH_KBD = (1 << 5);
public final static long NATIVE_TOUCH_JOY = (1 << 6);
public final static long NATIVE_TOUCH_MENU = (1 << 7);
public final static long NATIVE_TOUCH_JOY_KPAD = (1 << 8);
public final static long NATIVE_TOUCH_INPUT_DEVICE_CHANGED = (1 << 16);
public final static long NATIVE_TOUCH_CPU_SPEED_DEC = (1 << 17);
public final static long NATIVE_TOUCH_CPU_SPEED_INC = (1 << 18);
public final static long NATIVE_TOUCH_ASCII_SCANCODE_SHIFT = 32;
public final static long NATIVE_TOUCH_ASCII_SCANCODE_MASK = 0xFFFFL;
public final static long NATIVE_TOUCH_ASCII_MASK = 0xFF00L;
public final static long NATIVE_TOUCH_SCANCODE_MASK = 0x00FFL;
private Apple2Activity mActivity;
private Runnable mGraphicsInitializedRunnable;
private final InputManagerCompat mInputManager;
private float[] mXCoords = new float[MAX_FINGERS];
private float[] mYCoords = new float[MAX_FINGERS];
private Apple2Activity mActivity = null;
private Runnable mGraphicsInitializedRunnable = null;
private static native void nativeGraphicsInitialized(int width, int height);
@ -59,11 +73,24 @@ class Apple2View extends GLSurfaceView {
private static native void nativeRender();
private static native void nativeOnJoystickMove(int x, int y);
public static native long nativeOnTouch(int action, int pointerCount, int pointerIndex, float[] xCoords, float[] yCoords);
public Apple2View(Apple2Activity activity, Runnable graphicsInitializedRunnable) {
super(activity.getApplication());
mActivity = activity;
mGraphicsInitializedRunnable = graphicsInitializedRunnable;
setFocusable(true);
setFocusableInTouchMode(true);
mInputManager = InputManagerCompat.Factory.getInputManager(this.getContext());
if (mInputManager != null) {
mInputManager.registerInputDeviceListener(this, null);
}
/* By default, GLSurfaceView() creates a RGB_565 opaque surface.
* If we want a translucent one, we should change the surface's
* format here, using PixelFormat.TRANSLUCENT for GL Surfaces
@ -114,7 +141,7 @@ class Apple2View extends GLSurfaceView {
public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
Log.w(TAG, "creating OpenGL ES 2.0 context");
checkEglError("Before eglCreateContext", egl);
int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
checkEglError("After eglCreateContext", egl);
return context;
@ -149,12 +176,12 @@ class Apple2View extends GLSurfaceView {
*/
private static int EGL_OPENGL_ES2_BIT = 4;
private static int[] s_configAttribs2 = {
EGL10.EGL_RED_SIZE, 4,
EGL10.EGL_GREEN_SIZE, 4,
EGL10.EGL_BLUE_SIZE, 4,
EGL10.EGL_ALPHA_SIZE, 4,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_NONE
EGL10.EGL_RED_SIZE, 4,
EGL10.EGL_GREEN_SIZE, 4,
EGL10.EGL_BLUE_SIZE, 4,
EGL10.EGL_ALPHA_SIZE, 4,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_NONE
};
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
@ -174,7 +201,7 @@ class Apple2View extends GLSurfaceView {
egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
if (DEBUG) {
printConfigs(egl, display, configs);
printConfigs(egl, display, configs);
}
// Now return the "best" one
@ -303,11 +330,11 @@ class Apple2View extends GLSurfaceView {
for (int i = 0; i < attributes.length; i++) {
int attribute = attributes[i];
String name = names[i];
if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
if (egl.eglGetConfigAttrib(display, config, attribute, value)) {
Log.w(TAG, String.format(" %s: %d\n", name, value[0]));
} else {
// Log.w(TAG, String.format(" %s: failed\n", name));
while (egl.eglGetError() != EGL10.EGL_SUCCESS);
while (egl.eglGetError() != EGL10.EGL_SUCCESS) ;
}
}
}
@ -351,7 +378,7 @@ class Apple2View extends GLSurfaceView {
Apple2View.this.mGraphicsInitializedRunnable = null;
}
Apple2View.this.mActivity.maybeResumeCPU();
Apple2View.this.mActivity.maybeResumeEmulation();
}
@Override
@ -359,4 +386,193 @@ class Apple2View extends GLSurfaceView {
// Do nothing.
}
}
// --------------------------------------------------------------------------
// Event handling, touch, keyboard, gamepad
@Override
public void onInputDeviceAdded(int deviceId) {
}
@Override
public void onInputDeviceChanged(int deviceId) {
}
@Override
public void onInputDeviceRemoved(int deviceId) {
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
return super.onGenericMotionEvent(event);
}
if (mActivity.isEmulationPaused()) {
return super.onGenericMotionEvent(event);
}
// Check that the event came from a joystick or gamepad since a generic
// motion event could be almost anything.
int eventSource = event.getSource();
if ((event.getAction() == MotionEvent.ACTION_MOVE) && (((eventSource & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) || ((eventSource & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK))) {
int id = event.getDeviceId();
if (id != -1) {
InputDevice device = event.getDevice();
float x = getCenteredAxis(event, device, MotionEvent.AXIS_X);
if (x == 0) {
x = getCenteredAxis(event, device, MotionEvent.AXIS_HAT_X);
}
if (x == 0) {
x = getCenteredAxis(event, device, MotionEvent.AXIS_Z);
}
float y = getCenteredAxis(event, device, MotionEvent.AXIS_Y);
if (y == 0) {
y = getCenteredAxis(event, device, MotionEvent.AXIS_HAT_Y);
}
if (y == 0) {
y = getCenteredAxis(event, device, MotionEvent.AXIS_RZ);
}
int normal_x = (int) ((x + 1.f) * 128.f);
if (normal_x < 0) {
normal_x = 0;
}
if (normal_x > 255) {
normal_x = 255;
}
int normal_y = (int) ((y + 1.f) * 128.f);
if (normal_y < 0) {
normal_y = 0;
}
if (normal_y > 255) {
normal_y = 255;
}
nativeOnJoystickMove(normal_x, normal_y);
return true;
}
}
return super.onGenericMotionEvent(event);
}
private static float getCenteredAxis(MotionEvent event, InputDevice device, int axis) {
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
return 0;
}
final InputDevice.MotionRange range = device.getMotionRange(axis, event.getSource());
if (range != null) {
final float flat = range.getFlat();
final float value = event.getAxisValue(axis);
// Ignore axis values that are within the 'flat' region of the joystick axis center.
// A joystick at rest does not always report an absolute position of (0,0).
if (Math.abs(value) > flat) {
return value;
}
}
return 0;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
do {
if (Apple2Activity.isNativeBarfed()) {
break;
}
if (mActivity.getMainMenu() == null) {
break;
}
Apple2MenuView apple2MenuView = mActivity.peekApple2View();
if ((apple2MenuView != null) && (!apple2MenuView.isCalibrating())) {
break;
}
//printSamples(event);
int action = event.getActionMasked();
int pointerIndex = event.getActionIndex();
int pointerCount = event.getPointerCount();
for (int i = 0; i < pointerCount/* && i < MAX_FINGERS */; i++) {
mXCoords[i] = event.getX(i);
mYCoords[i] = event.getY(i);
}
long nativeFlags = nativeOnTouch(action, pointerCount, pointerIndex, mXCoords, mYCoords);
if ((nativeFlags & NATIVE_TOUCH_HANDLED) == 0) {
break;
}
if ((nativeFlags & NATIVE_TOUCH_REQUEST_SHOW_MENU) != 0) {
mActivity.getMainMenu().show();
}
if ((nativeFlags & NATIVE_TOUCH_KEY_TAP) != 0) {
if (Apple2Preferences.KEYBOARD_CLICK_ENABLED.booleanValue(mActivity)) {
AudioManager am = (AudioManager) mActivity.getSystemService(Context.AUDIO_SERVICE);
if (am != null) {
am.playSoundEffect(AudioManager.FX_KEY_CLICK);
}
}
if ((apple2MenuView != null) && apple2MenuView.isCalibrating()) {
long asciiScancodeLong = nativeFlags & (NATIVE_TOUCH_ASCII_SCANCODE_MASK << NATIVE_TOUCH_ASCII_SCANCODE_SHIFT);
int asciiInt = (int) (asciiScancodeLong >> (NATIVE_TOUCH_ASCII_SCANCODE_SHIFT + 8));
int scancode = (int) ((asciiScancodeLong >> NATIVE_TOUCH_ASCII_SCANCODE_SHIFT) & 0xFFL);
char ascii = (char) asciiInt;
apple2MenuView.onKeyTapCalibrationEvent(ascii, scancode);
}
}
if ((nativeFlags & NATIVE_TOUCH_MENU) == 0) {
break;
}
// handle menu-specific actions
if ((nativeFlags & NATIVE_TOUCH_INPUT_DEVICE_CHANGED) != 0) {
Apple2Preferences.TouchDeviceVariant nextVariant;
if ((nativeFlags & NATIVE_TOUCH_KBD) != 0) {
nextVariant = Apple2Preferences.TouchDeviceVariant.KEYBOARD;
} else if ((nativeFlags & NATIVE_TOUCH_JOY) != 0) {
nextVariant = Apple2Preferences.TouchDeviceVariant.JOYSTICK;
} else if ((nativeFlags & NATIVE_TOUCH_JOY_KPAD) != 0) {
nextVariant = Apple2Preferences.TouchDeviceVariant.JOYSTICK_KEYPAD;
} else {
int touchDevice = Apple2Preferences.nativeGetCurrentTouchDevice();
nextVariant = Apple2Preferences.TouchDeviceVariant.next(touchDevice);
}
Apple2Preferences.CURRENT_TOUCH_DEVICE.saveTouchDevice(mActivity, nextVariant);
} else if ((nativeFlags & NATIVE_TOUCH_CPU_SPEED_DEC) != 0) {
int percentSpeed = Apple2Preferences.nativeGetCPUSpeed();
if (percentSpeed > 400) { // HACK: max value from native side
percentSpeed = 375;
} else if (percentSpeed > 100) {
percentSpeed -= 25;
} else {
percentSpeed -= 5;
}
Apple2Preferences.CPU_SPEED_PERCENT.saveInt(mActivity, percentSpeed);
} else if ((nativeFlags & NATIVE_TOUCH_CPU_SPEED_INC) != 0) {
int percentSpeed = Apple2Preferences.nativeGetCPUSpeed();
if (percentSpeed >= 100) {
percentSpeed += 25;
} else {
percentSpeed += 5;
}
Apple2Preferences.CPU_SPEED_PERCENT.saveInt(mActivity, percentSpeed);
}
} while (false);
return true;
}
}

View File

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="black">#000000</color>
<color name="white">#ffffff</color>
<!-- developer-only options -->
<string name="crasher_summary">Test crash generation</string>
<string name="crasher_title">Crash emulator</string>
<string name="crash_null">NULL-deref</string>
<string name="crash_java_npe">Java NPE</string>
<string name="crash_stackcall_overflow">stack call overflow</string>
<string name="crash_stackbuf_overflow">stack buffer overflow</string>
<!-- main options -->
<string name="about_apple2ix">Über Apple2ix…</string>
<string name="about_apple2ix_summary">Über diese Software</string>
<string name="app_name">Apple2ix</string>
<string name="audio_configure">Audio-Konfiguration…</string>
<string name="audio_configure_summary">Lautstärke, Mockingboard, etc</string>
<string name="audio_latency">Audio Latency</string>
<string name="audio_latency_summary">Audio Latency in Sek.</string>
<string name="cancel">Abbrechen</string>
<string name="color_bw">Schwarz/Weiss</string>
<string name="color_color">Farbe</string>
<string name="color_interpolated">Interpolierte Farben</string>
<string name="crasher">Abstürze</string>
<string name="crasher_check_title">Prüfe auf Absturz-Berichte</string>
<string name="crasher_check_summary">Prüfe auf Absturz-Berichte zum Versand an den Entwickler</string>
<string name="crasher_send">Sende Absturz-Bericht?</string>
<string name="crasher_send_message">Entschuldigung. es gab ein Problemm. Möchten Sie einen Absturz-Bericht an den Entwickler senden?</string>
<string name="diskA">Laufwerk 1</string>
<string name="diskB">Laufwerk 2</string>
<string name="disk_eject">Auswerfen</string>
<string name="disk_insert_toast">Die eingelegte Diskette ist schreibgeschützt</string>
<string name="disk_insert_could_not_read">Entschuldigung, das Diskettenabbild konnte nicht gelesen werden!</string>
<string name="disk_read_only">Schreibgeschützt</string>
<string name="disk_read_write">Lesen/Schreiben</string>
<string name="disk_show_operation">Zeige Disk ][ Aktivität</string>
<string name="disk_show_operation_summary">Zeigt wenn die Laufwerke lesen oder schreiben</string>
<string name="emulation_continue">Fortsetzen…</string>
<string name="emulation_settings">Einstellungen…</string>
<string name="emulation_disks">Lade Disk-Image…</string>
<string name="header_disks">Diskette einlegen:</string>
<string name="input_current">Aktuelles Touch Device</string>
<string name="input_current_summary">Wähle ein aktuelles Touch Device</string>
<string name="joystick">Joystick</string>
<string name="joystick_axis_sensitivity_summary">Empfindlichkeiteinstellung der Joystickachsen (verlangsamen or beschleunigen)</string>
<string name="joystick_button_button1">Button 1 (Offener Apfel)</string>
<string name="joystick_button_button2">Button 2 (Geschlossener Apfel)</string>
<string name="joystick_button_button_both">Beide</string>
<string name="joystick_button_button_none">Keine</string>
<string name="joystick_button_tap_button">Drücke den Feuerknopf</string>
<string name="joystick_button_tap_button_summary">Ausgewählter Feuerknopf</string>
<string name="joystick_button_tapdelay_summary">Joystickknopf-Zeitverzögerung in Sek.</string>
<string name="joystick_button_swipe_up_button">Aufwärts wischen zum feuern</string>
<string name="joystick_button_swipe_up_button_summary">Feuerknopf zum feuern beim aufwärts wischen</string>
<string name="joystick_button_swipe_down_button">Abwärts wischen zum feuern</string>
<string name="joystick_button_swipe_down_button_summary">Feuerknopf zum feuern beim abwärts wischen</string>
<string name="joystick_button_threshold_summary">Joystick/Keypad Knopf Schaltschwellwert in pts</string>
<string name="joystick_calibrate">Kalibrieren…</string>
<string name="joystick_calibrate_summary">Konfiguriere und teste die aktuellen Einstellungen</string>
<string name="joystick_configure">Joystickkonfiguration…</string>
<string name="joystick_configure_summary">Achsen Touch, Knöpfe, etc</string>
<string name="joystick_axisleft">Joystick/Keypad Achse links</string>
<string name="joystick_axisleft_summary">Joystick/Keypad Achse links (Knöpfe rechts)</string>
<string name="joystick_visible">Sichtbarkeit Joystick/Keypad</string>
<string name="joystick_visible_summary">Zeige die Kontrollen als Overlay wenn aktiviert</string>
<string name="key_closed_apple">[GeschlossenerApfel]</string>
<string name="key_ctrl">[Strg]</string>
<string name="key_down">&#8595;</string>
<string name="key_esc">[ESC]</string>
<string name="key_left">&#8592;</string>
<string name="key_none">[Keine]</string>
<string name="key_open_apple">[OffenerApfel]</string>
<string name="key_ret">[Return]</string>
<string name="key_right">&#8594;</string>
<string name="key_space">[Space]</string>
<string name="key_up">&#8593;</string>
<string name="keyboard">Tastatur</string>
<string name="keyboard_choose_alt">Wähle alternative Tastatur…</string>
<string name="keyboard_choose_alt_summary">Wähle alternativ konfiguriertes Layout</string>
<string name="keyboard_click_enabled">Tastenton einschalten</string>
<string name="keyboard_click_enabled_summary">Aktiviert Tastenton wenn verfügbar</string>
<string name="keyboard_configure">Tastatur-Konfiguration…</string>
<string name="keyboard_configure_summary">Transparenz, Kleinbuchstaben, eigene Tasten</string>
<string name="keyboard_glyph_scale">Tastatur-Glyphenskalierung 2x</string>
<string name="keyboard_glyph_scale_summary">(Lässt die Tastaur weniger pixelig erscheinen auf grossen Bildschirmen)</string>
<string name="keyboard_lowercase_enabled">Kleinbuchstaben aktivieren</string>
<string name="keyboard_lowercase_enabled_summary">Aktiviren der Tasten für Kleinbuchstaben</string>
<string name="keyboard_visibility_active">Sichtbarkeit wenn aktiviert</string>
<string name="keyboard_visibility_active_summary">Sichtbarkeit des Keyboard und Touch Menüs wenn aktiviert</string>
<string name="keyboard_visibility_inactive">Sichtbarkeit wenn deaktiviert</string>
<string name="keyboard_visibility_inactive_summary">Sichtbarkeit des Keyboard und Touch Menüs wenn deaktiviert</string>
<string name="keypad">Keypad Joystick</string>
<string name="keypad_calibrate">@string/joystick_calibrate</string>
<string name="keypad_calibrate_summary">@string/joystick_calibrate</string>
<string name="keypad_choose">Auswahl der Keypad Tasten…</string>
<string name="keypad_choose_summary">Auswahl der Achsen und Knopf Tasten</string>
<string name="keypad_choose_title">Achse &amp; Knöpfe</string>
<string name="keypad_choose_current">Wähle XXX Taste: </string>
<string name="keypad_configure">Konfiguration Joystick Keypad…</string>
<string name="keypad_configure_summary">@string/joystick_configure_summary</string>
<string name="keypad_key_axis_c">Mitte</string>
<string name="keypad_key_axis_dn">Unten</string>
<string name="keypad_key_axis_dl">Unten und Links</string>
<string name="keypad_key_axis_dr">Unten und Rechts</string>
<string name="keypad_key_axis_l">Links</string>
<string name="keypad_key_axis_r">Rechts</string>
<string name="keypad_key_axis_ul">Oben und Links</string>
<string name="keypad_key_axis_up">Oben</string>
<string name="keypad_key_axis_ur">Oben und Rechts</string>
<string name="keypad_key_button_tap">antippen</string>
<string name="keypad_key_button_swipeup">Nach oben wischen</string>
<string name="keypad_key_button_swipedown">Nach unten wischen</string>
<string name="keypad_preset_crazy_seafox">Seafox Tasten ;-)…</string>
<string name="keypad_preset_custom">Auswahl einer Anpassung…</string>
<string name="keypad_preset_arrows_space">&#8593;,&#8592;,&#8594;,&#8595;, tippe auf die Leerstaste</string>
<string name="keypad_preset_az_left_right_space">A,Z,&#8592;,&#8594;, tippe auf die Leertaste</string>
<string name="keypad_preset_ijkm_space">I,J,K,M, tippe auf die Leertaste</string>
<string name="keypad_preset_left_right_space">&#8592;,&#8594;, tippe auf die Leertaste</string>
<string name="keypad_preset_wadx_space">W,A,D,X, tippe auf die Leertaste</string>
<string name="keypad_repeat_summary">Tastenwiederholungsschwellwert in Sek.</string>
<string name="menu_disks">Lade Disk-Image…</string>
<string name="menu_disks_summary">Einlegen eines Disk ][ Image</string>
<string name="menu_settings">Emulator Einstellungen…</string>
<string name="menu_settings_summary">Allgemeine Einstellungen, Joystick, Tastatur</string>
<string name="mockingboard_disabled_title">Mockingboard deaktiviert</string>
<string name="mockingboard_disabled_mesg">Mockingboard konnte nicht aktiviert werden</string>
<string name="mockingboard_enable">Aktiviere Mockingboard</string>
<string name="mockingboard_enable_summary">Revision C in Slot 4/5 (evtl. wird ein Restart benötigt)</string>
<string name="mockingboard_volume">Mockingboard Lautstärke</string>
<string name="mockingboard_volume_summary">Einstellen der Mockingboard Lautstärke</string>
<string name="no">Nein</string>
<string name="ok">OK</string>
<string name="preferences_reset_title">Einstellungen zurücksetzen</string>
<string name="preferences_reset_summary">Einstellungen auf Standard zurücksetzen und Emulator beenden</string>
<string name="preferences_reset_really">Wollen Sie wirklich resetten und beenden?</string>
<string name="preferences_reset_warning">Sie werden alle Ihre Einstellungen verlieren</string>
<string name="quit">Beenden</string>
<string name="quit_reboot">Neustart oder beenden des Emulators…</string>
<string name="quit_reboot_choice">Neustart oder beenden?</string>
<string name="reboot">Neustart</string>
<string name="restore">Schnelle Wiederherstellung</string>
<string name="save">Schnelle Speicherung</string>
<string name="saverestore">Speichern &amp; wiederherstellen…</string>
<string name="saverestore_choice">Aktuellen Status sichern oder vorherigen wiederherstellen?</string>
<string name="saverestore_summary">Schnellspeicherung und Wiederherstellung</string>
<string name="skip">Überspringen&#8594;</string>
<string name="speaker_volume">Lautsprecherlautstärke</string>
<string name="speaker_volume_summary">Lautsprecherlautstärke einstellen</string>
<string name="settings">Apple2ix Emulator Einstellungen</string>
<string name="settings_advanced">Erweiterte Einstellungen</string>
<string name="settings_advanced_summary">Warnung: diese Einstellungen verschlechtern die Performance</string>
<string name="settings_advanced_joystick">Erweiterte Joystick/Keypad Einstellungen</string>
<string name="settings_advanced_joystick_summary">Erweiterte Einstellungen für das Performance-Tuning</string>
<string name="touch_menu_enable">Aktiviere Touch Menüs</string>
<string name="touch_menu_enable_summary">Aktiviere Softmenü Knöpfe in den oberen Ecken des Bildschirms</string>
<string name="video_configure">Video-Konfiguration…</string>
<string name="video_configure_summary">Farbeinstellungen</string>
</resources>

View File

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="black">#000000</color>
<color name="white">#ffffff</color>
<!-- developer-only options -->
<string name="crasher_summary">Test crash generation</string>
<string name="crasher_title">Crash emulator</string>
<string name="crash_null">NULL-deref</string>
<string name="crash_java_npe">Java NPE</string>
<string name="crash_stackcall_overflow">stack call overflow</string>
<string name="crash_stackbuf_overflow">stack buffer overflow</string>
<!-- main options -->
<string name="about_apple2ix">Acerca de Apple2ix…</string>
<string name="about_apple2ix_summary">Acerca de este software</string>
<string name="app_name">Apple2ix</string>
<string name="audio_configure">Configurar audio…</string>
<string name="audio_configure_summary">Ajustar el volumen del altavoz, "Mockingboard", etc</string>
<string name="audio_latency">La latencia de audio</string>
<string name="audio_latency_summary">La latencia de audio en segundos</string>
<string name="cancel">Cancelar</string>
<string name="color_bw">Blanco/negro</string>
<string name="color_color">Color</string>
<string name="color_interpolated">Color interpolado</string>
<string name="crasher">Fallos del software</string>
<string name="crasher_check_title">Fallos del software</string>
<string name="crasher_check_summary">Verificar la presencia de fallos del software</string>
<string name="crasher_send">¿Enviar informe de error?</string>
<string name="crasher_send_message">Lo sentimos, ha habido un problema. ¿Desea enviar informe de error para el programador de software?</string>
<string name="diskA">Disquetera 1</string>
<string name="diskB">Disquetera 2</string>
<string name="disk_eject">Eyectar</string>
<string name="disk_insert_toast">Disco insertado en la disquetera de sólo lectura</string>
<string name="disk_insert_could_not_read">Lo sentimos, no se puede leer la imagen de disquete!</string>
<string name="disk_read_only">Sólo leer</string>
<string name="disk_read_write">Leer y escribir</string>
<string name="disk_show_operation">Mostrar las operaciones de "Disk ]["</string>
<string name="disk_show_operation_summary">Shows when disk drives are reading or writing</string>
<string name="emulation_continue">Continuar…</string>
<string name="emulation_settings">Configuración…</string>
<string name="emulation_disks">Insertar imagen de disquete…</string>
<string name="header_disks">Insertar imagen de disquete:</string>
<string name="input_current">Unidad de entrada actual</string>
<string name="input_current_summary">Elija unidad de entrada</string>
<string name="joystick">"Joystick"</string>
<string name="joystick_axis_sensitivity_summary">Afinar la sensibilidad del eje del joystick (desacelerar o acelerar)</string>
<string name="joystick_button_button1">Botón 1</string>
<string name="joystick_button_button2">Botón 2</string>
<string name="joystick_button_button_both">Los dos</string>
<string name="joystick_button_button_none">Ninguno</string>
<string name="joystick_button_tap_button">Toque para disparar</string>
<string name="joystick_button_tap_button_summary">Botón para disparar sobre toque abajo</string>
<string name="joystick_button_tapdelay_summary">Toque retardo del joystick en segundos</string>
<string name="joystick_button_swipe_up_button">Pase hacia arriba</string>
<string name="joystick_button_swipe_up_button_summary">Botón para disparar sobre pase el dedo hacia arriba</string>
<string name="joystick_button_swipe_down_button">Pase hacia abajo</string>
<string name="joystick_button_swipe_down_button_summary">Botón para disparar sobre pase el dedo hacia abajo</string>
<string name="joystick_button_threshold_summary">Umbral del joystick en puntos</string>
<string name="joystick_calibrate">Calibrar…</string>
<string name="joystick_calibrate_summary">Calibrar el joystick</string>
<string name="joystick_configure">Configurar el joystick…</string>
<string name="joystick_configure_summary">Eje táctil, los botónes, etc</string>
<string name="joystick_axisleft">Eje del joystick a la izquierda</string>
<string name="joystick_axisleft_summary">Eje del joystick a la izquierda (los botónes de la derecha)</string>
<string name="joystick_visible">Visibilidad del joystick</string>
<string name="joystick_visible_summary">Mostrar controles cuando se utiliza</string>
<string name="key_closed_apple">[Botón 2]</string>
<string name="key_ctrl">[Ctrl]</string>
<string name="key_down">&#8595;</string>
<string name="key_esc">[ESC]</string>
<string name="key_left">&#8592;</string>
<string name="key_none">[Ninguno]</string>
<string name="key_open_apple">[Botón 1]</string>
<string name="key_ret">[Retorno]</string>
<string name="key_right">&#8594;</string>
<string name="key_space">[Espaciadora]</string>
<string name="key_up">&#8593;</string>
<string name="keyboard">Teclado</string>
<string name="keyboard_choose_alt">Elija teclado alternativo…</string>
<string name="keyboard_choose_alt_summary">Elija el diseño de teclado alternativo</string>
<string name="keyboard_click_enabled">Habilitar la tecla de sonido de clic</string>
<string name="keyboard_click_enabled_summary">Haga clic en sonido de clave permite si está disponible</string>
<string name="keyboard_configure">Configurar el teclado…</string>
<string name="keyboard_configure_summary">Transparencia, minúsculas, teclado personalizado</string>
<string name="keyboard_lowercase_enabled">Habilitar minúsculas</string>
<string name="keyboard_lowercase_enabled_summary">Utilice las teclas minúsculas</string>
<string name="keyboard_visibility_active">Visibilidad cuando está activo</string>
<string name="keyboard_visibility_active_summary">Visibilidad del teclado y menú cuando está activo</string>
<string name="keyboard_visibility_inactive">Visibilidad cuando está inactivo</string>
<string name="keyboard_visibility_inactive_summary">Visibilidad del teclado y menú cuando está inactivo</string>
<string name="keypad">Joystick como teclado numérico</string>
<string name="keypad_calibrate">@string/joystick_calibrate</string>
<string name="keypad_calibrate_summary">@string/joystick_calibrate</string>
<string name="keypad_choose">Teclas del teclado numérico…</string>
<string name="keypad_choose_summary">Elegir las teclas del joystick del teclado numérico</string>
<string name="keypad_choose_title">Ejes y botones</string>
<string name="keypad_choose_current">Elija [XXX] tecla del teclado: </string>
<string name="keypad_configure">Configurar el joystick del teclado numérico…</string>
<string name="keypad_configure_summary">@string/joystick_configure_summary</string>
<string name="keypad_key_axis_c">Centro</string>
<string name="keypad_key_axis_dn">Abajo</string>
<string name="keypad_key_axis_dl">Abajo y a la izquierda</string>
<string name="keypad_key_axis_dr">Abajo y a la derecha</string>
<string name="keypad_key_axis_l">Izquierda</string>
<string name="keypad_key_axis_r">Derecha</string>
<string name="keypad_key_axis_ul">Arriba y a la izquierda</string>
<string name="keypad_key_axis_up">Arriba</string>
<string name="keypad_key_axis_ur">Arriba y a la derecha</string>
<string name="keypad_key_button_tap">Toque</string>
<string name="keypad_key_button_swipeup">Desliza el dedo hacia arriba</string>
<string name="keypad_key_button_swipedown"> Desliza el dedo hacia abajo</string>
<string name="keypad_preset_crazy_seafox">Seafox keys ;-)…</string>
<string name="keypad_preset_custom">Elija personalizado…</string>
<string name="keypad_preset_arrows_space">&#8593;,&#8592;,&#8594;,&#8595;, pulse espaciadora</string>
<string name="keypad_preset_az_left_right_space">A,Z,&#8592;,&#8594;, pulse espaciadora</string>
<string name="keypad_preset_ijkm_space">I,J,K,M, pulse espaciadora</string>
<string name="keypad_preset_left_right_space">&#8592;,&#8594;, pulse espaciadora</string>
<string name="keypad_preset_wadx_space">W,A,D,X, pulse espaciadora</string>
<string name="keypad_repeat_summary">Umbral de repetición de teclas en segundos</string>
<string name="menu_disks">Insertar imagen de disco…</string>
<string name="menu_disks_summary">Insertar imagen de "Disk ]["</string>
<string name="menu_settings">Configuración del emulador…</string>
<string name="menu_settings_summary">Configuración general, joystick, teclado</string>
<string name="mockingboard_disabled_title">Mockingboard desactivado</string>
<string name="mockingboard_disabled_mesg">Mockingboard no pudo ser habilitado</string>
<string name="mockingboard_enable">Activar Mockingboard</string>
<string name="mockingboard_enable_summary">Revisión C en la ranura 4/5 puede requerir reinicio</string>
<string name="mockingboard_volume">Volumen de Mockingboard</string>
<string name="mockingboard_volume_summary">Adjustar el volumen del Mockingboard</string>
<string name="no">No</string>
<string name="ok"></string>
<string name="preferences_reset_title">Restablecer preferencias</string>
<string name="preferences_reset_summary">Restablecer preferencias y salir</string>
<string name="preferences_reset_really">¿Restablecer realmente y salir?</string>
<string name="preferences_reset_warning">Usted perderá su configuración</string>
<string name="quit">Salir</string>
<string name="quit_reboot">Reiniciar o salir el emulador…</string>
<string name="quit_reboot_choice">¿Reiniciar o salir?</string>
<string name="reboot">Reiniciar</string>
<string name="restore">Restauración rápida</string>
<string name="save">Guardar rápido</string>
<string name="saverestore">Guardar y restaurar…</string>
<string name="saverestore_choice">¿Guardar el estado actual o anterior de restauración?</string>
<string name="saverestore_summary">Guardar y restaurar rápida</string>
<string name="skip">Saltar&#8594;</string>
<string name="speaker_volume">El volumen del altavoz</string>
<string name="speaker_volume_summary">Ajustar el volumen del altavoz</string>
<string name="settings">Configuración Apple2ix</string>
<string name="settings_advanced">Configuración avanzada</string>
<string name="settings_advanced_summary">Advertencia: estos valores puede degradar el rendimiento</string>
<string name="settings_advanced_joystick">Configuración de teclado y joystick avanzados</string>
<string name="settings_advanced_joystick_summary">Configuración avanzada y optimización del rendimiento</string>
<string name="touch_menu_enable">Activar menús táctiles</string>
<string name="touch_menu_enable_summary">Los botones del menú en la parte superior de la pantalla</string>
<string name="video_configure">Configurar el video…</string>
<string name="video_configure_summary">Ajustes de color</string>
</resources>

View File

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="black">#000000</color>
<color name="white">#ffffff</color>
<!-- developer-only options -->
<string name="crasher_summary">Génération du "Test crash"</string>
<string name="crasher_title">Plantage de l\'émulateur</string>
<string name="crash_null">NULL-deref</string>
<string name="crash_java_npe">Java NPE</string>
<string name="crash_stackcall_overflow">stack call overflow</string>
<string name="crash_stackbuf_overflow">stack buffer overflow</string>
<!-- main options -->
<string name="about_apple2ix">A propos d\'Apple2ix…</string>
<string name="about_apple2ix_summary">A propos de ce logiciel</string>
<string name="app_name">Apple2ix</string>
<string name="audio_configure">Configuration audio…</string>
<string name="audio_configure_summary">Volume du haut-parleur, Mockingboard, etc</string>
<string name="audio_latency">Délai audio</string>
<string name="audio_latency_summary">Délai audio en secs</string>
<string name="cancel">Annulation</string>
<string name="color_bw">Noir/blanc</string>
<string name="color_color">Couleurs</string>
<string name="color_interpolated">Interpolation couleurs</string>
<string name="crasher">Plantages</string>
<string name="crasher_check_title">Vérifier les logs de plantage</string>
<string name="crasher_check_summary">Vérifier les logs de plantage avec email au développeur</string>
<string name="crasher_send">Envoyer le log de plantage ?</string>
<string name="crasher_send_message">Désolé, il y a eu un problème. Voulez-vous envoyer le log du plantage au développeur ?</string>
<string name="diskA">Lecteur 1</string>
<string name="diskB">Lecteur 2</string>
<string name="disk_eject">Ejecter</string>
<string name="disk_insert_toast">Insérer la disquette dans le drive en lecture seulement</string>
<string name="disk_insert_could_not_read">Désolé, impossible de lire l\'image disque!</string>
<string name="disk_read_only">Lecture seulement</string>
<string name="disk_read_write">Lecture/Ecriture</string>
<string name="disk_show_operation">Afficher les opérations (disque) ][</string>
<string name="disk_show_operation_summary">Indique si les disques sont en lecture ou en écriture</string>
<string name="emulation_continue">Continuer…</string>
<string name="emulation_settings">Configurations…</string>
<string name="emulation_disks">Chargement de l\'image disque…</string>
<string name="header_disks">Insérer la disquettte :</string>
<string name="input_current">Tactile</string>
<string name="input_current_summary">Choisir l\'appareil courant</string>
<string name="joystick">Joystick</string>
<string name="joystick_axis_sensitivity_summary">Calibrer le joystick (décélérer/accélérer)</string>
<string name="joystick_button_button1">Bouton 1 (Pomme ouverte)</string>
<string name="joystick_button_button2">Bouton 2 (Pomme fermée)</string>
<string name="joystick_button_button_both">Les deux</string>
<string name="joystick_button_button_none">Rien</string>
<string name="joystick_button_tap_button">Sélectionner l\'action</string>
<string name="joystick_button_tap_button_summary">Bouton à activer lors d\'une pression vers le bas</string>
<string name="joystick_button_tapdelay_summary">Délai de pression du bouton Joystick en secondes</string>
<string name="joystick_button_swipe_up_button">Lancement du swipe up</string>
<string name="joystick_button_swipe_up_button_summary">Bouton à lancer sur swipe up</string>
<string name="joystick_button_swipe_down_button">Lancement du swipe down</string>
<string name="joystick_button_swipe_down_button_summary">Bouton à lancer sur swipe down</string>
<string name="joystick_button_threshold_summary">Limite en pts pour switcher sur les bouton Joystick/keypad</string>
<string name="joystick_calibrate">Calibrer…</string>
<string name="joystick_calibrate_summary">Configuration et test des paramètres courants</string>
<string name="joystick_configure">Configuration du joystick…</string>
<string name="joystick_configure_summary">Ajustements tactiles, boutons, etc</string>
<string name="joystick_axisleft">Ajustement du joystick/keypad sur gauche</string>
<string name="joystick_axisleft_summary">Ajustement du Joystick/keypad sur gauche (boutons sur droite)</string>
<string name="joystick_visible">Visibilité Joystick/keypad</string>
<string name="joystick_visible_summary">Montre les controles quand occupé</string>
<string name="key_closed_apple">[PommeFermée]</string>
<string name="key_ctrl">[Ctrl]</string>
<string name="key_down">&#8595;</string>
<string name="key_esc">[ESC]</string>
<string name="key_left">&#8592;</string>
<string name="key_none">[Rien]</string>
<string name="key_open_apple">[PommeOuverte]</string>
<string name="key_ret">[Entrée]</string>
<string name="key_right">&#8594;</string>
<string name="key_space">[Espace]</string>
<string name="key_up">&#8593;</string>
<string name="keyboard">Clavier</string>
<string name="keyboard_choose_alt">Choisir clavier "alt"…</string>
<string name="keyboard_choose_alt_summary">Choisir une configuration clavier customisée</string>
<string name="keyboard_click_enabled">Permettre le click sur une touche</string>
<string name="keyboard_click_enabled_summary">Si disponible, son du click sur une touche</string>
<string name="keyboard_configure">Configuration clavier…</string>
<string name="keyboard_configure_summary">Transparence, minuscules, touches customisées</string>
<string name="keyboard_lowercase_enabled">Permettre les minuscules</string>
<string name="keyboard_lowercase_enabled_summary">Permettre les touches en minuscules</string>
<string name="keyboard_visibility_active">Visibilité quand actif</string>
<string name="keyboard_visibility_active_summary">Clavier et menu tactile visible quand actif</string>
<string name="keyboard_visibility_inactive">Visibilité quand inactif</string>
<string name="keyboard_visibility_inactive_summary">Clavier et menu tactile visible quand inactif</string>
<string name="keypad">Keypad Joystick</string>
<string name="keypad_calibrate">@string/joystick_calibrate</string>
<string name="keypad_calibrate_summary">@string/joystick_calibrate</string>
<string name="keypad_choose">Sélection des touches du keypad…</string>
<string name="keypad_choose_summary">Sélection des touches pour les axes et boutons</string>
<string name="keypad_choose_title">Axis &amp; boutons</string>
<string name="keypad_choose_current">Choisir XXX Key: </string>
<string name="keypad_configure">Configuration du "keypad joystick"…</string>
<string name="keypad_configure_summary">@string/joystick_configure_summary</string>
<string name="keypad_key_axis_c">Centre</string>
<string name="keypad_key_axis_dn">Bas</string>
<string name="keypad_key_axis_dl">Bas et Gauche</string>
<string name="keypad_key_axis_dr">Bas et Droite</string>
<string name="keypad_key_axis_l">Gauche</string>
<string name="keypad_key_axis_r">Droite</string>
<string name="keypad_key_axis_ul">Haut et Gauche</string>
<string name="keypad_key_axis_up">Haut</string>
<string name="keypad_key_axis_ur">Haut et Droite</string>
<string name="keypad_key_button_tap">Presser</string>
<string name="keypad_key_button_swipeup">Slider vers le haut</string>
<string name="keypad_key_button_swipedown">Slider vers le bas</string>
<string name="keypad_preset_crazy_seafox">Touches Seafox ;-)…</string>
<string name="keypad_preset_custom">Choisir customisation…</string>
<string name="keypad_preset_arrows_space">&#8593;,&#8592;,&#8594;,&#8595;, pressez barre d\'espace</string>
<string name="keypad_preset_az_left_right_space">A,Z,&#8592;,&#8594;, pressez barre d\'espace</string>
<string name="keypad_preset_ijkm_space">I,J,K,M, pressez barre d\'espace</string>
<string name="keypad_preset_left_right_space">&#8592;,&#8594;, pressez barre d\'espace</string>
<string name="keypad_preset_wadx_space">W,A,D,X, pressez barre d\'espace</string>
<string name="keypad_repeat_summary">Répétition des touches en secs</string>
<string name="menu_disks">Chargement de l\'image disque…</string>
<string name="menu_disks_summary">Insérer un fichier image (disque) ][</string>
<string name="menu_settings">Paramètres de l\'émulateur…</string>
<string name="menu_settings_summary">Paramètres généraux, joystick, keyboard</string>
<string name="mockingboard_disabled_title">Mockingboard désactivé</string>
<string name="mockingboard_disabled_mesg">Le Mockingboard ne peut être activé</string>
<string name="mockingboard_enable">Activer le Mockingboard</string>
<string name="mockingboard_enable_summary">Révision C dans Slot 4/5 (redémarrage possible)</string>
<string name="mockingboard_volume">Volume du Mockingboard</string>
<string name="mockingboard_volume_summary">Placer le volume du Mockingboard</string>
<string name="no">Non</string>
<string name="ok">OK</string>
<string name="preferences_reset_title">Reset des préférences</string>
<string name="preferences_reset_summary">Restaurer les préférences par défaut et quitter l\'émulateur</string>
<string name="preferences_reset_really">Etes-vous sûr de vouloir faire un reset?</string>
<string name="preferences_reset_warning">Vous perdrez toutes vos options de configuration</string>
<string name="quit">Quitter</string>
<string name="quit_reboot">Rebooter ou quitter l\'émulateur…</string>
<string name="quit_reboot_choice">Rebooter ou quitter?</string>
<string name="reboot">Rebooter</string>
<string name="restore">Restauration rapide</string>
<string name="save">Sauvegarde rapide</string>
<string name="saverestore">Sauvegarde &amp; restauration…</string>
<string name="saverestore_choice">Sauvegarde de l\'état courant ou restaurer un état précédent?</string>
<string name="saverestore_summary">Sauvegarde/restauration rapide</string>
<string name="skip">Ignorer&#8594;</string>
<string name="speaker_volume">Volume du haut-parleur</string>
<string name="speaker_volume_summary">Placer le volume du haut-parleur</string>
<string name="settings">Options de configuration de l\'émulateur Apple2ix</string>
<string name="settings_advanced">Configuration avancée</string>
<string name="settings_advanced_summary">Attention: ces options peuvent dégrader les performances</string>
<string name="settings_advanced_joystick">Configuration avancée du joystick/keypad</string>
<string name="settings_advanced_joystick_summary">Configuration avancée et tuning de performance</string>
<string name="touch_menu_enable">Activation des menus tactiles</string>
<string name="touch_menu_enable_summary">Activation soft des bouton du menu dans les coins en haut de l\'écran</string>
<string name="video_configure">Configuration de la vidéo…</string>
<string name="video_configure_summary">Configuration des couleurs</string>
</resources>

View File

@ -4,11 +4,17 @@
<color name="black">#000000</color>
<color name="white">#ffffff</color>
<!-- developer-only options -->
<string name="crasher_summary">Test crash generation</string>
<string name="crasher_title">Crash emulator</string>
<string name="crash_null">NULL-deref</string>
<string name="crash_java_npe">Java NPE</string>
<string name="crash_stackcall_overflow">stack call overflow</string>
<string name="crash_stackbuf_overflow">stack buffer overflow</string>
<!-- main options -->
<string name="about_apple2ix">About Apple2ix…</string>
<string name="about_apple2ix_summary">About this software</string>
<string name="about_apple2">About Apple //e…</string>
<string name="about_apple2_summary">More information about the Apple //e computer</string>
<string name="action_settings">Settings</string>
<string name="app_name">Apple2ix</string>
<string name="audio_configure">Configure audio…</string>
<string name="audio_configure_summary">Speaker volume, Mockingboard, etc</string>
@ -18,43 +24,30 @@
<string name="color_bw">Black/white</string>
<string name="color_color">Color</string>
<string name="color_interpolated">Interpolated color</string>
<string name="crasher">Crasher</string>
<string name="crasher">Crashes</string>
<string name="crasher_check_title">Check for crash reports</string>
<string name="crasher_check_summary">Check for crash reports to email developer)</string>
<string name="crasher_processing">Processing…</string>
<string name="crasher_processing_message">Processing crash reports…</string>
<string name="crasher_check_summary">Check for crash reports to email developer</string>
<string name="crasher_send">Send crash report?</string>
<string name="crasher_send_message">Sorry there has been a problem. Do you want to send a crash report to the developer?</string>
<string name="crasher_summary">Test crash generation</string>
<string name="crasher_title">Crash emulator</string>
<string name="crash_null">NULL-deref</string>
<string name="crash_java_npe">Java NPE</string>
<string name="crash_stackcall_overflow">stack call overflow</string>
<string name="crash_stackbuf_overflow">stack buffer overflow</string>
<string name="diskA">Drive 1</string>
<string name="diskB">Drive 2</string>
<string name="disk_eject">Eject</string>
<string name="disk_insert_toast">Inserted disk in drive 1 read-only</string>
<string name="disk_insert_could_not_read">OOPS, could not read the disk image!</string>
<string name="disk_insert_toast">Inserted disk in drive read-only</string>
<string name="disk_insert_could_not_read">Sorry, could not read the disk image!</string>
<string name="disk_read_only">Read only</string>
<string name="disk_read_write">Read/write</string>
<string name="disk_show_operation">Show Disk ][ operations</string>
<string name="disk_show_operation_summary">Shows when disk drives are reading or writing</string>
<string name="emulation_continue">Continue…</string>
<string name="emulation_settings">Settings…</string>
<string name="emulation_disks">Load disk image…</string>
<string name="header_disks">Insert disk:</string>
<string name="input_configure">Configure input devices…</string>
<string name="input_configure_summary">Keyboard, joystick, etc</string>
<string name="input_current">Current touch device</string>
<string name="input_current_summary">Choose current touch device</string>
<string name="input_first_joystick">Touch joystick</string>
<string name="input_first_keyboard">Touch keyboard</string>
<string name="joystick">Joystick</string>
<string name="joystickA">Touch Joystick</string>
<string name="joystick_axis_sensitivity_summary">Tune joystick axis sensitivity (decelerate or accelerate)</string>
<string name="joystick_button_axis_enable">Enable button axis</string>
<string name="joystick_button_axis_enable_summary">Enable button axis</string>
<string name="joystick_button_button1">Button1 (Open Apple)</string>
<string name="joystick_button_button2">Button2 (Closed Apple)</string>
<string name="joystick_button_button1">Button 1 (Open Apple)</string>
<string name="joystick_button_button2">Button 2 (Closed Apple)</string>
<string name="joystick_button_button_both">Both</string>
<string name="joystick_button_button_none">None</string>
<string name="joystick_button_tap_button">Tap fire</string>
@ -64,15 +57,15 @@
<string name="joystick_button_swipe_up_button_summary">Button to fire on swipe up</string>
<string name="joystick_button_swipe_down_button">Swipe down fire</string>
<string name="joystick_button_swipe_down_button_summary">Button to fire on swipe down</string>
<string name="joystick_button_threshold_summary">Joystick/keypad button switch threshold in pts</string>
<string name="joystick_button_threshold_summary">Joystick/keypad button switch threshold in pts (max: &#8531; screen height)</string>
<string name="joystick_calibrate">Calibrate…</string>
<string name="joystick_calibrate_summary">Configure and test current settings</string>
<string name="joystick_configure">Configure joystick…</string>
<string name="joystick_configure_summary">Axis touch, buttons, etc</string>
<string name="joystick_current">Current joystick flavor</string>
<string name="joystick_current_summary">Emulated physical joystick or keypad</string>
<string name="joystick_axisleft">Joystick/keypad axis on left</string>
<string name="joystick_axisleft_summary">Joystick/keypad axis on left (buttons on right)</string>
<string name="joystick_azimuth_visible">Show joystick/keypad heading</string>
<string name="joystick_azimuth_visible_summary">Shows current axis direction and magnitude</string>
<string name="joystick_visible">Joystick/keypad visibility</string>
<string name="joystick_visible_summary">Show controls overlay when engaged</string>
<string name="key_closed_apple">[ClosedApple]</string>
@ -93,25 +86,21 @@
<string name="keyboard_click_enabled_summary">Enables key click sound if available</string>
<string name="keyboard_configure">Configure keyboard…</string>
<string name="keyboard_configure_summary">Transparency, lowercase, custom keys</string>
<string name="keyboard_glyph_scale">Keyboard glyphs scaled 2x</string>
<string name="keyboard_glyph_scale_summary">(Makes keyboard appear less pixelated on large screens)</string>
<string name="keyboard_lowercase_enabled">Enable lowercase</string>
<string name="keyboard_lowercase_enabled_summary">Enable lowercase keys</string>
<string name="keyboard_preset_default">Default</string>
<string name="keyboard_visibility_active">Visibility when active</string>
<string name="keyboard_visibility_active_summary">Keyboard visibility when active</string>
<string name="keyboard_visibility_active_summary">Keyboard and touch menu visibility when active</string>
<string name="keyboard_visibility_inactive">Visibility when inactive</string>
<string name="keyboard_visibility_inactive_summary">Keyboard visibility when inactive</string>
<string name="keyboard_visibility_inactive_summary">Keyboard and touch menu visibility when inactive</string>
<string name="keypad">Keypad Joystick</string>
<string name="keypadA">Touch Keypad Joystick</string>
<string name="keypad_button_tap_button">Tap key:</string>
<string name="keypad_button_swipe_up_button">Swipe up key:</string>
<string name="keypad_button_swipe_down_button">Swipe down key:</string>
<string name="keypad_calibrate">Calibrate…</string>
<string name="keypad_calibrate_summary">Configure and test current settings</string>
<string name="keypad_calibrate">@string/joystick_calibrate</string>
<string name="keypad_calibrate_summary">@string/joystick_calibrate</string>
<string name="keypad_choose">Choose keypad keys…</string>
<string name="keypad_choose_summary">Choose axis and button keys</string>
<string name="keypad_choose_title">Axis &amp; buttons</string>
<string name="keypad_choose_current">Choose XXX Key: </string>
<string name="keypad_chosen_keys">I,J,K,M [Space]</string>
<string name="keypad_configure">Configure keypad joystick…</string>
<string name="keypad_configure_summary">@string/joystick_configure_summary</string>
<string name="keypad_key_axis_c">Center</string>
@ -130,58 +119,45 @@
<string name="keypad_preset_custom">Choose custom…</string>
<string name="keypad_preset_arrows_space">&#8593;,&#8592;,&#8594;,&#8595;, tap spacebar</string>
<string name="keypad_preset_az_left_right_space">A,Z,&#8592;,&#8594;, tap spacebar</string>
<string name="keypad_preset_ijkl_uo">I,J,L,K, tap U, swipe down O</string>
<string name="keypad_preset_ijkm_space">I,J,K,M, tap spacebar</string>
<string name="keypad_preset_left_right_space">&#8592;,&#8594;, tap spacebar</string>
<string name="keypad_preset_wadx_space">W,A,D,X, tap spacebar</string>
<string name="keypad_repeat_summary">Key repeat threshold in secs</string>
<string name="max">Max</string>
<string name="menu_disks">Load disk image…</string>
<string name="menu_disks_summary">Insert a Disk ][ image file</string>
<string name="menu_settings">Emulator settings…</string>
<string name="menu_settings_summary">General, CPU, Joystick</string>
<string name="menu_settings_summary">General settings, joystick, keyboard</string>
<string name="mockingboard_disabled_title">Mockingboard disabled</string>
<string name="mockingboard_disabled_mesg">Mockingboard could not be enabled</string>
<string name="mockingboard_enable">Enable Mockingboard</string>
<string name="mockingboard_enable_summary">Revision C in Slot 4/5 (may require restart)</string>
<string name="mockingboard_volume">Mockingboard volume</string>
<string name="mockingboard_volume_summary">Set the Mockingboard(s) volume</string>
<string name="mockingboard_volume_summary">Set the Mockingboard volume</string>
<string name="no">No</string>
<string name="ok">OK</string>
<string name="preferences_reset_title">Reset preferences</string>
<string name="preferences_reset_summary">Reset preferences to defaults</string>
<string name="preferences_reset_really">Really reset?</string>
<string name="preferences_reset_summary">Reset preferences to defaults and quit emulator</string>
<string name="preferences_reset_really">Really reset and quit?</string>
<string name="preferences_reset_warning">You will lose your settings</string>
<string name="quit">Quit emulator…</string>
<string name="quit_summary"></string>
<string name="quit_really">Quit emulator?</string>
<string name="quit_warning">You will lose unsaved progress</string>
<string name="reboot">Reboot emulator…</string>
<string name="reboot_really">Reboot emulator?</string>
<string name="reboot_summary"></string>
<string name="reboot_warning">You will lose unsaved progress</string>
<string name="quit">Quit</string>
<string name="quit_reboot">Reboot or quit emulator…</string>
<string name="quit_reboot_choice">Reboot or quit?</string>
<string name="reboot">Reboot</string>
<string name="restore">Quick restore</string>
<string name="save">Quick save</string>
<string name="saverestore">Save &amp; restore…</string>
<string name="saverestore_choice">Save current state or restore previous?</string>
<string name="saverestore_summary">Quick save and restore</string>
<string name="skip">Skip&#8594;</string>
<string name="spacer"></string>
<string name="speaker_disabled_title">Speaker disabled</string>
<string name="speaker_disabled_mesg">Speaker could not be enabled</string>
<string name="speaker_enable">Enable speaker</string>
<string name="speaker_enable_summary">(Speaker cannot be disabled)</string>
<string name="speaker_volume">Speaker volume</string>
<string name="speaker_volume_summary">Set the speaker volume</string>
<string name="speed_alt">Alternate CPU speed</string>
<string name="speed_cpu">CPU Speed</string>
<string name="settings">Apple2ix emulator settings</string>
<string name="settings_audio">Apple2ix audio settings</string>
<string name="settings_advanced">Advanced settings</string>
<string name="settings_advanced_summary">Warning: these settings may potentially degrade emulation performance</string>
<string name="settings_advanced_summary">Warning: these settings may degrade performance</string>
<string name="settings_advanced_joystick">Advanced joystick/keypad settings</string>
<string name="settings_advanced_joystick_summary">Advanced settings and performance tuning</string>
<string name="tab_general">General</string>
<string name="tab_joystick">Joystick</string>
<string name="touch_menu_enable">Enable touch menus</string>
<string name="touch_menu_enable_summary">Enables soft menu buttons in top screen corners</string>
<string name="touch_menu_visibility">Touch menu visibility</string>
<string name="touch_menu_visibility_summary">Touch menu visibility when inactive</string>
<string name="video_configure">Configure video…</string>
<string name="video_configure_summary">Color settings</string>

View File

@ -5,7 +5,6 @@
"_comment" : "hex code for special glyphs",
"_AA" : "b5",
"_CTRL": "b3",
"_XX" : "9b",
"_ESC" : "bc",
"_OA" : "81",
"_CA" : "80",
@ -20,7 +19,7 @@
["_AA", "", "_CTRL", "", "_ESC", "", "_OA", "", "_CA", ""],
[ "", "", "", "", "", "", "", "", "", ""],
[ "", "", "", "", "", "_UP", "", "", "", ""],
[ "", "", "", "", "_LT", "_XX", "_RT", "", "", ""],
[ "", "", "", "", "_LT", "_AA", "_RT", "", "", ""],
[ "", "", "", "", "", "_DN", "", "", "", ""],
[ "", "", "", "", "", "", "", "", "", ""]
]

View File

@ -9,11 +9,11 @@
"_SP" : "b1"
},
[ "reserved for future use" ],
[ "reserved for future use" ],
[ "", "", "", "", "", "", "", "", "", "" ],
[ "_AA", "", "", "", "", "", "", "", "", "" ],
[ "", "", "", "", "", "", "", "", "", "" ],
[ "", "", "", "", "", "", "", "", "", "" ],
[ "", "", "", "", "", "", "", "", "", "" ],
[ "Q", "", "", "", "", "", "", "", "A", "" ],
[ "", "", "", "", "", "", "", "_LT", "", "_RT" ],
[ "_SP", "", "", "", "", "", "", "", "Z", "" ]

View File

@ -0,0 +1,19 @@
[
"Alt keyboard optimized for Moebius",
{
"_comment" : "hex code for special glyphs",
"_AA" : "b5",
"_ESC" : "bc",
"_SP" : "b1"
},
[ "Q", "", "", "", "", "", "", "", "", "" ],
[ "", "", "", "", "", "", "", "", "", "V"],
[ "_AA", "", "", "", "", "", "", "", "", "D"],
[ "_ESC", "", "", "", "", "", "", "", "", "G"],
[ "Y", "", "", "", "", "", "", "", "", "" ],
[ "N", "", "", "", "", "", "", "I", "O", "P"],
[ "U", "A", "S", "E", "F", "M", "", "K", "L", ";"],
[ "C", "Z", "X", "B", "H", "T", "_SP",",", ".", "/"]
]

View File

@ -5,19 +5,19 @@
"_comment" : "hex code for special glyphs",
"_AA" : "b5",
"_ESC" : "bc",
"_UP" : "8b",
"_UP" : "8d",
"_LT" : "88",
"_RT" : "95",
"_DN" : "8a",
"_SP" : "b1"
},
["reserved for future use"],
["reserved for future use"],
[ "Q", "", "", "", "", "", "", "", "K", "X"],
[ "P", "", "", "", "", "", "", "", "D", "B"],
["_AA", "", "", "", "", "", "1", "2", "3", "4"],
[ "N", "", "", "", "", "", "5", "6", "7", "8"],
[ "Y", "", "", "", "", "", "Z", "G", "", "_ESC"],
[ "S", "", "", "", "", "", "C", "", "_UP", "" ],
[ "", "", "", "", "", "", "", "_LT", "", "_RT"],
[ "A", "", "T", "O", "", "", "_SP", "", "_DN", ""]
[ "", "", "", "", "", "", "", "_LT", "", "_RT"],
[ "A", "", "T", "O", "F", "E", "_SP", "", "_DN", ""]
]

View File

@ -0,0 +1 @@
../../../src/video/SolidColor.fsh

View File

@ -0,0 +1 @@
../../../src/video/SolidColor.vsh

View File

View File

@ -40,6 +40,19 @@ void android_keycode_to_emulator(int keyCode, int metaState, bool pressed) {
break;
}
switch (keyCode) {
case KEYCODE_BUTTON_A:
case KEYCODE_BUTTON_X:
case KEYCODE_BUTTON_L1:
joydriver_setButton0Pressed(pressed);
return;
case KEYCODE_BUTTON_B:
case KEYCODE_BUTTON_Y:
case KEYCODE_BUTTON_R1:
joydriver_setButton1Pressed(pressed);
return;
}
switch (keyCode) {
case KEYCODE_0:
key = _is_shifted(metaState) ? ')' : keyCode + ASCII_0_OFFSET;

View File

@ -98,6 +98,8 @@
#define KEYCODE_BUTTON_L2 0x68
#define KEYCODE_BUTTON_R1 0x67
#define KEYCODE_BUTTON_R2 0x69
#define KEYCODE_BUTTON_X 0x63
#define KEYCODE_BUTTON_Y 0x64
#define META_ALT_LEFT_ON 0x00000010
#define META_ALT_RIGHT_ON 0x00000020

View File

@ -35,6 +35,12 @@ else
LOCAL_SRC_FILES += $(APPLE2_ARM_SRC)
endif
ifeq ($(BUILD_MODE),release)
LOCAL_CFLAGS += -DNDEBUG=1
else
LOCAL_CFLAGS += -g
endif
ifeq ($(EMBEDDED_STACKWALKER),1)
LOCAL_CPPFLAGS += -DEMBEDDED_STACKWALKER=1
else

View File

@ -12,7 +12,7 @@ usage() {
echo "$0"
echo " # uninstalls $package_id"
else
echo "$0 [build] [load|debug]"
echo "$0 [build|release] [load|debug]"
echo " # default builds $package_id and then load or debug"
fi
exit 0
@ -22,6 +22,14 @@ export EMBEDDED_STACKWALKER=1
while test "x$1" != "x"; do
case "$1" in
"build")
do_build=1
;;
"release")
do_release=1
;;
"debug")
do_debug=1
;;
@ -45,6 +53,11 @@ while test "x$1" != "x"; do
shift
done
if test "x$do_build" = "x1" -a "x$do_release" = "x1" ; then
echo "Must specify either build or release"
usage
fi
set -x
if test "$(basename $0)" = "clean" ; then
@ -74,22 +87,6 @@ if test "$(basename $0)" = "uninstall" ; then
exit 0
fi
#CC=`which clang`
CC=`which gcc`
CFLAGS="-std=gnu11"
# ROMz
$CC $CFLAGS -o $apple2_src_path/genrom $apple2_src_path/genrom.c && \
$apple2_src_path/genrom $apple2_src_path/rom/apple_IIe.rom $apple2_src_path/rom/slot6.rom > $apple2_src_path/rom.c
# font
$CC $CFLAGS -o $apple2_src_path/genfont $apple2_src_path/genfont.c && \
$apple2_src_path/genfont < $apple2_src_path/font.txt > $apple2_src_path/font.c
# glue
$apple2_src_path/x86/genglue $glue_srcs > $apple2_src_path/x86/glue.S
$apple2_src_path/arm/genglue $glue_srcs > $apple2_src_path/arm/glue.S
if test "$(basename $0)" = "testcpu" ; then
ln -s testcpu.mk Android.mk
elif test "$(basename $0)" = "testvm" ; then
@ -104,61 +101,91 @@ fi
###############################################################################
# build native sources
ndk-build V=1 NDK_MODULE_PATH=. NDK_DEBUG=1 # NDK_TOOLCHAIN_VERSION=clang
ret=$?
if test "x$ret" != "x0" ; then
exit $ret
if test "x$do_build" = "x1" -o "x$do_release" = "x1" ; then
#CC=`which clang`
CC=`which gcc`
CFLAGS="-std=gnu11"
# ROMz
$CC $CFLAGS -o $apple2_src_path/genrom $apple2_src_path/genrom.c && \
$apple2_src_path/genrom $apple2_src_path/rom/apple_IIe.rom $apple2_src_path/rom/slot6.rom > $apple2_src_path/rom.c
# font
$CC $CFLAGS -o $apple2_src_path/genfont $apple2_src_path/genfont.c && \
$apple2_src_path/genfont < $apple2_src_path/font.txt > $apple2_src_path/font.c
# glue
$apple2_src_path/x86/genglue $glue_srcs > $apple2_src_path/x86/glue.S
$apple2_src_path/arm/genglue $glue_srcs > $apple2_src_path/arm/glue.S
if test "x$do_build" = "x1" ; then
export BUILD_MODE=debug
ndk-build V=1 NDK_MODULE_PATH=. NDK_DEBUG=1 # NDK_TOOLCHAIN_VERSION=clang
ret=$?
if test "x$ret" != "x0" ; then
exit $ret
fi
else
export BUILD_MODE=release
ndk-build V=1 NDK_MODULE_PATH=. # NDK_TOOLCHAIN_VERSION=clang
ret=$?
if test "x$ret" != "x0" ; then
exit $ret
fi
fi
# Symbolicate and move symbols file into location to be deployed on device
SYMFILE=libapple2ix.so.sym
ARCHES_TO_SYMBOLICATE='armeabi armeabi-v7a x86'
for arch in $ARCHES_TO_SYMBOLICATE ; do
SYMDIR=../assets/symbols/$arch/libapple2ix.so
# remove old symbols (if any)
/bin/rm -rf $SYMDIR
# Run Breakpad's dump_syms
../../externals/bin/dump_syms ../obj/local/$arch/libapple2ix.so > $SYMFILE
ret=$?
if test "x$ret" != "x0" ; then
echo "OOPS, dump_syms failed for $arch"
exit $ret
fi
# strip to the just the numeric id in the .sym header and verify it makes sense
sym_id=$(head -1 $SYMFILE | cut -d ' ' -f 4)
sym_id_check=$(echo $sym_id | wc -c)
if test "x$sym_id_check" != "x34" ; then
echo "OOPS symbol header not expected size, meat-space intervention needed =P"
exit 1
fi
sym_id_check=$(echo $sym_id | tr -d 'A-Fa-f0-9' | wc -c)
if test "x$sym_id_check" != "x1" ; then
echo "OOPS unexpected characters in symbol header, meat-space intervention needed =P"
exit 1
fi
mkdir -p $SYMDIR/$sym_id
ret=$?
if test "x$ret" != "x0" ; then
echo "OOPS, could not create symbols directory for arch:$arch and sym_id:$sym_id"
exit $ret
fi
/bin/mv $SYMFILE $SYMDIR/$sym_id/
ret=$?
if test "x$ret" != "x0" ; then
echo "OOPS, could not move $SYMFILE to $SYMDIR/$sym_id/"
exit $ret
fi
done
fi
###############################################################################
# Symbolicate and move symbols file into location to be deployed on device
SYMFILE=libapple2ix.so.sym
ARCHES_TO_SYMBOLICATE='armeabi armeabi-v7a x86'
for arch in $ARCHES_TO_SYMBOLICATE ; do
SYMDIR=../assets/symbols/$arch/libapple2ix.so
# remove old symbols (if any)
/bin/rm -rf $SYMDIR
# Run Breakpad's dump_syms
../../externals/bin/dump_syms ../obj/local/$arch/libapple2ix.so > $SYMFILE
ret=$?
if test "x$ret" != "x0" ; then
echo "OOPS, dump_syms failed for $arch"
exit $ret
fi
# strip to the just the numeric id in the .sym header and verify it makes sense
sym_id=$(head -1 $SYMFILE | cut -d ' ' -f 4)
sym_id_check=$(echo $sym_id | wc -c)
if test "x$sym_id_check" != "x34" ; then
echo "OOPS symbol header not expected size, meat-space intervention needed =P"
exit 1
fi
sym_id_check=$(echo $sym_id | tr -d 'A-Fa-f0-9' | wc -c)
if test "x$sym_id_check" != "x1" ; then
echo "OOPS unexpected characters in symbol header, meat-space intervention needed =P"
exit 1
fi
mkdir -p $SYMDIR/$sym_id
ret=$?
if test "x$ret" != "x0" ; then
echo "OOPS, could not create symbols directory for arch:$arch and sym_id:$sym_id"
exit $ret
fi
/bin/mv $SYMFILE $SYMDIR/$sym_id/
ret=$?
if test "x$ret" != "x0" ; then
echo "OOPS, could not move $SYMFILE to $SYMDIR/$sym_id/"
exit $ret
fi
done
###############################################################################
# usually we should build the Java stuff from within Android Studio
if test "x$do_load" = "x1" ; then

View File

@ -113,6 +113,8 @@ void Java_org_deadc0de_apple2ix_Apple2CrashHandler_nativeProcessCrash(JNIEnv *en
if (android_armArchV7A) {
asprintf(&symbolsPath, "%s/symbols/armeabi-v7a", data_dir);
} else if (android_x86) {
asprintf(&symbolsPath, "%s/symbols/x86", data_dir);
} else /*if (android_armArch)*/ {
asprintf(&symbolsPath, "%s/symbols/armeabi", data_dir);
} /*else { moar archs ... } */
@ -129,7 +131,7 @@ void Java_org_deadc0de_apple2ix_Apple2CrashHandler_nativeProcessCrash(JNIEnv *en
}
if (symbolsPath) {
FREE(symbolsPath);
ASPRINTF_FREE(symbolsPath);
}
(*env)->ReleaseStringUTFChars(env, jCrashPath, crashPath);

View File

@ -47,6 +47,7 @@ typedef enum lifecycle_seq_t {
static lifecycle_seq_t appState = APP_RUNNING;
#if TESTING
static bool running_tests = false;
static void _run_tests(void) {
char *local_argv[] = {
"-f",
@ -102,6 +103,7 @@ static void discover_cpu_family(void) {
AndroidCpuFamily family = android_getCpuFamily();
uint64_t features = android_getCpuFeatures();
if (family == ANDROID_CPU_FAMILY_X86) {
android_x86 = true;
if (features & ANDROID_CPU_X86_FEATURE_SSSE3) {
LOG("nANDROID_CPU_X86_FEATURE_SSSE3");
android_x86SSSE3Enabled = true;
@ -141,7 +143,7 @@ static void discover_cpu_family(void) {
// ----------------------------------------------------------------------------
// JNI functions
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnCreate(JNIEnv *env, jobject obj, jstring j_dataDir, jint sampleRate, jint monoBufferSize, jint stereoBufferSize) {
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnCreate(JNIEnv *env, jclass cls, jstring j_dataDir, jint sampleRate, jint monoBufferSize, jint stereoBufferSize) {
const char *dataDir = (*env)->GetStringUTFChars(env, j_dataDir, 0);
// Android lifecycle can call onCreate() multiple times...
@ -169,11 +171,9 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnCreate(JNIEnv *env, jobje
android_monoBufferSubmitSizeSamples = (unsigned long)monoBufferSize;
android_stereoBufferSubmitSizeSamples = (unsigned long)stereoBufferSize;
#if TESTING
assert(cpu_thread_id == 0 && "CPU thread must not be initialized yet...");
_run_tests();
// CPU thread is started from testsuite (if needed)
#else
joydriver_setClampBeyondRadius(true);
#if !TESTING
cpu_pause();
emulator_start();
#endif
@ -186,29 +186,38 @@ void Java_org_deadc0de_apple2ix_Apple2View_nativeGraphicsChanged(JNIEnv *env, jc
}
void Java_org_deadc0de_apple2ix_Apple2View_nativeGraphicsInitialized(JNIEnv *env, jclass cls, jint width, jint height) {
// WANRING : this needs to happen on the GL thread only
// WARNING : this needs to happen on the GL thread only
LOG("width:%d height:%d", width, height);
video_shutdown();
video_backend->reshape(width, height);
video_backend->init((void *)0);
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeEmulationResume(JNIEnv *env, jobject obj) {
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeEmulationResume(JNIEnv *env, jclass cls) {
#if TESTING
// test driver thread is managing CPU
if (!running_tests) {
running_tests = true;
assert(cpu_thread_id == 0 && "CPU thread must not be initialized yet...");
_run_tests();
}
#else
if (!cpu_isPaused()) {
return;
}
LOG("...");
#if TESTING
// test driver thread is managing CPU
#else
cpu_resume();
#endif
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeEmulationPause(JNIEnv *env, jobject obj) {
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeEmulationPause(JNIEnv *env, jclass cls) {
if (appState != APP_RUNNING) {
return;
}
disk6_flush(0);
disk6_flush(1);
if (cpu_isPaused()) {
return;
}
@ -252,12 +261,12 @@ void Java_org_deadc0de_apple2ix_Apple2View_nativeRender(JNIEnv *env, jclass cls)
video_backend->render();
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeReboot(JNIEnv *env, jobject obj) {
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeReboot(JNIEnv *env, jclass cls) {
LOG("...");
cpu65_reboot();
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnQuit(JNIEnv *env, jobject obj) {
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnQuit(JNIEnv *env, jclass cls) {
#if TESTING
// test driver thread is managing CPU
#else
@ -272,21 +281,25 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnQuit(JNIEnv *env, jobject
#endif
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnKeyDown(JNIEnv *env, jobject obj, jint keyCode, jint metaState) {
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnKeyDown(JNIEnv *env, jclass cls, jint keyCode, jint metaState) {
if (UNLIKELY(appState != APP_RUNNING)) {
return;
}
android_keycode_to_emulator(keyCode, metaState, true);
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnKeyUp(JNIEnv *env, jobject obj, jint keyCode, jint metaState) {
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnKeyUp(JNIEnv *env, jclass cls, jint keyCode, jint metaState) {
if (UNLIKELY(appState != APP_RUNNING)) {
return;
}
android_keycode_to_emulator(keyCode, metaState, false);
}
jlong Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnTouch(JNIEnv *env, jobject obj, jint action, jint pointerCount, jint pointerIndex, jfloatArray xCoords, jfloatArray yCoords) {
void Java_org_deadc0de_apple2ix_Apple2View_nativeOnJoystickMove(JNIEnv *env, jclass cls, jint x, jint y) {
joydriver_setAxisValue((uint8_t)x, (uint8_t)y);
}
jlong Java_org_deadc0de_apple2ix_Apple2View_nativeOnTouch(JNIEnv *env, jclass cls, jint action, jint pointerCount, jint pointerIndex, jfloatArray xCoords, jfloatArray yCoords) {
//LOG(": %d/%d/%d :", action, pointerCount, pointerIndex);
SCOPE_TRACE_TOUCH("nativeOnTouch");
@ -311,7 +324,7 @@ jlong Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnTouch(JNIEnv *env, jobje
return flags;
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeChooseDisk(JNIEnv *env, jobject obj, jstring jPath, jboolean driveA, jboolean readOnly) {
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeChooseDisk(JNIEnv *env, jclass cls, jstring jPath, jboolean driveA, jboolean readOnly) {
const char *path = (*env)->GetStringUTFChars(env, jPath, NULL);
int drive = driveA ? 0 : 1;
int ro = readOnly ? 1 : 0;
@ -329,18 +342,60 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeChooseDisk(JNIEnv *env, job
} else {
video_backend->animation_showDiskChosen(drive);
}
FREE(gzPath);
ASPRINTF_FREE(gzPath);
} else {
video_backend->animation_showDiskChosen(drive);
}
(*env)->ReleaseStringUTFChars(env, jPath, path);
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeEjectDisk(JNIEnv *env, jobject obj, jboolean driveA) {
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeEjectDisk(JNIEnv *env, jclass cls, jboolean driveA) {
LOG("...");
disk6_eject(!driveA);
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeSaveState(JNIEnv *env, jclass cls, jstring jPath) {
const char *path = (*env)->GetStringUTFChars(env, jPath, NULL);
assert(cpu_isPaused() && "considered dangerous to save state when CPU thread is running");
LOG(": (%s)", path);
if (!emulator_saveState(path)) {
LOG("OOPS, could not save emulator state");
}
(*env)->ReleaseStringUTFChars(env, jPath, path);
}
jstring Java_org_deadc0de_apple2ix_Apple2Activity_nativeLoadState(JNIEnv *env, jclass cls, jstring jPath) {
const char *path = (*env)->GetStringUTFChars(env, jPath, NULL);
assert(cpu_isPaused() && "considered dangerous to save state when CPU thread is running");
LOG(": (%s)", path);
if (!emulator_loadState(path)) {
LOG("OOPS, could not load emulator state");
}
(*env)->ReleaseStringUTFChars(env, jPath, path);
// restoring state may cause a change in disk paths, so we need to notify the Java/Android menu system of the change
// (normally we drive state from the Java/menu side...)
char *disk1 = disk6.disk[0].file_name;
bool readOnly1 = disk6.disk[0].is_protected;
char *disk2 = disk6.disk[1].file_name;
bool readOnly2 = disk6.disk[1].is_protected;
char *str = NULL;
jstring jstr = NULL;
asprintf(&str, "{ disk1 = \"%s\"; readOnly1 = %s; disk2 = \"%s\"; readOnly2 = %s }", (disk1 ?: ""), readOnly1 ? "true" : "false", (disk2 ?: ""), readOnly2 ? "true" : "false");
if (str) {
jstr = (*env)->NewStringUTF(env, str);
ASPRINTF_FREE(str);
}
return jstr;
}
// ----------------------------------------------------------------------------
// Constructor

View File

@ -110,6 +110,11 @@ void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetTouchJoystickVisibili
joydriver_setShowControls(visibility);
}
void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetTouchJoystickAzimuthVisibility(JNIEnv *env, jclass cls, jboolean visibility) {
LOG("visibility: %d", visibility);
joydriver_setShowAzimuth(visibility);
}
jint Java_org_deadc0de_apple2ix_Apple2Preferences_nativeGetCurrentTouchDevice(JNIEnv *env, jclass cls) {
LOG("%s", "");
if (joydriver_ownsScreen()) {
@ -130,19 +135,28 @@ void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetTouchMenuEnabled(JNIE
interface_setTouchMenuEnabled(enabled);
}
void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetShowDiskOperationAnimation(JNIEnv *env, jclass cls, jboolean enabled) {
LOG("enabled : %d", enabled);
if (video_backend && video_backend->animation_setEnableShowTrackSector) {
video_backend->animation_setEnableShowTrackSector(enabled);
}
}
void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetTouchKeyboardLowercaseEnabled(JNIEnv *env, jclass cls, jboolean enabled) {
LOG("enabled : %d", enabled);
keydriver_setLowercaseEnabled(enabled);
}
void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetTouchMenuVisibility(JNIEnv *env, jclass cls, jfloat alpha) {
LOG("visibility : %f", alpha);
interface_setTouchMenuVisibility(alpha);
}
void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetTouchKeyboardVisibility(JNIEnv *env, jclass cls, jfloat inactiveAlpha, jfloat activeAlpha) {
LOG("inactive:%f active:%f", inactiveAlpha, activeAlpha);
keydriver_setVisibilityWhenOwnsScreen(inactiveAlpha, activeAlpha);
interface_setTouchMenuVisibility(inactiveAlpha, activeAlpha);
}
void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetTouchKeyboardGlyphScale(JNIEnv *env, jclass cls, jint glyphScale) {
LOG("glyphScale:%d", glyphScale);
keydriver_setGlyphScale(glyphScale);
interface_setGlyphScale(glyphScale);
}
void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetTouchJoystickButtonTypes(JNIEnv *env, jclass cls, jint touchDownButton, jint northButton, jint southButton) {
@ -170,7 +184,7 @@ void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetTouchJoystickButtonTy
rosetteChars[ROSETTE_NORTH] = (uint8_t)MOUSETEXT_UP; rosetteScancodes[ROSETTE_NORTH] = -1;
rosetteChars[ROSETTE_NORTHEAST] = ' '; rosetteScancodes[ROSETTE_NORTHEAST] = -1;
rosetteChars[ROSETTE_WEST] = (uint8_t)MOUSETEXT_LEFT; rosetteScancodes[ROSETTE_WEST] = -1;
rosetteChars[ROSETTE_CENTER] = '+'; rosetteScancodes[ROSETTE_CENTER] = -1;
rosetteChars[ROSETTE_CENTER] = ICONTEXT_MENU_TOUCHJOY; rosetteScancodes[ROSETTE_CENTER] = -1;
rosetteChars[ROSETTE_EAST] = (uint8_t)MOUSETEXT_RIGHT; rosetteScancodes[ROSETTE_EAST] = -1;
rosetteChars[ROSETTE_SOUTHWEST] = ' '; rosetteScancodes[ROSETTE_SOUTHWEST] = -1;
rosetteChars[ROSETTE_SOUTH] = (uint8_t)MOUSETEXT_DOWN; rosetteScancodes[ROSETTE_SOUTH] = -1;
@ -227,6 +241,9 @@ void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeTouchJoystickSetKeypadTy
for (unsigned int i=0; i<(ROSETTE_ROWS * ROSETTE_COLS); i++) {
actualChars[i] = (uint8_t)rosetteChars[i];
}
if (actualChars[4] == ICONTEXT_NONACTIONABLE) {
actualChars[4] = ICONTEXT_MENU_TOUCHJOY;
}
joydriver_setTouchAxisTypes(actualChars, rosetteScans);
joydriver_setTouchButtonTypes(
(touchjoy_button_type_t)buttonsChars[0], buttonsScans[0],

View File

@ -39,7 +39,7 @@ APPLE2_MAIN_SRC = \
$(APPLE2_SRC_PATH)/interface.c $(APPLE2_SRC_PATH)/disk.c $(APPLE2_SRC_PATH)/cpu-supp.c \
jnihooks.c jniprefs.c androidkeys.c
APPLE2_OPTIM_CFLAGS := -g -O2
APPLE2_OPTIM_CFLAGS := -O2
APPLE2_BASE_CFLAGS := -DAPPLE2IX=1 -DINTERFACE_TOUCH=1 -DMOBILE_DEVICE=1 -DVIDEO_OPENGL=1 -DDEBUGGER=1 -DAUDIO_ENABLED=1 -std=gnu11 -DPREVENT_TEXTREL=1 -fPIC $(APPLE2_OPTIM_CFLAGS) -I$(APPLE2_SRC_PATH)
APPLE2_BASE_LDLIBS := -llog -landroid -lGLESv2 -lz -lOpenSLES

View File

@ -12,12 +12,13 @@ include $(COMMON_SOURCES_MK)
LOCAL_MODULE := libapple2ix
LOCAL_SRC_FILES := $(APPLE2_SRC_PATH)/test/testcommon.c $(APPLE2_SRC_PATH)/test/testcpu.c
LOCAL_CFLAGS := $(APPLE2_BASE_CFLAGS) -DTEST_CPU -DTESTING=1
LOCAL_CFLAGS := $(APPLE2_BASE_CFLAGS) -g -DTEST_CPU -DTESTING=1
LOCAL_LDLIBS := $(APPLE2_BASE_LDLIBS)
# Add assembly files first ... mostly for the benefit of the ARM assembler ...
ifeq ($(TARGET_ARCH_ABI),x86)
LOCAL_SRC_FILES += $(APPLE2_X86_SRC)
LOCAL_CFLAGS += -DNO_UNDERSCORES=1
else
LOCAL_SRC_FILES += $(APPLE2_ARM_SRC)
endif

View File

@ -12,12 +12,13 @@ include $(COMMON_SOURCES_MK)
LOCAL_MODULE := libapple2ix
LOCAL_SRC_FILES := $(APPLE2_SRC_PATH)/test/testcommon.c $(APPLE2_SRC_PATH)/test/testdisk.c
LOCAL_CFLAGS := $(APPLE2_BASE_CFLAGS) -DTEST_DISK -DTESTING=1 -DDISK_TRACING=1
LOCAL_CFLAGS := $(APPLE2_BASE_CFLAGS) -g -DTEST_DISK -DTESTING=1 -DDISK_TRACING=1
LOCAL_LDLIBS := $(APPLE2_BASE_LDLIBS)
# Add assembly files first ... mostly for the benefit of the ARM assembler ...
ifeq ($(TARGET_ARCH_ABI),x86)
LOCAL_SRC_FILES += $(APPLE2_X86_SRC)
LOCAL_CFLAGS += -DNO_UNDERSCORES=1
else
LOCAL_SRC_FILES += $(APPLE2_ARM_SRC)
endif

View File

@ -12,12 +12,13 @@ include $(COMMON_SOURCES_MK)
LOCAL_MODULE := libapple2ix
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_CFLAGS := $(APPLE2_BASE_CFLAGS) -g -DTEST_DISPLAY -DTESTING=1
LOCAL_LDLIBS := $(APPLE2_BASE_LDLIBS)
# Add assembly files first ... mostly for the benefit of the ARM assembler ...
ifeq ($(TARGET_ARCH_ABI),x86)
LOCAL_SRC_FILES += $(APPLE2_X86_SRC)
LOCAL_CFLAGS += -DNO_UNDERSCORES=1
else
LOCAL_SRC_FILES += $(APPLE2_ARM_SRC)
endif

View File

@ -12,12 +12,13 @@ include $(COMMON_SOURCES_MK)
LOCAL_MODULE := libapple2ix
LOCAL_SRC_FILES := $(APPLE2_SRC_PATH)/test/testcommon.c $(APPLE2_SRC_PATH)/test/testvm.c
LOCAL_CFLAGS := $(APPLE2_BASE_CFLAGS) -DTEST_VM -DTESTING=1
LOCAL_CFLAGS := $(APPLE2_BASE_CFLAGS) -g -DTEST_VM -DTESTING=1
LOCAL_LDLIBS := $(APPLE2_BASE_LDLIBS)
# Add assembly files first ... mostly for the benefit of the ARM assembler ...
ifeq ($(TARGET_ARCH_ABI),x86)
LOCAL_SRC_FILES += $(APPLE2_X86_SRC)
LOCAL_CFLAGS += -DNO_UNDERSCORES=1
else
LOCAL_SRC_FILES += $(APPLE2_ARM_SRC)
endif

View File

@ -56,26 +56,31 @@ static int _convert_crlf_to_lf(void) {
// convert CRLF -> LF
ssize_t outlen=0;
ssize_t outmax=0;
for (ssize_t i=0; i<inlen; i++) {
char c = inbuf[i];
if (sawCR && (c != LF)) {
outbuf[outlen++] = CR;
outbuf[outmax++] = CR;
}
sawCR = false;
if (c == CR) {
sawCR = true;
} else {
outbuf[outlen++] = c;
outbuf[outmax++] = c;
}
}
if (TEMP_FAILURE_RETRY(write(STDOUT_FILENO, outbuf, outlen)) == -1) {
errWrt = "error writing to stdout";
break;
}
ssize_t outlen = 0;
do {
if (TEMP_FAILURE_RETRY(outlen = write(STDOUT_FILENO, outbuf, outmax)) == -1) {
errWrt = "error writing to stdout";
break;
}
outbuf += outlen;
outmax -= outlen;
} while (outmax > 0);
}
if (sawCR) {

View File

@ -0,0 +1,17 @@
//
// Prefix header
//
// The contents of this file are implicitly included at the beginning of every source file.
//
#import <TargetConditionals.h>
#if TARGET_OS_IPHONE
# ifdef __OBJC__
# import <UIKit/UIKit.h>
# endif
#else
# ifdef __OBJC__
# import <Cocoa/Cocoa.h>
# endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -6,10 +6,14 @@
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleHelpBookFolder</key>
<string>Apple2Mac.help</string>
<key>CFBundleHelpBookName</key>
<string>org.deadc0de.Apple2Mac.help</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>org.deadc0de.Apple2Mac</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
@ -22,10 +26,6 @@
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>CFBundleHelpBookFolder</key>
<string>Apple2Mac.help</string>
<key>CFBundleHelpBookName</key>
<string>org.deadc0de.Apple2Mac.help</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.education</string>
<key>LSMinimumSystemVersion</key>

View File

@ -0,0 +1,23 @@
//
// AppleViewController.h
// Apple2Mac
//
// Created by Jerome Vernet on 24/12/2015.
// Copyright © 2015 deadc0de.org. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "iosPrefControllerViewController.h"
@interface AppleViewController : UIViewController
@property (nonatomic, assign) BOOL paused;
@property (assign) IBOutlet UIToolbar *mainToolBar;
@property (assign) IBOutlet iosPrefControllerViewController *viewPrefs;
-(IBAction)rebootItemSelected:(id)sender;
-(IBAction)prefsItemSelected:(id)sender;
-(IBAction)toggleCPUSpeedItemSelected:(id)sender;
-(IBAction)togglePauseItemSelected:(id)sender;
-(IBAction)diskInsert:(id)sender;
@end

View File

@ -0,0 +1,120 @@
//
// AppleViewController.m
// Apple2Mac
//
// Created by Jerome Vernet on 24/12/2015.
// Copyright © 2015 deadc0de.org. All rights reserved.
//
#import "AppleViewController.h"
#import "common.h"
#import "modelUtil.h"
@interface AppleViewController ()
@end
@implementation AppleViewController
@synthesize paused = _paused;
- (void)viewDidLoad {
[super viewDidLoad];
// [self mainToolBar ];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
cpu_pause();
}
- (IBAction)unwindForSegue:(UIStoryboardSegue*)sender
{
cpu_resume();
}
- (IBAction)upSwipe:(id)sender
{
self.mainToolBar.hidden=NO;
}
- (IBAction)diskInsert:(id)sender
{
NSLog(@"LISTING ALL FILES FOUND");
int Count;
NSString *path;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Disks"];
NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL];
for (Count = 0; Count < (int)[directoryContent count]; Count++)
{
NSLog(@"File %d: %@", (Count + 1), [directoryContent objectAtIndex:Count]);
}
}
-(IBAction)rebootItemSelected:(id)sender{
cpu65_reboot();
}
-(IBAction)prefsItemSelected:(id)sender{
cpu_pause();
//[self.viewPrefs ];
//pause
//show pref windows
cpu_resume();
}
- (IBAction)toggleCPUSpeedItemSelected:(id)sender
{
cpu_pause();
timing_toggleCPUSpeed();
if (video_backend && video_backend->animation_showCPUSpeed)
{
video_backend->animation_showCPUSpeed();
}
cpu_resume();
}
- (IBAction)togglePauseItemSelected:(id)sender
{
NSAssert(pthread_main_np(), @"Pause emulation called from non-main thread");
self.paused = !_paused;
}
- (void)setPaused:(BOOL)paused
{
if (_paused == paused)
{
return;
}
_paused = paused;
if (paused)
{
cpu_pause();
}
else
{
cpu_resume();
}
if (video_backend && video_backend->animation_showPaused)
{
video_backend->animation_showPaused();
}
}
- (void)dealloc {
[super dealloc];
}
@end

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6245" systemVersion="13F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment version="1060" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6245"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9531"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
@ -88,7 +88,7 @@
<rect key="contentRect" x="196" y="240" width="480" height="270"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1178"/>
<view key="contentView" id="6V4-fW-Bkm">
<rect key="frame" x="7" y="11" width="480" height="270"/>
<rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
<autoresizingMask key="autoresizingMask"/>
</view>
</window>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="8191" systemVersion="14F27" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment version="1060" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="8191"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9531"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
@ -23,27 +23,6 @@
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
</connections>
</menuItem>
<menuItem title="Reboot Emulator" id="FjO-UG-hG2" userLabel="Menu Item - Reboot">
<string key="keyEquivalent" base64-UTF8="YES">
CA
</string>
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="reboot:" target="M8b-ga-iOS" id="AbH-Xq-1VZ"/>
</connections>
</menuItem>
<menuItem title="Disks" id="IU3-Bt-BuK" userLabel="Menu Item - Disks">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Disks" systemMenu="help" id="Wh3-tN-xkr">
<items>
<menuItem title="Insert..." keyEquivalent="D" id="Oj8-qO-A80" userLabel="Menu Item - Insert">
<connections>
<action selector="showDisksWindow:" target="M8b-ga-iOS" id="GVw-D1-gi0"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="236">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
@ -52,21 +31,6 @@ CA
<action selector="showPreferences:" target="M8b-ga-iOS" id="oDD-g4-QEJ"/>
</connections>
</menuItem>
<menuItem title="Toggle Full Screen" keyEquivalent="F" id="rP9-cs-9dM">
<connections>
<action selector="toggleFullScreen:" target="M8b-ga-iOS" id="Xan-eQ-CRM"/>
</connections>
</menuItem>
<menuItem title="Toggle CPU Speed" keyEquivalent="S" id="b9q-zr-oNh">
<connections>
<action selector="toggleCPUSpeed:" target="M8b-ga-iOS" id="fA3-dJ-wtg"/>
</connections>
</menuItem>
<menuItem title="Pause Emulation" keyEquivalent="X" id="r9g-Ro-UwW">
<connections>
<action selector="togglePause:" target="M8b-ga-iOS" id="c65-mm-bIj"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="143">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
@ -103,6 +67,299 @@ CA
</items>
</menu>
</menuItem>
<menuItem title="File" id="4dZ-4f-42V">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="File" id="ma8-CB-dnr">
<items>
<menuItem title="Reboot Emulator" id="Xr5-Y9-tRL" userLabel="Menu Item - Reboot">
<string key="keyEquivalent" base64-UTF8="YES">
CA
</string>
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="reboot:" target="M8b-ga-iOS" id="XtR-At-SSS"/>
</connections>
</menuItem>
<menuItem title="Toggle CPU Speed" keyEquivalent="S" id="pJl-yR-ULm">
<connections>
<action selector="toggleCPUSpeed:" target="M8b-ga-iOS" id="JUd-Uf-yyX"/>
</connections>
</menuItem>
<menuItem title="Pause Emulation" keyEquivalent="X" id="OKW-bt-a58">
<connections>
<action selector="togglePause:" target="M8b-ga-iOS" id="KLo-hL-5zu"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="Bp7-3g-GDj"/>
<menuItem title="Disks" id="rp2-u6-d0B" userLabel="Menu Item - Disks">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Disks" systemMenu="help" id="8XK-7x-7hh">
<items>
<menuItem title="Insert..." keyEquivalent="D" id="JhN-ZL-f2O" userLabel="Menu Item - Insert">
<connections>
<action selector="showDisksWindow:" target="M8b-ga-iOS" id="EEd-WE-b9g"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="Mec-fL-Gcp"/>
<menuItem title="Page Setup…" enabled="NO" keyEquivalent="P" id="0HU-OV-39A">
<connections>
<action selector="runPageLayout:" target="-1" id="GVI-mL-WRX"/>
</connections>
</menuItem>
<menuItem title="Print…" enabled="NO" keyEquivalent="p" id="dXC-8t-bQ7">
<connections>
<action selector="print:" target="-1" id="MkR-UN-gGO"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Edit" id="ZKa-Nk-KCW">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Edit" id="WCv-04-9tQ">
<items>
<menuItem title="Undo" enabled="NO" keyEquivalent="z" id="7ji-O5-1oP">
<connections>
<action selector="undo:" target="-1" id="nTg-8e-qqX"/>
</connections>
</menuItem>
<menuItem title="Redo" enabled="NO" keyEquivalent="Z" id="jYN-aO-Gse">
<connections>
<action selector="redo:" target="-1" id="3cC-fV-e1H"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="cRv-NN-CM3"/>
<menuItem title="Cut" keyEquivalent="x" id="B9f-O6-lco">
<connections>
<action selector="cut:" target="-1" id="cEF-Mr-gEI"/>
</connections>
</menuItem>
<menuItem title="Copy" keyEquivalent="c" id="BRV-TN-Pzv">
<connections>
<action selector="copy:" target="-1" id="xcu-og-fVt"/>
</connections>
</menuItem>
<menuItem title="Paste" keyEquivalent="v" id="geM-qO-aZ2">
<connections>
<action selector="paste:" target="-1" id="uDP-lX-2QO"/>
</connections>
</menuItem>
<menuItem title="Paste and Match Style" enabled="NO" keyEquivalent="V" id="gUM-x3-iEs">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteAsPlainText:" target="-1" id="62M-Kk-7W0"/>
</connections>
</menuItem>
<menuItem title="Delete" id="i2b-GO-OI0">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="delete:" target="-1" id="Ofc-Df-mrY"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="l6c-o9-Lcb">
<connections>
<action selector="selectAll:" target="-1" id="hfq-sH-Hrd"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="gPI-YZ-Ej7"/>
<menuItem title="Find" id="wpu-4I-0bh">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Find" id="Hm4-5s-n7i">
<items>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="xx4-kU-rZA">
<connections>
<action selector="performFindPanelAction:" target="-1" id="QjO-TQ-NTO"/>
</connections>
</menuItem>
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="Mzr-n7-gii">
<connections>
<action selector="performFindPanelAction:" target="-1" id="uJq-AO-zpb"/>
</connections>
</menuItem>
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="EcB-rH-6Fn">
<connections>
<action selector="performFindPanelAction:" target="-1" id="7oO-Bh-siN"/>
</connections>
</menuItem>
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="cYe-Hg-XZ2">
<connections>
<action selector="performFindPanelAction:" target="-1" id="NLQ-EP-xeT"/>
</connections>
</menuItem>
<menuItem title="Jump to Selection" keyEquivalent="j" id="VRT-xH-o4f">
<connections>
<action selector="centerSelectionInVisibleArea:" target="-1" id="hvL-8z-0XQ"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Spelling and Grammar" id="lBL-48-NL8">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Spelling" id="7rr-yF-apD">
<items>
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="TxR-Iv-fxN">
<connections>
<action selector="showGuessPanel:" target="-1" id="Fi5-eF-xtd"/>
</connections>
</menuItem>
<menuItem title="Check Document Now" keyEquivalent=";" id="1NC-db-BRz">
<connections>
<action selector="checkSpelling:" target="-1" id="4Cb-VT-uRv"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="1VO-3p-hKr"/>
<menuItem title="Check Spelling While Typing" id="R7T-Py-IUl">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleContinuousSpellChecking:" target="-1" id="fRX-Xn-i0s"/>
</connections>
</menuItem>
<menuItem title="Check Grammar With Spelling" id="A2e-bf-a76">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleGrammarChecking:" target="-1" id="PYu-Cs-Nvn"/>
</connections>
</menuItem>
<menuItem title="Correct Spelling Automatically" id="Z8h-ou-V7a">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="keB-gX-m3T"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Substitutions" id="jb7-2B-6xa">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Substitutions" id="iMe-LJ-g9B">
<items>
<menuItem title="Show Substitutions" id="Fa7-uJ-Naj">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="PoI-1s-Hjv"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="lQF-eK-0p9"/>
<menuItem title="Smart Copy/Paste" id="KS0-Pe-biv">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleSmartInsertDelete:" target="-1" id="Rrf-F9-auF"/>
</connections>
</menuItem>
<menuItem title="Smart Quotes" id="uXJ-Bm-7aA">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="pZw-O8-1Q6"/>
</connections>
</menuItem>
<menuItem title="Smart Dashes" id="8KL-lT-U1f">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="EHC-04-hyV"/>
</connections>
</menuItem>
<menuItem title="Smart Links" id="hq9-VC-W6c">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticLinkDetection:" target="-1" id="3BN-Bo-i7K"/>
</connections>
</menuItem>
<menuItem title="Data Detectors" id="qeO-vj-7ge">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDataDetection:" target="-1" id="fAF-LU-W4B"/>
</connections>
</menuItem>
<menuItem title="Text Replacement" id="vGB-cx-gYU">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticTextReplacement:" target="-1" id="sQF-gF-l9g"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Transformations" id="898-0g-Oio">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Transformations" id="7Zl-6t-TqO">
<items>
<menuItem title="Make Upper Case" id="6C2-i8-KVq">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="uppercaseWord:" target="-1" id="pjO-OZ-Lwk"/>
</connections>
</menuItem>
<menuItem title="Make Lower Case" id="ZZP-5z-YrA">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowercaseWord:" target="-1" id="4ZN-4K-BgR"/>
</connections>
</menuItem>
<menuItem title="Capitalize" id="MIg-Ae-S5l">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="capitalizeWord:" target="-1" id="wNF-kk-YaV"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Speech" id="phA-NA-yWC">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Speech" id="voe-xv-aqn">
<items>
<menuItem title="Start Speaking" id="zfA-gc-OcH">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="startSpeaking:" target="-1" id="kdt-Em-BHj"/>
</connections>
</menuItem>
<menuItem title="Stop Speaking" id="FHw-p7-luT">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="stopSpeaking:" target="-1" id="cAo-hP-Ubn"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="TP0-Ag-yPc">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Window" systemMenu="window" id="v0D-uE-mdE">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="dq0-ap-hiO">
<connections>
<action selector="performMiniaturize:" target="-1" id="wuW-Cq-NVB"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="Kw3-wb-a0i">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="performZoom:" target="-1" id="Rab-bb-j9C"/>
</connections>
</menuItem>
<menuItem title="Toggle Full Screen" keyEquivalent="F" id="Lem-uE-El9">
<connections>
<action selector="toggleFullScreen:" target="M8b-ga-iOS" id="0fX-bE-3MN"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="yFd-C5-chc"/>
<menuItem title="Bring All to Front" id="Kwp-da-LVP">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="arrangeInFront:" target="-1" id="iee-gu-gae"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="490">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="491">
@ -118,21 +375,50 @@ CA
</items>
</menu>
<window title="Apple2Mac" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371" userLabel="Window - Apple2Mac" customClass="EmulatorWindow">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" unifiedTitleAndToolbar="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="200" y="200" width="568" height="384"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1178"/>
<view key="contentView" id="372" customClass="EmulatorGLView">
<rect key="frame" x="0.0" y="-1" width="568" height="384"/>
<rect key="frame" x="0.0" y="0.0" width="568" height="384"/>
<autoresizingMask key="autoresizingMask"/>
</view>
<point key="canvasLocation" x="-315" y="-1328"/>
<toolbar key="toolbar" implicitIdentifier="8323D01A-4ECF-4973-8DC6-3BB0A67F10FD" allowsUserCustomization="NO" displayMode="iconAndLabel" sizeMode="small" id="gXM-1s-f0F">
<allowedToolbarItems>
<toolbarItem implicitItemIdentifier="NSToolbarShowColorsItem" id="oed-am-Cfb"/>
<toolbarItem implicitItemIdentifier="NSToolbarPrintItem" id="sk6-41-C3g"/>
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="AoN-cv-QQ2"/>
<toolbarItem implicitItemIdentifier="CBD2C3ED-B0AA-40F1-818F-B61B04F93E7F" label="Preferences" paletteLabel="Preferences" tag="-1" image="Prefs" id="85b-WO-tks"/>
<toolbarItem implicitItemIdentifier="1AF00BE2-1806-4F36-AA9B-EDCD8587D441" label="Reboot" paletteLabel="Reboot" tag="-1" image="Reboot" id="hOg-ec-Okz"/>
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="372-hX-Xt1"/>
<toolbarItem implicitItemIdentifier="ED8F052E-C9AE-42F6-BA6D-2A675E8390E5" label="Disks" paletteLabel="Disks" tag="-1" image="Disks" id="jHk-qj-bmw"/>
<toolbarItem implicitItemIdentifier="0E674D24-EE72-4444-A2D2-256161A8EEC6" label="CPU" paletteLabel="CPU" tag="-1" image="CPU" id="xjq-6u-Yc9" userLabel="CPU">
<connections>
<action selector="toggleCPUSpeed:" target="M8b-ga-iOS" id="FVD-QZ-joo"/>
</connections>
</toolbarItem>
<toolbarItem implicitItemIdentifier="B1B89899-E7C4-4A6A-9B19-B29D3C7FB7CC" label="Pause" paletteLabel="Pause" tag="-1" image="Stop" id="hkP-Yj-QZG"/>
<toolbarItem implicitItemIdentifier="3358D7A0-4F67-4503-ADD8-6E900BB291CC" label="Toolbar Item" paletteLabel="Toolbar Item" tag="-1" image="NSUser" id="JbN-Qp-xsc"/>
<toolbarItem implicitItemIdentifier="E796EDE5-7BB6-4CBB-AC6B-17DA3FC696C9" label="FullScreen" paletteLabel="FullScreen" tag="-1" image="Fullscreen" id="Ahr-ZD-7wt"/>
</allowedToolbarItems>
<defaultToolbarItems>
<toolbarItem reference="hOg-ec-Okz"/>
<toolbarItem reference="hkP-Yj-QZG"/>
<toolbarItem reference="Ahr-ZD-7wt"/>
<toolbarItem reference="AoN-cv-QQ2"/>
<toolbarItem reference="AoN-cv-QQ2"/>
<toolbarItem reference="jHk-qj-bmw"/>
<toolbarItem reference="372-hX-Xt1"/>
<toolbarItem reference="sk6-41-C3g"/>
<toolbarItem reference="85b-WO-tks"/>
</defaultToolbarItems>
</toolbar>
<point key="canvasLocation" x="-201" y="-1220"/>
</window>
<customObject id="494" userLabel="EmulatorGLView" customClass="EmulatorGLView"/>
<customObject id="M8b-ga-iOS" customClass="EmulatorWindowController" colorLabel="IBBuiltInLabel-Blue">
<connections>
<outlet property="disksWindow" destination="RAk-at-ZT4" id="64k-qW-zF5"/>
<outlet property="pauseMenuItem" destination="r9g-Ro-UwW" id="4YW-pt-lai"/>
<outlet property="prefsWindow" destination="Mzv-VG-jce" id="dQt-pf-qdi"/>
<outlet property="view" destination="372" id="pRG-Kn-92X"/>
<outlet property="window" destination="371" id="z3B-S9-PsV"/>
@ -238,7 +524,7 @@ CA
<rect key="frame" x="20" y="153" width="212" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<size key="cellSize" width="89" height="18"/>
<size key="cellSize" width="88" height="18"/>
<size key="intercellSpacing" width="4" height="2"/>
<buttonCell key="prototype" type="radio" title="Radio" imagePosition="left" alignment="left" inset="2" id="800-L1-WxW">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
@ -266,7 +552,7 @@ CA
<rect key="frame" x="271" y="153" width="212" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<size key="cellSize" width="89" height="18"/>
<size key="cellSize" width="88" height="18"/>
<size key="intercellSpacing" width="4" height="2"/>
<buttonCell key="prototype" type="radio" title="Radio" imagePosition="left" alignment="left" inset="2" id="uEc-fa-XXZ">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
@ -365,7 +651,7 @@ DQ
<rect key="contentRect" x="109" y="132" width="580" height="360"/>
<rect key="screenRect" x="0.0" y="0.0" width="1280" height="778"/>
<view key="contentView" id="bfK-7M-z1X">
<rect key="frame" x="0.0" y="1" width="580" height="360"/>
<rect key="frame" x="0.0" y="0.0" width="580" height="360"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<tabView id="xvZ-VK-VbM">
@ -729,5 +1015,15 @@ DQ
<outlet property="window" destination="Mzv-VG-jce" id="86q-Ys-9Mt"/>
</connections>
</customObject>
<toolbarItem implicitItemIdentifier="ED8F052E-C9AE-42F6-BA6D-2A675E8390E5" label="Disks" paletteLabel="Disks" tag="-1" image="Disks" id="iyV-hM-okT"/>
</objects>
<resources>
<image name="CPU" width="32" height="32"/>
<image name="Disks" width="32" height="32"/>
<image name="Fullscreen" width="32" height="32"/>
<image name="NSUser" width="32" height="32"/>
<image name="Prefs" width="32" height="32"/>
<image name="Reboot" width="32" height="32"/>
<image name="Stop" width="32" height="32"/>
</resources>
</document>

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "cpu32.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "cpu64.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "cpu128.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "floppy32.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "floppy64.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "floppy128.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "fullscreen32.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "fullscreen64.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "fullscreen128.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "pref32.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "pref64.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "pref128.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "reboot32.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "play32.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "play64.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "play128.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "stop32.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "stop64.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "stop128.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,19 @@
//
// disksViewController.h
// Apple2Mac
//
// Created by Jerome Vernet on 31/12/2015.
// Copyright © 2015 deadc0de.org. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface disksViewController : UIViewController<UIPickerViewDataSource, UIPickerViewDelegate>
@property (retain, nonatomic) IBOutlet UIPickerView *disk1Picker;
@property (retain, nonatomic) IBOutlet UIPickerView *disk2Picker;
@property (retain, nonatomic) IBOutlet UISwitch *diskAProtection;
@property (retain, nonatomic) IBOutlet UISwitch *diskBProtection;
@property (strong,nonatomic) NSArray *_disks;
@property (retain,nonatomic) NSString *path;
@end

View File

@ -0,0 +1,93 @@
//
// disksViewController.m
// Apple2Mac
//
// Created by Jerome Vernet on 31/12/2015.
// Copyright © 2015 deadc0de.org. All rights reserved.
//
#import "disksViewController.h"
#import "common.h"
@implementation disksViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//self.path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Disks"];
self.path = [paths objectAtIndex:0];
NSLog(@"Path:%@",self.path);
self._disks=[[NSFileManager defaultManager] contentsOfDirectoryAtPath:self.path error:NULL];
// Connect data
self.disk1Picker.dataSource = self;
self.disk1Picker.delegate = self;
self.disk2Picker.dataSource = self;
self.disk2Picker.delegate = self;
}
// The number of columns of data
- (int)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
// The number of rows of data
- (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return self._disks.count;
//_pickerData.cout;
}
// The data to return for the row and component (column) that's being passed in
- (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [self._disks objectAtIndex:row];
}
// Catpure the picker view selection
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// This method is triggered whenever the user makes a change to the picker selection.
// The parameter named row and component represents what was selected.
int drive=0;
BOOL ro=YES;
if(pickerView==self.disk1Picker)
{
drive=0;
ro=self.diskAProtection.on;
}
if(pickerView==self.disk2Picker)
{
drive=1;
ro=self.diskBProtection.on;
}
NSLog(@"Selected Row %d %@ %c", row,(NSString*)[self._disks objectAtIndex:row],ro);
disk6_eject(drive);
const char *errMsg = disk6_insert(drive, [[self.path stringByAppendingPathComponent:[self._disks objectAtIndex:row]] UTF8String], ro);
}
- (IBAction)unwindToMainViewController:(UIStoryboardSegue*)sender
{ }
-(IBAction)goodbye:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
cpu_resume();
}
- (void)dealloc {
[_diskAProtection release];
[_diskBProtection release];
[super dealloc];
}
@end

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
{\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf210
{\fonttbl\f0\fnil\fcharset0 Menlo-Bold;\f1\fnil\fcharset0 Menlo-Regular;\f2\fnil\fcharset0 Menlo-Italic;
}
{\colortbl;\red255\green255\blue255;}
\vieww9600\viewh8400\viewkind0
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\sl216\slmult1\qc
\f0\b\fs24 \cf0 Authors\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\sl216\slmult1\pardirnatural\qc
\f1\b0 \cf0 Aaron Culliney\
and other contributors\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\sl120\slmult1\pardirnatural\qc
\cf0 \
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\sl216\slmult1\pardirnatural\qc
\f0\b \cf0 Web Resources
\f1\b0 \
\f2\i ftp.apple.asimov.net
\f1\i0 and elsewhere\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\sl120\slmult1\pardirnatural\qc
\cf0 \
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\sl216\slmult1\pardirnatural\qc
\f0\b \cf0 Special thanks to
\f1\b0 \
Tom Charlesworth\
and the AppleWin project}

View File

@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */

View File

@ -0,0 +1,45 @@
/* Class = "NSMenu"; title = "AMainMenu"; ObjectID = "29"; */
"29.title" = "AMainMenu";
/* Class = "NSMenuItem"; title = "Apple2Mac"; ObjectID = "56"; */
"56.title" = "Apple2Mac";
/* Class = "NSMenu"; title = "Apple2Mac"; ObjectID = "57"; */
"57.title" = "Apple2Mac";
/* Class = "NSMenuItem"; title = "About Apple2Mac"; ObjectID = "58"; */
"58.title" = "About Apple2Mac";
/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "129"; */
"129.title" = "Preferences…";
/* Class = "NSMenu"; title = "Services"; ObjectID = "130"; */
"130.title" = "Services";
/* Class = "NSMenuItem"; title = "Services"; ObjectID = "131"; */
"131.title" = "Services";
/* Class = "NSMenuItem"; title = "Hide Apple2Mac"; ObjectID = "134"; */
"134.title" = "Hide Apple2Mac";
/* Class = "NSMenuItem"; title = "Quit Apple2Mac"; ObjectID = "136"; */
"136.title" = "Quit Apple2Mac";
/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "145"; */
"145.title" = "Hide Others";
/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "150"; */
"150.title" = "Show All";
/* Class = "NSMenuItem"; title = "Help"; ObjectID = "490"; */
"490.title" = "Help";
/* Class = "NSMenu"; title = "Help"; ObjectID = "491"; */
"491.title" = "Help";
/* Class = "NSMenuItem"; title = "Apple2Mac Help"; ObjectID = "492"; */
"492.title" = "Apple2Mac Help";
/* Class = "NSWindow"; title = "Window"; ObjectID = "HyN-la-Rec"; */
"HyN-la-Rec.title" = "Window";

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
//
// iosPrefControllerViewController.h
// Apple2Mac
//
// Created by Jerome Vernet on 24/12/2015.
// Copyright © 2015 deadc0de.org. All rights reserved.
//
#import <UIKit/UIKit.h>
#define kApple2SavedPrefs @"kApple2SavedPrefs"
#define kApple2CPUSpeed @"kApple2CPUSpeed"
#define kApple2CPUSpeedIsMax @"kApple2CPUSpeedIsMax"
#define kApple2AltSpeed @"kApple2AltSpeed"
#define kApple2AltSpeedIsMax @"kApple2AltSpeedIsMax"
#define kApple2SoundcardConfig @"kApple2SoundcardConfig"
#define kApple2ColorConfig @"kApple2ColorConfig"
#define kApple2JoystickConfig @"kApple2JoystickConfig"
#define kApple2JoystickAutoRecenter @"kApple2JoystickAutoRecenter"
#define kApple2JoystickClipToRadius @"kApple2JoystickClipToRadius"
#define kApple2PrefStartupDiskA @"kApple2PrefStartupDiskA"
#define kApple2PrefStartupDiskAProtected @"kApple2PrefStartupDiskAProtected"
#define kApple2PrefStartupDiskB @"kApple2PrefStartupDiskB"
#define kApple2PrefStartupDiskBProtected @"kApple2PrefStartupDiskBProtected"
#define kApple2JoystickStep @"kApple2JoystickStep"
@interface iosPrefControllerViewController : UIViewController<UIPickerViewDataSource, UIPickerViewDelegate>
@property (retain, nonatomic) IBOutlet UIPickerView *videoModePicker;
@property (retain, nonatomic) IBOutlet UISlider *cpuSlider;
@property (retain, nonatomic) IBOutlet UISlider *altSlider;
@property (retain, nonatomic) IBOutlet UILabel *cpuSliderLabel;
@property (retain, nonatomic) IBOutlet UILabel *altSliderLabel;
@property (retain, nonatomic) IBOutlet UISwitch *cpuMaxChoice;
@property (retain, nonatomic) IBOutlet UISwitch *altMaxChoice;
@property (strong,nonatomic) NSArray *_videoMode;
@end

View File

@ -0,0 +1,230 @@
//
// iosPrefControllerViewController.m
// Apple2Mac
//
// Created by Jerome Vernet on 24/12/2015.
// Copyright © 2015 deadc0de.org. All rights reserved.
//
#import "iosPrefControllerViewController.h"
#import "common.h"
#import "modelUtil.h"
@implementation iosPrefControllerViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self._videoMode = [[NSArray alloc] initWithObjects:@"Mono",@"Color", nil];
// Connect data
self.videoModePicker.dataSource = self;
self.videoModePicker.delegate = self;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
BOOL firstTime = ![defaults boolForKey:kApple2SavedPrefs];
if (firstTime)
{
[defaults setBool:YES forKey:kApple2SavedPrefs];
[defaults setDouble:1.0 forKey:kApple2CPUSpeed];
[defaults setDouble:CPU_SCALE_SLOWEST forKey:kApple2AltSpeed];
[defaults setBool:NO forKey:kApple2CPUSpeedIsMax];
[defaults setBool:NO forKey:kApple2AltSpeedIsMax];
[defaults setInteger:COLOR_INTERP forKey:kApple2ColorConfig];
// [defaults setInteger:JOY_KPAD forKey:kApple2JoystickConfig];
[defaults setBool:YES forKey:kApple2JoystickAutoRecenter];
[defaults removeObjectForKey:kApple2PrefStartupDiskA];
[defaults removeObjectForKey:kApple2PrefStartupDiskB];
}
cpu_scale_factor = [defaults doubleForKey:kApple2CPUSpeed];
[self.cpuSlider setValue:cpu_scale_factor animated:NO];
self.cpuSliderLabel.text=[NSString stringWithFormat:@"%.0f%%", cpu_scale_factor*100];
if ([defaults boolForKey:kApple2CPUSpeedIsMax])
{
cpu_scale_factor = CPU_SCALE_FASTEST;
[self.cpuMaxChoice setOn:YES];
[self.cpuSlider setEnabled:NO];
}
else
{
[self.cpuMaxChoice setOn:NO];
[self.cpuSlider setEnabled:YES];
}
cpu_altscale_factor = [defaults doubleForKey:kApple2AltSpeed];
[self.altSlider setValue:cpu_altscale_factor];
self.altSliderLabel.text = [NSString stringWithFormat:@"%.0f%%", cpu_altscale_factor*100];
if ([defaults boolForKey:kApple2AltSpeedIsMax])
{
cpu_altscale_factor = CPU_SCALE_FASTEST;
[self.altMaxChoice setOn:YES];
[self.altSlider setEnabled:NO];
}
else
{
[self.altMaxChoice setOn:NO];
[self.altSlider setEnabled:YES];
}
NSInteger mode = [defaults integerForKey:kApple2ColorConfig];
if (! ((mode >= COLOR_NONE) && (mode < NUM_COLOROPTS)) )
{
mode = COLOR_NONE;
}
//[self.videoModePicker d:mode];
color_mode = (color_mode_t)mode;
mode = [defaults integerForKey:kApple2JoystickConfig];
if (! ((mode >= JOY_PCJOY) && (mode < NUM_JOYOPTS)) )
{
mode = JOY_PCJOY;
}
joy_mode = (joystick_mode_t)mode;
// [self.joystickChoice selectItemAtIndex:mode];
/*
#ifdef KEYPAD_JOYSTICK
joy_auto_recenter = [defaults integerForKey:kApple2JoystickAutoRecenter];
[self.joystickRecenter setState:joy_auto_recenter ? NSOnState : NSOffState];
joy_step = [defaults integerForKey:kApple2JoystickStep];
if (!joy_step)
{
joy_step = 1;
}
[self.joystickStepLabel setIntegerValue:joy_step];
[self.joystickStepper setIntegerValue:joy_step];
#endif
joy_clip_to_radius = [defaults boolForKey:kApple2JoystickClipToRadius];
[self.joystickClipToRadius setState:joy_clip_to_radius ? NSOnState : NSOffState];
[self _setupJoystickUI];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(drawJoystickCalibration:) name:(NSString *)kDrawTimerNotification object:nil];
*/
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// The number of columns of data
- (int)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
// The number of rows of data
- (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return 2;
//_pickerData.count;
}
// The data to return for the row and component (column) that's being passed in
- (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [self._videoMode objectAtIndex:row];
}
// Catpure the picker view selection
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// This method is triggered whenever the user makes a change to the picker selection.
// The parameter named row and component represents what was selected.
NSLog(@"Selected Row %d", row);
}
- (void)_savePrefs
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:YES forKey:kApple2SavedPrefs];
[defaults setDouble:cpu_scale_factor forKey:kApple2CPUSpeed];
[defaults setDouble:cpu_altscale_factor forKey:kApple2AltSpeed];
// [defaults setBool:([self.cpuMaxChoice state] == NSOnState) forKey:kApple2CPUSpeedIsMax];
// [defaults setBool:([self.altMaxChoice state] == NSOnState) forKey:kApple2AltSpeedIsMax];
[defaults setInteger:color_mode forKey:kApple2ColorConfig];
[defaults setInteger:joy_mode forKey:kApple2JoystickConfig];
// [defaults setInteger:joy_step forKey:kApple2JoystickStep];
// [defaults setBool:joy_auto_recenter forKey:kApple2JoystickAutoRecenter];
[defaults setBool:joy_clip_to_radius forKey:kApple2JoystickClipToRadius];
}
- (IBAction)sliderDidMove:(id)sender
{
UISlider *slider = (UISlider *)sender;
double value = slider.value;
if (slider == self.cpuSlider)
{
cpu_scale_factor = value;
self.cpuSliderLabel.text=[NSString stringWithFormat:@"%.0f%%", value*100];
}
else
{
cpu_altscale_factor = value;
self.altSliderLabel.text=[NSString stringWithFormat:@"%.0f%%", value*100];
}
timing_initialize();
[self _savePrefs];
}
- (IBAction)peggedChoiceChanged:(id)sender
{
UISwitch *maxButton = (UISwitch *)sender;
if (maxButton == self.cpuMaxChoice)
{
[self.cpuSlider setEnabled:([maxButton state] != YES)];
cpu_scale_factor = ([maxButton state] == NO) ? CPU_SCALE_FASTEST : self.cpuSlider.value;
}
else
{
[self.altSlider setEnabled:([maxButton state] != YES)];
cpu_altscale_factor = ([maxButton state] == YES) ? CPU_SCALE_FASTEST : self.altSlider.value;
}
timing_initialize();
[self _savePrefs];
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (void)dealloc {
/* [_videoModePicker release];
[_cpuSlider release];
[_altSlider release];
[_cpuSliderLabel release];
[_altSlider release];
[_cpuMaxChoice release];
[_altMaxChoice release];
*/
[super dealloc];
}
-(IBAction)goodbye:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
cpu_resume();
}
- (IBAction)unwindToMainViewController:(UIStoryboardSegue*)sender
{
}
@end

View File

@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */

View File

@ -0,0 +1,17 @@
//
// AppDelegate.h
// Apple2etvOS
//
// Created by Jerome Vernet on 01/01/2016.
// Copyright © 2016 deadc0de.org. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

View File

@ -0,0 +1,45 @@
//
// AppDelegate.m
// Apple2etvOS
//
// Created by Jerome Vernet on 01/01/2016.
// Copyright © 2016 deadc0de.org. All rights reserved.
//
#import "AppDelegate.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "tv",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,17 @@
{
"layers" : [
{
"filename" : "Front.imagestacklayer"
},
{
"filename" : "Middle.imagestacklayer"
},
{
"filename" : "Back.imagestacklayer"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "tv",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "tv",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "tv",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,17 @@
{
"layers" : [
{
"filename" : "Front.imagestacklayer"
},
{
"filename" : "Middle.imagestacklayer"
},
{
"filename" : "Back.imagestacklayer"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "tv",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "tv",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Some files were not shown because too many files have changed in this diff Show More