mirror of
https://github.com/LIV2/pistorm.git
synced 2025-12-06 07:02:48 +00:00
Merge pull request #7 from borb/feature/fixes-and-keyb-mouse-autoconnect-and-grab
Fixes; keyboard and mouse autoconnect and keyboard grab (steal from the Pi).
This commit is contained in:
commit
9ef4a891f5
@ -61,12 +61,12 @@ int get_config_item_type(char *cmd) {
|
||||
unsigned int get_m68k_cpu_type(char *name) {
|
||||
for (int i = 0; i < M68K_CPU_TYPES; i++) {
|
||||
if (strcmp(name, cpu_types[i]) == 0) {
|
||||
printf("Set CPU type to %s.\n", cpu_types[i]);
|
||||
printf("[CFG] Set CPU type to %s.\n", cpu_types[i]);
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf ("Invalid CPU type %s specified, defaulting to 68000.\n", name);
|
||||
printf("[CFG] Invalid CPU type %s specified, defaulting to 68000.\n", name);
|
||||
return M68K_CPU_TYPE_68000;
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ unsigned int get_int(char *str) {
|
||||
case 'M': ret_int = ret_int * SIZE_MEGA; break;
|
||||
case 'G': ret_int = ret_int * SIZE_GIGA; break;
|
||||
default:
|
||||
printf("Unknown character %c in hex value.\n", str[i]);
|
||||
printf("[CFG] Unknown character %c in hex value.\n", str[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -179,7 +179,7 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad
|
||||
index++;
|
||||
}
|
||||
if (index == MAX_NUM_MAPPED_ITEMS) {
|
||||
printf("Unable to map item, only %d items can be mapped with current binary.\n", MAX_NUM_MAPPED_ITEMS);
|
||||
printf("[CFG] Unable to map item, only %d items can be mapped with current binary.\n", MAX_NUM_MAPPED_ITEMS);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -195,10 +195,10 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad
|
||||
|
||||
switch(type) {
|
||||
case MAPTYPE_RAM:
|
||||
printf("Allocating %d bytes for RAM mapping (%d MB)...\n", size, size / 1024 / 1024);
|
||||
printf("[CFG] Allocating %d bytes for RAM mapping (%d MB)...\n", size, size / 1024 / 1024);
|
||||
cfg->map_data[index] = (unsigned char *)malloc(size);
|
||||
if (!cfg->map_data[index]) {
|
||||
printf("ERROR: Unable to allocate memory for mapped RAM!\n");
|
||||
printf("[CFG] ERROR: Unable to allocate memory for mapped RAM!\n");
|
||||
goto mapping_failed;
|
||||
}
|
||||
memset(cfg->map_data[index], 0x00, size);
|
||||
@ -206,7 +206,7 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad
|
||||
case MAPTYPE_ROM:
|
||||
in = fopen(filename, "rb");
|
||||
if (!in) {
|
||||
printf("Failed to open file %s for ROM mapping.\n", filename);
|
||||
printf("[CFG] Failed to open file %s for ROM mapping.\n", filename);
|
||||
goto mapping_failed;
|
||||
}
|
||||
fseek(in, 0, SEEK_END);
|
||||
@ -219,7 +219,7 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad
|
||||
cfg->map_data[index] = (unsigned char *)calloc(1, cfg->map_size[index]);
|
||||
cfg->rom_size[index] = (cfg->map_size[index] <= file_size) ? cfg->map_size[index] : file_size;
|
||||
if (!cfg->map_data[index]) {
|
||||
printf("ERROR: Unable to allocate memory for mapped ROM!\n");
|
||||
printf("[CFG] ERROR: Unable to allocate memory for mapped ROM!\n");
|
||||
goto mapping_failed;
|
||||
}
|
||||
memset(cfg->map_data[index], 0x00, cfg->map_size[index]);
|
||||
@ -231,7 +231,7 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad
|
||||
break;
|
||||
}
|
||||
|
||||
printf("[MAP %d] Added %s mapping for range %.8lX-%.8lX ID: %s\n", index, map_type_names[type], cfg->map_offset[index], cfg->map_high[index] - 1, cfg->map_id[index] ? cfg->map_id[index] : "None");
|
||||
printf("[CFG] [MAP %d] Added %s mapping for range %.8lX-%.8lX ID: %s\n", index, map_type_names[type], cfg->map_offset[index], cfg->map_high[index] - 1, cfg->map_id[index] ? cfg->map_id[index] : "None");
|
||||
if (cfg->map_size[index] == cfg->rom_size[index])
|
||||
m68k_add_rom_range(cfg->map_offset[index], cfg->map_high[index], cfg->map_data[index]);
|
||||
|
||||
@ -246,7 +246,7 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad
|
||||
struct emulator_config *load_config_file(char *filename) {
|
||||
FILE *in = fopen(filename, "rb");
|
||||
if (in == NULL) {
|
||||
printf("Failed to open config file %s for reading.\n", filename);
|
||||
printf("[CFG] Failed to open config file %s for reading.\n", filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -257,12 +257,12 @@ struct emulator_config *load_config_file(char *filename) {
|
||||
|
||||
parse_line = (char *)calloc(1, 512);
|
||||
if (!parse_line) {
|
||||
printf("Failed to allocate memory for config file line buffer.\n");
|
||||
printf("[CFG] Failed to allocate memory for config file line buffer.\n");
|
||||
return NULL;
|
||||
}
|
||||
cfg = (struct emulator_config *)calloc(1, sizeof(struct emulator_config));
|
||||
if (!cfg) {
|
||||
printf("Failed to allocate memory for temporary emulator config.\n");
|
||||
printf("[CFG] Failed to allocate memory for temporary emulator config.\n");
|
||||
goto load_failed;
|
||||
}
|
||||
|
||||
@ -332,7 +332,7 @@ struct emulator_config *load_config_file(char *filename) {
|
||||
mirraddr = get_int(cur_cmd);
|
||||
break;
|
||||
default:
|
||||
printf("Unknown/unhandled map argument %s on line %d.\n", cur_cmd, cur_line);
|
||||
printf("[CFG] Unknown/unhandled map argument %s on line %d.\n", cur_cmd, cur_line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -342,7 +342,7 @@ struct emulator_config *load_config_file(char *filename) {
|
||||
}
|
||||
case CONFITEM_LOOPCYCLES:
|
||||
cfg->loop_cycles = get_int(parse_line + str_pos);
|
||||
printf("Set CPU loop cycles to %d.\n", cfg->loop_cycles);
|
||||
printf("[CFG] Set CPU loop cycles to %d.\n", cfg->loop_cycles);
|
||||
break;
|
||||
case CONFITEM_MOUSE:
|
||||
get_next_string(parse_line, cur_cmd, &str_pos, ' ');
|
||||
@ -350,27 +350,37 @@ struct emulator_config *load_config_file(char *filename) {
|
||||
strcpy(cfg->mouse_file, cur_cmd);
|
||||
get_next_string(parse_line, cur_cmd, &str_pos, ' ');
|
||||
cfg->mouse_toggle_key = cur_cmd[0];
|
||||
get_next_string(parse_line, cur_cmd, &str_pos, ' ');
|
||||
cfg->mouse_autoconnect = (strcmp(cur_cmd, "autoconnect") == 0) ? 1 : 0;
|
||||
cfg->mouse_enabled = 1;
|
||||
printf("Enabled mouse event forwarding from file %s, toggle key %c.\n", cfg->mouse_file, cfg->mouse_toggle_key);
|
||||
printf("[CFG] Enabled mouse event forwarding from file %s, toggle key %c.\n", cfg->mouse_file, cfg->mouse_toggle_key);
|
||||
break;
|
||||
case CONFITEM_KEYBOARD:
|
||||
get_next_string(parse_line, cur_cmd, &str_pos, ' ');
|
||||
cfg->keyboard_file = (char *)calloc(1, strlen(cur_cmd) + 1);
|
||||
cfg->keyboard_toggle_key = cur_cmd[0];
|
||||
printf("Enabled keyboard event forwarding, toggle key %c.\n", cfg->keyboard_toggle_key);
|
||||
get_next_string(parse_line, cur_cmd, &str_pos, ' ');
|
||||
cfg->keyboard_grab = (strcmp(cur_cmd, "grab") == 0) ? 1 : 0;
|
||||
get_next_string(parse_line, cur_cmd, &str_pos, ' ');
|
||||
cfg->keyboard_autoconnect = (strcmp(cur_cmd, "autoconnect") == 0) ? 1 : 0;
|
||||
printf("[CFG] Enabled keyboard event forwarding, toggle key %c", cfg->keyboard_toggle_key);
|
||||
if (cfg->keyboard_grab)
|
||||
printf(", locking from host when connected");
|
||||
if (cfg->keyboard_autoconnect)
|
||||
printf(", connected to guest at startup");
|
||||
printf(".\n");
|
||||
break;
|
||||
case CONFITEM_KBFILE:
|
||||
get_next_string(parse_line, cur_cmd, &str_pos, ' ');
|
||||
cfg->keyboard_file = (char *)calloc(1, strlen(cur_cmd) + 1);
|
||||
strcpy(cfg->keyboard_file, cur_cmd);
|
||||
printf("Set keyboard event source file to %s.\n", cfg->keyboard_file);
|
||||
printf("[CFG] Set keyboard event source file to %s.\n", cfg->keyboard_file);
|
||||
break;
|
||||
case CONFITEM_PLATFORM: {
|
||||
char platform_name[128], platform_sub[128];
|
||||
memset(platform_name, 0x00, 128);
|
||||
memset(platform_sub, 0x00, 128);
|
||||
get_next_string(parse_line, platform_name, &str_pos, ' ');
|
||||
printf("Setting platform to %s", platform_name);
|
||||
printf("[CFG] Setting platform to %s", platform_name);
|
||||
get_next_string(parse_line, platform_sub, &str_pos, ' ');
|
||||
if (strlen(platform_sub))
|
||||
printf(" (sub: %s)", platform_sub);
|
||||
@ -380,7 +390,7 @@ struct emulator_config *load_config_file(char *filename) {
|
||||
}
|
||||
case CONFITEM_SETVAR: {
|
||||
if (!cfg->platform) {
|
||||
printf("Warning: esetvar used in config file with no platform specified.\n");
|
||||
printf("[CFG] Warning: setvar used in config file with no platform specified.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -395,11 +405,11 @@ struct emulator_config *load_config_file(char *filename) {
|
||||
}
|
||||
case CONFITEM_NONE:
|
||||
default:
|
||||
printf("Unknown config item %s on line %d.\n", cur_cmd, cur_line);
|
||||
printf("[CFG] Unknown config item %s on line %d.\n", cur_cmd, cur_line);
|
||||
break;
|
||||
}
|
||||
|
||||
skip_line:;
|
||||
skip_line:
|
||||
cur_line++;
|
||||
}
|
||||
goto load_successful;
|
||||
|
||||
@ -68,7 +68,7 @@ struct emulator_config {
|
||||
char *mouse_file, *keyboard_file;
|
||||
|
||||
char mouse_toggle_key, keyboard_toggle_key;
|
||||
unsigned char mouse_enabled, keyboard_enabled;
|
||||
unsigned char mouse_enabled, mouse_autoconnect, keyboard_enabled, keyboard_grab, keyboard_autoconnect;
|
||||
|
||||
unsigned int loop_cycles;
|
||||
unsigned int mapped_low, mapped_high;
|
||||
|
||||
14
default.cfg
14
default.cfg
@ -42,12 +42,18 @@ platform amiga
|
||||
# Uncomment this line to enable the (currently non-working) Pi-Net interface.
|
||||
#setvar pi-net
|
||||
|
||||
# Forward mouse events to host system, defaults to off unless toggle key is pressed on the Pi.
|
||||
# Syntax is mouse [device] [toggle key]
|
||||
#mouse /dev/input/mouse0 m
|
||||
# Forward keyboard events to host system, defaults to off unless toggle key is pressed, toggled off using F12.
|
||||
#keyboard k
|
||||
# Syntax: keyboard [grab key] [grab|nograb] [autoconnect|noautoconnect]
|
||||
# "grab" steals the keyboard from the Pi so Amiga/etc. input is not sent to the Pi
|
||||
# (also helps prevent sending any ctrl-alt-del to the Amiga from resetting the Pi)
|
||||
#
|
||||
# "autoconnect" connects the keyboard to the Amiga/etc. on startup
|
||||
keyboard k nograb noautoconnect
|
||||
# Select a specific filename for the keyboard event source.
|
||||
# This is typically /dev/input/event1 or event0, but it may be event3 with for instance a wireless keyboard.
|
||||
# Use ls /dev/input/event* to check which event files are available and try until you find the one that works.
|
||||
#kbfile /dev/input/event1
|
||||
# Forward mouse events to host system, defaults to off unless toggle key is pressed on the Pi.
|
||||
# Syntax is mouse [device] [toggle key] [autoconnect|noautoconnect]
|
||||
# (see "keyboard" above for autoconnect description)
|
||||
mouse /dev/input/mice m noautoconnect
|
||||
|
||||
74
emulator.c
74
emulator.c
@ -59,9 +59,10 @@ extern volatile uint16_t srdata;
|
||||
extern uint8_t realtime_graphics_debug;
|
||||
uint8_t realtime_disassembly, int2_enabled = 0;
|
||||
uint32_t do_disasm = 0, old_level;
|
||||
char c = 0, c_code = 0, c_type = 0; // @todo temporary main/cpu_task scope workaround until input moved to a thread
|
||||
uint32_t last_irq = 8, last_last_irq = 8;
|
||||
|
||||
uint8_t end_signal = 0;
|
||||
|
||||
char disasm_buf[4096];
|
||||
|
||||
#define KICKBASE 0xF80000
|
||||
@ -239,7 +240,6 @@ cpu_loop:
|
||||
// printf("CPU emulation reset.\n");
|
||||
}
|
||||
|
||||
|
||||
if (mouse_hook_enabled && (mouse_extra != 0x00)) {
|
||||
// mouse wheel events have occurred; unlike l/m/r buttons, these are queued as keypresses, so add to end of buffer
|
||||
switch (mouse_extra) {
|
||||
@ -256,46 +256,66 @@ cpu_loop:
|
||||
// dampen the scroll wheel until next while loop iteration
|
||||
mouse_extra = 0x00;
|
||||
}
|
||||
|
||||
if (end_signal)
|
||||
goto stop_cpu_emulation;
|
||||
|
||||
goto cpu_loop;
|
||||
|
||||
//stop_cpu_emulation:
|
||||
stop_cpu_emulation:
|
||||
printf("[CPU] End of CPU thread\n");
|
||||
return (void *)NULL;
|
||||
}
|
||||
|
||||
void *keyboard_task() {
|
||||
struct pollfd kbdfd[1];
|
||||
int kpoll;
|
||||
struct pollfd kbdpoll[1];
|
||||
int kpollrc;
|
||||
char c = 0, c_code = 0, c_type = 0;
|
||||
char grab_message[] = "[KBD] Grabbing keyboard from input layer\n",
|
||||
ungrab_message[] = "[KBD] Ungrabbing keyboard\n";
|
||||
|
||||
printf("[KBD] Keyboard thread started\n");
|
||||
|
||||
kbdfd[0].fd = keyboard_fd;
|
||||
kbdfd[0].events = POLLIN;
|
||||
// because we permit the keyboard to be grabbed on startup, quickly check if we need to grab it
|
||||
if (kb_hook_enabled && cfg->keyboard_grab) {
|
||||
printf(grab_message);
|
||||
grab_device(keyboard_fd);
|
||||
}
|
||||
|
||||
kbdpoll[0].fd = keyboard_fd;
|
||||
kbdpoll[0].events = POLLIN;
|
||||
|
||||
key_loop:
|
||||
kpoll = poll(kbdfd, 1, KEY_POLL_INTERVAL_MSEC);
|
||||
if ((kpoll > 0) && (kbdfd[0].revents & POLLHUP)) {
|
||||
kpollrc = poll(kbdpoll, 1, KEY_POLL_INTERVAL_MSEC);
|
||||
if ((kpollrc > 0) && (kbdpoll[0].revents & POLLHUP)) {
|
||||
// in the event that a keyboard is unplugged, keyboard_task will whiz up to 100% utilisation
|
||||
// this is undesired, so if the keyboard HUPs, end the thread without ending the emulation
|
||||
printf("[KBD] Keyboard node returned HUP (unplugged?)\n");
|
||||
goto key_end;
|
||||
}
|
||||
|
||||
// if kpoll > 0 then it contains number of events to pull, also check if POLLIN is set in revents
|
||||
if ((kpoll <= 0) || !(kbdfd[0].revents & POLLIN)) {
|
||||
// if kpollrc > 0 then it contains number of events to pull, also check if POLLIN is set in revents
|
||||
if ((kpollrc <= 0) || !(kbdpoll[0].revents & POLLIN)) {
|
||||
goto key_loop;
|
||||
}
|
||||
|
||||
while (get_key_char(&c, &c_code, &c_type)) {
|
||||
if (c && c == cfg->keyboard_toggle_key && !kb_hook_enabled) {
|
||||
kb_hook_enabled = 1;
|
||||
printf("Keyboard hook enabled.\n");
|
||||
}
|
||||
else if (kb_hook_enabled) {
|
||||
printf("[KBD] Keyboard hook enabled.\n");
|
||||
if (cfg->keyboard_grab) {
|
||||
grab_device(keyboard_fd);
|
||||
printf(grab_message);
|
||||
}
|
||||
} else if (kb_hook_enabled) {
|
||||
if (c == 0x1B && c_type) {
|
||||
kb_hook_enabled = 0;
|
||||
printf("Keyboard hook disabled.\n");
|
||||
}
|
||||
else {
|
||||
printf("[KBD] Keyboard hook disabled.\n");
|
||||
if (cfg->keyboard_grab) {
|
||||
release_device(keyboard_fd);
|
||||
printf(ungrab_message);
|
||||
}
|
||||
} else {
|
||||
if (queue_keypress(c_code, c_type, cfg->platform->id) && int2_enabled && last_irq != 2) {
|
||||
//last_irq = 0;
|
||||
//M68K_SET_IRQ(2);
|
||||
@ -328,11 +348,11 @@ key_loop:
|
||||
//m68k_pulse_reset();
|
||||
printf("CPU emulation reset.\n");
|
||||
}
|
||||
// @todo work out how to signal the main process that we want to quit
|
||||
// if (c == 'q') {
|
||||
// printf("Quitting and exiting emulator.\n");
|
||||
// goto stop_cpu_emulation;
|
||||
// }
|
||||
if (c == 'q') {
|
||||
printf("Quitting and exiting emulator.\n");
|
||||
end_signal = 1;
|
||||
goto key_end;
|
||||
}
|
||||
if (c == 'd') {
|
||||
realtime_disassembly ^= 1;
|
||||
do_disasm = 1;
|
||||
@ -360,6 +380,10 @@ key_loop:
|
||||
|
||||
key_end:
|
||||
printf("[KBD] Keyboard thread ending\n");
|
||||
if (cfg->keyboard_grab) {
|
||||
printf(ungrab_message);
|
||||
release_device(keyboard_fd);
|
||||
}
|
||||
return (void*)NULL;
|
||||
}
|
||||
|
||||
@ -496,6 +520,12 @@ int main(int argc, char *argv[]) {
|
||||
printf("Failed to open keyboard event source.\n");
|
||||
}
|
||||
|
||||
if (cfg->mouse_autoconnect)
|
||||
mouse_hook_enabled = 1;
|
||||
|
||||
if (cfg->keyboard_autoconnect)
|
||||
kb_hook_enabled = 1;
|
||||
|
||||
InitGayle();
|
||||
|
||||
signal(SIGINT, sigint_handler);
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#include <linux/input.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@ -211,3 +212,15 @@ void pop_queued_key(uint8_t *c, uint8_t *t) {
|
||||
queued_keypresses--;
|
||||
return;
|
||||
}
|
||||
|
||||
int grab_device(int fd) {
|
||||
int rc = 0;
|
||||
rc = ioctl(fd, EVIOCGRAB, (void *)1);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int release_device(int fd) {
|
||||
int rc = 0;
|
||||
rc = ioctl(fd, EVIOCGRAB, (void *)0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -11,3 +11,5 @@ int get_key_char(char *c, char *code, char *event_type);
|
||||
int queue_keypress(uint8_t keycode, uint8_t event_type, uint8_t platform);
|
||||
int get_num_kb_queued();
|
||||
void pop_queued_key(uint8_t *c, uint8_t *t);
|
||||
int grab_device(int fd);
|
||||
int release_device(int fd);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user