mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-12-22 20:30:22 +00:00
First cut at translating Android keys to Emulator keys
This commit is contained in:
parent
1d6e9cd0d5
commit
2cb26b089f
231
Android/jni/androidkeys.c
Normal file
231
Android/jni/androidkeys.c
Normal file
@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Apple // emulator for *nix
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "androidkeys.h"
|
||||
|
||||
static inline bool _is_shifted(int metaState) {
|
||||
return (metaState & META_SHIFT_MASK);
|
||||
}
|
||||
|
||||
void android_keycode_to_emulator(int keyCode, int metaState, bool pressed) {
|
||||
int key = -1;
|
||||
bool isASCII = true;
|
||||
|
||||
do {
|
||||
if ((keyCode >= KEYCODE_NUMPAD_0) && (keyCode <= KEYCODE_NUMPAD_9)) {
|
||||
key = keyCode - ASCII_NUMPAD_0_OFFSET;
|
||||
break;
|
||||
} else if ((keyCode >= KEYCODE_A) && (keyCode <= KEYCODE_Z)) {
|
||||
key = caps_lock || _is_shifted(metaState) ? (keyCode + ASCII_UCASE_OFFSET) : (keyCode + ASCII_LCASE_OFFSET);
|
||||
break;
|
||||
} else if ((keyCode >= KEYCODE_F1) && (keyCode <= KEYCODE_F12)) {
|
||||
isASCII = false;
|
||||
key = keyCode - FN_OFFSET;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (keyCode) {
|
||||
case KEYCODE_0:
|
||||
key = _is_shifted(metaState) ? ')' : keyCode + ASCII_0_OFFSET;
|
||||
break;
|
||||
case KEYCODE_1:
|
||||
key = _is_shifted(metaState) ? '!' : keyCode + ASCII_0_OFFSET;
|
||||
break;
|
||||
case KEYCODE_2:
|
||||
key = _is_shifted(metaState) ? '@' : keyCode + ASCII_0_OFFSET;
|
||||
break;
|
||||
case KEYCODE_3:
|
||||
key = _is_shifted(metaState) ? '#' : keyCode + ASCII_0_OFFSET;
|
||||
break;
|
||||
case KEYCODE_4:
|
||||
key = _is_shifted(metaState) ? '$' : keyCode + ASCII_0_OFFSET;
|
||||
break;
|
||||
case KEYCODE_5:
|
||||
key = _is_shifted(metaState) ? '%' : keyCode + ASCII_0_OFFSET;
|
||||
break;
|
||||
case KEYCODE_6:
|
||||
key = _is_shifted(metaState) ? '^' : keyCode + ASCII_0_OFFSET;
|
||||
break;
|
||||
case KEYCODE_7:
|
||||
key = _is_shifted(metaState) ? '&' : keyCode + ASCII_0_OFFSET;
|
||||
break;
|
||||
case KEYCODE_8:
|
||||
key = _is_shifted(metaState) ? '*' : keyCode + ASCII_0_OFFSET;
|
||||
break;
|
||||
case KEYCODE_9:
|
||||
key = _is_shifted(metaState) ? '(' : keyCode + ASCII_0_OFFSET;
|
||||
break;
|
||||
case KEYCODE_APOSTROPHE:
|
||||
key = _is_shifted(metaState) ? '"' : '\'';
|
||||
break;
|
||||
case KEYCODE_AT:
|
||||
key = '@';
|
||||
break;
|
||||
case KEYCODE_BACKSLASH:
|
||||
key = _is_shifted(metaState) ? '|' : '\\';
|
||||
break;
|
||||
case KEYCODE_COMMA:
|
||||
key = _is_shifted(metaState) ? '<' : ',';
|
||||
break;
|
||||
case KEYCODE_EQUALS:
|
||||
key = _is_shifted(metaState) ? '+' : '=';
|
||||
break;
|
||||
case KEYCODE_GRAVE:
|
||||
key = _is_shifted(metaState) ? '~' : '`';
|
||||
break;
|
||||
case KEYCODE_LEFT_BRACKET:
|
||||
key = _is_shifted(metaState) ? '{' : '[';
|
||||
break;
|
||||
case KEYCODE_MINUS:
|
||||
key = _is_shifted(metaState) ? '_' : '-';
|
||||
break;
|
||||
case KEYCODE_NUMPAD_ADD:
|
||||
key = '+';
|
||||
break;
|
||||
case KEYCODE_NUMPAD_COMMA:
|
||||
key = ',';
|
||||
break;
|
||||
case KEYCODE_NUMPAD_DIVIDE:
|
||||
key = '/';
|
||||
break;
|
||||
case KEYCODE_NUMPAD_DOT:
|
||||
key = '.';
|
||||
break;
|
||||
case KEYCODE_NUMPAD_EQUALS:
|
||||
key = '=';
|
||||
break;
|
||||
case KEYCODE_NUMPAD_LEFT_PAREN:
|
||||
key = '(';
|
||||
break;
|
||||
case KEYCODE_NUMPAD_RIGHT_PAREN:
|
||||
key = ')';
|
||||
break;
|
||||
case KEYCODE_NUMPAD_MULTIPLY:
|
||||
key = '*';
|
||||
break;
|
||||
case KEYCODE_NUMPAD_SUBTRACT:
|
||||
key = '-';
|
||||
break;
|
||||
case KEYCODE_PERIOD:
|
||||
key = _is_shifted(metaState) ? '>' : '.';
|
||||
break;
|
||||
case KEYCODE_PLUS:
|
||||
key = '+';
|
||||
break;
|
||||
case KEYCODE_POUND:
|
||||
key = '#';
|
||||
break;
|
||||
case KEYCODE_RIGHT_BRACKET:
|
||||
key = _is_shifted(metaState) ? '}' : ']';
|
||||
break;
|
||||
case KEYCODE_SEMICOLON:
|
||||
key = _is_shifted(metaState) ? ':' : ';';
|
||||
break;
|
||||
case KEYCODE_SLASH:
|
||||
key = _is_shifted(metaState) ? '?' : '/';
|
||||
break;
|
||||
case KEYCODE_SPACE:
|
||||
key = ' ';
|
||||
break;
|
||||
case KEYCODE_STAR:
|
||||
key = '*';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (key != -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
// META
|
||||
isASCII = false;
|
||||
|
||||
switch (keyCode) {
|
||||
case KEYCODE_DPAD_LEFT:
|
||||
key = SCODE_L;
|
||||
break;
|
||||
case KEYCODE_DPAD_RIGHT:
|
||||
key = SCODE_R;
|
||||
break;
|
||||
case KEYCODE_DPAD_DOWN:
|
||||
key = SCODE_D;
|
||||
break;
|
||||
case KEYCODE_DPAD_UP:
|
||||
key = SCODE_U;
|
||||
break;
|
||||
case KEYCODE_DPAD_CENTER:
|
||||
key = SCODE_HOME;
|
||||
break;
|
||||
|
||||
case KEYCODE_PAGE_UP:
|
||||
key = SCODE_PGUP;
|
||||
break;
|
||||
case KEYCODE_PAGE_DOWN:
|
||||
key = SCODE_PGDN;
|
||||
break;
|
||||
case KEYCODE_INSERT:
|
||||
key = SCODE_INS;
|
||||
break;
|
||||
|
||||
case KEYCODE_SHIFT_LEFT:
|
||||
key = SCODE_L_SHIFT;
|
||||
break;
|
||||
case KEYCODE_SHIFT_RIGHT:
|
||||
key = SCODE_R_SHIFT;
|
||||
break;
|
||||
|
||||
case KEYCODE_CTRL_LEFT:
|
||||
key = SCODE_L_CTRL;
|
||||
break;
|
||||
case KEYCODE_CTRL_RIGHT:
|
||||
key = SCODE_R_CTRL;
|
||||
break;
|
||||
|
||||
case KEYCODE_ALT_LEFT:
|
||||
case KEYCODE_META_LEFT:
|
||||
key = SCODE_L_ALT;
|
||||
break;
|
||||
case KEYCODE_ALT_RIGHT:
|
||||
case KEYCODE_META_RIGHT:
|
||||
key = SCODE_R_ALT;
|
||||
break;
|
||||
case KEYCODE_BREAKPAUSE:
|
||||
key = SCODE_BRK;
|
||||
break;
|
||||
case KEYCODE_CAPS_LOCK:
|
||||
caps_lock = (metaState & META_CAPS_LOCK_ON);
|
||||
return;
|
||||
case KEYCODE_DEL:
|
||||
key = SCODE_DEL;
|
||||
break;
|
||||
case KEYCODE_ENTER:
|
||||
key = SCODE_RET;
|
||||
break;
|
||||
case KEYCODE_TAB:
|
||||
key = SCODE_TAB;
|
||||
break;
|
||||
case KEYCODE_ESC:
|
||||
key = SCODE_ESC;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
LOG("keyCode:%08x -> key:%02x ('%c') metaState:%08x", keyCode, key, key, metaState);
|
||||
|
||||
assert(key < 0x80);
|
||||
c_keys_handle_input(key, pressed, isASCII);
|
||||
}
|
||||
|
113
Android/jni/androidkeys.h
Normal file
113
Android/jni/androidkeys.h
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Apple // emulator for *nix
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#define ASCII_UCASE_OFFSET 0x24
|
||||
#define ASCII_LCASE_OFFSET 0x44
|
||||
#define ASCII_0_OFFSET 0x29
|
||||
#define ASCII_NUMPAD_0_OFFSET 0x60
|
||||
#define FN_OFFSET 0x48
|
||||
|
||||
#define KEYCODE_0 0x07
|
||||
#define KEYCODE_1 0x08
|
||||
#define KEYCODE_2 0x09
|
||||
#define KEYCODE_3 0x0a
|
||||
#define KEYCODE_4 0x0b
|
||||
#define KEYCODE_5 0x0c
|
||||
#define KEYCODE_6 0x0d
|
||||
#define KEYCODE_7 0x0e
|
||||
#define KEYCODE_8 0x0f
|
||||
#define KEYCODE_9 0x10
|
||||
#define KEYCODE_A 0x1d
|
||||
#define KEYCODE_Z 0x36
|
||||
|
||||
#define KEYCODE_APOSTROPHE 0x4b
|
||||
#define KEYCODE_AT 0x4d
|
||||
#define KEYCODE_BACKSLASH 0x49
|
||||
#define KEYCODE_COMMA 0x37
|
||||
#define KEYCODE_EQUALS 0x46
|
||||
#define KEYCODE_GRAVE 0x44
|
||||
#define KEYCODE_LEFT_BRACKET 0x47
|
||||
#define KEYCODE_MINUS 0x45
|
||||
#define KEYCODE_PERIOD 0x38
|
||||
#define KEYCODE_PLUS 0x51
|
||||
#define KEYCODE_POUND 0x12
|
||||
#define KEYCODE_RIGHT_BRACKET 0x48
|
||||
#define KEYCODE_SEMICOLON 0x4a
|
||||
#define KEYCODE_SLASH 0x4c
|
||||
#define KEYCODE_SPACE 0x3e
|
||||
#define KEYCODE_STAR 0x11
|
||||
|
||||
// numpad
|
||||
#define KEYCODE_NUMPAD_0 0x90
|
||||
#define KEYCODE_NUMPAD_9 0x99
|
||||
#define KEYCODE_NUMPAD_ADD 0x9d
|
||||
#define KEYCODE_NUMPAD_COMMA 0x9f
|
||||
#define KEYCODE_NUMPAD_DIVIDE 0x9a
|
||||
#define KEYCODE_NUMPAD_DOT 0x9e
|
||||
#define KEYCODE_NUMPAD_EQUALS 0xa1
|
||||
#define KEYCODE_NUMPAD_LEFT_PAREN 0xa2
|
||||
#define KEYCODE_NUMPAD_RIGHT_PAREN 0xa3
|
||||
#define KEYCODE_NUMPAD_MULTIPLY 0x9b
|
||||
#define KEYCODE_NUMPAD_SUBTRACT 0x9c
|
||||
|
||||
// various meta keys
|
||||
#define KEYCODE_ALT_LEFT 0x39
|
||||
#define KEYCODE_ALT_RIGHT 0x3a
|
||||
#define KEYCODE_BREAKPAUSE 0x79
|
||||
#define KEYCODE_CAPS_LOCK 0x73
|
||||
#define KEYCODE_CTRL_LEFT 0x71
|
||||
#define KEYCODE_CTRL_RIGHT 0x72
|
||||
#define KEYCODE_DEL 0x43
|
||||
#define KEYCODE_ENTER 0x42
|
||||
#define KEYCODE_ESC 0x6f
|
||||
#define KEYCODE_INSERT 0x7c
|
||||
#define KEYCODE_META_LEFT 0x75
|
||||
#define KEYCODE_META_RIGHT 0x76
|
||||
#define KEYCODE_PAGE_DOWN 0x5d
|
||||
#define KEYCODE_PAGE_UP 0x5c
|
||||
#define KEYCODE_SHIFT_LEFT 0x3b
|
||||
#define KEYCODE_SHIFT_RIGHT 0x3c
|
||||
#define KEYCODE_TAB 0x3d
|
||||
|
||||
// F1-F12
|
||||
#define KEYCODE_F1 0x83
|
||||
#define KEYCODE_F12 0x8e
|
||||
|
||||
// Directional pad movements
|
||||
#define KEYCODE_DPAD_CENTER 0x17
|
||||
#define KEYCODE_DPAD_DOWN 0x14
|
||||
#define KEYCODE_DPAD_LEFT 0x15
|
||||
#define KEYCODE_DPAD_RIGHT 0x16
|
||||
#define KEYCODE_DPAD_UP 0x13
|
||||
|
||||
// Game pad buttons
|
||||
#define KEYCODE_BUTTON_1 0xbc
|
||||
#define KEYCODE_BUTTON_16 0xcb
|
||||
#define KEYCODE_BUTTON_A 0x60
|
||||
#define KEYCODE_BUTTON_B 0x61
|
||||
#define KEYCODE_BUTTON_C 0x62
|
||||
#define KEYCODE_BUTTON_L1 0x66
|
||||
#define KEYCODE_BUTTON_L2 0x68
|
||||
#define KEYCODE_BUTTON_R1 0x67
|
||||
#define KEYCODE_BUTTON_R2 0x69
|
||||
|
||||
#define META_ALT_LEFT_ON 0x00000010
|
||||
#define META_ALT_RIGHT_ON 0x00000020
|
||||
#define META_CAPS_LOCK_ON 0x00100000
|
||||
#define META_CTRL_LEFT_ON 0x00002000
|
||||
#define META_CTRL_RIGHT_ON 0x00004000
|
||||
#define META_SHIFT_MASK 0x000000c1
|
||||
#define META_SHIFT_ON 0x00000040
|
||||
#define META_SHIFT_LEFT_ON 0x00000040
|
||||
#define META_SHIFT_RIGHT_ON 0x00000080
|
||||
|
||||
void android_keycode_to_emulator(int keyCode, int metaState, bool pressed);
|
||||
|
@ -4,14 +4,14 @@ include $(CLEAR_VARS)
|
||||
|
||||
PACKAGE_IDENTIFIER := "org.deadc0de.apple2"
|
||||
PACKAGE_NAME := "apple2ix"
|
||||
COMMON_SOURCES_MK := sources.mk
|
||||
COMMON_SOURCES_MK := $(LOCAL_PATH)/sources.mk
|
||||
include $(COMMON_SOURCES_MK)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Android build config
|
||||
|
||||
LOCAL_MODULE := libapple2ix
|
||||
LOCAL_SRC_FILES := jnihooks.c
|
||||
LOCAL_SRC_FILES := jnihooks.c androidkeys.c
|
||||
LOCAL_CFLAGS := $(APPLE2_BASE_CFLAGS) -DHEADLESS=0
|
||||
LOCAL_LDLIBS := -llog -landroid -lGLESv2 -lz
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <jni.h>
|
||||
#include "common.h"
|
||||
#include "video/renderer.h"
|
||||
#include "androidkeys.h"
|
||||
|
||||
void Java_org_deadc0de_apple2_Apple2Activity_nativeOnCreate(JNIEnv *env, jobject obj, jstring j_dataDir) {
|
||||
const char *dataDir = (*env)->GetStringUTFChars(env, j_dataDir, 0);
|
||||
@ -24,8 +25,8 @@ void Java_org_deadc0de_apple2_Apple2Activity_nativeGraphicsInitialized(JNIEnv *e
|
||||
LOG("%s", "native graphicsInitialized...");
|
||||
video_driver_reshape(width, height);
|
||||
#if !TESTING
|
||||
#warning FIXME TODO ...
|
||||
// TODO ...
|
||||
c_initialize_firsttime();
|
||||
pthread_create(&cpu_thread_id, NULL, (void *) &cpu_thread, (void *)NULL);
|
||||
#else
|
||||
char *local_argv[] = {
|
||||
"-f",
|
||||
@ -81,6 +82,20 @@ void Java_org_deadc0de_apple2_Apple2Activity_nativeRender(JNIEnv *env, jobject o
|
||||
}
|
||||
#endif
|
||||
|
||||
extern volatile bool _vid_dirty;
|
||||
_vid_dirty = true;
|
||||
video_driver_render();
|
||||
}
|
||||
|
||||
void Java_org_deadc0de_apple2_Apple2Activity_nativeOnKeyDown(JNIEnv *env, jobject obj, jint keyCode, jint metaState) {
|
||||
#if !TESTING
|
||||
android_keycode_to_emulator(keyCode, metaState, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Java_org_deadc0de_apple2_Apple2Activity_nativeOnKeyUp(JNIEnv *env, jobject obj, jint keyCode, jint metaState) {
|
||||
#if !TESTING
|
||||
android_keycode_to_emulator(keyCode, metaState, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
@ -44,6 +45,8 @@ public class Apple2Activity extends Activity {
|
||||
private native void nativeOnPause();
|
||||
public native void nativeGraphicsInitialized(int width, int height);
|
||||
public native void nativeRender();
|
||||
private native void nativeOnKeyDown(int keyCode, int metaState);
|
||||
private native void nativeOnKeyUp(int keyCode, int metaState);
|
||||
|
||||
// HACK NOTE 2015/02/22 : Apparently native code cannot easily access stuff in the APK ... so copy various resources
|
||||
// out of the APK and into the /data/data/... for ease of access. Because this is FOSS software we don't care about
|
||||
@ -145,4 +148,17 @@ public class Apple2Activity extends Activity {
|
||||
mView.onPause();
|
||||
nativeOnPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
nativeOnKeyDown(keyCode, event.getMetaState());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
nativeOnKeyUp(keyCode, event.getMetaState());
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user