Enable joystick emulation key definition.

This commit is contained in:
sorgelig
2017-07-03 17:05:49 +08:00
parent b039f7c0d2
commit f89fa29f50
5 changed files with 181 additions and 154 deletions

261
input.c
View File

@@ -369,15 +369,15 @@ static int check_devs()
/*
else if ( event->mask & IN_MODIFY )
{
result = 1;
if ( event->mask & IN_ISDIR )
{
printf( "The directory %s was modified.\n", event->name );
}
else
{
printf( "The file %s was modified.\n", event->name );
}
result = 1;
if ( event->mask & IN_ISDIR )
{
printf( "The directory %s was modified.\n", event->name );
}
else
{
printf( "The file %s was modified.\n", event->name );
}
}
*/
}
@@ -441,6 +441,7 @@ int toggle_kbdled(int mask)
static int mapping = 0;
static int mapping_button;
static int mapping_dev;
static int mapping_type;
static int mapping_count;
void start_map_setting(int cnt)
@@ -448,14 +449,20 @@ void start_map_setting(int cnt)
mapping_button = 0;
mapping = 1;
mapping_dev = -1;
mapping_type = 1;
mapping_count = cnt;
}
int get_map_button()
int get_map_button()
{
return mapping_button;
}
int get_map_type()
{
return mapping_type;
}
static char *get_map_name(int dev)
{
static char name[128];
@@ -487,14 +494,15 @@ uint16_t get_map_pid()
#define KEY_EMU_UP (KEY_MAX+3)
#define KEY_EMU_DOWN (KEY_MAX+4)
static uint16_t joy[2] = { 0 };
static void input_cb(struct input_event *ev, int dev);
static void joy_digital(int num, uint16_t mask, char press, int bnum)
{
static uint16_t joy[2] = { 0 };
if (num < 2)
{
if (user_io_osd_is_visible() || (bnum == 16))
if (user_io_osd_is_visible() || (bnum == 17))
{
memset(joy, 0, sizeof(joy));
struct input_event ev;
@@ -531,7 +539,7 @@ static void joy_digital(int num, uint16_t mask, char press, int bnum)
break;
default:
ev.code = (bnum == 16) ? KEY_F12 : 0;
ev.code = (bnum == 17) ? KEY_F12 : 0;
}
input_cb(&ev, 0);
@@ -540,88 +548,46 @@ static void joy_digital(int num, uint16_t mask, char press, int bnum)
{
if (press) joy[num] |= (char)mask;
else joy[num] &= ~(char)mask;
user_io_joystick(num, joy[num]);
user_io_digital_joystick(num, joy[num]);
}
}
}
static void joy_analog(int num, int axis, int offset)
{
static int pos[2][2] = { 0 };
if (num < 2)
{
pos[num][axis] = offset;
user_io_analog_joystick(num, (char)(pos[num][0]), (char)(pos[num][1]));
}
}
static void input_cb(struct input_event *ev, int dev)
{
static int key_mapped = 0;
static uint8_t modifiers = 0;
static char keys[6] = { 0,0,0,0,0,0 };
static unsigned char mouse_btn = 0;
static int kbd_toggle = 0;
int map_skip = (mapping && ev->type == EV_KEY && ev->code == 57 && mapping_dev >= 0);
// repeat events won'tbe processed
if (ev->type == EV_KEY && ev->value > 1) return;
int map_skip = (mapping && ev->type == EV_KEY && ev->code == 57 && mapping_dev >= 0 && mapping_type);
int map_cancel = (mapping && ev->type == EV_KEY && ev->code == 1);
//mouse
switch (ev->type)
{
case EV_KEY:
if (ev->code >= 272 && ev->code <= 279)
{
if (ev->code == 272)
{
if (ev->value <= 1)
{
mouse_btn = (mouse_btn & ~1) | ev->value;
user_io_mouse(mouse_btn, 0, 0);
}
return;
}
if (ev->code == 273)
{
if (ev->value <= 1)
{
mouse_btn = (mouse_btn & ~2) | (ev->value << 1);
user_io_mouse(mouse_btn, 0, 0);
}
return;
}
int key = (ev->code < (sizeof(ev2usb) / sizeof(ev2usb[0]))) ? ev2usb[ev->code] : NONE;
if ((key != NONE) && !map_skip)
{
if (ev->value > 1)
{
return;
}
if (key & MODMASK)
{
modifiers = (ev->value) ? modifiers | (uint8_t)(key >> 8) : modifiers & ~(uint8_t)(key >> 8);
}
else
{
if (ev->value)
{
int found = 0;
for (int i = 0; i < (sizeof(keys) / sizeof(keys[0])); i++) if (keys[i] == (uint8_t)key) found = 1;
if (!found)
{
for (int i = 0; i < (sizeof(keys) / sizeof(keys[0])); i++)
{
if (!keys[i])
{
keys[i] = (uint8_t)key;
break;
}
}
}
}
else
{
for (int i = 0; i < (sizeof(keys) / sizeof(keys[0])); i++) if (keys[i] == (uint8_t)key) keys[i] = 0;
}
int j = 0;
for (int i = 0; i < (sizeof(keys) / sizeof(keys[0])); i++) if (keys[i]) keys[j++] = keys[i];
while (j < (sizeof(keys) / sizeof(keys[0]))) keys[j++] = 0;
}
user_io_kbd(modifiers, keys, input[dev].vid, input[dev].pid);
return;
}
unsigned char mask = 1 << (ev->code - 272);
mouse_btn = (ev->value) ? mouse_btn | mask : mouse_btn & ~mask;
user_io_mouse(mouse_btn, 0, 0);
return;
}
break;
@@ -641,7 +607,6 @@ static void input_cb(struct input_event *ev, int dev)
}
break;
}
if (!input[dev].has_map)
{
@@ -652,38 +617,52 @@ static void input_cb(struct input_event *ev, int dev)
input[dev].has_map = 1;
}
//joystick
if (mapping && (mapping_dev >=0 || ev->value))
//joystick mapping
if (mapping && (mapping_dev >=0 || ev->value) && !map_cancel)
{
if ((ev->type == EV_KEY && ev->value <= 1 && ev->code >= BTN_JOYSTICK))
if (ev->type == EV_KEY)
{
if (mapping_dev < 0) mapping_dev = dev;
if (mapping_dev == dev && mapping_button < mapping_count)
if ((mapping_dev < 0) || ((ev->code >= BTN_JOYSTICK) ? mapping_type : !mapping_type))
{
if (ev->value)
if (mapping_dev < 0)
{
if(!mapping_button) memset(&input[dev].map, 0, sizeof(input[dev].map));
mapping_dev = dev;
mapping_type = (ev->code >= BTN_JOYSTICK) ? 1 : 0;
}
int found = 0;
for (int i = 0; i < mapping_button; i++) if (input[dev].map[i] == ev->code) found = 1;
if (!found)
if (mapping_dev == dev && mapping_button < mapping_count)
{
if (ev->value)
{
input[dev].map[(mapping_button == (mapping_count-1)) ? 16 : mapping_button] = ev->code;
key_mapped = 1;
if (!mapping_button) memset(&input[dev].map, 0, sizeof(input[dev].map));
int found = 0;
for (int i = 0; i < mapping_button; i++) if (input[dev].map[i] == ev->code) found = 1;
if (!found)
{
input[dev].map[(mapping_button == (mapping_count - 1)) ? 16 + mapping_type : mapping_button] = ev->code;
key_mapped = 1;
}
}
else
{
if (key_mapped) mapping_button++;
key_mapped = 0;
}
}
else
{
if(key_mapped) mapping_button++;
key_mapped = 0;
}
return;
}
}
if (map_skip && mapping_button < mapping_count && ev->value == 1)
if (map_skip && mapping_button < mapping_count)
{
mapping_button++;
if (ev->value == 1)
{
mapping_button++;
}
return;
}
}
else
@@ -691,13 +670,13 @@ static void input_cb(struct input_event *ev, int dev)
key_mapped = 0;
switch (ev->type)
{
//buttons, digital directions
case EV_KEY:
if (ev->value <= 1)
//joystick buttons, digital directions
if (ev->code >= BTN_JOYSTICK)
{
if (first_joystick < 0) first_joystick = dev;
for (int i = 0; i <= 16; i++)
for (int i = 0; i <= 17; i++)
{
if (ev->code == input[dev].map[i])
{
@@ -705,6 +684,75 @@ static void input_cb(struct input_event *ev, int dev)
return;
}
}
return;
}
// keyboard
else
{
if(!user_io_osd_is_visible() && ((user_io_get_kbdemu() != EMU_JOY0) || (user_io_get_kbdemu() != EMU_JOY1)))
{
if (!kbd_toggle)
{
for (int i = 0; i <= 15; i++)
{
if (ev->code == input[dev].map[i])
{
joy_digital((user_io_get_kbdemu() != EMU_JOY0) ? 0 : 1, 1 << i, ev->value, i);
return;
}
}
}
if (ev->code == input[dev].map[16])
{
if (ev->value) kbd_toggle = !kbd_toggle;
return;
}
}
else
{
kbd_toggle = 0;
}
int key = (ev->code < (sizeof(ev2usb) / sizeof(ev2usb[0]))) ? ev2usb[ev->code] : NONE;
if(key != NONE)
{
if (key & MODMASK)
{
modifiers = (ev->value) ? modifiers | (uint8_t)(key >> 8) : modifiers & ~(uint8_t)(key >> 8);
}
else
{
if (ev->value)
{
int found = 0;
for (int i = 0; i < (sizeof(keys) / sizeof(keys[0])); i++) if (keys[i] == (uint8_t)key) found = 1;
if (!found)
{
for (int i = 0; i < (sizeof(keys) / sizeof(keys[0])); i++)
{
if (!keys[i])
{
keys[i] = (uint8_t)key;
break;
}
}
}
}
else
{
for (int i = 0; i < (sizeof(keys) / sizeof(keys[0])); i++) if (keys[i] == (uint8_t)key) keys[i] = 0;
}
int j = 0;
for (int i = 0; i < (sizeof(keys) / sizeof(keys[0])); i++) if (keys[i]) keys[j++] = keys[i];
while (j < (sizeof(keys) / sizeof(keys[0]))) keys[j++] = 0;
}
user_io_kbd(modifiers, keys, input[dev].vid, input[dev].pid);
return;
}
}
break;
@@ -721,7 +769,7 @@ static void input_cb(struct input_event *ev, int dev)
{
int offset = 0;
if (ev->value < 127 || ev->value>129) offset = ev->value - 128;
//joy_analog((first_joystick == dev) ? 0 : 1, 0, offset);
joy_analog((first_joystick == dev) ? 0 : 1, 0, offset);
return;
}
@@ -729,7 +777,7 @@ static void input_cb(struct input_event *ev, int dev)
{
int offset = 0;
if (ev->value < 127 || ev->value>129) offset = ev->value - 128;
//joy_analog((first_joystick == dev) ? 0 : 1, 1, offset);
joy_analog((first_joystick == dev) ? 0 : 1, 1, offset);
return;
}
break;
@@ -858,7 +906,7 @@ int input_poll(int getchar)
if (ev.code == 60) break; //ps3 accel axis
if (ev.code == 59) break; //ps3 accel axis
//reduce spam on PS3 gamepad
//reduce flood from PS3 gamepad
if (input[i].vid == 0x054c && input[i].pid == 0x0268)
{
if (ev.code <= 5 && ev.value > 118 && ev.value < 138) break;
@@ -872,7 +920,6 @@ int input_poll(int getchar)
}
}
input_cb(&ev, i);
//sumulate digital directions from analog

View File

@@ -15,7 +15,8 @@ int input_poll(int getchar);
void start_map_setting(int cnt);
int get_map_button();
int get_map_button();
int get_map_type();
void finish_map_setting(int dismiss);
uint16_t get_map_vid();
uint16_t get_map_pid();

12
menu.c
View File

@@ -155,7 +155,7 @@ char *config_autofire_msg[] = { " AUTOFIRE OFF", " AUTOFIRE FAST",
const char *config_cd32pad_msg[] = { "OFF", "ON" };
char *config_button_turbo_msg[] = { "OFF", "FAST", "MEDIUM", "SLOW" };
char *config_button_turbo_choice_msg[] = { "A only", "B only", "A & B" };
char *joy_button_map[] = { "RIGHT", "LEFT", "DOWN", "UP", "BUTTON 1", "BUTTON 2", "BUTTON 3", "BUTTON 4", "BUTTON OSD" };
char *joy_button_map[] = { "RIGHT", "LEFT", "DOWN", "UP", "BUTTON 1", "BUTTON 2", "BUTTON 3", "BUTTON 4", "KBD TOGGLE", "BUTTON OSD" };
char joy_bnames[12][32];
int joy_bcount = 0;
@@ -1224,19 +1224,21 @@ void HandleUI(void)
}
else if(joy_bcount)
{
p = (get_map_button() < joy_bcount + 4) ? joy_bnames[get_map_button() - 4] : joy_button_map[8];
p = (get_map_button() < joy_bcount + 4) ? joy_bnames[get_map_button() - 4] : joy_button_map[8+get_map_type()];
}
else
{
p = (get_map_button() < 9) ? joy_button_map[get_map_button()] : "";
p = (get_map_button() < 8) ? joy_button_map[get_map_button()] : joy_button_map[8 + get_map_type()];
}
sprintf(s, " Press: %s", p);
OsdWrite(3, s, 0, 0);
if (get_map_button())
{
OsdWrite(OsdGetSize() - 1, " finish (SPACE - skip)", menusub == 0, 0);
sprintf(s, " Joystick ID: %04x:%04x", get_map_vid(), get_map_pid());
if(get_map_type()) OsdWrite(OsdGetSize() - 1, " finish (SPACE - skip)", menusub == 0, 0);
else OsdWrite(OsdGetSize() - 1, "", 0, 0);
sprintf(s, " %s ID: %04x:%04x", get_map_type() ? "Joystick" : "Keyboard", get_map_vid(), get_map_pid());
OsdWrite(5, s, 0, 0);
}

View File

@@ -32,7 +32,6 @@ unsigned char key_remap_table[MAX_REMAP][2];
fileTYPE sd_image;
// mouse and keyboard emulation state
typedef enum { EMU_NONE, EMU_MOUSE, EMU_JOY0, EMU_JOY1 } emu_mode_t;
static emu_mode_t emu_mode = EMU_NONE;
static unsigned char emu_state = 0;
static unsigned long emu_timer = 0;
@@ -364,15 +363,6 @@ static char dig2ana(char min, char max)
return 0;
}
void user_io_joystick(unsigned char joystick, uint16_t map)
{
// digital joysticks also send analog signals
user_io_digital_joystick(joystick, map);
user_io_analog_joystick(joystick,
dig2ana(map&JOY_LEFT, map&JOY_RIGHT),
dig2ana(map&JOY_UP, map&JOY_DOWN));
}
// transmit serial/rs232 data into core
void user_io_serial_tx(char *chr, uint16_t cnt)
{
@@ -1386,7 +1376,7 @@ static unsigned char is_emu_key(unsigned char c, unsigned alt) {
0x61, JOY_BTN2
};
if (emu_mode == EMU_NONE) return 0;
if (emu_mode != EMU_MOUSE) return 0;
if (alt)
{
@@ -1679,9 +1669,9 @@ void user_io_kbd(unsigned char m, unsigned char *k, unsigned short vid, unsigned
}
// modifier keys are used as buttons in emu mode
if (emu_mode != EMU_NONE && !osd_is_visible)
if (emu_mode == EMU_MOUSE && !osd_is_visible)
{
char last_btn = emu_state & (JOY_BTN1 | JOY_BTN2 | JOY_BTN3 | JOY_BTN4);
char last_btn = emu_state & (JOY_BTN1 | JOY_BTN2);
if (keyrah != 2)
{
if (m & (1 << EMU_BTN1)) emu_state |= JOY_BTN1;
@@ -1689,29 +1679,15 @@ void user_io_kbd(unsigned char m, unsigned char *k, unsigned short vid, unsigned
if (m & (1 << EMU_BTN2)) emu_state |= JOY_BTN2;
else emu_state &= ~JOY_BTN2;
}
if (m & (1 << EMU_BTN3)) emu_state |= JOY_BTN3;
else emu_state &= ~JOY_BTN3;
if (m & (1 << EMU_BTN4)) emu_state |= JOY_BTN4;
else emu_state &= ~JOY_BTN4;
// check if state of mouse buttons has changed
// (on a mouse only two buttons are supported)
if ((last_btn & (JOY_BTN1 | JOY_BTN2)) != (emu_state & (JOY_BTN1 | JOY_BTN2)))
{
if (emu_mode == EMU_MOUSE)
{
unsigned char b;
if (emu_state & JOY_BTN1) b |= 1;
if (emu_state & JOY_BTN2) b |= 2;
user_io_mouse(b, 0, 0);
}
}
// check if state of joystick buttons has changed
if (last_btn != (emu_state & (JOY_BTN1 | JOY_BTN2 | JOY_BTN3 | JOY_BTN4)))
{
if (emu_mode == EMU_JOY0) user_io_joystick(joystick_renumber(0), emu_state);
if (emu_mode == EMU_JOY1) user_io_joystick(joystick_renumber(1), emu_state);
unsigned char b;
if (emu_state & JOY_BTN1) b |= 1;
if (emu_state & JOY_BTN2) b |= 2;
user_io_mouse(b, 0, 0);
}
}
@@ -1723,8 +1699,8 @@ void user_io_kbd(unsigned char m, unsigned char *k, unsigned short vid, unsigned
// Do we have a downstroke on a modifier key?
if ((m & (1 << i)) && !(modifier & (1 << i)))
{
// shift keys are used for mouse joystick emulation in emu mode
if (((i != EMU_BTN1) && (i != EMU_BTN2) && (i != EMU_BTN3) && (i != EMU_BTN4)) || (emu_mode == EMU_NONE))
// shift keys are used for mouse emulation in emu mode
if (((i != EMU_BTN1) && (i != EMU_BTN2)) || (emu_mode != EMU_MOUSE))
{
if (modifier_keycode(i) != MISS) send_keycode(modifier_keycode(i));
}
@@ -1732,7 +1708,7 @@ void user_io_kbd(unsigned char m, unsigned char *k, unsigned short vid, unsigned
if (!(m & (1 << i)) && (modifier & (1 << i)))
{
if (((i != EMU_BTN1) && (i != EMU_BTN2) && (i != EMU_BTN3) && (i != EMU_BTN4)) || (emu_mode == EMU_NONE))
if (((i != EMU_BTN1) && (i != EMU_BTN2)) || (emu_mode != EMU_MOUSE))
{
if (modifier_keycode(i) != MISS) send_keycode(BREAK | modifier_keycode(i));
}
@@ -1778,8 +1754,6 @@ void user_io_kbd(unsigned char m, unsigned char *k, unsigned short vid, unsigned
if (is_emu_key(pressed[i], keyrah) && !osd_is_visible)
{
emu_state &= ~is_emu_key(pressed[i], keyrah);
if (emu_mode == EMU_JOY0) user_io_joystick(joystick_renumber(0), emu_state);
if (emu_mode == EMU_JOY1) user_io_joystick(joystick_renumber(1), emu_state);
if (keyrah == 2)
{
unsigned char b;
@@ -1834,10 +1808,6 @@ void user_io_kbd(unsigned char m, unsigned char *k, unsigned short vid, unsigned
{
emu_state |= is_emu_key(k[i], keyrah);
// joystick emulation is also affected by the presence of
// usb joysticks
if (emu_mode == EMU_JOY0) user_io_joystick(joystick_renumber(0), emu_state);
if (emu_mode == EMU_JOY1) user_io_joystick(joystick_renumber(1), emu_state);
if (keyrah == 2)
{
unsigned char b;
@@ -1988,3 +1958,8 @@ unsigned char user_io_ext_idx(char *name, char* ext)
printf("0\n", name, ext, 0);
return 0;
}
emu_mode_t user_io_get_kbdemu()
{
return emu_mode;
}

View File

@@ -134,6 +134,7 @@
#define UIO_PRIORITY_KEYBOARD 0
#define UIO_PRIORITY_GAMEPAD 1
typedef enum { EMU_NONE, EMU_MOUSE, EMU_JOY0, EMU_JOY1 } emu_mode_t;
// serial status data type returned from the core
typedef struct {
@@ -166,6 +167,8 @@ char *user_io_get_core_name();
char *user_io_get_core_name_ex();
char is_menu_core();
emu_mode_t user_io_get_kbdemu();
// io controllers interface for FPGA ethernet emulation using usb ethernet
// devices attached to the io controller (ethernec emulation)
void user_io_eth_send_mac(uint8_t *);
@@ -181,7 +184,6 @@ void user_io_digital_joystick(unsigned char, uint16_t);
void user_io_analog_joystick(unsigned char, char, char);
char user_io_osd_is_visible();
void user_io_send_buttons(char);
void user_io_joystick(unsigned char joystick, uint16_t map);
void user_io_key_remap(char *);
void add_modifiers(uint8_t mod, uint16_t* keys_ps2);