mirror of
https://github.com/mauiaaron/apple2.git
synced 2026-01-23 06:16:08 +00:00
Compare commits
38 Commits
android-1.
...
android-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20278ca91e | ||
|
|
b996083a42 | ||
|
|
3e777477e2 | ||
|
|
4d9eda4862 | ||
|
|
4deedb2215 | ||
|
|
bf3ef3ae18 | ||
|
|
9fd288c0b9 | ||
|
|
abe1346051 | ||
|
|
145b6a6cef | ||
|
|
22b1bc9ad8 | ||
|
|
2f7f7bd359 | ||
|
|
7dd0f0b3cf | ||
|
|
3ff877d80c | ||
|
|
13de08f8cb | ||
|
|
1d248c5e22 | ||
|
|
e5e2f98835 | ||
|
|
1e573c34ad | ||
|
|
e165da72fc | ||
|
|
1c50d12963 | ||
|
|
d69b416c58 | ||
|
|
a1fbc63f98 | ||
|
|
c7c209907b | ||
|
|
5bd7ff2fe1 | ||
|
|
72fb577166 | ||
|
|
69b096ec14 | ||
|
|
f872e0c05c | ||
|
|
5211722d63 | ||
|
|
785577e252 | ||
|
|
3a20c96296 | ||
|
|
2c8284d41f | ||
|
|
9e5274ee18 | ||
|
|
26e452c3a3 | ||
|
|
870a24ced6 | ||
|
|
2dbd77e344 | ||
|
|
699746a743 | ||
|
|
74e97ccc97 | ||
|
|
1f0021667b | ||
|
|
836044c80b |
1
Android/.idea/compiler.xml
generated
1
Android/.idea/compiler.xml
generated
@@ -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">
|
||||
|
||||
49
Android/.idea/misc.xml
generated
49
Android/.idea/misc.xml
generated
@@ -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>
|
||||
@@ -27,8 +27,8 @@ android {
|
||||
applicationId "org.deadc0de.apple2ix.basic"
|
||||
minSdkVersion 10
|
||||
targetSdkVersion 23
|
||||
versionCode 12
|
||||
versionName "1.1.2"
|
||||
versionCode 13
|
||||
versionName "1.1.3"
|
||||
ndk {
|
||||
moduleName "apple2ix"
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,17 +14,14 @@ 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.content.pm.PackageManager;
|
||||
import android.media.AudioManager;
|
||||
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;
|
||||
@@ -38,14 +35,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.deadc0de.apple2ix.basic.BuildConfig;
|
||||
import org.deadc0de.apple2ix.basic.R;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class Apple2Activity extends Activity {
|
||||
|
||||
private final static String TAG = "Apple2Activity";
|
||||
private final static int MAX_FINGERS = 32;// HACK ...
|
||||
private final static String SAVE_FILE = "emulator.state";
|
||||
private static volatile boolean DEBUG_STRICT = false;
|
||||
|
||||
private Apple2View mView = null;
|
||||
@@ -60,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;
|
||||
@@ -76,50 +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 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;
|
||||
|
||||
public final static int REQUEST_PERMISSION_RWSTORE = 42;
|
||||
|
||||
private native void nativeOnCreate(String dataDir, int sampleRate, int monoBufferSize, int stereoBufferSize);
|
||||
private static native void nativeOnCreate(String dataDir, int sampleRate, int monoBufferSize, int stereoBufferSize);
|
||||
|
||||
private native void nativeOnKeyDown(int keyCode, int metaState);
|
||||
private static native void nativeOnKeyDown(int keyCode, int metaState);
|
||||
|
||||
private native void nativeOnKeyUp(int keyCode, int metaState);
|
||||
private static native void nativeOnKeyUp(int keyCode, int metaState);
|
||||
|
||||
private native void nativeSaveState(String path);
|
||||
private static native void nativeSaveState(String path);
|
||||
|
||||
private native String nativeLoadState(String path);
|
||||
private static native String nativeLoadState(String path);
|
||||
|
||||
public native void nativeEmulationResume();
|
||||
private static native void nativeEmulationResume();
|
||||
|
||||
public native void nativeEmulationPause();
|
||||
private static native void nativeEmulationPause();
|
||||
|
||||
public native void nativeOnQuit();
|
||||
private static native void nativeOnQuit();
|
||||
|
||||
public native long nativeOnTouch(int action, int pointerCount, int pointerIndex, float[] xCoords, float[] yCoords);
|
||||
private static native void nativeReboot();
|
||||
|
||||
public native void nativeReboot();
|
||||
private static native void nativeChooseDisk(String path, boolean driveA, boolean readOnly);
|
||||
|
||||
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) {
|
||||
@@ -164,7 +137,7 @@ public class Apple2Activity extends Activity {
|
||||
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);
|
||||
Log.v(TAG, "Triggering migration to Apple2ix version : " + BuildConfig.VERSION_NAME);
|
||||
}
|
||||
|
||||
showSplashScreen(!firstTime);
|
||||
@@ -295,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) {
|
||||
@@ -322,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() {
|
||||
@@ -533,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) {
|
||||
@@ -626,29 +496,40 @@ 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 maybeRebootQuit() {
|
||||
public void pauseEmulation() {
|
||||
nativeEmulationPause();
|
||||
}
|
||||
|
||||
AlertDialog rebootQuitDialog = new AlertDialog.Builder(this).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) {
|
||||
nativeReboot();
|
||||
Apple2Activity.this.mMainMenu.dismiss();
|
||||
}
|
||||
}).setNeutralButton(R.string.quit, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
quitEmulator();
|
||||
}
|
||||
}).setNegativeButton(R.string.cancel, null).create();
|
||||
public void rebootEmulation() {
|
||||
nativeReboot();
|
||||
}
|
||||
|
||||
registerAndShowDialog(rebootQuitDialog);
|
||||
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() {
|
||||
@@ -666,41 +547,4 @@ public class Apple2Activity extends Activity {
|
||||
}
|
||||
}.run();
|
||||
}
|
||||
|
||||
public void maybeSaveRestore() {
|
||||
nativeEmulationPause();
|
||||
|
||||
final String quickSavePath = Apple2DisksMenu.getDataDir(this) + File.separator + SAVE_FILE;
|
||||
|
||||
AlertDialog saveRestoreDialog = new AlertDialog.Builder(this).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) {
|
||||
Apple2Activity.this.nativeSaveState(quickSavePath);
|
||||
Apple2Activity.this.mMainMenu.dismiss();
|
||||
}
|
||||
}).setNeutralButton(R.string.restore, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
// loading state can change the disk inserted ... reflect that in
|
||||
String jsonData = Apple2Activity.this.nativeLoadState(quickSavePath);
|
||||
try {
|
||||
JSONObject map = new JSONObject(jsonData);
|
||||
String diskPath1 = map.getString("disk1");
|
||||
boolean readOnly1 = map.getBoolean("readOnly1");
|
||||
Apple2Preferences.CURRENT_DISK_A.setPath(Apple2Activity.this, diskPath1);
|
||||
Apple2Preferences.CURRENT_DISK_A_RO.saveBoolean(Apple2Activity.this, readOnly1);
|
||||
|
||||
String diskPath2 = map.getString("disk2");
|
||||
boolean readOnly2 = map.getBoolean("readOnly2");
|
||||
Apple2Preferences.CURRENT_DISK_B.setPath(Apple2Activity.this, diskPath2);
|
||||
Apple2Preferences.CURRENT_DISK_B_RO.saveBoolean(Apple2Activity.this, readOnly2);
|
||||
} catch (JSONException je) {
|
||||
Log.v(TAG, "OOPS : "+je);
|
||||
}
|
||||
Apple2Activity.this.mMainMenu.dismiss();
|
||||
}
|
||||
}).setNegativeButton(R.string.cancel, null).create();
|
||||
|
||||
registerAndShowDialog(saveRestoreDialog);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -140,7 +142,7 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
||||
if (sExternalFilesDir == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final ProgressBar bar = (ProgressBar) activity.findViewById(R.id.crash_progressBar);
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
@@ -155,7 +157,7 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
||||
});
|
||||
|
||||
Log.v(TAG, "Overwriting system files in /sdcard/apple2ix/ (external storage) ...");
|
||||
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"keyboards", /*to location:*/sExternalFilesDir.getAbsolutePath());
|
||||
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"keyboards", /*to location:*/sExternalFilesDir.getAbsolutePath(), false);
|
||||
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
@@ -186,12 +188,19 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
||||
|
||||
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());
|
||||
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());
|
||||
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
|
||||
@@ -207,7 +216,7 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -351,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()) {
|
||||
@@ -362,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;
|
||||
@@ -402,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) {
|
||||
@@ -446,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) {
|
||||
@@ -562,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();
|
||||
}
|
||||
@@ -574,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();
|
||||
}
|
||||
@@ -616,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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
},
|
||||
SAVE_RESTORE {
|
||||
@Override public String getTitle(Context ctx) {
|
||||
@Override
|
||||
public String getTitle(Context ctx) {
|
||||
return ctx.getResources().getString(R.string.saverestore);
|
||||
}
|
||||
@Override public String getSummary(Context ctx) {
|
||||
|
||||
@Override
|
||||
public String getSummary(Context ctx) {
|
||||
return ctx.getResources().getString(R.string.saverestore_summary);
|
||||
}
|
||||
@Override public void handleSelection(Apple2MainMenu mainMenu) {
|
||||
mainMenu.mActivity.maybeSaveRestore();
|
||||
|
||||
@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();
|
||||
}
|
||||
},
|
||||
REBOOT_QUIT_EMULATOR {
|
||||
@Override public String getTitle(Context ctx) {
|
||||
@Override
|
||||
public String getTitle(Context ctx) {
|
||||
return ctx.getResources().getString(R.string.quit_reboot);
|
||||
}
|
||||
@Override public String getSummary(Context ctx) {
|
||||
|
||||
@Override
|
||||
public String getSummary(Context ctx) {
|
||||
return "";
|
||||
}
|
||||
@Override public void handleSelection(Apple2MainMenu mainMenu) {
|
||||
mainMenu.mActivity.maybeRebootQuit();
|
||||
|
||||
@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,8 +203,8 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1034,7 +1034,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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
162
Android/app/src/main/res/values-es/strings.xml
Normal file
162
Android/app/src/main/res/values-es/strings.xml
Normal 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">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">↓</string>
|
||||
<string name="key_esc">[ESC]</string>
|
||||
<string name="key_left">←</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">→</string>
|
||||
<string name="key_space">[Espaciadora]</string>
|
||||
<string name="key_up">↑</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 cuando está activo</string>
|
||||
<string name="keyboard_visibility_inactive">Visibilidad cuando está inactivo</string>
|
||||
<string name="keyboard_visibility_inactive_summary">Visibilidad del teclado 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">↑,←,→,↓, pulse espaciadora</string>
|
||||
<string name="keypad_preset_az_left_right_space">A,Z,←,→, pulse espaciadora</string>
|
||||
<string name="keypad_preset_ijkm_space">I,J,K,M, pulse espaciadora</string>
|
||||
<string name="keypad_preset_left_right_space">←,→, 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">Sí</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→</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="touch_menu_visibility">Visibilidad del menú</string>
|
||||
<string name="touch_menu_visibility_summary">Visibilidad del menú cuando está inactivo</string>
|
||||
<string name="video_configure">Configurar el video…</string>
|
||||
<string name="video_configure_summary">Ajustes de color</string>
|
||||
|
||||
</resources>
|
||||
@@ -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", "", "", "", ""],
|
||||
[ "", "", "", "", "", "", "", "", "", ""]
|
||||
]
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
"_SP" : "b1"
|
||||
},
|
||||
|
||||
[ "reserved for future use" ],
|
||||
[ "reserved for future use" ],
|
||||
[ "", "", "", "", "", "", "", "", "", "" ],
|
||||
[ "_AA", "", "", "", "", "", "", "", "", "" ],
|
||||
[ "", "", "", "", "", "", "", "", "", "" ],
|
||||
[ "", "", "", "", "", "", "", "", "", "" ],
|
||||
[ "", "", "", "", "", "", "", "", "", "" ],
|
||||
[ "Q", "", "", "", "", "", "", "", "A", "" ],
|
||||
[ "", "", "", "", "", "", "", "_LT", "", "_RT" ],
|
||||
[ "_SP", "", "", "", "", "", "", "", "Z", "" ]
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
"_SP" : "b1"
|
||||
},
|
||||
|
||||
["reserved for future use"],
|
||||
["reserved for future use"],
|
||||
["_AA", "", "", "", "", "", "", "", "", "D"],
|
||||
[ "Q", "", "", "", "", "", "", "", "", "" ],
|
||||
[ "", "", "", "", "", "", "", "", "", "V"],
|
||||
[ "_AA", "", "", "", "", "", "", "", "", "D"],
|
||||
[ "_ESC", "", "", "", "", "", "", "", "", "G"],
|
||||
[ "Y", "", "", "", "", "", "", "", "", "" ],
|
||||
[ "N", "", "", "", "", "", "", "I", "O", "P"],
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
"_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", "J", "E", "_SP", "", "_DN", ""]
|
||||
]
|
||||
|
||||
0
Android/assets/symbols/x86/.blank
Normal file
0
Android/assets/symbols/x86/.blank
Normal 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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
@@ -142,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...
|
||||
@@ -170,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
|
||||
@@ -187,26 +186,31 @@ 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;
|
||||
}
|
||||
@@ -257,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
|
||||
@@ -277,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");
|
||||
@@ -316,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;
|
||||
@@ -341,15 +349,15 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeChooseDisk(JNIEnv *env, job
|
||||
(*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, jobject obj, jstring jPath) {
|
||||
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 CPU thread is running");
|
||||
assert(cpu_isPaused() && "considered dangerous to save state when CPU thread is running");
|
||||
|
||||
LOG(": (%s)", path);
|
||||
if (!emulator_saveState(path)) {
|
||||
@@ -359,10 +367,10 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeSaveState(JNIEnv *env, jobj
|
||||
(*env)->ReleaseStringUTFChars(env, jPath, path);
|
||||
}
|
||||
|
||||
jstring Java_org_deadc0de_apple2ix_Apple2Activity_nativeLoadState(JNIEnv *env, jobject obj, jstring jPath) {
|
||||
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 CPU thread is running");
|
||||
assert(cpu_isPaused() && "considered dangerous to save state when CPU thread is running");
|
||||
|
||||
LOG(": (%s)", path);
|
||||
if (!emulator_loadState(path)) {
|
||||
|
||||
@@ -18,6 +18,7 @@ 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
|
||||
|
||||
@@ -18,6 +18,7 @@ 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
|
||||
|
||||
@@ -18,6 +18,7 @@ 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
|
||||
|
||||
@@ -18,6 +18,7 @@ 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
|
||||
|
||||
@@ -127,26 +127,6 @@ void gldriver_joystick_reset(void) {
|
||||
#pragma mark NSObject(DDHidJoystickDelegate)
|
||||
|
||||
#define DDHID_JOYSTICK_NORMALIZER ((float)JOY_RANGE/(DDHID_JOYSTICK_VALUE_MAX*2))
|
||||
#define QUARTER_JOY (HALF_JOY_RANGE>>1)
|
||||
|
||||
static inline void clampBeyondRadius(void) {
|
||||
CGFloat half_x = joy_x - HALF_JOY_RANGE;
|
||||
CGFloat half_y = joy_y - HALF_JOY_RANGE;
|
||||
CGFloat r = sqrtf(half_x*half_x + half_y*half_y);
|
||||
bool shouldClip = (r > HALF_JOY_RANGE);
|
||||
if (joy_clip_to_radius && shouldClip) {
|
||||
if (joy_x < HALF_JOY_RANGE) {
|
||||
joy_x = (joy_x < QUARTER_JOY) ? 0.f : joy_x;
|
||||
} else {
|
||||
joy_x = (joy_x < HALF_JOY_RANGE+QUARTER_JOY) ? joy_x : JOY_RANGE-1;
|
||||
}
|
||||
if (joy_y < HALF_JOY_RANGE) {
|
||||
joy_y = (joy_y < QUARTER_JOY) ? 0.f : joy_y;
|
||||
} else {
|
||||
joy_y = (joy_y < HALF_JOY_RANGE+QUARTER_JOY) ? joy_y : JOY_RANGE-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)ddhidJoystick:(DDHidJoystick *)joystick stick:(unsigned int)stick xChanged:(int)value
|
||||
{
|
||||
@@ -156,12 +136,8 @@ static inline void clampBeyondRadius(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
joy_x = (uint16_t)((value+DDHID_JOYSTICK_VALUE_MAX) * DDHID_JOYSTICK_NORMALIZER);
|
||||
if (joy_x > 0xFF) {
|
||||
joy_x = 0xFF;
|
||||
}
|
||||
|
||||
clampBeyondRadius();
|
||||
uint8_t x = (uint8_t)((value+DDHID_JOYSTICK_VALUE_MAX) * DDHID_JOYSTICK_NORMALIZER);
|
||||
joydriver_setAxisValue(x, joydriver_getAxisY());
|
||||
}
|
||||
|
||||
- (void)ddhidJoystick:(DDHidJoystick *)joystick stick:(unsigned int)stick yChanged:(int)value
|
||||
@@ -172,12 +148,8 @@ static inline void clampBeyondRadius(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
joy_y = (uint16_t)((value+DDHID_JOYSTICK_VALUE_MAX) * DDHID_JOYSTICK_NORMALIZER);
|
||||
if (joy_y > 0xFF) {
|
||||
joy_y = 0xFF;
|
||||
}
|
||||
|
||||
clampBeyondRadius();
|
||||
uint8_t y = (uint8_t)((value+DDHID_JOYSTICK_VALUE_MAX) * DDHID_JOYSTICK_NORMALIZER);
|
||||
joydriver_setAxisValue(joydriver_getAxisX(), y);
|
||||
}
|
||||
|
||||
- (void)ddhidJoystick:(DDHidJoystick *)joystick stick:(unsigned int)stick otherAxis:(unsigned)otherAxis valueChanged:(int)value
|
||||
|
||||
@@ -741,20 +741,17 @@ static long opensles_systemResume(AudioContext_s *audio_context) {
|
||||
break;
|
||||
}
|
||||
|
||||
#if !TESTING
|
||||
assert(state != SL_PLAYSTATE_PLAYING && "mismatch between systemPause/systemResume");
|
||||
#endif
|
||||
if (state != SL_PLAYSTATE_PLAYING) {
|
||||
ERRLOG("WARNING: possible audio lifecycle mismatch ... continuing anyway");
|
||||
}
|
||||
|
||||
if (state == SL_PLAYSTATE_PAUSED) {
|
||||
// Balanced resume OK here
|
||||
SLresult result = (*(ctx->bqPlayerPlay))->SetPlayState(ctx->bqPlayerPlay, SL_PLAYSTATE_PLAYING);
|
||||
#if !TESTING
|
||||
} else {
|
||||
} else if (state == SL_PLAYSTATE_STOPPED) {
|
||||
// Do not resume for stopped state, let this get forced from CPU/speaker thread otherwise we starve. (The
|
||||
// stopped state happens if user dynamically changed buffer parameters in menu settings which triggered an
|
||||
// OpenSLES destroy/re-initialization ... e.g. audio_setLatency() was invoked)
|
||||
assert(state == SL_PLAYSTATE_STOPPED);
|
||||
#endif
|
||||
}
|
||||
} while (0);
|
||||
|
||||
|
||||
@@ -253,6 +253,55 @@ void c_joystick_reset(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
// clamps modern gamepad controller axis values to the "corners" of a traditional joystick as used on the Apple //e
|
||||
static inline void clampBeyondRadius(uint8_t *x, uint8_t *y) {
|
||||
float half_x = (*x) - HALF_JOY_RANGE;
|
||||
float half_y = (*y) - HALF_JOY_RANGE;
|
||||
float r = sqrtf(half_x*half_x + half_y*half_y);
|
||||
bool shouldClip = (r > HALF_JOY_RANGE);
|
||||
if (joy_clip_to_radius && shouldClip) {
|
||||
if ((*x) < HALF_JOY_RANGE) {
|
||||
(*x) = ((*x) < QUARTER_JOY_RANGE) ? 0.f : (*x);
|
||||
} else {
|
||||
(*x) = ((*x) < HALF_JOY_RANGE+QUARTER_JOY_RANGE) ? (*x) : 0xFF;
|
||||
}
|
||||
if ((*y) < HALF_JOY_RANGE) {
|
||||
(*y) = ((*y) < QUARTER_JOY_RANGE) ? 0.f : (*y);
|
||||
} else {
|
||||
(*y) = ((*y) < HALF_JOY_RANGE+QUARTER_JOY_RANGE) ? (*y) : JOY_RANGE-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void joydriver_setClampBeyondRadius(bool clamp) {
|
||||
joy_clip_to_radius = clamp;
|
||||
}
|
||||
|
||||
void joydriver_setAxisValue(uint8_t x, uint8_t y) {
|
||||
clampBeyondRadius(&x, &y);
|
||||
joy_x = x;
|
||||
joy_y = y;
|
||||
}
|
||||
|
||||
uint8_t joydriver_getAxisX(void) {
|
||||
return joy_x;
|
||||
}
|
||||
|
||||
// return Y axis value
|
||||
uint8_t joydriver_getAxisY(void) {
|
||||
return joy_y;
|
||||
}
|
||||
|
||||
// set button 0 pressed
|
||||
void joydriver_setButton0Pressed(bool pressed) {
|
||||
joy_button0 = (pressed) ? 0x80 : 0x0;
|
||||
}
|
||||
|
||||
// set button 1 pressed
|
||||
void joydriver_setButton1Pressed(bool pressed) {
|
||||
joy_button1 = (pressed) ? 0x80 : 0x0;
|
||||
}
|
||||
|
||||
#if INTERFACE_TOUCH
|
||||
bool (*joydriver_isTouchJoystickAvailable)(void) = NULL;
|
||||
void (*joydriver_setTouchJoystickEnabled)(bool enabled) = NULL;
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
#define _JOYSTICK_H_
|
||||
|
||||
#define JOY_RANGE 0x100
|
||||
#define HALF_JOY_RANGE 0x80
|
||||
#define HALF_JOY_RANGE (JOY_RANGE>>1)
|
||||
#define QUARTER_JOY_RANGE (HALF_JOY_RANGE>>1)
|
||||
|
||||
extern uint16_t joy_x;
|
||||
extern uint16_t joy_y;
|
||||
@@ -32,6 +33,24 @@ void c_joystick_reset(void);
|
||||
void c_calibrate_joystick(void);
|
||||
#endif
|
||||
|
||||
// enable/disable gamepad clamping to joystick corners
|
||||
void joydriver_setClampBeyondRadius(bool clamp);
|
||||
|
||||
// set joystick axis values
|
||||
void joydriver_setAxisValue(uint8_t x, uint8_t y);
|
||||
|
||||
// return X axis value
|
||||
uint8_t joydriver_getAxisX(void);
|
||||
|
||||
// return Y axis value
|
||||
uint8_t joydriver_getAxisY(void);
|
||||
|
||||
// set button 0 pressed
|
||||
void joydriver_setButton0Pressed(bool pressed);
|
||||
|
||||
// set button 1 pressed
|
||||
void joydriver_setButton1Pressed(bool pressed);
|
||||
|
||||
#if INTERFACE_TOUCH
|
||||
|
||||
typedef enum touchjoy_variant_t {
|
||||
|
||||
@@ -128,9 +128,10 @@ void test_common_init() {
|
||||
}
|
||||
|
||||
int test_setup_boot_disk(const char *fileName, int readonly) {
|
||||
char *disk = NULL;
|
||||
int err = 0;
|
||||
#ifdef __APPLE__
|
||||
char **path = NULL;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
CFBundleRef mainBundle = CFBundleGetMainBundle();
|
||||
CFStringRef fileString = CFStringCreateWithCString(/*allocator*/NULL, fileName, CFStringGetSystemEncoding());
|
||||
CFURLRef fileURL = CFBundleCopyResourceURL(mainBundle, fileString, NULL, NULL);
|
||||
@@ -144,15 +145,48 @@ int test_setup_boot_disk(const char *fileName, int readonly) {
|
||||
FREE(disk);
|
||||
}
|
||||
CFRELEASE(filePath);
|
||||
|
||||
char *paths[] = {
|
||||
disk,
|
||||
NULL,
|
||||
};
|
||||
#else
|
||||
asprintf(&disk, "%s/disks/%s", data_dir, fileName);
|
||||
char *paths[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
asprintf(&paths[0], "%s/disks/%s", data_dir, fileName);
|
||||
asprintf(&paths[1], "%s/disks/demo/%s", data_dir, fileName);
|
||||
asprintf(&paths[2], "%s/disks/blanks/%s", data_dir, fileName);
|
||||
#endif
|
||||
if (disk6_insert(0, disk, readonly)) {
|
||||
|
||||
path = &paths[0];
|
||||
while (*path) {
|
||||
char *disk = *path;
|
||||
++path;
|
||||
|
||||
err = disk6_insert(0, disk, readonly) != NULL;
|
||||
if (!err) {
|
||||
break;
|
||||
}
|
||||
|
||||
int len = strlen(disk);
|
||||
disk[len-3] = '\0'; // try again without '.gz' extension
|
||||
err = (disk6_insert(0, disk, readonly) != NULL);
|
||||
err = disk6_insert(0, disk, readonly) != NULL;
|
||||
if (!err) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
FREE(disk);
|
||||
|
||||
path = &paths[0];
|
||||
while (*path) {
|
||||
char *disk = *path;
|
||||
++path;
|
||||
FREE(disk);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -161,6 +195,5 @@ void sha1_to_str(const uint8_t * const md, char *buf) {
|
||||
for (int j=0; j<SHA_DIGEST_LENGTH; j++, i+=2) {
|
||||
sprintf(buf+i, "%02X", md[j]);
|
||||
}
|
||||
sprintf(buf+i, "%c", '\0');
|
||||
}
|
||||
|
||||
|
||||
1760
src/test/testcpu.c
1760
src/test/testcpu.c
File diff suppressed because it is too large
Load Diff
@@ -237,7 +237,7 @@ TEST test_read_null_bytes() {
|
||||
c_debugger_go();
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
ASSERT(apple_ii_64k[0][TESTOUT_ADDR] == 0x00);
|
||||
ASSERT(apple_ii_64k[0][TESTOUT_ADDR] == 0xFF);
|
||||
|
||||
PASS();
|
||||
}
|
||||
@@ -1436,12 +1436,16 @@ GREATEST_MAIN_DEFS();
|
||||
static char **test_argv = NULL;
|
||||
static int test_argc = 0;
|
||||
|
||||
static void *test_thread(void *dummyptr) {
|
||||
static int _test_thread(void) {
|
||||
int argc = test_argc;
|
||||
char **argv = test_argv;
|
||||
GREATEST_MAIN_BEGIN();
|
||||
RUN_SUITE(test_suite_disk);
|
||||
GREATEST_MAIN_END();
|
||||
}
|
||||
|
||||
static void *test_thread(void *dummyptr) {
|
||||
_test_thread();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ static void testdisplay_teardown(void *arg) {
|
||||
// Various Display Tests ...
|
||||
|
||||
TEST test_boot_disk() {
|
||||
test_setup_boot_disk("testdisplay1.nib.gz", 1);
|
||||
test_setup_boot_disk("testdisplay1.dsk.gz", 1);
|
||||
|
||||
BOOT_TO_DOS();
|
||||
|
||||
@@ -306,13 +306,13 @@ TEST test_80col_hires() {
|
||||
c_debugger_go();
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
ASSERT_SHA("10F63A7B11EBF5019AE6D1F64AA7BACEA903426D");
|
||||
ASSERT_SHA("126363F103F3A24BB2EB2AEC5B4972F46F7CA24B");
|
||||
|
||||
apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00;
|
||||
c_debugger_go();
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
ASSERT_SHA("CC81BD3FE7055126D3FA13231CBD86E7C49590AA");
|
||||
ASSERT_SHA("91F63831B6D1145446F0DBACE8EBD284B5690D81");
|
||||
|
||||
PASS();
|
||||
}
|
||||
@@ -443,12 +443,16 @@ GREATEST_MAIN_DEFS();
|
||||
static char **test_argv = NULL;
|
||||
static int test_argc = 0;
|
||||
|
||||
static void *test_thread(void *dummyptr) {
|
||||
static int _test_thread(void) {
|
||||
int argc = test_argc;
|
||||
char **argv = test_argv;
|
||||
GREATEST_MAIN_BEGIN();
|
||||
RUN_SUITE(test_suite_display);
|
||||
GREATEST_MAIN_END();
|
||||
}
|
||||
|
||||
static void *test_thread(void *dummyptr) {
|
||||
_test_thread();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ static void testvm_teardown(void *arg) {
|
||||
// VM TESTS ...
|
||||
|
||||
TEST test_boot_disk() {
|
||||
test_setup_boot_disk("testvm1.nib.gz", 1);
|
||||
test_setup_boot_disk("testvm1.dsk.gz", 1);
|
||||
|
||||
BOOT_TO_DOS();
|
||||
|
||||
@@ -1071,8 +1071,6 @@ TEST test_HIRES_off(bool flag_ramrd, bool flag_ramwrt) {
|
||||
uint32_t switch_save = softswitches;
|
||||
uint8_t *save_base_textrd = base_textrd;
|
||||
uint8_t *save_base_textwrt = base_textwrt;
|
||||
uint8_t *save_base_hgrrd = base_hgrrd;
|
||||
uint8_t *save_base_hgrwrt = base_hgrwrt;
|
||||
int save_current_page = video__current_page;
|
||||
|
||||
apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00;
|
||||
@@ -1288,8 +1286,6 @@ TEST test_lc_c082() {
|
||||
uint8_t *save_base_textwrt = base_textwrt;
|
||||
uint8_t *save_base_hgrrd = base_hgrrd;
|
||||
uint8_t *save_base_hgrwrt = base_hgrwrt;
|
||||
uint8_t *save_base_d000_wrt = base_d000_wrt;
|
||||
uint8_t *save_base_e000_wrt = base_e000_wrt;
|
||||
int save_current_page = video__current_page;
|
||||
|
||||
ASM_INIT();
|
||||
@@ -1541,8 +1537,6 @@ TEST test_lc_c08a() {
|
||||
uint8_t *save_base_textwrt = base_textwrt;
|
||||
uint8_t *save_base_hgrrd = base_hgrrd;
|
||||
uint8_t *save_base_hgrwrt = base_hgrwrt;
|
||||
uint8_t *save_base_d000_wrt = base_d000_wrt;
|
||||
uint8_t *save_base_e000_wrt = base_e000_wrt;
|
||||
int save_current_page = video__current_page;
|
||||
|
||||
ASM_INIT();
|
||||
@@ -1755,11 +1749,8 @@ TEST test_80store_on(bool flag_hires, bool flag_page2) {
|
||||
ASSERT(flag_page2 ? (softswitches & SS_PAGE2) : !(softswitches & SS_PAGE2) );
|
||||
|
||||
uint32_t switch_save = softswitches;
|
||||
uint8_t *save_base_textrd = base_textrd;
|
||||
uint8_t *save_base_textwrt = base_textwrt;
|
||||
uint8_t *save_base_hgrrd = base_hgrrd;
|
||||
uint8_t *save_base_hgrwrt = base_hgrwrt;
|
||||
int save_current_page = video__current_page;
|
||||
|
||||
apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00;
|
||||
c_debugger_go();
|
||||
@@ -1856,11 +1847,6 @@ TEST test_80store_off(bool flag_ramrd, bool flag_ramwrt, bool flag_page2) {
|
||||
ASSERT(flag_page2 ? (softswitches & SS_PAGE2) : !(softswitches & SS_PAGE2) );
|
||||
|
||||
uint32_t switch_save = softswitches;
|
||||
uint8_t *save_base_textrd = base_textrd;
|
||||
uint8_t *save_base_textwrt = base_textwrt;
|
||||
uint8_t *save_base_hgrrd = base_hgrrd;
|
||||
uint8_t *save_base_hgrwrt = base_hgrwrt;
|
||||
int save_current_page = video__current_page;
|
||||
|
||||
apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00;
|
||||
apple_ii_64k[1][WATCHPOINT_ADDR] = 0x00;
|
||||
@@ -1984,7 +1970,6 @@ TEST test_ramrd_main(bool flag_80store, bool flag_hires) {
|
||||
ASSERT(flag_hires ? (softswitches & SS_HIRES) : !(softswitches & SS_HIRES) );
|
||||
|
||||
uint32_t switch_save = softswitches;
|
||||
uint8_t *save_base_ramrd = base_ramrd;
|
||||
uint8_t *save_base_ramwrt = base_ramwrt;
|
||||
uint8_t *save_base_textrd = base_textrd;
|
||||
uint8_t *save_base_textwrt = base_textwrt;
|
||||
@@ -2066,7 +2051,6 @@ TEST test_ramrd_aux(bool flag_80store, bool flag_hires) {
|
||||
ASSERT(flag_hires ? (softswitches & SS_HIRES) : !(softswitches & SS_HIRES) );
|
||||
|
||||
uint32_t switch_save = softswitches;
|
||||
uint8_t *save_base_ramrd = base_ramrd;
|
||||
uint8_t *save_base_ramwrt = base_ramwrt;
|
||||
uint8_t *save_base_textrd = base_textrd;
|
||||
uint8_t *save_base_textwrt = base_textwrt;
|
||||
@@ -2184,7 +2168,6 @@ TEST test_ramwrt_main(bool flag_80store, bool flag_hires) {
|
||||
|
||||
uint32_t switch_save = softswitches;
|
||||
uint8_t *save_base_ramrd = base_ramrd;
|
||||
uint8_t *save_base_ramwrt = base_ramwrt;
|
||||
uint8_t *save_base_textrd = base_textrd;
|
||||
uint8_t *save_base_textwrt = base_textwrt;
|
||||
uint8_t *save_base_hgrrd = base_hgrrd;
|
||||
@@ -2265,7 +2248,6 @@ TEST test_ramwrt_aux(bool flag_80store, bool flag_hires) {
|
||||
|
||||
uint32_t switch_save = softswitches;
|
||||
uint8_t *save_base_ramrd = base_ramrd;
|
||||
uint8_t *save_base_ramwrt = base_ramwrt;
|
||||
uint8_t *save_base_textrd = base_textrd;
|
||||
uint8_t *save_base_textwrt = base_textwrt;
|
||||
uint8_t *save_base_hgrrd = base_hgrrd;
|
||||
@@ -2602,10 +2584,6 @@ TEST test_80col_off() {
|
||||
ASSERT((softswitches & SS_80COL));
|
||||
|
||||
uint32_t switch_save = softswitches;
|
||||
uint8_t *save_base_d000_rd = base_d000_rd;
|
||||
uint8_t *save_base_d000_wrt = base_d000_wrt;
|
||||
uint8_t *save_base_e000_rd = base_e000_rd;
|
||||
uint8_t *save_base_e000_wrt = base_e000_wrt;
|
||||
int save_current_page = video__current_page;
|
||||
|
||||
apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00;
|
||||
@@ -2713,10 +2691,6 @@ TEST test_altchar_off() {
|
||||
ASSERT((softswitches & SS_ALTCHAR));
|
||||
|
||||
uint32_t switch_save = softswitches;
|
||||
uint8_t *save_base_d000_rd = base_d000_rd;
|
||||
uint8_t *save_base_d000_wrt = base_d000_wrt;
|
||||
uint8_t *save_base_e000_rd = base_e000_rd;
|
||||
uint8_t *save_base_e000_wrt = base_e000_wrt;
|
||||
int save_current_page = video__current_page;
|
||||
|
||||
apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00;
|
||||
@@ -2824,10 +2798,6 @@ TEST test_ioudis_off() {
|
||||
ASSERT((softswitches & SS_IOUDIS));
|
||||
|
||||
uint32_t switch_save = softswitches;
|
||||
uint8_t *save_base_d000_rd = base_d000_rd;
|
||||
uint8_t *save_base_d000_wrt = base_d000_wrt;
|
||||
uint8_t *save_base_e000_rd = base_e000_rd;
|
||||
uint8_t *save_base_e000_wrt = base_e000_wrt;
|
||||
int save_current_page = video__current_page;
|
||||
|
||||
apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00;
|
||||
@@ -2943,10 +2913,6 @@ TEST test_dhires_off(bool flag_ioudis/* FIXME TODO : possibly testing a existing
|
||||
ASSERT((softswitches & SS_DHIRES));
|
||||
|
||||
uint32_t switch_save = softswitches;
|
||||
uint8_t *save_base_d000_rd = base_d000_rd;
|
||||
uint8_t *save_base_d000_wrt = base_d000_wrt;
|
||||
uint8_t *save_base_e000_rd = base_e000_rd;
|
||||
uint8_t *save_base_e000_wrt = base_e000_wrt;
|
||||
int save_current_page = video__current_page;
|
||||
|
||||
apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00;
|
||||
@@ -3023,7 +2989,6 @@ TEST test_c3rom_internal() {
|
||||
ASSERT(!(softswitches & SS_C3ROM));
|
||||
|
||||
uint32_t switch_save = softswitches;
|
||||
uint8_t *save_base_c3rom = base_c3rom;
|
||||
|
||||
apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00;
|
||||
c_debugger_go();
|
||||
@@ -3145,10 +3110,6 @@ TEST test_cxrom_internal() {
|
||||
ASSERT(!(softswitches & SS_CXROM));
|
||||
|
||||
uint32_t switch_save = softswitches;
|
||||
uint8_t *save_base_cxrom = base_cxrom;
|
||||
uint8_t *save_base_c3rom = base_c3rom;
|
||||
uint8_t *save_base_c4rom = base_c4rom;
|
||||
uint8_t *save_base_c5rom = base_c5rom;
|
||||
|
||||
apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00;
|
||||
c_debugger_go();
|
||||
@@ -3195,7 +3156,6 @@ TEST test_cxrom_peripheral(bool flag_c3rom) {
|
||||
ASSERT((softswitches & SS_CXROM));
|
||||
|
||||
uint32_t switch_save = softswitches;
|
||||
uint8_t *save_base_cxrom = base_cxrom;
|
||||
uint8_t *save_base_c3rom = base_c3rom;
|
||||
|
||||
apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00;
|
||||
@@ -3462,12 +3422,16 @@ GREATEST_MAIN_DEFS();
|
||||
static char **test_argv = NULL;
|
||||
static int test_argc = 0;
|
||||
|
||||
static void *test_thread(void *dummyptr) {
|
||||
static int _test_thread(void) {
|
||||
int argc = test_argc;
|
||||
char **argv = test_argv;
|
||||
GREATEST_MAIN_BEGIN();
|
||||
RUN_SUITE(test_suite_vm);
|
||||
GREATEST_MAIN_END();
|
||||
}
|
||||
|
||||
static void *test_thread(void *dummyptr) {
|
||||
_test_thread();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -316,12 +316,12 @@ static void _animation_showDiskChosen(int drive) {
|
||||
static void _animation_showTrackSector(int drive, int track, int sect) {
|
||||
|
||||
#define DISK_TRACK_SECTOR_ROWS 3
|
||||
#define DISK_TRACK_SECTOR_COLS 9
|
||||
#define DISK_TRACK_SECTOR_COLS 8
|
||||
|
||||
static char diskTrackSectorTemplate[DISK_TRACK_SECTOR_ROWS][DISK_TRACK_SECTOR_COLS+1] = {
|
||||
" ",
|
||||
"D / TT/SS",
|
||||
" ",
|
||||
" ",
|
||||
"D / TT/S",
|
||||
" ",
|
||||
};
|
||||
char *template = diskTrackSectorTemplate[0];
|
||||
|
||||
@@ -343,7 +343,7 @@ static void _animation_showTrackSector(int drive, int track, int sect) {
|
||||
assert(false && "should not happen");
|
||||
break;
|
||||
}
|
||||
snprintf(&diskTrackSectorTemplate[1][0], DISK_TRACK_SECTOR_COLS+1, "%d %c %02X/%02X", drive+1, c, track, sect);
|
||||
snprintf(&diskTrackSectorTemplate[1][0], DISK_TRACK_SECTOR_COLS+1, "%d %c %02X/%01X", drive+1, c, track, sect);
|
||||
|
||||
_animation_showMessage(template, DISK_TRACK_SECTOR_COLS, DISK_TRACK_SECTOR_ROWS);
|
||||
}
|
||||
|
||||
@@ -29,17 +29,19 @@
|
||||
#define MODEL_DEPTH -1/32.f
|
||||
|
||||
#define KBD_TEMPLATE_COLS 10
|
||||
#define KBD_TEMPLATE_ROWS 6
|
||||
#define KBD_TEMPLATE_ROWS 8
|
||||
|
||||
#define DEFAULT_CTRL_COL 2
|
||||
|
||||
#define _ROWOFF 2 // main keyboard row offset
|
||||
#define CTRLROW 2 // first non-empty default row
|
||||
#define MAINROW 4 // main keyboard row offset
|
||||
#define SWITCHCOL 0
|
||||
|
||||
#define KBD_FB_WIDTH (KBD_TEMPLATE_COLS * FONT80_WIDTH_PIXELS)
|
||||
#define KBD_FB_HEIGHT (KBD_TEMPLATE_ROWS * FONT_HEIGHT_PIXELS)
|
||||
|
||||
#define KBD_OBJ_W 2.0
|
||||
#define KBD_OBJ_H 1.5
|
||||
#define KBD_OBJ_H 2.0
|
||||
|
||||
HUD_CLASS(GLModelHUDKeyboard,
|
||||
// ...
|
||||
@@ -55,6 +57,8 @@ static float minAlpha = 0.f;
|
||||
static float maxAlpha = 1.f;
|
||||
|
||||
static uint8_t kbdTemplateUCase[KBD_TEMPLATE_ROWS][KBD_TEMPLATE_COLS+1] = {
|
||||
" ",
|
||||
" ",
|
||||
"@ @ @ @ @ ",
|
||||
"1234567890",
|
||||
"QWERTYUIOP",
|
||||
@@ -64,6 +68,8 @@ static uint8_t kbdTemplateUCase[KBD_TEMPLATE_ROWS][KBD_TEMPLATE_COLS+1] = {
|
||||
};
|
||||
|
||||
static uint8_t kbdTemplateLCase[KBD_TEMPLATE_ROWS][KBD_TEMPLATE_COLS+1] = {
|
||||
" ",
|
||||
" ",
|
||||
"@ @ @ @ @ ",
|
||||
"1234567890",
|
||||
"qwertyuiop",
|
||||
@@ -73,6 +79,8 @@ static uint8_t kbdTemplateLCase[KBD_TEMPLATE_ROWS][KBD_TEMPLATE_COLS+1] = {
|
||||
};
|
||||
|
||||
static uint8_t kbdTemplateAlt[KBD_TEMPLATE_ROWS][KBD_TEMPLATE_COLS+1] = {
|
||||
" ",
|
||||
" ",
|
||||
"@ @ @ @ @ ",
|
||||
"1234567890",
|
||||
"@#%&*/-+()",
|
||||
@@ -82,6 +90,8 @@ static uint8_t kbdTemplateAlt[KBD_TEMPLATE_ROWS][KBD_TEMPLATE_COLS+1] = {
|
||||
};
|
||||
|
||||
static uint8_t kbdTemplateUserAlt[KBD_TEMPLATE_ROWS][KBD_TEMPLATE_COLS+1] = {
|
||||
" ",
|
||||
" ",
|
||||
"@ @ @ @ @ ",
|
||||
" ",
|
||||
" @ ",
|
||||
@@ -214,16 +224,6 @@ static inline void _switch_keyboard(GLModel *parent, uint8_t *template) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline void _show_useralt_kbd(void) {
|
||||
GLModelHUDKeyboard *hudKeyboard = (GLModelHUDKeyboard *)kbd.model->custom;
|
||||
uint8_t c = hudKeyboard->tpl[_ROWOFF*(KBD_TEMPLATE_COLS+1)];
|
||||
if (c == ICONTEXT_NONACTIONABLE) {
|
||||
_switch_keyboard(kbd.model, kbdTemplateUCase[0]);
|
||||
} else {
|
||||
_switch_keyboard(kbd.model, kbdTemplateUserAlt[0]);
|
||||
}
|
||||
}
|
||||
|
||||
#warning FIXME TODO ... this can become a common helper function ...
|
||||
static inline float _get_keyboard_visibility(void) {
|
||||
struct timespec now = { 0 };
|
||||
@@ -314,9 +314,9 @@ static inline int64_t _tap_key_at_point(float x, float y) {
|
||||
case ICONTEXT_SHOWALT1:
|
||||
key = 0;
|
||||
if (allowLowercase && !isCalibrating) {
|
||||
kbdTemplateAlt[0][0] = ICONTEXT_LOWERCASE;
|
||||
kbdTemplateAlt[CTRLROW][SWITCHCOL] = ICONTEXT_LOWERCASE;
|
||||
} else {
|
||||
kbdTemplateAlt[0][0] = ICONTEXT_UPPERCASE;
|
||||
kbdTemplateAlt[CTRLROW][SWITCHCOL] = ICONTEXT_UPPERCASE;
|
||||
}
|
||||
_switch_keyboard(kbd.model, kbdTemplateAlt[0]);
|
||||
break;
|
||||
@@ -375,7 +375,8 @@ static inline int64_t _tap_key_at_point(float x, float y) {
|
||||
|
||||
case ICONTEXT_MENU_SPROUT:
|
||||
key = 0;
|
||||
_show_useralt_kbd();
|
||||
kbd.ctrlPressed = false;
|
||||
_switch_keyboard(kbd.model, kbdTemplateUserAlt[0]);
|
||||
break;
|
||||
|
||||
case ICONTEXT_GOTO:
|
||||
@@ -737,26 +738,26 @@ static void gltouchkbd_loadAltKbd(const char *kbdPath) {
|
||||
break;
|
||||
}
|
||||
|
||||
// next is reserved0 array
|
||||
if (parsedData.jsonTokens[idx].type != JSMN_ARRAY) {
|
||||
ERRLOG("Expecting a reserved array at JSON token position 3");
|
||||
break;
|
||||
}
|
||||
++idx;
|
||||
idx += parsedData.jsonTokens[idx-1].size;
|
||||
|
||||
// next is reserved1 array
|
||||
if (parsedData.jsonTokens[idx].type != JSMN_ARRAY) {
|
||||
ERRLOG("Expecting a reserved array at JSON token position 4");
|
||||
break;
|
||||
}
|
||||
++idx;
|
||||
idx += parsedData.jsonTokens[idx-1].size;
|
||||
|
||||
// next are the character rows
|
||||
int row = 0;
|
||||
while (idx < tokCount) {
|
||||
if ( !((parsedData.jsonTokens[idx].type == JSMN_ARRAY) && (parsedData.jsonTokens[idx].size == KBD_TEMPLATE_COLS) && (parsedData.jsonTokens[idx].parent == 0)) ) {
|
||||
if (row < 2) {
|
||||
if ( !((parsedData.jsonTokens[idx].type == JSMN_ARRAY) && (parsedData.jsonTokens[idx].parent == 0)) ) {
|
||||
ERRLOG("Expecting a reserved array at keyboard row %d", row+1);
|
||||
break;
|
||||
}
|
||||
if (parsedData.jsonTokens[idx].size != KBD_TEMPLATE_COLS) {
|
||||
// backwards compatibility when we only had the lower 6 rows for keyboard data ...
|
||||
LOG("You can now edit %d columns of row %d in your custom keyboard", KBD_TEMPLATE_COLS, row+1);
|
||||
for (int col=0; col<KBD_TEMPLATE_COLS; col++) {
|
||||
kbdTemplateUserAlt[row][col] = ICONTEXT_NONACTIONABLE;
|
||||
}
|
||||
++row;
|
||||
++idx;
|
||||
idx += parsedData.jsonTokens[idx-1].size;
|
||||
continue;
|
||||
}
|
||||
} else if ( !((parsedData.jsonTokens[idx].type == JSMN_ARRAY) && (parsedData.jsonTokens[idx].size == KBD_TEMPLATE_COLS) && (parsedData.jsonTokens[idx].parent == 0)) ) {
|
||||
ERRLOG("Expecting an array of ten items at keyboard row %d", row+1);
|
||||
break;
|
||||
}
|
||||
@@ -815,6 +816,10 @@ static void gltouchkbd_loadAltKbd(const char *kbdPath) {
|
||||
}
|
||||
|
||||
++row;
|
||||
|
||||
if (row >= KBD_TEMPLATE_ROWS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (row != KBD_TEMPLATE_ROWS) {
|
||||
@@ -847,7 +852,7 @@ static void _animation_hideTouchKeyboard(void) {
|
||||
|
||||
static void _initialize_keyboard_templates(void) {
|
||||
|
||||
for (unsigned int i=0; i<(_ROWOFF-1); i++) {
|
||||
for (unsigned int i=0; i<(MAINROW-1); i++) {
|
||||
for (unsigned int j=0; j<KBD_TEMPLATE_COLS; j++) {
|
||||
kbdTemplateUCase[i][j] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateLCase[i][j] = ICONTEXT_NONACTIONABLE;
|
||||
@@ -862,86 +867,86 @@ static void _initialize_keyboard_templates(void) {
|
||||
}
|
||||
}
|
||||
|
||||
kbdTemplateLCase[0][0] = ICONTEXT_UPPERCASE;
|
||||
kbdTemplateUCase[0][0] = ICONTEXT_SHOWALT1;
|
||||
kbdTemplateAlt [0][0] = ICONTEXT_UPPERCASE;
|
||||
kbdTemplateUserAlt[0][0] = ICONTEXT_UPPERCASE;
|
||||
kbdTemplateLCase[CTRLROW+0][0] = ICONTEXT_UPPERCASE;
|
||||
kbdTemplateUCase[CTRLROW+0][0] = ICONTEXT_SHOWALT1;
|
||||
kbdTemplateAlt [CTRLROW+0][0] = ICONTEXT_UPPERCASE;
|
||||
kbdTemplateUserAlt[CTRLROW+0][0] = ICONTEXT_UPPERCASE;
|
||||
|
||||
kbdTemplateUCase[0][2] = ICONTEXT_CTRL;
|
||||
kbdTemplateLCase[0][2] = ICONTEXT_CTRL;
|
||||
kbdTemplateAlt [0][2] = ICONTEXT_CTRL;
|
||||
kbdTemplateUserAlt[0][2] = ICONTEXT_CTRL;
|
||||
kbdTemplateUCase[CTRLROW+0][2] = ICONTEXT_CTRL;
|
||||
kbdTemplateLCase[CTRLROW+0][2] = ICONTEXT_CTRL;
|
||||
kbdTemplateAlt [CTRLROW+0][2] = ICONTEXT_CTRL;
|
||||
kbdTemplateUserAlt[CTRLROW+0][2] = ICONTEXT_CTRL;
|
||||
|
||||
kbdTemplateUCase[0][4] = ICONTEXT_ESC;
|
||||
kbdTemplateLCase[0][4] = ICONTEXT_ESC;
|
||||
kbdTemplateAlt [0][4] = ICONTEXT_ESC;
|
||||
kbdTemplateUserAlt[0][4] = ICONTEXT_ESC;
|
||||
kbdTemplateUCase[CTRLROW+0][4] = ICONTEXT_ESC;
|
||||
kbdTemplateLCase[CTRLROW+0][4] = ICONTEXT_ESC;
|
||||
kbdTemplateAlt [CTRLROW+0][4] = ICONTEXT_ESC;
|
||||
kbdTemplateUserAlt[CTRLROW+0][4] = ICONTEXT_ESC;
|
||||
|
||||
kbdTemplateUCase[0][6] = MOUSETEXT_OPENAPPLE;
|
||||
kbdTemplateLCase[0][6] = MOUSETEXT_OPENAPPLE;
|
||||
kbdTemplateAlt [0][6] = MOUSETEXT_OPENAPPLE;
|
||||
kbdTemplateUserAlt[0][6] = MOUSETEXT_OPENAPPLE;
|
||||
kbdTemplateUCase[CTRLROW+0][6] = MOUSETEXT_OPENAPPLE;
|
||||
kbdTemplateLCase[CTRLROW+0][6] = MOUSETEXT_OPENAPPLE;
|
||||
kbdTemplateAlt [CTRLROW+0][6] = MOUSETEXT_OPENAPPLE;
|
||||
kbdTemplateUserAlt[CTRLROW+0][6] = MOUSETEXT_OPENAPPLE;
|
||||
|
||||
kbdTemplateUCase[0][8] = MOUSETEXT_CLOSEDAPPLE;
|
||||
kbdTemplateLCase[0][8] = MOUSETEXT_CLOSEDAPPLE;
|
||||
kbdTemplateAlt [0][8] = MOUSETEXT_CLOSEDAPPLE;
|
||||
kbdTemplateUserAlt[0][8] = MOUSETEXT_CLOSEDAPPLE;
|
||||
kbdTemplateUCase[CTRLROW+0][8] = MOUSETEXT_CLOSEDAPPLE;
|
||||
kbdTemplateLCase[CTRLROW+0][8] = MOUSETEXT_CLOSEDAPPLE;
|
||||
kbdTemplateAlt [CTRLROW+0][8] = MOUSETEXT_CLOSEDAPPLE;
|
||||
kbdTemplateUserAlt[CTRLROW+0][8] = MOUSETEXT_CLOSEDAPPLE;
|
||||
|
||||
kbdTemplateUserAlt[2][5] = MOUSETEXT_UP;
|
||||
kbdTemplateUserAlt[3][4] = MOUSETEXT_LEFT;
|
||||
kbdTemplateUserAlt[3][6] = MOUSETEXT_RIGHT;
|
||||
kbdTemplateUserAlt[4][5] = MOUSETEXT_DOWN;
|
||||
kbdTemplateUserAlt[CTRLROW+2][5] = MOUSETEXT_UP;
|
||||
kbdTemplateUserAlt[CTRLROW+3][4] = MOUSETEXT_LEFT;
|
||||
kbdTemplateUserAlt[CTRLROW+3][6] = MOUSETEXT_RIGHT;
|
||||
kbdTemplateUserAlt[CTRLROW+4][5] = MOUSETEXT_DOWN;
|
||||
|
||||
kbdTemplateUCase[3][5] = ICONTEXT_MENU_SPROUT;
|
||||
kbdTemplateLCase[3][5] = ICONTEXT_MENU_SPROUT;
|
||||
kbdTemplateAlt [3][5] = ICONTEXT_MENU_SPROUT;
|
||||
kbdTemplateUserAlt[3][5] = ICONTEXT_MENU_SPROUT;
|
||||
kbdTemplateUCase[CTRLROW+3][5] = ICONTEXT_MENU_SPROUT;
|
||||
kbdTemplateLCase[CTRLROW+3][5] = ICONTEXT_MENU_SPROUT;
|
||||
kbdTemplateAlt [CTRLROW+3][5] = ICONTEXT_MENU_SPROUT;
|
||||
kbdTemplateUserAlt[CTRLROW+3][5] = ICONTEXT_UPPERCASE;
|
||||
|
||||
kbdTemplateUCase[_ROWOFF+2][0] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateLCase[_ROWOFF+2][0] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateUCase[MAINROW+2][0] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateLCase[MAINROW+2][0] = ICONTEXT_NONACTIONABLE;
|
||||
|
||||
kbdTemplateUCase[_ROWOFF+2][8] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateLCase[_ROWOFF+2][8] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateAlt [_ROWOFF+2][8] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateUCase[MAINROW+2][8] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateLCase[MAINROW+2][8] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateAlt [MAINROW+2][8] = ICONTEXT_NONACTIONABLE;
|
||||
|
||||
kbdTemplateUCase[_ROWOFF+2][9] = ICONTEXT_BACKSPACE;
|
||||
kbdTemplateLCase[_ROWOFF+2][9] = ICONTEXT_BACKSPACE;
|
||||
kbdTemplateAlt [_ROWOFF+2][9] = ICONTEXT_BACKSPACE;
|
||||
kbdTemplateUCase[MAINROW+2][9] = ICONTEXT_BACKSPACE;
|
||||
kbdTemplateLCase[MAINROW+2][9] = ICONTEXT_BACKSPACE;
|
||||
kbdTemplateAlt [MAINROW+2][9] = ICONTEXT_BACKSPACE;
|
||||
|
||||
// last row specials
|
||||
|
||||
kbdTemplateLCase[_ROWOFF+3][0] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateUCase[_ROWOFF+3][0] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateLCase[MAINROW+3][0] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateUCase[MAINROW+3][0] = ICONTEXT_NONACTIONABLE;
|
||||
|
||||
kbdTemplateUCase[_ROWOFF+3][1] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateLCase[_ROWOFF+3][1] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateUCase[MAINROW+3][1] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateLCase[MAINROW+3][1] = ICONTEXT_NONACTIONABLE;
|
||||
|
||||
kbdTemplateUCase[_ROWOFF+3][2] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateLCase[_ROWOFF+3][2] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateUCase[MAINROW+3][2] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateLCase[MAINROW+3][2] = ICONTEXT_NONACTIONABLE;
|
||||
|
||||
kbdTemplateUCase[_ROWOFF+3][0] = ICONTEXT_GOTO;
|
||||
kbdTemplateLCase[_ROWOFF+3][0] = ICONTEXT_GOTO;
|
||||
kbdTemplateUCase[MAINROW+3][0] = ICONTEXT_GOTO;
|
||||
kbdTemplateLCase[MAINROW+3][0] = ICONTEXT_GOTO;
|
||||
|
||||
kbdTemplateUCase[_ROWOFF+3][3] = ICONTEXT_LEFTSPACE;
|
||||
kbdTemplateLCase[_ROWOFF+3][3] = ICONTEXT_LEFTSPACE;
|
||||
kbdTemplateAlt [_ROWOFF+3][3] = ICONTEXT_LEFTSPACE;
|
||||
kbdTemplateUCase[_ROWOFF+3][4] = ICONTEXT_MIDSPACE;
|
||||
kbdTemplateLCase[_ROWOFF+3][4] = ICONTEXT_MIDSPACE;
|
||||
kbdTemplateAlt [_ROWOFF+3][4] = ICONTEXT_MIDSPACE;
|
||||
kbdTemplateUCase[_ROWOFF+3][5] = ICONTEXT_RIGHTSPACE;
|
||||
kbdTemplateLCase[_ROWOFF+3][5] = ICONTEXT_RIGHTSPACE;
|
||||
kbdTemplateAlt [_ROWOFF+3][5] = ICONTEXT_RIGHTSPACE;
|
||||
kbdTemplateUCase[MAINROW+3][3] = ICONTEXT_LEFTSPACE;
|
||||
kbdTemplateLCase[MAINROW+3][3] = ICONTEXT_LEFTSPACE;
|
||||
kbdTemplateAlt [MAINROW+3][3] = ICONTEXT_LEFTSPACE;
|
||||
kbdTemplateUCase[MAINROW+3][4] = ICONTEXT_MIDSPACE;
|
||||
kbdTemplateLCase[MAINROW+3][4] = ICONTEXT_MIDSPACE;
|
||||
kbdTemplateAlt [MAINROW+3][4] = ICONTEXT_MIDSPACE;
|
||||
kbdTemplateUCase[MAINROW+3][5] = ICONTEXT_RIGHTSPACE;
|
||||
kbdTemplateLCase[MAINROW+3][5] = ICONTEXT_RIGHTSPACE;
|
||||
kbdTemplateAlt [MAINROW+3][5] = ICONTEXT_RIGHTSPACE;
|
||||
|
||||
kbdTemplateUCase[_ROWOFF+3][7] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateLCase[_ROWOFF+3][7] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateUCase[MAINROW+3][7] = ICONTEXT_NONACTIONABLE;
|
||||
kbdTemplateLCase[MAINROW+3][7] = ICONTEXT_NONACTIONABLE;
|
||||
|
||||
kbdTemplateUCase[_ROWOFF+3][8] = ICONTEXT_RETURN_L;
|
||||
kbdTemplateLCase[_ROWOFF+3][8] = ICONTEXT_RETURN_L;
|
||||
kbdTemplateAlt [_ROWOFF+3][8] = ICONTEXT_RETURN_L;
|
||||
kbdTemplateUCase[MAINROW+3][8] = ICONTEXT_RETURN_L;
|
||||
kbdTemplateLCase[MAINROW+3][8] = ICONTEXT_RETURN_L;
|
||||
kbdTemplateAlt [MAINROW+3][8] = ICONTEXT_RETURN_L;
|
||||
|
||||
kbdTemplateUCase[_ROWOFF+3][9] = ICONTEXT_RETURN_R;
|
||||
kbdTemplateLCase[_ROWOFF+3][9] = ICONTEXT_RETURN_R;
|
||||
kbdTemplateAlt [_ROWOFF+3][9] = ICONTEXT_RETURN_R;
|
||||
kbdTemplateUCase[MAINROW+3][9] = ICONTEXT_RETURN_R;
|
||||
kbdTemplateLCase[MAINROW+3][9] = ICONTEXT_RETURN_R;
|
||||
kbdTemplateAlt [MAINROW+3][9] = ICONTEXT_RETURN_R;
|
||||
}
|
||||
|
||||
__attribute__((constructor(CTOR_PRIORITY_LATE)))
|
||||
@@ -967,7 +972,7 @@ static void _init_gltouchkbd(void) {
|
||||
kbd.selectedRow = -1;
|
||||
|
||||
kbd.ctrlCol = DEFAULT_CTRL_COL;
|
||||
kbd.ctrlRow = 0;
|
||||
kbd.ctrlRow = CTRLROW;
|
||||
|
||||
glnode_registerNode(RENDER_LOW, (GLNode){
|
||||
.setup = &gltouchkbd_setup,
|
||||
|
||||
@@ -1713,7 +1713,8 @@ ENTRY(op_SBC_dec)
|
||||
incb SYM(cpu65_opcycles) // +1 cycle
|
||||
GetFromEA_B
|
||||
DebugBCDCheck
|
||||
btc $C_Flag_Bit, AF_Reg_X
|
||||
bt $C_Flag_Bit, AF_Reg_X
|
||||
cmc
|
||||
xchgb A_Reg, %al
|
||||
#if !defined(__LP64__)
|
||||
sbbb A_Reg, %al
|
||||
@@ -1722,7 +1723,6 @@ ENTRY(op_SBC_dec)
|
||||
cmc
|
||||
FlagNVZC
|
||||
#else
|
||||
cmc
|
||||
sbbb A_Reg, %al
|
||||
// DAS algorithm : http://www.ray.masmcode.com/BCDdas.html
|
||||
// CF_old = CF
|
||||
|
||||
Reference in New Issue
Block a user