mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-09-27 09:56:08 +00:00
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:
parent
ca5f76fc1a
commit
b9815968a1
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
203
src/joystick.c
203
src/joystick.c
@ -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
|
||||
|
||||
|
400
src/keys.c
400
src/keys.c
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
57
src/xvideo.c
57
src/xvideo.c
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user