add support for joystick/add remove events

This commit is contained in:
Joseph 2016-12-06 18:58:19 -06:00 committed by Anthony Pesch
parent 0f4f3bd914
commit edda563e32
12 changed files with 133 additions and 29 deletions

View File

@ -140,6 +140,18 @@ static void emu_keydown(void *data, int device_index, enum keycode code,
dc_keydown(emu->dc, device_index, code, value);
}
static void emu_joy_add(void *data, int joystick_index) {
struct emu *emu = data;
dc_joy_add(emu->dc, joystick_index);
}
static void emu_joy_remove(void *data, int joystick_index) {
struct emu *emu = data;
dc_joy_remove(emu->dc, joystick_index);
}
static void emu_close(void *data) {
struct emu *emu = data;
@ -223,9 +235,16 @@ struct emu *emu_create(struct window *window) {
struct emu *emu = calloc(1, sizeof(struct emu));
emu->window = window;
emu->listener =
(struct window_listener){emu, &emu_paint, &emu_debug_menu, &emu_keydown,
NULL, NULL, &emu_close, {0}};
emu->listener = (struct window_listener){emu,
&emu_paint,
&emu_debug_menu,
&emu_joy_add,
&emu_joy_remove,
&emu_keydown,
NULL,
NULL,
&emu_close,
{0}};
win_add_listener(emu->window, &emu->listener);
return emu;

View File

@ -864,8 +864,8 @@ struct tracer *tracer_create(struct window *window) {
tracer->window = window;
tracer->listener = (struct window_listener){
tracer, &tracer_paint, NULL, &tracer_keydown,
NULL, NULL, &tracer_close, {0}};
tracer, &tracer_paint, NULL, NULL, NULL,
&tracer_keydown, NULL, NULL, &tracer_close, {0}};
tracer->provider =
(struct texture_provider){tracer, &tracer_texture_provider_find_texture};
tracer->rb = window->rb;

View File

@ -17,6 +17,22 @@
DEFINE_OPTION_BOOL(gdb, false, "Run gdb debug server");
void dc_joy_remove(struct dreamcast *dc, int joystick_index) {
list_for_each_entry(dev, &dc->devices, struct device, it) {
if (dev->window_if && dev->window_if->joy_remove) {
dev->window_if->joy_remove(dev, joystick_index);
}
}
}
void dc_joy_add(struct dreamcast *dc, int joystick_index) {
list_for_each_entry(dev, &dc->devices, struct device, it) {
if (dev->window_if && dev->window_if->joy_add) {
dev->window_if->joy_add(dev, joystick_index);
}
}
}
void dc_keydown(struct dreamcast *dc, int device_index, enum keycode code,
int16_t value) {
list_for_each_entry(dev, &dc->devices, struct device, it) {
@ -95,10 +111,13 @@ void dc_destroy_window_interface(struct window_interface *window) {
}
struct window_interface *dc_create_window_interface(
device_debug_menu_cb debug_menu, device_keydown_cb keydown) {
device_debug_menu_cb debug_menu, device_keydown_cb keydown,
device_joy_add_cb joy_add, device_joy_remove_cb joy_remove) {
struct window_interface *window = calloc(1, sizeof(struct window_interface));
window->debug_menu = debug_menu;
window->keydown = keydown;
window->joy_add = joy_add;
window->joy_remove = joy_remove;
return window;
}
@ -140,7 +159,6 @@ struct device *dc_get_device(struct dreamcast *dc, const char *name) {
return dev;
}
}
return NULL;
}

View File

@ -88,10 +88,14 @@ struct memory_interface {
/* window interface */
typedef void (*device_debug_menu_cb)(struct device *, struct nk_context *);
typedef void (*device_keydown_cb)(struct device *, int, enum keycode, int16_t);
typedef void (*device_joy_add_cb)(struct device *, int);
typedef void (*device_joy_remove_cb)(struct device *, int);
struct window_interface {
device_debug_menu_cb debug_menu;
device_keydown_cb keydown;
device_joy_add_cb joy_add;
device_joy_remove_cb joy_remove;
};
/*
@ -164,7 +168,8 @@ struct memory_interface *dc_create_memory_interface(struct dreamcast *dc,
void dc_destroy_memory_interface(struct memory_interface *memory);
struct window_interface *dc_create_window_interface(
device_debug_menu_cb debug_menu, device_keydown_cb keydown);
device_debug_menu_cb debug_menu, device_keydown_cb keydown,
device_joy_add_cb joy_add, device_joy_remove_cb joy_remove);
void dc_destroy_window_interface(struct window_interface *window);
bool dc_init(struct dreamcast *dc);
@ -174,5 +179,7 @@ void dc_tick(struct dreamcast *dc, int64_t ns);
void dc_debug_menu(struct dreamcast *dc, struct nk_context *ctx);
void dc_keydown(struct dreamcast *dc, int device_index, enum keycode code,
int16_t value);
void dc_joy_add(struct dreamcast *dc, int joystick_index);
void dc_joy_remove(struct dreamcast *dc, int joystick_index);
#endif

View File

@ -11,6 +11,20 @@ struct maple {
struct maple_device *devices[MAPLE_NUM_PORTS][MAPLE_MAX_UNITS];
};
static void maple_unregister_device(struct maple *mp, int port, int unit) {
struct maple_device **dev = &mp->devices[port][unit];
if (!*dev) {
return;
}
if ((*dev)->destroy) {
(*dev)->destroy(*dev);
}
*dev = NULL;
}
static void maple_register_device(struct maple *mp, const char *device_type,
int port, int unit) {
CHECK(!mp->devices[port][unit],
@ -26,6 +40,34 @@ static void maple_register_device(struct maple *mp, const char *device_type,
}
}
void maple_joy_add(struct device *data, int joystick_index) {
struct maple *mp = (struct maple *)data;
/* ignore out of range events or events for the default controller which is
always connected */
if (joystick_index <= 0 || joystick_index >= MAPLE_NUM_PORTS) {
return;
}
/* attach joystick to the corresponding maple port */
maple_register_device(mp, "controller", joystick_index, 0);
}
void maple_joy_remove(struct device *data, int joystick_index) {
struct maple *mp = (struct maple *)data;
/* ignore out of range events or events for the default controller which is
always connected */
if (joystick_index <= 0 || joystick_index >= MAPLE_NUM_PORTS) {
return;
}
/* remove all units from the corresponding maple port */
for (int i = 0; i < MAPLE_MAX_UNITS; i++) {
maple_unregister_device(mp, joystick_index, i);
}
}
static void maple_keydown(struct device *d, int device_index, enum keycode key,
int16_t value) {
if (device_index >= MAPLE_NUM_PORTS) {
@ -34,11 +76,6 @@ static void maple_keydown(struct device *d, int device_index, enum keycode key,
struct maple *mp = (struct maple *)d;
/* create a controller if getting data from a new device */
if (!mp->devices[device_index][0]) {
maple_register_device(mp, "controller", device_index, 0);
}
for (int i = 0; i < MAPLE_MAX_UNITS; i++) {
struct maple_device *dev = mp->devices[device_index][i];
@ -127,11 +164,7 @@ static bool maple_init(struct device *dev) {
void maple_destroy(struct maple *mp) {
for (int i = 0; i < MAPLE_NUM_PORTS; i++) {
for (int j = 0; j < MAPLE_MAX_UNITS; j++) {
struct maple_device *dev = mp->devices[i][j];
if (dev && dev->destroy) {
dev->destroy(dev);
}
maple_unregister_device(mp, i, j);
}
}
@ -142,7 +175,8 @@ void maple_destroy(struct maple *mp) {
struct maple *maple_create(struct dreamcast *dc) {
struct maple *mp =
dc_create_device(dc, sizeof(struct maple), "maple", &maple_init);
mp->window_if = dc_create_window_interface(NULL, &maple_keydown);
mp->window_if = dc_create_window_interface(NULL, &maple_keydown,
&maple_joy_add, &maple_joy_remove);
/* add one controller and vmu by default */
maple_register_device(mp, "controller", 0, 0);

View File

@ -962,7 +962,7 @@ struct ta *ta_create(struct dreamcast *dc) {
ta_build_tables();
struct ta *ta = dc_create_device(dc, sizeof(struct ta), "ta", &ta_init);
ta->window_if = dc_create_window_interface(&ta_debug_menu, NULL);
ta->window_if = dc_create_window_interface(&ta_debug_menu, NULL, NULL, NULL);
ta->provider =
(struct texture_provider){ta, &ta_texture_provider_find_texture};
ta->pending_mutex = mutex_create();

View File

@ -346,7 +346,8 @@ struct sh4 *sh4_create(struct dreamcast *dc) {
struct sh4 *sh4 = dc_create_device(dc, sizeof(struct sh4), "sh", &sh4_init);
sh4->execute_if = dc_create_execute_interface(&sh4_run, 0);
sh4->memory_if = dc_create_memory_interface(dc, &sh4_data_map);
sh4->window_if = dc_create_window_interface(&sh4_debug_menu, NULL);
sh4->window_if =
dc_create_window_interface(&sh4_debug_menu, NULL, NULL, NULL);
return sh4;
}

View File

@ -271,7 +271,8 @@ struct microprofile *mp_create(struct window *window) {
calloc(1, sizeof(struct microprofile)));
mp->window = window;
mp->listener = {mp, NULL, NULL, &mp_keydown, NULL, &mp_mousemove, NULL, {}};
mp->listener = {mp, NULL, NULL, NULL, NULL,
&mp_keydown, NULL, &mp_mousemove, NULL, {}};
win_add_listener(mp->window, &mp->listener);

View File

@ -160,7 +160,8 @@ struct nuklear *nk_create(struct window *window) {
struct nuklear *nk = calloc(1, sizeof(struct nuklear));
nk->window = window;
nk->listener = (struct window_listener){
nk, NULL, NULL, &nk_keydown, &nk_textinput, &nk_mousemove, NULL, {0}};
nk, NULL, NULL, NULL, NULL,
&nk_keydown, &nk_textinput, &nk_mousemove, NULL, {0}};
win_add_listener(nk->window, &nk->listener);

View File

@ -15,10 +15,23 @@ static void win_destroy_joystick(struct window *win, SDL_Joystick *del) {
for (int i = 0; i < MAX_JOYSTICKS; i++) {
SDL_Joystick **joy = &win->joysticks[i];
if (*joy == del) {
SDL_JoystickClose(*joy);
*joy = NULL;
if (*joy != del) {
continue;
}
LOG_INFO("Closing joystick %d: %s", i, SDL_JoystickName(*joy));
SDL_JoystickClose(*joy);
*joy = NULL;
/* inform listeners */
list_for_each_entry(listener, &win->listeners, struct window_listener, it) {
if (listener->joy_remove) {
listener->joy_remove(listener->data, i);
}
}
break;
}
}
@ -36,11 +49,18 @@ static void win_create_joystick(struct window *win, int joystick_index) {
break;
}
LOG_INFO("Opened joystick %d: %s", i, SDL_JoystickName(win->joysticks[i]));
LOG_INFO("Opened joystick %d: %s", i, SDL_JoystickName(*joy));
/* reset state */
memset(win->hat_state[i], 0, sizeof(win->hat_state[i]));
/* inform listeners */
list_for_each_entry(listener, &win->listeners, struct window_listener, it) {
if (listener->joy_add) {
listener->joy_add(listener->data, joystick_index);
}
}
break;
}
}
@ -927,6 +947,7 @@ void win_destroy(struct window *win) {
if (win->handle) {
SDL_DestroyWindow(win->handle);
}
for (int i = 0; i < MAX_JOYSTICKS; i++) {
if (win->joysticks[i]) {
win_destroy_joystick(win, win->joysticks[i]);

View File

@ -32,6 +32,8 @@ struct window_listener {
void *data;
void (*paint)(void *data);
void (*debug_menu)(void *data, struct nk_context *ctx);
void (*joy_add)(void *data, int joystick_index);
void (*joy_remove)(void *data, int joystick_index);
void (*keydown)(void *data, int device_index, enum keycode code,
int16_t value);
void (*textinput)(void *data, const char *text);

View File

@ -713,8 +713,8 @@ void rb_destroy(struct render_backend *rb) {
struct render_backend *rb_create(struct window *window) {
struct render_backend *rb = calloc(1, sizeof(struct render_backend));
rb->window = window;
rb->listener = (struct window_listener){rb, NULL, &rb_debug_menu, NULL,
NULL, NULL, NULL, {0}};
rb->listener = (struct window_listener){
rb, NULL, &rb_debug_menu, NULL, NULL, NULL, NULL, NULL, NULL, {0}};
win_add_listener(rb->window, &rb->listener);