Various fixes for input handling

* Merges input handling into one routine called thru video_sync at refresh rate
    * Adds keypad joystick calibration routine
    * Simplify joystick calibration routines to use same codepath as main emulator joystick handling
This commit is contained in:
Aaron Culliney 2013-12-28 13:08:35 -08:00
parent ca5f76fc1a
commit b9815968a1
7 changed files with 368 additions and 305 deletions

View File

@ -28,8 +28,6 @@
#include <zlib.h>
#define MOUSETEXT_BEGIN 0x90
static struct stat statbuf;
static int altdrive;
@ -1007,7 +1005,7 @@ void c_interface_parameters()
cur_y = option = 0; /* wrap both to first */
}
}
else if ((ch == kLEFT) && (!is_backspace())) /* Arrow left */
else if ((ch == kLEFT) && (c_rawkey() != SCODE_BS)) /* Arrow left */
{
switch (option)
{

View File

@ -19,6 +19,8 @@
#define INTERFACE_SCREEN_X 80
#define MOUSETEXT_BEGIN 0x90
void c_interface_print(int x, int y, const int cs, const char *s);
void c_interface_print_submenu_centered(char *submenu, const int xlen, const int ylen);
void c_load_interface_font();

View File

@ -32,10 +32,19 @@
#include "misc.h"
#include "prefs.h"
/* parameters for generic and keyboard-simulated joysticks */
short joy_x = HALF_JOY_RANGE;
short joy_y = HALF_JOY_RANGE;
unsigned char joy_button0 = 0;
unsigned char joy_button1 = 0;
#ifdef PC_JOYSTICK
int js_fd = -1; /* joystick file descriptor */
struct JS_DATA_TYPE js; /* joystick data struct */
int raw_js_x;
int raw_js_y;
int js_lowerrange_x,
js_upperrange_x,
js_lowerrange_y,
@ -103,7 +112,6 @@ void c_close_pc_joystick()
* ------------------------------------------------------------------------- */
static void c_calculate_pc_joystick_parms()
{
js_lowerrange_x = js_center_x - js_min_x;
js_upperrange_x = js_max_x - js_center_x;
js_lowerrange_y = js_center_y - js_min_y;
@ -127,7 +135,7 @@ extern void copy_and_pad_string(char *dest, const char* src, const char c, const
static void c_calibrate_pc_joystick()
{
#define JOYERR_PAD 35
#define JOYERR_SUBMENU_H 8
#define JOYERR_SUBMENU_H 9
#define JOYERR_SUBMENU_W 40
char errmenu[JOYERR_SUBMENU_H][JOYERR_SUBMENU_W+1] =
//1. 5. 10. 15. 20. 25. 30. 35. 40.
@ -135,6 +143,7 @@ static void c_calibrate_pc_joystick()
"| |",
"| An error occurred: |",
"| |",
"| |",
"| Is a joystick device connected? |",
"| Is the proper kernel module loaded? |",
"| |",
@ -160,75 +169,69 @@ static void c_calibrate_pc_joystick()
}
}
#define CALIBRATE_SUBMENU_H 7
#define CALIBRATE_SUBMENU_H 9
#define CALIBRATE_SUBMENU_W 40
char submenu[CALIBRATE_SUBMENU_H][CALIBRATE_SUBMENU_W+1] =
//1. 5. 10. 15. 20. 25. 30. 35. 40.
{ "||||||||||||||||||||||||||||||||||||||||",
"| |",
"| Move joystick to all extremes then |",
"| center it and long-press joy button |",
"| Move joystick to extremes of x and y |",
"| axes and then center it. |",
"| |",
"| btn1:@ btn2:@ x:@@@@ y:@@@@ |",
"| |",
"| ESC to continue... |",
"||||||||||||||||||||||||||||||||||||||||" };
#define LONG_PRESS_THRESHOLD 120
#define SHOW_JOYSTICK_AXES(MENU, WIDTH, HEIGHT, X, Y) \
sprintf(temp, "%04x", (short)(X)); \
copy_and_pad_string(&MENU[HEIGHT-2][24], temp, ' ', 5, ' '); \
sprintf(temp, "%04x", (short)(Y)); \
copy_and_pad_string(&MENU[HEIGHT-2][32], temp, ' ', 5, ' '); \
snprintf(temp, TEMPSIZE, "%04x", (short)(X)); \
copy_and_pad_string(&MENU[HEIGHT-4][24], temp, ' ', 5, ' '); \
snprintf(temp, TEMPSIZE, "%04x", (short)(Y)); \
copy_and_pad_string(&MENU[HEIGHT-4][32], temp, ' ', 5, ' '); \
c_interface_print_submenu_centered(MENU[0], WIDTH, HEIGHT);
#define SHOW_BUTTONS(MENU, HEIGHT) \
MENU[HEIGHT-2][8] = (js.buttons & 0x01) ? 'X' : ' '; \
MENU[HEIGHT-2][15] = (js.buttons & 0x02) ? 'X' : ' '; \
if (js.buttons & 0x03) \
{ \
++long_press; \
} \
else \
{ \
long_press = 0; \
}
MENU[HEIGHT-4][8] = joy_button0 ? 'X' : ' '; \
MENU[HEIGHT-4][15] = joy_button1 ? 'X' : ' ';
unsigned int long_press = 0;
while ((read(js_fd, &js, JS_RETURN) > 0))
for (;;)
{
int ch = c_mygetch(0);
SHOW_BUTTONS(submenu, CALIBRATE_SUBMENU_H);
SHOW_JOYSTICK_AXES(submenu, CALIBRATE_SUBMENU_W, CALIBRATE_SUBMENU_H, js.x, js.y);
video_sync(0);
SHOW_JOYSTICK_AXES(submenu, CALIBRATE_SUBMENU_W, CALIBRATE_SUBMENU_H, raw_js_x, raw_js_y);
if (js_max_x < js.x)
if (js_max_x < raw_js_x)
{
js_max_x = js.x;
js_max_x = raw_js_x;
}
if (js_max_y < js.y)
if (js_max_y < raw_js_y)
{
js_max_y = js.y;
js_max_y = raw_js_y;
}
if (js_min_x > js.x)
if (js_min_x > raw_js_x)
{
js_min_x = js.x;
js_min_x = raw_js_x;
}
if (js_min_y > js.y)
if (js_min_y > raw_js_y)
{
js_min_y = js.y;
js_min_y = raw_js_y;
}
if (long_press > LONG_PRESS_THRESHOLD)
if (ch == kESC)
{
break;
}
static struct timespec ts = { .tv_sec=0, .tv_nsec=33333333 };
nanosleep(&ts, NULL);
}
long_press = 0;
js_center_x = js.x;
js_center_y = js.y;
js_center_x = raw_js_x;
js_center_y = raw_js_y;
#ifndef NDEBUG
LOG("js_min_x = %d", js_min_x);
@ -261,14 +264,12 @@ static void c_calibrate_pc_joystick()
#define CALIBRATE_JOYMENU_H 20
#define CALIBRATE_JOYMENU_W 40
#define CALIBRATE_TURTLE_X0 4
#define CALIBRATE_TURTLE_Y0 5
#define CALIBRATE_TURTLE_Y0 3
#define CALIBRATE_TURTLE_STEP_X (30.f / 255.f)
#define CALIBRATE_TURTLE_STEP_Y (10.f / 255.f)
char joymenu[CALIBRATE_JOYMENU_H][CALIBRATE_JOYMENU_W+1] =
//1. 5. 10. 15. 20. 25. 30. 35. 40.
{ "||||||||||||||||||||||||||||||||||||||||",
"| |",
"| Long press joy button to quit |",
"| |",
"| ||||||||||||||||||||||||||||||||| |",
"| | | |",
@ -285,27 +286,20 @@ static void c_calibrate_pc_joystick()
"| ||||||||||||||||||||||||||||||||| |",
"| |",
"| btn1:@ btn2:@ x:@@@@ y:@@@@ |",
"| |",
"| ESC quits calibration |",
"||||||||||||||||||||||||||||||||||||||||" };
uint8_t x_val=0, y_val=0;
uint8_t x_last=CALIBRATE_JOYMENU_W>>1, y_last=CALIBRATE_JOYMENU_H>>1;
const char* const spinney = "|/-\\";
uint8_t spinney_idx=0;
bool finished_press = false;
while (read(js_fd, &js, JS_RETURN) > 0)
for (;;)
{
x_val = (js.x < js_center_x)
? (js.x - js_offset_x) * js_adjustlow_x
: (js.x - (js_center_x /*+js_offset_x*/)) * js_adjusthigh_x +
HALF_JOY_RANGE;
int ch = c_mygetch(0);
y_val = (js.y < js_center_y)
? (js.y - js_offset_y) * js_adjustlow_y
: (js.y - (js_center_y /*+js_offset_y*/)) * js_adjusthigh_y +
HALF_JOY_RANGE;
int x_plot = CALIBRATE_TURTLE_X0 + (int)(x_val * CALIBRATE_TURTLE_STEP_X);
int y_plot = CALIBRATE_TURTLE_Y0 + (int)(y_val * CALIBRATE_TURTLE_STEP_Y);
int x_plot = CALIBRATE_TURTLE_X0 + (int)(joy_x * CALIBRATE_TURTLE_STEP_X);
int y_plot = CALIBRATE_TURTLE_Y0 + (int)(joy_y * CALIBRATE_TURTLE_STEP_Y);
joymenu[y_last][x_last] = ' ';
joymenu[y_plot][x_plot] = spinney[spinney_idx];
@ -314,19 +308,18 @@ static void c_calibrate_pc_joystick()
y_last = y_plot;
SHOW_BUTTONS(joymenu, CALIBRATE_JOYMENU_H);
SHOW_JOYSTICK_AXES(joymenu, CALIBRATE_JOYMENU_W, CALIBRATE_JOYMENU_H, x_val, y_val);
SHOW_JOYSTICK_AXES(joymenu, CALIBRATE_JOYMENU_W, CALIBRATE_JOYMENU_H, joy_x, joy_y);
video_sync(0);
spinney_idx = (spinney_idx+1) % 4;
if (!js.buttons)
{
finished_press = true;
}
if (finished_press && (long_press > LONG_PRESS_THRESHOLD))
if (ch == kESC)
{
break;
}
static struct timespec ts = { .tv_sec=0, .tv_nsec=33333333 };
nanosleep(&ts, NULL);
}
}
#endif // PC_JOYSTICK
@ -334,7 +327,97 @@ static void c_calibrate_pc_joystick()
#ifdef KEYPAD_JOYSTICK
static void c_calibrate_keypad_joystick()
{
// TODO ....
#define KEYPAD_SUBMENU_H 20
#define KEYPAD_SUBMENU_W 40
#define CALIBRATE_TURTLE_KP_X0 4
#define CALIBRATE_TURTLE_KP_Y0 5
#define CALIBRATE_TURTLE_KP_STEP_X (14.f / 255.f)
char submenu[KEYPAD_SUBMENU_H][KEYPAD_SUBMENU_W+1] =
//1. 5. 10. 15. 20. 25. 30. 35. 40.
{ "||||||||||||||||||||||||||||||||||||||||",
"| |",
"| Use keypad to test & tune joystick |",
"| |",
"| ||||||||||||||||| [You may need to |",
"| | | enable NumLock] |",
"| | | |",
"| | | |",
"| | | 7 @ 9 |",
"| | | @ 5 @ |",
"| | . | 1 @ 3 |",
"| | | Alt-l Alt-r |",
"| | | |",
"| | | |",
"| | | |",
"| | | < or > to change |",
"| ||||||||||||||||| sensitivity: @@ |",
"| |",
"| Alt btn1:@ Alt btn2:@ x:@@ y:@@ |",
"||||||||||||||||||||||||||||||||||||||||" };
submenu[8][29] = MOUSETEXT_BEGIN + 0x0b;
submenu[9][27] = MOUSETEXT_BEGIN + 0x08;
submenu[9][31] = MOUSETEXT_BEGIN + 0x15;
submenu[10][29] = MOUSETEXT_BEGIN + 0x0a;
joy_x = HALF_JOY_RANGE;
joy_y = HALF_JOY_RANGE;
int ch = -1;
uint8_t x_last=CALIBRATE_JOYMENU_W>>1, y_last=CALIBRATE_JOYMENU_H>>1;
const char* const spinney = "|/-\\";
uint8_t spinney_idx=0;
for (;;)
{
submenu[KEYPAD_SUBMENU_H-2][12] = joy_button0 ? 'X' : ' ';
submenu[KEYPAD_SUBMENU_H-2][23] = joy_button1 ? 'X' : ' ';
snprintf(temp, TEMPSIZE, "%02x", (uint8_t)joy_x);
copy_and_pad_string(&submenu[KEYPAD_SUBMENU_H-2][31], temp, ' ', 3, ' ');
snprintf(temp, TEMPSIZE, "%02x", (uint8_t)joy_y);
copy_and_pad_string(&submenu[KEYPAD_SUBMENU_H-2][36], temp, ' ', 3, ' ');
snprintf(temp, TEMPSIZE, "%02x", (uint8_t)joy_step);
copy_and_pad_string(&submenu[KEYPAD_SUBMENU_H-4][36], temp, ' ', 3, ' ');
int x_plot = CALIBRATE_TURTLE_KP_X0 + (int)(joy_x * CALIBRATE_TURTLE_KP_STEP_X);
int y_plot = CALIBRATE_TURTLE_KP_Y0 + (int)(joy_y * CALIBRATE_TURTLE_STEP_Y);
submenu[y_last][x_last] = ' ';
submenu[y_plot][x_plot] = spinney[spinney_idx];
x_last = x_plot;
y_last = y_plot;
spinney_idx = (spinney_idx+1) % 4;
c_interface_print_submenu_centered(submenu[0], KEYPAD_SUBMENU_W, KEYPAD_SUBMENU_H);
ch = c_mygetch(0);
if (ch == kESC)
{
break;
}
else if (ch == '<')
{
if (joy_step > 1)
{
--joy_step;
}
}
else if (ch == '>')
{
if (joy_step < 0xFF)
{
++joy_step;
}
}
static struct timespec ts = { .tv_sec=0, .tv_nsec=33333333 };
nanosleep(&ts, NULL);
}
}
#endif

View File

@ -36,26 +36,24 @@ extern uid_t user, privileged;
extern void c_do_debugging();
/* parameters for generic and keyboard-simulated joysticks */
short joy_x = 127;
short joy_y = 127;
unsigned char joy_button0 = 0;
unsigned char joy_button1 = 0;
unsigned char joy_button2 = 0;
extern short joy_x;
extern short joy_y;
extern unsigned char joy_button0;
extern unsigned char joy_button1;
/* mutex used to synchronize between cpu and main threads */
pthread_mutex_t interface_mutex = PTHREAD_MUTEX_INITIALIZER;
#ifdef PC_JOYSTICK
#include <linux/joystick.h>
int x_val, y_val;
extern int raw_js_x;
extern int raw_js_y;
#endif
#define SCODE_BS 14
static int next_key = -1;
static int last_scancode = -1;
static char caps_lock = 1; /* is enabled */
static int in_mygetch = 0;
static bool in_interface = false;
/* ----------------------------------------------------
Keymap. Mapping scancodes to Apple II+ US Keyboard
@ -207,115 +205,198 @@ static int apple_iie_keymap_shift_ctrl[128] =
-1, -1, -1, -1, -1, -1, -1, kPAUSE, /* 112-119 */
-1, -1, -1, -1, -1, -1, -1, -1 }; /* 120-127 */
static char key_pressed[ 256 ];
static char key_pressed[ 256 ] = { 0 };
/* -------------------------------------------------------------------------
* This routine is called periodically to update the state of the emulator.
* -handles switching to menus
* -polls PC Joystick
* -update palette for flashing text
* ------------------------------------------------------------------------- */
void c_periodic_update(int dummysig) {
int current_key;
void c_handle_input() : Handle input : keys and joystick.
------------------------------------------------------------------------- */
void c_handle_input(int scancode, int pressed)
{
int *keymap = NULL;
video_sync(0);
// raw key input mapping ...
if (next_key >= 0)
if (scancode >= 0)
{
current_key = next_key;
next_key = -1;
last_scancode = scancode;
if (current_key < 128)
/* determine which key mapping to use */
if (apple_mode == IIE_MODE || in_interface)
{
apple_ii_64k[0][0xC000] = current_key | 0x80;
apple_ii_64k[1][0xC000] = current_key | 0x80;
/* set/reset caps lock */
if (key_pressed[ SCODE_CAPS ])
{
caps_lock = !caps_lock;
}
if ((key_pressed[ SCODE_L_SHIFT ] || key_pressed[ SCODE_R_SHIFT ]) && /* shift-ctrl */
(key_pressed[ SCODE_L_CTRL ] || key_pressed[ SCODE_R_CTRL ]))
{
keymap = apple_iie_keymap_shift_ctrl;
}
else if (key_pressed[ SCODE_L_CTRL ] || key_pressed[ SCODE_R_CTRL ]) /* ctrl */
{
keymap = apple_iie_keymap_ctrl;
}
else if (key_pressed[ SCODE_L_SHIFT ] || key_pressed[ SCODE_R_SHIFT ]) /* shift */
{
keymap = apple_iie_keymap_shifted;
}
else if (caps_lock)
{
keymap = apple_iie_keymap_caps;
}
else /* plain */
{
keymap = apple_iie_keymap_plain;
}
}
else
{
switch (current_key)
if (key_pressed[ SCODE_L_CTRL ] || key_pressed[ SCODE_R_CTRL ])
{
case kEND:
if (key_pressed[ SCODE_L_CTRL ] || key_pressed[ SCODE_R_CTRL ])
{
cpu65_interrupt(ResetSig);
}
break;
keymap = apple_ii_keymap_ctrl;
}
else if (key_pressed[ SCODE_L_SHIFT ] || key_pressed[ SCODE_R_SHIFT ])
{
keymap = apple_ii_keymap_shifted;
}
else
{
keymap = apple_ii_keymap_plain;
}
}
case J_C:
joy_x = HALF_JOY_RANGE;
joy_y = HALF_JOY_RANGE;
/* key is pressed */
if (pressed)
{
key_pressed[ scancode ] = 1;
switch (keymap[ scancode ])
{
case JB0:
joy_button0 = 0xff; /* open apple */
break;
case kF1:
pthread_mutex_lock(&interface_mutex);
SoundSystemPause();
c_interface_select_diskette( 0 );
SoundSystemUnpause();
pthread_mutex_unlock(&interface_mutex);
case JB1:
joy_button1 = 0xff; /* closed apple */
break;
case kF2:
pthread_mutex_lock(&interface_mutex);
SoundSystemPause();
c_interface_select_diskette( 1 );
SoundSystemUnpause();
pthread_mutex_unlock(&interface_mutex);
default:
next_key = keymap[scancode];
break;
case kPAUSE:
pthread_mutex_lock(&interface_mutex);
SoundSystemPause();
while (c_mygetch(1) == -1)
{
struct timespec ts = { .tv_sec=0, .tv_nsec=1 };
nanosleep(&ts, NULL);
}
SoundSystemUnpause();
pthread_mutex_unlock(&interface_mutex);
}
}
/* key is released */
else
{
key_pressed[ scancode ] = 0;
switch (keymap[ scancode ])
{
case JB0:
joy_button0 = 0x00;
break;
case kF5:
pthread_mutex_lock(&interface_mutex);
SoundSystemPause();
c_interface_keyboard_layout();
SoundSystemUnpause();
pthread_mutex_unlock(&interface_mutex);
case JB1:
joy_button1 = 0x00;
break;
case kF7:
pthread_mutex_lock(&interface_mutex);
SoundSystemPause();
c_do_debugging();
SoundSystemUnpause();
pthread_mutex_unlock(&interface_mutex);
break;
case kF8:
pthread_mutex_lock(&interface_mutex);
SoundSystemPause();
c_interface_credits();
SoundSystemUnpause();
pthread_mutex_unlock(&interface_mutex);
break;
case kF9:
timing_toggle_cpu_speed();
break;
case kF10:
pthread_mutex_lock(&interface_mutex);
SoundSystemPause();
c_interface_parameters();
SoundSystemUnpause();
pthread_mutex_unlock(&interface_mutex);
default:
break;
}
}
}
/* simulated joystick from PC Keypad */
if (joy_mode == JOY_KPAD)
// key input consumption
if ((next_key >= 0) && !in_interface)
{
do {
int current_key = next_key;
next_key = -1;
if (current_key < 128)
{
apple_ii_64k[0][0xC000] = current_key | 0x80;
apple_ii_64k[1][0xC000] = current_key | 0x80;
break;
}
if (current_key == kF9)
{
timing_toggle_cpu_speed();
break;
}
if (current_key == kEND)
{
if (key_pressed[ SCODE_L_CTRL ] || key_pressed[ SCODE_R_CTRL ])
{
cpu65_interrupt(ResetSig);
}
break;
}
if ( !(c_keys_is_interface_key(current_key) || (current_key == kPAUSE)) )
{
break;
}
pthread_mutex_lock(&interface_mutex);
SoundSystemPause();
in_interface = true;
switch (current_key)
{
case kF1:
c_interface_select_diskette( 0 );
break;
case kF2:
c_interface_select_diskette( 1 );
break;
case kPAUSE:
while (c_mygetch(1) == -1)
{
struct timespec ts = { .tv_sec=0, .tv_nsec=1 };
nanosleep(&ts, NULL);
}
break;
case kF5:
c_interface_keyboard_layout();
break;
#ifdef DEBUGGER
case kF7:
c_do_debugging();
break;
#endif
case kF8:
c_interface_credits();
break;
case kF10:
c_interface_parameters();
break;
default:
break;
}
SoundSystemUnpause();
pthread_mutex_unlock(&interface_mutex);
in_interface = false;
} while(0);
}
// joystick processing
if (joy_mode == JOY_OFF)
{
joy_x = joy_y = 0xFF;
}
#if defined(KEYPAD_JOYSTICK)
else if (joy_mode == JOY_KPAD)
{
if (key_pressed[ SCODE_J_U ])
{
@ -364,9 +445,15 @@ void c_periodic_update(int dummysig) {
joy_x = JOY_RANGE-1;
}
}
}
#ifdef PC_JOYSTICK
if (key_pressed[ SCODE_J_C ])
{
joy_x = HALF_JOY_RANGE;
joy_y = HALF_JOY_RANGE;
}
}
#endif
#if defined(PC_JOYSTICK)
else if ((joy_mode == JOY_PCJOY) && !(js_fd < 0))
{
if (read(js_fd, &js, JS_RETURN) == -1)
@ -374,11 +461,14 @@ void c_periodic_update(int dummysig) {
// error
}
x_val = (js.x < js_center_x)
raw_js_x = js.x;
raw_js_y = js.y;
int x_val = (js.x < js_center_x)
? (js.x - js_offset_x) * js_adjustlow_x
: (js.x - js_center_x) * js_adjusthigh_x + HALF_JOY_RANGE;
y_val = (js.y < js_center_y)
int y_val = (js.y < js_center_y)
? (js.y - js_offset_y) * js_adjustlow_y
: (js.y - js_center_y) * js_adjusthigh_y + HALF_JOY_RANGE;
@ -405,125 +495,19 @@ void c_periodic_update(int dummysig) {
{
joy_button1 = (js.buttons & 0x02) ? 0x80 : 0x0;
}
if (!(joy_button2 & 0x7f))
{
joy_button2 = (js.buttons & 0x03) ? 0x80 : 0x0;
}
}
#endif
else if (joy_mode == JOY_OFF)
{
joy_x = joy_y = 256;
}
}
/* -------------------------------------------------------------------------
void c_read_raw_key() : handle a scancode
------------------------------------------------------------------------- */
void c_read_raw_key(int scancode, int pressed) {
int *keymap = NULL;
last_scancode = scancode;
/* determine which key mapping to use */
if (apple_mode == IIE_MODE || in_mygetch)
{
/* set/reset caps lock */
if (key_pressed[ SCODE_CAPS ])
{
caps_lock = !caps_lock;
}
if ((key_pressed[ SCODE_L_SHIFT ] || key_pressed[ SCODE_R_SHIFT ]) && /* shift-ctrl */
(key_pressed[ SCODE_L_CTRL ] || key_pressed[ SCODE_R_CTRL ]))
{
keymap = apple_iie_keymap_shift_ctrl;
}
else if (key_pressed[ SCODE_L_CTRL ] || key_pressed[ SCODE_R_CTRL ]) /* ctrl */
{
keymap = apple_iie_keymap_ctrl;
}
else if (key_pressed[ SCODE_L_SHIFT ] || key_pressed[ SCODE_R_SHIFT ]) /* shift */
{
keymap = apple_iie_keymap_shifted;
}
else if (caps_lock)
{
keymap = apple_iie_keymap_caps;
}
else /* plain */
{
keymap = apple_iie_keymap_plain;
}
}
else
{
if (key_pressed[ SCODE_L_CTRL ] || key_pressed[ SCODE_R_CTRL ])
{
keymap = apple_ii_keymap_ctrl;
}
else if (key_pressed[ SCODE_L_SHIFT ] || key_pressed[ SCODE_R_SHIFT ])
{
keymap = apple_ii_keymap_shifted;
}
else
{
keymap = apple_ii_keymap_plain;
}
}
/* key is pressed */
if (pressed)
{
key_pressed[ scancode ] = 1;
switch (keymap[ scancode ])
{
case JB0:
joy_button0 = 0xff; /* open apple */
break;
case JB1:
joy_button1 = 0xff; /* closed apple */
break;
case JB2:
joy_button2 = 0xff; /* unused? */
break;
default:
next_key = keymap[scancode];
break;
}
}
/* key is released */
else
{
key_pressed[ scancode ] = 0;
switch (keymap[ scancode ])
{
case JB0:
joy_button0 = 0x00;
break;
case JB1:
joy_button1 = 0x00;
break;
case JB2:
joy_button2 = 0x00;
break;
}
}
}
bool is_backspace()
int c_rawkey()
{
return (last_scancode == SCODE_BS);
return last_scancode;
}
int c_mygetch(int block)
{
int retval;
in_mygetch = 1;
if (block)
{
while (next_key == -1)
@ -538,8 +522,6 @@ int c_mygetch(int block)
video_sync(0);
}
in_mygetch = 0;
retval = next_key;
next_key = -1;

View File

@ -19,6 +19,7 @@
#ifndef A2_KEYS_H
#define A2_KEYS_H
#define SCODE_BS 14
#define SCODE_L_CTRL 29
#define SCODE_R_CTRL 97
#define SCODE_L_SHIFT 42
@ -81,11 +82,9 @@ extern int js_offset_x, js_offset_y;
extern float js_adjustlow_x, js_adjustlow_y, js_adjusthigh_x, js_adjusthigh_y;
#endif
void c_read_raw_key(int scancode, int pressed);
void c_periodic_update(int dummysig);
void enter_debugger(void);
int c_mygetch(int block);
bool is_backspace(); // is the current key actually a backspace?
int c_rawkey();
void c_keys_set_key(int key);
bool c_keys_is_interface_key(int key);

View File

@ -821,7 +821,7 @@ static void main_thread(void *dummyptr) {
c_keys_set_key(kF8); // show credits
do
{
c_periodic_update(0);
video_sync(0);
nanosleep(&sleeptime, NULL);
} while (1);
}

View File

@ -528,47 +528,46 @@ static void c_flash_cursor(int on) {
}
}
extern void c_handle_input(int scancode, int pressed);
/* FIXME: blocking not implemented... */
void video_sync(int block) {
static int flash_count = 0;
// post the image and loop waiting for it to finish and
// also process other input events
post_image();
LOOP:
if (doShm)
{
XNextEvent(
display,
&xevent);
}
else if (!XCheckMaskEvent(
display,
KeyPressMask|KeyReleaseMask,
&xevent))
{
goto POLL_FINISHED;
}
switch (xevent.type)
{
case KeyPress:
c_read_raw_key(keysym_to_scancode(), 1);
break;
case KeyRelease:
c_read_raw_key(keysym_to_scancode(), 0);
break;
default:
if (xevent.type == xshmeventtype)
bool keyevent = true;
do {
if (doShm)
{
goto POLL_FINISHED;
XNextEvent(display, &xevent);
keyevent = !(xevent.type == xshmeventtype);
}
else
{
keyevent = XCheckMaskEvent(display, KeyPressMask|KeyReleaseMask, &xevent);
}
break;
}
int scancode = -1;
int pressed = 0;
switch (xevent.type)
{
case KeyPress:
scancode = keysym_to_scancode();
pressed = 1;
break;
case KeyRelease:
scancode = keysym_to_scancode();
pressed = 0;
break;
default:
break;
}
goto LOOP;
c_handle_input(scancode, pressed);
POLL_FINISHED:
} while (keyevent);
switch (++flash_count)
{