mirror of https://github.com/inolen/redream.git
add support for joystick/add remove events
This commit is contained in:
parent
0f4f3bd914
commit
edda563e32
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue