mirror of https://github.com/inolen/redream.git
added all 4 controllers by default to avoid extra joystick added / removed state handling
added explicit update polling callback made controller_input callback take in the actual dreamcast button pressed removed controller profile code from maple
This commit is contained in:
parent
e54fc92cfd
commit
c0a713613c
|
@ -65,16 +65,8 @@ struct emu {
|
|||
struct list live_frames;
|
||||
};
|
||||
|
||||
/*
|
||||
* multithreaded, offscreen video rendering
|
||||
*/
|
||||
static void emu_cancel_render(struct emu *emu) {
|
||||
mutex_lock(emu->pending_mutex);
|
||||
|
||||
emu->pending_ctx = NULL;
|
||||
cond_signal(emu->pending_cond);
|
||||
|
||||
mutex_unlock(emu->pending_mutex);
|
||||
static int16_t emu_get_input(void *userdata, int port, int button) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void emu_finish_render(void *userdata) {
|
||||
|
@ -118,6 +110,18 @@ static void emu_push_audio(void *userdata, const int16_t *data, int frames) {
|
|||
ringbuf_advance_write_ptr(emu->audio_buffer, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* multithreaded, offscreen video rendering
|
||||
*/
|
||||
static void emu_cancel_render(struct emu *emu) {
|
||||
mutex_lock(emu->pending_mutex);
|
||||
|
||||
emu->pending_ctx = NULL;
|
||||
cond_signal(emu->pending_cond);
|
||||
|
||||
mutex_unlock(emu->pending_mutex);
|
||||
}
|
||||
|
||||
static struct frame *emu_pop_frame(struct emu *emu) {
|
||||
mutex_lock(emu->frames_mutex);
|
||||
|
||||
|
@ -274,18 +278,6 @@ 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;
|
||||
|
||||
|
@ -510,8 +502,8 @@ struct emu *emu_create(struct window *win) {
|
|||
emu->win = win;
|
||||
|
||||
/* add window input listeners */
|
||||
emu->listener = (struct window_listener){
|
||||
emu, &emu_joy_add, &emu_joy_remove, &emu_keydown, NULL, &emu_close, {0}};
|
||||
emu->listener =
|
||||
(struct window_listener){emu, &emu_keydown, NULL, &emu_close, {0}};
|
||||
win_add_listener(emu->win, &emu->listener);
|
||||
|
||||
/* create dreamcast */
|
||||
|
@ -520,6 +512,8 @@ struct emu *emu_create(struct window *win) {
|
|||
client.push_audio = &emu_push_audio;
|
||||
client.start_render = &emu_start_render;
|
||||
client.finish_render = &emu_finish_render;
|
||||
client.poll_input = NULL;
|
||||
client.get_input = &emu_get_input;
|
||||
emu->dc = dc_create(&client);
|
||||
|
||||
/* create render backend */
|
||||
|
|
|
@ -17,38 +17,44 @@
|
|||
|
||||
DEFINE_OPTION_INT(gdb, 0, "Run gdb debug server");
|
||||
|
||||
void dc_finish_render(struct dreamcast *dc) {
|
||||
if (dc->client.finish_render) {
|
||||
dc->client.finish_render(dc->client.userdata);
|
||||
int16_t dc_get_input(struct dreamcast *dc, int port, int button) {
|
||||
if (!dc->client.get_input) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return dc->client.get_input(dc->client.userdata, port, button);
|
||||
}
|
||||
|
||||
void dc_poll_input(struct dreamcast *dc) {
|
||||
if (!dc->client.poll_input) {
|
||||
return;
|
||||
}
|
||||
|
||||
dc->client.poll_input(dc->client.userdata);
|
||||
}
|
||||
|
||||
void dc_finish_render(struct dreamcast *dc) {
|
||||
if (!dc->client.finish_render) {
|
||||
return;
|
||||
}
|
||||
|
||||
dc->client.finish_render(dc->client.userdata);
|
||||
}
|
||||
|
||||
void dc_start_render(struct dreamcast *dc, struct tile_ctx *ctx) {
|
||||
if (dc->client.start_render) {
|
||||
dc->client.start_render(dc->client.userdata, ctx);
|
||||
if (!dc->client.start_render) {
|
||||
return;
|
||||
}
|
||||
|
||||
dc->client.start_render(dc->client.userdata, ctx);
|
||||
}
|
||||
|
||||
void dc_push_audio(struct dreamcast *dc, const int16_t *data, int frames) {
|
||||
if (dc->client.push_audio) {
|
||||
dc->client.push_audio(dc->client.userdata, data, frames);
|
||||
if (!dc->client.push_audio) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
dc->client.push_audio(dc->client.userdata, data, frames);
|
||||
}
|
||||
|
||||
void dc_keydown(struct dreamcast *dc, int device_index, enum keycode code,
|
||||
|
@ -183,13 +189,9 @@ void dc_destroy_window_interface(struct window_interface *window) {
|
|||
free(window);
|
||||
}
|
||||
|
||||
struct window_interface *dc_create_window_interface(
|
||||
device_keydown_cb keydown, device_joy_add_cb joy_add,
|
||||
device_joy_remove_cb joy_remove) {
|
||||
struct window_interface *dc_create_window_interface(device_keydown_cb keydown) {
|
||||
struct window_interface *window = calloc(1, sizeof(struct window_interface));
|
||||
window->keydown = keydown;
|
||||
window->joy_add = joy_add;
|
||||
window->joy_remove = joy_remove;
|
||||
return window;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,8 +92,6 @@ typedef void (*device_joy_remove_cb)(struct device *, int);
|
|||
|
||||
struct window_interface {
|
||||
device_keydown_cb keydown;
|
||||
device_joy_add_cb joy_add;
|
||||
device_joy_remove_cb joy_remove;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -135,12 +133,16 @@ struct device {
|
|||
typedef void (*push_audio_cb)(void *, const int16_t *, int);
|
||||
typedef void (*start_render_cb)(void *, struct tile_ctx *);
|
||||
typedef void (*finish_render_cb)(void *);
|
||||
typedef void (*poll_input_cb)(void *);
|
||||
typedef int16_t (*get_input_cb)(void *, int, int);
|
||||
|
||||
struct dreamcast_client {
|
||||
void *userdata;
|
||||
push_audio_cb push_audio;
|
||||
start_render_cb start_render;
|
||||
finish_render_cb finish_render;
|
||||
poll_input_cb poll_input;
|
||||
get_input_cb get_input;
|
||||
};
|
||||
|
||||
struct dreamcast {
|
||||
|
@ -180,9 +182,7 @@ struct memory_interface *dc_create_memory_interface(struct dreamcast *dc,
|
|||
address_map_cb mapper);
|
||||
void dc_destroy_memory_interface(struct memory_interface *memory);
|
||||
|
||||
struct window_interface *dc_create_window_interface(
|
||||
device_keydown_cb keydown, device_joy_add_cb joy_add,
|
||||
device_joy_remove_cb joy_remove);
|
||||
struct window_interface *dc_create_window_interface(device_keydown_cb keydown);
|
||||
void dc_destroy_window_interface(struct window_interface *window);
|
||||
|
||||
int dc_init(struct dreamcast *dc);
|
||||
|
@ -194,11 +194,12 @@ 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);
|
||||
|
||||
/* client functionality */
|
||||
void dc_push_audio(struct dreamcast *dc, const int16_t *data, int frames);
|
||||
void dc_start_render(struct dreamcast *dc, struct tile_ctx *ctx);
|
||||
void dc_finish_render(struct dreamcast *dc);
|
||||
void dc_poll_input(struct dreamcast *dc);
|
||||
int16_t dc_get_input(struct dreamcast *dc, int port, int button);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,133 +1,38 @@
|
|||
#include <ini.h>
|
||||
#include "core/log.h"
|
||||
#include "core/option.h"
|
||||
#include "core/string.h"
|
||||
#include "hw/maple/maple.h"
|
||||
|
||||
DEFINE_OPTION_STRING(profile, "profiles/ps4.ini", "Controller profile");
|
||||
|
||||
enum {
|
||||
CONT_C = 0x1,
|
||||
CONT_B = 0x2,
|
||||
CONT_A = 0x4,
|
||||
CONT_START = 0x8,
|
||||
CONT_DPAD_UP = 0x10,
|
||||
CONT_DPAD_DOWN = 0x20,
|
||||
CONT_DPAD_LEFT = 0x40,
|
||||
CONT_DPAD_RIGHT = 0x80,
|
||||
CONT_Z = 0x100,
|
||||
CONT_Y = 0x200,
|
||||
CONT_X = 0x400,
|
||||
CONT_D = 0x800,
|
||||
CONT_DPAD2_UP = 0x1000,
|
||||
CONT_DPAD2_DOWN = 0x2000,
|
||||
CONT_DPAD2_LEFT = 0x4000,
|
||||
CONT_DPAD2_RIGHT = 0x8000,
|
||||
/* only used by internal button map */
|
||||
CONT_JOYX = 0x10000,
|
||||
CONT_JOYY = 0x20000,
|
||||
CONT_LTRIG = 0x40000,
|
||||
CONT_RTRIG = 0x80000
|
||||
};
|
||||
|
||||
struct controller {
|
||||
struct maple_device;
|
||||
struct maple_cond cnd;
|
||||
int map[K_NUM_KEYS];
|
||||
};
|
||||
|
||||
static int controller_ini_handler(void *user, const char *section,
|
||||
const char *name, const char *value) {
|
||||
struct controller *ctrl = user;
|
||||
static void controller_update(struct controller *ctrl) {
|
||||
dc_poll_input(ctrl->dc);
|
||||
|
||||
int button = 0;
|
||||
if (!strcmp(name, "joyx")) {
|
||||
button = CONT_JOYX;
|
||||
} else if (!strcmp(name, "joyy")) {
|
||||
button = CONT_JOYY;
|
||||
} else if (!strcmp(name, "ltrig")) {
|
||||
button = CONT_LTRIG;
|
||||
} else if (!strcmp(name, "rtrig")) {
|
||||
button = CONT_RTRIG;
|
||||
} else if (!strcmp(name, "start")) {
|
||||
button = CONT_START;
|
||||
} else if (!strcmp(name, "a")) {
|
||||
button = CONT_A;
|
||||
} else if (!strcmp(name, "b")) {
|
||||
button = CONT_B;
|
||||
} else if (!strcmp(name, "x")) {
|
||||
button = CONT_X;
|
||||
} else if (!strcmp(name, "y")) {
|
||||
button = CONT_Y;
|
||||
} else if (!strcmp(name, "dpad_up")) {
|
||||
button = CONT_DPAD_UP;
|
||||
} else if (!strcmp(name, "dpad_down")) {
|
||||
button = CONT_DPAD_DOWN;
|
||||
} else if (!strcmp(name, "dpad_left")) {
|
||||
button = CONT_DPAD_LEFT;
|
||||
} else if (!strcmp(name, "dpad_right")) {
|
||||
button = CONT_DPAD_RIGHT;
|
||||
} else {
|
||||
LOG_WARNING("Unknown button %s", name);
|
||||
return 0;
|
||||
}
|
||||
for (int button = 0; button < NUM_CONTROLS; button++) {
|
||||
int button_mask = 1 << button;
|
||||
|
||||
enum keycode key = get_key_by_name(value);
|
||||
if (key == K_UNKNOWN) {
|
||||
LOG_WARNING("Unknown key %s", value);
|
||||
return 0;
|
||||
}
|
||||
/* scale incoming int16_t -> uint8_t */
|
||||
int16_t value = dc_get_input(ctrl->dc, ctrl->port, button);
|
||||
uint8_t scaled = ((int32_t)value - INT16_MIN) >> 8;
|
||||
|
||||
ctrl->map[key] = button;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void controller_load_profile(struct controller *ctrl, const char *path) {
|
||||
if (!*path) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO("Loading controller profile %s", path);
|
||||
|
||||
if (ini_parse(path, controller_ini_handler, ctrl) < 0) {
|
||||
LOG_WARNING("Failed to parse %s", path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int controller_input(struct maple_device *dev, enum keycode key,
|
||||
int16_t value) {
|
||||
struct controller *ctrl = (struct controller *)dev;
|
||||
|
||||
/* map incoming key to dreamcast button */
|
||||
int button = ctrl->map[key];
|
||||
|
||||
/* scale incoming int16_t -> uint8_t */
|
||||
uint8_t scaled = ((int32_t)value - INT16_MIN) >> 8;
|
||||
|
||||
if (!button) {
|
||||
LOG_DEBUG("Unhandled key %s", get_name_by_key(key));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (button <= CONT_DPAD2_RIGHT) {
|
||||
if (value > 0) {
|
||||
ctrl->cnd.buttons &= ~button;
|
||||
} else {
|
||||
ctrl->cnd.buttons |= button;
|
||||
if (button <= CONT_DPAD2_RIGHT) {
|
||||
if (value > 0) {
|
||||
ctrl->cnd.buttons &= ~button_mask;
|
||||
} else {
|
||||
ctrl->cnd.buttons |= button_mask;
|
||||
}
|
||||
} else if (button == CONT_JOYX) {
|
||||
ctrl->cnd.joyx = scaled;
|
||||
} else if (button == CONT_JOYY) {
|
||||
ctrl->cnd.joyy = scaled;
|
||||
} else if (button == CONT_LTRIG) {
|
||||
ctrl->cnd.ltrig = scaled;
|
||||
} else if (button == CONT_RTRIG) {
|
||||
ctrl->cnd.rtrig = scaled;
|
||||
}
|
||||
} else if (button == CONT_JOYX) {
|
||||
ctrl->cnd.joyx = scaled;
|
||||
} else if (button == CONT_JOYY) {
|
||||
ctrl->cnd.joyy = scaled;
|
||||
} else if (button == CONT_LTRIG) {
|
||||
ctrl->cnd.ltrig = scaled;
|
||||
} else if (button == CONT_RTRIG) {
|
||||
ctrl->cnd.rtrig = scaled;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int controller_frame(struct maple_device *dev,
|
||||
|
@ -155,12 +60,15 @@ static int controller_frame(struct maple_device *dev,
|
|||
}
|
||||
return 1;
|
||||
|
||||
case MAPLE_REQ_GETCOND:
|
||||
case MAPLE_REQ_GETCOND: {
|
||||
controller_update(ctrl);
|
||||
|
||||
res->header.command = MAPLE_RES_TRANSFER;
|
||||
res->header.recv_addr = frame->header.send_addr;
|
||||
res->header.send_addr = frame->header.recv_addr;
|
||||
res->header.num_words = sizeof(ctrl->cnd) >> 2;
|
||||
memcpy(res->params, &ctrl->cnd, sizeof(ctrl->cnd));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -172,12 +80,13 @@ static void controller_destroy(struct maple_device *dev) {
|
|||
free(ctrl);
|
||||
}
|
||||
|
||||
struct maple_device *controller_create(int port, int unit) {
|
||||
struct maple_device *controller_create(struct dreamcast *dc, int port,
|
||||
int unit) {
|
||||
struct controller *ctrl = calloc(1, sizeof(struct controller));
|
||||
ctrl->dc = dc;
|
||||
ctrl->port = port;
|
||||
ctrl->unit = unit;
|
||||
ctrl->destroy = &controller_destroy;
|
||||
ctrl->input = &controller_input;
|
||||
ctrl->frame = &controller_frame;
|
||||
|
||||
/* default state */
|
||||
|
@ -186,21 +95,5 @@ struct maple_device *controller_create(int port, int unit) {
|
|||
ctrl->cnd.rtrig = ctrl->cnd.ltrig = 0;
|
||||
ctrl->cnd.joyy = ctrl->cnd.joyx = ctrl->cnd.joyx2 = ctrl->cnd.joyy2 = 0x80;
|
||||
|
||||
/* default profile */
|
||||
ctrl->map[K_SPACE] = CONT_START;
|
||||
ctrl->map['k'] = CONT_A;
|
||||
ctrl->map['l'] = CONT_B;
|
||||
ctrl->map['j'] = CONT_X;
|
||||
ctrl->map['i'] = CONT_Y;
|
||||
ctrl->map['w'] = CONT_DPAD_UP;
|
||||
ctrl->map['s'] = CONT_DPAD_DOWN;
|
||||
ctrl->map['a'] = CONT_DPAD_LEFT;
|
||||
ctrl->map['d'] = CONT_DPAD_RIGHT;
|
||||
ctrl->map['o'] = CONT_LTRIG;
|
||||
ctrl->map['p'] = CONT_RTRIG;
|
||||
|
||||
/* load profile */
|
||||
controller_load_profile(ctrl, OPTION_profile);
|
||||
|
||||
return (struct maple_device *)ctrl;
|
||||
}
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
#include "hw/holly/holly.h"
|
||||
#include "hw/sh4/sh4.h"
|
||||
|
||||
#define MAPLE_NUM_PORTS 4
|
||||
#define MAPLE_MAX_UNITS 6
|
||||
|
||||
struct maple {
|
||||
struct device;
|
||||
struct maple_device *devices[MAPLE_NUM_PORTS][MAPLE_MAX_UNITS];
|
||||
|
@ -27,64 +24,21 @@ static void maple_unregister_device(struct maple *mp, int port, int unit) {
|
|||
|
||||
static void maple_register_device(struct maple *mp, const char *device_type,
|
||||
int port, int unit) {
|
||||
struct dreamcast *dc = mp->dc;
|
||||
|
||||
CHECK(!mp->devices[port][unit],
|
||||
"Device already registered for port %d, unit %d", port, unit);
|
||||
struct maple_device **dev = &mp->devices[port][unit];
|
||||
|
||||
if (!strcmp(device_type, "controller")) {
|
||||
*dev = controller_create(port, unit);
|
||||
*dev = controller_create(dc, port, unit);
|
||||
} else if (!strcmp(device_type, "vmu")) {
|
||||
*dev = vmu_create(port, unit);
|
||||
*dev = vmu_create(dc, port, unit);
|
||||
} else {
|
||||
LOG_WARNING("Unsupported device type: %s", 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) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct maple *mp = (struct maple *)d;
|
||||
|
||||
for (int i = 0; i < MAPLE_MAX_UNITS; i++) {
|
||||
struct maple_device *dev = mp->devices[device_index][i];
|
||||
|
||||
if (dev && dev->input) {
|
||||
dev->input(dev, key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* on each maple port, there are up to 6 addressable units. there is one main
|
||||
unit (controller, keyboard, etc.) that can have up to 5 sub-units connected
|
||||
to it (vmu, microphone, etc.). each maple frame header contains an 8-bit
|
||||
|
@ -168,19 +122,18 @@ void maple_destroy(struct maple *mp) {
|
|||
}
|
||||
}
|
||||
|
||||
dc_destroy_window_interface(mp->window_if);
|
||||
dc_destroy_device((struct device *)mp);
|
||||
}
|
||||
|
||||
struct maple *maple_create(struct dreamcast *dc) {
|
||||
struct maple *mp =
|
||||
dc_create_device(dc, sizeof(struct maple), "maple", &maple_init, NULL);
|
||||
mp->window_if = dc_create_window_interface(&maple_keydown, &maple_joy_add,
|
||||
&maple_joy_remove);
|
||||
|
||||
/* add one controller and vmu by default */
|
||||
maple_register_device(mp, "controller", 0, 0);
|
||||
maple_register_device(mp, "vmu", 0, 1);
|
||||
/* register a controller and vmu for all ports by default */
|
||||
for (int i = 0; i < MAPLE_NUM_PORTS; i++) {
|
||||
maple_register_device(mp, "controller", i, 0);
|
||||
maple_register_device(mp, "vmu", i, 1);
|
||||
}
|
||||
|
||||
return mp;
|
||||
}
|
||||
|
|
|
@ -3,17 +3,16 @@
|
|||
|
||||
#include "hw/dreamcast.h"
|
||||
#include "hw/maple/maple_types.h"
|
||||
#include "ui/keycode.h"
|
||||
|
||||
struct dreamcast;
|
||||
struct maple;
|
||||
struct maple_device;
|
||||
|
||||
struct maple_device {
|
||||
struct dreamcast *dc;
|
||||
int port;
|
||||
int unit;
|
||||
void (*destroy)(struct maple_device *);
|
||||
int (*input)(struct maple_device *, enum keycode, int16_t);
|
||||
int (*frame)(struct maple_device *, const struct maple_frame *,
|
||||
struct maple_frame *);
|
||||
};
|
||||
|
@ -24,7 +23,8 @@ void maple_destroy(struct maple *mp);
|
|||
int maple_handle_command(struct maple *mp, struct maple_frame *frame,
|
||||
struct maple_frame *res);
|
||||
|
||||
struct maple_device *controller_create(int port, int unit);
|
||||
struct maple_device *vmu_create(int port, int unit);
|
||||
struct maple_device *controller_create(struct dreamcast *dc, int port,
|
||||
int unit);
|
||||
struct maple_device *vmu_create(struct dreamcast *dc, int port, int unit);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#ifndef MAPLE_TYPES_H
|
||||
#define MAPLE_TYPES_H
|
||||
|
||||
#define MAPLE_NUM_PORTS 4
|
||||
#define MAPLE_MAX_UNITS 6
|
||||
|
||||
/* maple pattern codes. indicate how to process the incoming instruction */
|
||||
enum maple_pattern {
|
||||
MAPLE_PATTERN_NORMAL = 0x0,
|
||||
|
@ -133,4 +136,30 @@ struct maple_blockread {
|
|||
uint32_t data[];
|
||||
};
|
||||
|
||||
/* controller buttons */
|
||||
enum {
|
||||
CONT_C,
|
||||
CONT_B,
|
||||
CONT_A,
|
||||
CONT_START,
|
||||
CONT_DPAD_UP,
|
||||
CONT_DPAD_DOWN,
|
||||
CONT_DPAD_LEFT,
|
||||
CONT_DPAD_RIGHT,
|
||||
CONT_Z,
|
||||
CONT_Y,
|
||||
CONT_X,
|
||||
CONT_D,
|
||||
CONT_DPAD2_UP,
|
||||
CONT_DPAD2_DOWN,
|
||||
CONT_DPAD2_LEFT,
|
||||
CONT_DPAD2_RIGHT,
|
||||
/* only used by internal button map */
|
||||
CONT_JOYX,
|
||||
CONT_JOYY,
|
||||
CONT_LTRIG,
|
||||
CONT_RTRIG,
|
||||
NUM_CONTROLS,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -184,8 +184,9 @@ static void vmu_destroy(struct maple_device *dev) {
|
|||
free(vmu);
|
||||
}
|
||||
|
||||
struct maple_device *vmu_create(int port, int unit) {
|
||||
struct maple_device *vmu_create(struct dreamcast *dc, int port, int unit) {
|
||||
struct vmu *vmu = calloc(1, sizeof(struct vmu));
|
||||
vmu->dc = dc;
|
||||
vmu->port = port;
|
||||
vmu->unit = unit;
|
||||
vmu->destroy = &vmu_destroy;
|
||||
|
|
|
@ -854,7 +854,7 @@ struct tracer *tracer_create(struct window *win) {
|
|||
|
||||
/* add window input listeners */
|
||||
tracer->listener = (struct window_listener){
|
||||
tracer, NULL, NULL, &tracer_keydown, NULL, &tracer_close, {0}};
|
||||
tracer, &tracer_keydown, NULL, &tracer_close, {0}};
|
||||
win_add_listener(tracer->win, &tracer->listener);
|
||||
|
||||
/* setup render backend */
|
||||
|
|
|
@ -275,7 +275,7 @@ struct microprofile *mp_create(struct window *win, struct render_backend *r) {
|
|||
mp->r = r;
|
||||
|
||||
/* add input event listeners */
|
||||
mp->listener = {mp, NULL, NULL, &mp_keydown, &mp_mousemove, NULL, {}};
|
||||
mp->listener = {mp, &mp_keydown, &mp_mousemove, NULL, {}};
|
||||
win_add_listener(mp->win, &mp->listener);
|
||||
|
||||
/* register and enable cpu and gpu groups by default */
|
||||
|
|
|
@ -151,8 +151,8 @@ struct nuklear *nk_create(struct window *win, struct render_backend *r) {
|
|||
nk->r = r;
|
||||
|
||||
/* add input event listeners */
|
||||
nk->listener = (struct window_listener){
|
||||
nk, NULL, NULL, &nk_keydown, &nk_mousemove, NULL, {0}};
|
||||
nk->listener =
|
||||
(struct window_listener){nk, &nk_keydown, &nk_mousemove, NULL, {0}};
|
||||
win_add_listener(nk->win, &nk->listener);
|
||||
|
||||
/* create default font texture */
|
||||
|
|
|
@ -12,8 +12,6 @@ typedef void *glcontext_t;
|
|||
|
||||
struct window_listener {
|
||||
void *data;
|
||||
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 (*mousemove)(void *data, int x, int y);
|
||||
|
|
|
@ -45,13 +45,6 @@ static void win_destroy_joystick(struct window *win, SDL_Joystick *del) {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
@ -75,13 +68,6 @@ static void win_create_joystick(struct window *win, int joystick_index) {
|
|||
/* 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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue