pbus: fix orbatak silly pad to 24-bit and split trackball/buttons

This commit is contained in:
Antonio SJ Musumeci authored and trapexit committed 2026-07-09 23:07:20 -05:00
1 parent 340f9e9014
commit 80d871b4bd
4 files changed
+77 -35

No files matched your search

+13 -7
View File
@@ -283,7 +283,7 @@ opera_pbus_add_arcade_lightgun(const opera_pbus_arcade_lightgun_t *lg_)
void
opera_pbus_add_orbatak_trackball(const opera_pbus_orbatak_trackball_t *tb_)
{
if(!pbus_reserve(8))
if(!pbus_reserve(4))
return;
PBUS.buf[PBUS.idx++] = PBUS_ORBATAK_TRACKBALL_ID;
@@ -291,15 +291,21 @@ opera_pbus_add_orbatak_trackball(const opera_pbus_orbatak_trackball_t *tb_)
PBUS.buf[PBUS.idx++] = (((tb_->y & 0x03F) << 2) |
((tb_->x & 0x300) >> 8));
PBUS.buf[PBUS.idx++] = (tb_->x & 0xFF);
}
void
opera_pbus_add_orbatak_buttons(const opera_pbus_orbatak_buttons_t *btn_)
{
if(!pbus_reserve(3))
return;
PBUS.buf[PBUS.idx++] = PBUS_ORBATAK_BUTTONS_ID;
PBUS.buf[PBUS.idx++] = 0;
PBUS.buf[PBUS.idx++] = ((tb_->coin_p1 << PBUS_ORBATAK_SHIFT_COIN_P1) |
(tb_->coin_p2 << PBUS_ORBATAK_SHIFT_COIN_P2) |
(tb_->start_p1 << PBUS_ORBATAK_SHIFT_START_P1) |
(tb_->start_p2 << PBUS_ORBATAK_SHIFT_START_P2) |
(tb_->service << PBUS_ORBATAK_SHIFT_SERVICE));
PBUS.buf[PBUS.idx++] = 0;
PBUS.buf[PBUS.idx++] = ((btn_->coin_p1 << PBUS_ORBATAK_SHIFT_COIN_P1) |
(btn_->coin_p2 << PBUS_ORBATAK_SHIFT_COIN_P2) |
(btn_->start_p1 << PBUS_ORBATAK_SHIFT_START_P1) |
(btn_->start_p2 << PBUS_ORBATAK_SHIFT_START_P2) |
(btn_->service << PBUS_ORBATAK_SHIFT_SERVICE));
}
void*
+8 -3
View File
@@ -72,15 +72,18 @@ struct opera_pbus_arcade_lightgun_s
};
struct opera_pbus_orbatak_trackball_s
{
int16_t x;
int16_t y;
};
struct opera_pbus_orbatak_buttons_s
{
uint8_t start_p1;
uint8_t start_p2;
uint8_t coin_p1;
uint8_t coin_p2;
uint8_t service;
int16_t x;
int16_t y;
};
typedef struct opera_pbus_joypad_s opera_pbus_joypad_t;
@@ -89,6 +92,7 @@ typedef struct opera_pbus_mouse_s opera_pbus_mouse_t;
typedef struct opera_pbus_lightgun_s opera_pbus_lightgun_t;
typedef struct opera_pbus_arcade_lightgun_s opera_pbus_arcade_lightgun_t;
typedef struct opera_pbus_orbatak_trackball_s opera_pbus_orbatak_trackball_t;
typedef struct opera_pbus_orbatak_buttons_s opera_pbus_orbatak_buttons_t;
void* opera_pbus_buf(void);
uint32_t opera_pbus_size(void);
@@ -100,5 +104,6 @@ void opera_pbus_add_mouse(const opera_pbus_mouse_t *mouse_);
void opera_pbus_add_lightgun(const opera_pbus_lightgun_t *lightgun_);
void opera_pbus_add_arcade_lightgun(const opera_pbus_arcade_lightgun_t *lightgun_);
void opera_pbus_add_orbatak_trackball(const opera_pbus_orbatak_trackball_t *tb_);
void opera_pbus_add_orbatak_buttons(const opera_pbus_orbatak_buttons_t *btn_);
#endif /* LIBOPERA_PBUS_H_INCLUDED */
+23 -13
View File
@@ -169,21 +169,31 @@ y = ((10 * counter) / NTSC_DEFAULT_YSCANTIME);
### ORBATAK TRACKBALL
Orbatak uses two different devices. The trackballs are just mice as
described above. The buttons (coins, start, service) are managed via
the "SILLY_CONTROL_PAD" as defined in the 3DO SDK (event.h) or in the
least uses the same identifier.
Orbatak uses two different devices per player. The trackballs are just
mice as described above. The buttons (coins, start, service) use the
SILLY_CONTROL_PAD (0xC0) identifier as defined in the 3DO SDK (event.h).
The Portfolio OS EventBroker parses 0xC0 as a 24-bit (3 byte) device
(EventBroker.c: inBits=24, outBits=8).
The standard SILLY_CONTROL_PAD format (3 bytes, 24 bits):
MSB -> LSB
8bit: identifier (0xC0)
8bit: 0x00
3bit: unused
1bit: coin (p1)
1bit: coin (p2)
1bit: start (p2)
1bit: start (p1)
1bit: service
8bit: 0x00
* 8bit: identifier (0xC0) in bits 7-5, standard control pad buttons
(down, up, right, left, A) in bits 4-0
* 8bit: standard control pad buttons (B, C, Start, X, RT, LT) in
bits 7-2, unused in bits 1-0
* 8bit: unused by the standard driver, available for custom devices
Orbatak maps its arcade buttons in byte 2 (the third byte):
MSB -> LSB
2bit: unused (bits 7,6)
1bit: coin (p1) (bit 5)
1bit: coin (p2) (bit 4)
1bit: unused (bit 3)
1bit: start (p2) (bit 2)
1bit: start (p1) (bit 1)
1bit: service (bit 0)
## Device Usage In Games
+33 -12
View File
@@ -7,6 +7,8 @@
#include <libretro.h>
#include <string.h>
static uint32_t ACTIVE_DEVICES = 0;
static unsigned PBUS_DEVICES[LR_INPUT_MAX_DEVICES] = {0};
@@ -149,7 +151,7 @@ lr_input_poll_lightgun(const int port_)
lg.trigger = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_TRIGGER);
lg.option = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_SELECT);
lg.reload = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_RELOAD);
if(poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN))
{
lg.trigger = 0;
@@ -174,7 +176,7 @@ lr_input_poll_arcade_lightgun(const int port_)
lg.coins = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_SELECT);
lg.start = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_START);
lg.holster = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_RELOAD);
if(poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN))
{
lg.trigger = 0;
@@ -210,15 +212,21 @@ lr_input_poll_orbatak_trackball(const int port_)
tb.y = 24;
}
tb.start_p1 = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_SELECT);
tb.start_p2 = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_START);
tb.coin_p1 = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_L);
tb.coin_p2 = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_R);
tb.service = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_R2);
opera_pbus_add_orbatak_trackball(&tb);
}
static
void
lr_input_poll_orbatak_buttons(const int port_,
opera_pbus_orbatak_buttons_t *btn_)
{
btn_->start_p1 |= poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_SELECT);
btn_->start_p2 |= poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_START);
btn_->coin_p1 |= poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_L);
btn_->coin_p2 |= poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_R);
btn_->service |= poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_R2);
}
static
void
lr_input_poll(const int port_)
@@ -243,9 +251,6 @@ lr_input_poll(const int port_)
case RETRO_DEVICE_ARCADE_LIGHTGUN:
lr_input_poll_arcade_lightgun(port_);
break;
case RETRO_DEVICE_ORBATAK_TRACKBALL:
lr_input_poll_orbatak_trackball(port_);
break;
}
}
@@ -293,6 +298,11 @@ lr_input_update(const uint32_t active_devices_)
{
int i;
uint32_t active_devices;
int has_orbatak;
opera_pbus_orbatak_buttons_t orbatak_buttons;
has_orbatak = 0;
memset(&orbatak_buttons,0,sizeof(orbatak_buttons));
opera_pbus_reset();
retro_input_poll_cb();
@@ -302,6 +312,17 @@ lr_input_update(const uint32_t active_devices_)
{
if(PBUS_DEVICES[i] == RETRO_DEVICE_NONE)
continue;
lr_input_poll(i);
if(PBUS_DEVICES[i] == RETRO_DEVICE_ORBATAK_TRACKBALL)
{
lr_input_poll_orbatak_trackball(i);
lr_input_poll_orbatak_buttons(i,&orbatak_buttons);
has_orbatak = 1;
}
else
lr_input_poll(i);
}
if(has_orbatak)
opera_pbus_add_orbatak_buttons(&orbatak_buttons);
}