Skip to content

Commit

Permalink
[SEGAIO] Rework mouse support
Browse files Browse the repository at this point in the history
  • Loading branch information
darthcloud committed Mar 19, 2021
1 parent 849cf71 commit 73fa186
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 96 deletions.
53 changes: 16 additions & 37 deletions main/adapter/genesis.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ struct sega_mouse_map {
uint8_t twh_buttons;
uint8_t flags;
};
uint8_t axes[2];
uint8_t align[1];
uint8_t relative[2];
int32_t raw_axes[2];
} __packed;

static const uint32_t sega_mouse_mask[4] = {0x190100F0, 0x00000000, 0x00000000, 0x00000000};
Expand Down Expand Up @@ -200,6 +202,7 @@ static const uint32_t genesis_twh_btns_mask[32] = {

static void sega_mouse_from_generic(struct generic_ctrl *ctrl_data, struct wired_data *wired_data) {
struct sega_mouse_map map_tmp;
int32_t *raw_axes = (int32_t *)(wired_data->output + 28);

memcpy((void *)&map_tmp, wired_data->output, sizeof(map_tmp));

Expand All @@ -214,46 +217,20 @@ static void sega_mouse_from_generic(struct generic_ctrl *ctrl_data, struct wired
}
}

for (uint32_t i = 0; i < ADAPTER_MAX_AXES; i++) {
for (uint32_t i = 2; i < 4; i++) {
if (ctrl_data->map_mask[0] & (axis_to_btn_mask(i) & sega_mouse_desc[0])) {
uint8_t sign_mask;
int32_t tmp_val;

if (i & 0x01) {
sign_mask = 0x20;
}
else {
sign_mask = 0x10;
}

if (map_tmp.flags & sign_mask) {
tmp_val = ctrl_data->axes[i].value + (int32_t)(map_tmp.axes[sega_mouse_axes_idx[i]] | 0xFFFFFFF0);
}
else {
tmp_val = ctrl_data->axes[i].value + (int32_t)(map_tmp.axes[sega_mouse_axes_idx[i]]);
}

if (tmp_val > ctrl_data->axes[i].meta->size_max) {
map_tmp.axes[sega_mouse_axes_idx[i]] = 0xFF;
map_tmp.flags &= ~sign_mask;
}
else if (tmp_val < ctrl_data->axes[i].meta->size_min) {
map_tmp.axes[sega_mouse_axes_idx[i]] = 0x00;
map_tmp.flags |= sign_mask;
if (ctrl_data->axes[i].relative) {
map_tmp.relative[sega_mouse_axes_idx[i]] = 1;
atomic_add(&raw_axes[sega_mouse_axes_idx[i]], ctrl_data->axes[i].value);
}
else {
map_tmp.axes[sega_mouse_axes_idx[i]] = (uint8_t)tmp_val;
if (tmp_val < 0) {
map_tmp.flags |= sign_mask;
}
else {
map_tmp.flags &= ~sign_mask;
}
map_tmp.relative[sega_mouse_axes_idx[i]] = 0;
raw_axes[sega_mouse_axes_idx[i]] = ctrl_data->axes[i].value;
}
}
}

memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp));
memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp) - 8);
}

static void genesis_std_from_generic(struct generic_ctrl *ctrl_data, struct wired_data *wired_data) {
Expand Down Expand Up @@ -405,9 +382,11 @@ void IRAM_ATTR genesis_init_buffer(int32_t dev_mode, struct wired_data *wired_da

if (dev_mode == DEV_MOUSE) {
struct sega_mouse_map *map = (struct sega_mouse_map *)wired_data->output;
map->flags = 0x00;
map->axes[0] = 0x00;
map->axes[1] = 0x00;
map->twh_buttons = 0x00;
for (uint32_t i = 0; i < 2; i++) {
map->raw_axes[i] = 0;
map->relative[i] = 1;
}
}
else {
struct genesis_map *map = (struct genesis_map *)wired_data->output;
Expand Down
53 changes: 18 additions & 35 deletions main/adapter/saturn.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ struct sega_mouse_map {
uint8_t buttons;
uint8_t flags;
};
uint8_t axes[2];
uint8_t align[1];
uint8_t relative[2];
int32_t raw_axes[2];
} __packed;

static const uint32_t saturn_mask[4] = {0xBB1F0F0F, 0x00000000, 0x00000000, 0x00000000};
Expand Down Expand Up @@ -155,7 +157,13 @@ void IRAM_ATTR saturn_init_buffer(int32_t dev_mode, struct wired_data *wired_dat
}
case DEV_MOUSE:
{
memset(wired_data->output, 0 , 3);
struct sega_mouse_map *map = (struct sega_mouse_map *)wired_data->output;

map->buttons = 0x00;
for (uint32_t i = 0; i < 2; i++) {
map->raw_axes[i] = 0;
map->relative[i] = 1;
}
break;
}
default:
Expand Down Expand Up @@ -239,6 +247,7 @@ void saturn_ctrl_from_generic(struct generic_ctrl *ctrl_data, struct wired_data

static void saturn_mouse_from_generic(struct generic_ctrl *ctrl_data, struct wired_data *wired_data) {
struct sega_mouse_map map_tmp;
int32_t *raw_axes = (int32_t *)(wired_data->output + 4);

memcpy((void *)&map_tmp, wired_data->output, sizeof(map_tmp));

Expand All @@ -253,46 +262,20 @@ static void saturn_mouse_from_generic(struct generic_ctrl *ctrl_data, struct wir
}
}

for (uint32_t i = 0; i < ADAPTER_MAX_AXES; i++) {
for (uint32_t i = 2; i < 4; i++) {
if (ctrl_data->map_mask[0] & (axis_to_btn_mask(i) & sega_mouse_desc[0])) {
uint8_t sign_mask;
int32_t tmp_val;

if (i & 0x01) {
sign_mask = 0x20;
}
else {
sign_mask = 0x10;
}

if (map_tmp.flags & sign_mask) {
tmp_val = ctrl_data->axes[i].value + (int32_t)(map_tmp.axes[sega_mouse_axes_idx[i]] | 0xFFFFFFF0);
if (ctrl_data->axes[i].relative) {
map_tmp.relative[sega_mouse_axes_idx[i]] = 1;
atomic_add(&raw_axes[sega_mouse_axes_idx[i]], ctrl_data->axes[i].value);
}
else {
tmp_val = ctrl_data->axes[i].value + (int32_t)(map_tmp.axes[sega_mouse_axes_idx[i]]);
}

if (tmp_val > ctrl_data->axes[i].meta->size_max) {
map_tmp.axes[sega_mouse_axes_idx[i]] = 0xFF;
map_tmp.flags &= ~sign_mask;
}
else if (tmp_val < ctrl_data->axes[i].meta->size_min) {
map_tmp.axes[sega_mouse_axes_idx[i]] = 0x00;
map_tmp.flags |= sign_mask;
}
else {
map_tmp.axes[sega_mouse_axes_idx[i]] = (uint8_t)tmp_val;
if (tmp_val < 0) {
map_tmp.flags |= sign_mask;
}
else {
map_tmp.flags &= ~sign_mask;
}
map_tmp.relative[sega_mouse_axes_idx[i]] = 0;
raw_axes[sega_mouse_axes_idx[i]] = ctrl_data->axes[i].value;
}
}
}

memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp));
memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp) - 8);
}

static void saturn_kb_from_generic(struct generic_ctrl *ctrl_data, struct wired_data *wired_data) {
Expand Down
93 changes: 69 additions & 24 deletions main/wired/sega_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,56 @@ static uint8_t buffer[6*6];
static uint32_t *map1 = (uint32_t *)wired_adapter.data[0].output;
static uint32_t *map2 = (uint32_t *)wired_adapter.data[1].output;

static inline void load_mouse_axes(uint8_t port, uint8_t *flags, uint8_t *axes) {
uint8_t *relative = NULL;
int32_t *raw_axes = NULL;
int32_t val = 0;
uint8_t sign_mask = 0;

if (wired_adapter.system_id == GENESIS) {
relative = (uint8_t *)(wired_adapter.data[port].output + 26);
raw_axes = (int32_t *)(wired_adapter.data[port].output + 28);
}
else {
relative = (uint8_t *)(wired_adapter.data[port].output + 2);
raw_axes = (int32_t *)(wired_adapter.data[port].output + 4);
}

for (uint32_t i = 0; i < 2; i++) {
if (i & 0x01) {
sign_mask = 0x20;
}
else {
sign_mask = 0x10;
}

if (relative[i]) {
val = atomic_clear(&raw_axes[i]);
}
else {
val = raw_axes[i];
}

if (val > 255) {
axes[i] = 0xFF;
*flags &= ~sign_mask;
}
else if (val < -256) {
axes[i] = 0x00;
*flags |= sign_mask;
}
else {
axes[i] = (uint8_t)val;
if (val < 0) {
*flags |= sign_mask;
}
else {
*flags &= ~sign_mask;
}
}
}
}

static void tx_nibble(uint8_t port, uint8_t data) {
for (uint8_t i = SIO_R, mask = 0x8; mask; mask >>= 1, i++) {
if (data & mask) {
Expand Down Expand Up @@ -242,16 +292,12 @@ static void set_analog_pad(uint8_t port, uint8_t src_port) {
static void set_sega_mouse(uint8_t port, uint8_t src_port) {
buffer[0] = 0xFF;
if (wired_adapter.system_id == GENESIS) {
memcpy(&buffer[1], &wired_adapter.data[src_port].output[24], 3);
wired_adapter.data[src_port].output[24] &= 0x0F;
wired_adapter.data[src_port].output[25] = 0x00;
wired_adapter.data[src_port].output[26] = 0x00;
memcpy(&buffer[1], &wired_adapter.data[src_port].output[24], 1);
load_mouse_axes(port, &buffer[1], &buffer[2]);
}
else {
memcpy(&buffer[1], wired_adapter.data[src_port].output, 3);
wired_adapter.data[src_port].output[0] &= 0x0F;
wired_adapter.data[src_port].output[1] = 0x00;
wired_adapter.data[src_port].output[2] = 0x00;
memcpy(&buffer[1], wired_adapter.data[src_port].output, 1);
load_mouse_axes(port, &buffer[1], &buffer[2]);
}
buffer[4] = ID0_MOUSE >> 4;

Expand Down Expand Up @@ -304,10 +350,8 @@ static void set_saturn_multitap(uint8_t port, uint8_t first_port, uint8_t nb_por
break;
case DEV_SEGA_MOUSE:
*data++ = (ID2_LEGACY << 4) | 3;
memcpy(data, wired_adapter.data[j].output, 3);
wired_adapter.data[j].output[0] &= 0x0F;
wired_adapter.data[j].output[1] = 0x00;
wired_adapter.data[j].output[2] = 0x00;
memcpy(data, wired_adapter.data[j].output, 1);
load_mouse_axes(j, data, &data[1]);
data += 3;
break;
}
Expand Down Expand Up @@ -353,21 +397,22 @@ static void set_gen_multitap(uint8_t port, uint8_t first_port, uint8_t nb_port)
break;
case DEV_SEGA_MOUSE:
if (odd) {
*data++ &= (wired_adapter.data[j].output[24] >> 4) | 0xF0;
*data = (wired_adapter.data[j].output[24] << 4) | 0xF;
*data++ &= (wired_adapter.data[j].output[25] >> 4) | 0xF0;
*data = (wired_adapter.data[j].output[25] << 4) | 0xF;
*data++ &= (wired_adapter.data[j].output[26] >> 4) | 0xF0;
*data = (wired_adapter.data[j].output[26] << 4) | 0xF;
uint8_t tmp[3] = {0};
tmp[0] = wired_adapter.data[j].output[24];
load_mouse_axes(j, &tmp[0], &tmp[1]);

*data++ &= (tmp[0] >> 4) | 0xF0;
*data = (tmp[0] << 4) | 0xF;
*data++ &= (tmp[1] >> 4) | 0xF0;
*data = (tmp[1] << 4) | 0xF;
*data++ &= (tmp[2] >> 4) | 0xF0;
*data = (tmp[2] << 4) | 0xF;
}
else {
*data++ = wired_adapter.data[j].output[24];
*data++ = wired_adapter.data[j].output[25];
*data++ = wired_adapter.data[j].output[26];
*data = wired_adapter.data[j].output[24];
load_mouse_axes(j, data, &data[1]);
data += 3;
}
wired_adapter.data[j].output[24] &= 0x0F;
wired_adapter.data[j].output[25] = 0x00;
wired_adapter.data[j].output[26] = 0x00;
break;
}
}
Expand Down

0 comments on commit 73fa186

Please sign in to comment.