Skip to content

Commit

Permalink
Add OGX360 support from netham45
Browse files Browse the repository at this point in the history
  • Loading branch information
Jack Rayner committed Jan 9, 2024
1 parent f37d552 commit 4425812
Show file tree
Hide file tree
Showing 17 changed files with 358 additions and 5 deletions.
2 changes: 2 additions & 0 deletions configs/hw1/ogx360
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CONFIG_BLUERETRO_HW2=n
CONFIG_BLUERETRO_SYSTEM_OGX360=y
1 change: 1 addition & 0 deletions configs/hw2/ogx360
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONFIG_BLUERETRO_SYSTEM_OGX360=y
2 changes: 2 additions & 0 deletions main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ idf_component_register(SRCS "main.c"
"adapter/wired/parallel_1p.c"
"adapter/wired/parallel_2p.c"
"adapter/wired/wired.c"
"adapter/wired/ogx360.c"
"adapter/wireless/hid_generic.c"
"adapter/wireless/ps3.c"
"adapter/wireless/wii.c"
Expand Down Expand Up @@ -80,6 +81,7 @@ idf_component_register(SRCS "main.c"
"wired/jag_io.c"
"wired/sea_io.c"
"wired/wii_i2c.c"
"wired/ogx360_i2c.c"
"zephyr/atomic.S"
PRIV_INCLUDE_DIRS "."
LDFRAGMENTS linker.lf)
Expand Down
5 changes: 5 additions & 0 deletions main/Kconfig.projbuild
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ menu "BlueRetro"
help
Select this to support only SEA Board.

config BLUERETRO_SYSTEM_OGX360
bool "OGX360"
help
Select this to support only OGX360.

endchoice

menu "Debug"
Expand Down
3 changes: 3 additions & 0 deletions main/adapter/adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ enum {
PARALLEL_1P_OD,
PARALLEL_2P_OD,
SEA_BOARD,
OGX360,
WIRED_MAX,
};

Expand Down Expand Up @@ -453,6 +454,8 @@ struct generic_fb {
uint32_t start;
};
};
uint32_t left_motor;
uint32_t right_motor;
};

struct raw_fb_header {
Expand Down
215 changes: 215 additions & 0 deletions main/adapter/wired/ogx360.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
#include "ogx360.h"
#include <string.h>
#include "bluetooth/host.h"
#include "adapter/wireless/wireless.h"
#include "wired/ogx360_i2c.h" // Hack
#include <esp32/rom/ets_sys.h>

#define BIT(x) (1<<x)

#define BUTTON_MASK_SIZE 32
#define BUTTON_MASK_SIZE 32
#define NUM_DIGITAL_BUTTONS 8
#define NUM_ANALOG_BUTTONS 6
#define NUM_8BIT_AXIS 2
#define NUM_16BIT_AXIS 4

enum { // Digital buttons
OGX360_D_UP,
OGX360_D_DOWN,
OGX360_D_LEFT,
OGX360_D_RIGHT,
OGX360_START,
OGX360_BACK,
OGX360_LSTICK,
OGX360_RSTICK
};

enum { // Analog buttons
OGX360_A,
OGX360_B,
OGX360_X,
OGX360_Y,
OGX360_BLACK,
OGX360_WHITE,
};

static DRAM_ATTR const int ogx360_digital_btns_mask[BUTTON_MASK_SIZE] = {
-1, -1, -1, -1,
-1, -1, -1, -1,
OGX360_D_LEFT, OGX360_D_RIGHT, OGX360_D_DOWN, OGX360_D_UP,
-1, -1, -1, -1,
-1, -1, -1, -1,
OGX360_START, OGX360_BACK, -1, -1,
-1, -1, -1, OGX360_LSTICK,
-1, -1, -1, OGX360_RSTICK
};

static DRAM_ATTR const int ogx360_analog_btns_mask[BUTTON_MASK_SIZE] = {
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
OGX360_X, OGX360_B, OGX360_A, OGX360_Y,
-1, -1, -1, -1,
-1, OGX360_BLACK, -1, -1,
-1, OGX360_WHITE, -1, -1,
};

static DRAM_ATTR const struct ctrl_meta ogx360_axes_meta[ADAPTER_MAX_AXES] =
{
{.size_min = -32768, .size_max = 32767, .neutral = 0x00, .abs_max = 32767},
{.size_min = -32768, .size_max = 32767, .neutral = 0x00, .abs_max = 32767},
{.size_min = -32768, .size_max = 32767, .neutral = 0x00, .abs_max = 32767},
{.size_min = -32768, .size_max = 32767, .neutral = 0x00, .abs_max = 32767},
{.size_min = 0, .size_max = 255, .neutral = 0x00, .abs_max = 255},
{.size_min = 0, .size_max = 255, .neutral = 0x00, .abs_max = 255},
};

static const uint32_t ogx360_mask[4] = {0xBBFF0FFF, 0x00000000, 0x00000000, 0x00000000};
static const uint32_t ogx360_desc[4] = {0x110000FF, 0x00000000, 0x00000000, 0x00000000};

typedef struct __attribute__((packed)) usbd_duke_out
{
uint8_t controllerType; // 0xF1
uint8_t startByte; // 0x00
uint8_t bLength; // 0x06
uint16_t wButtons;
uint8_t analogButtons[NUM_ANALOG_BUTTONS];
uint8_t axis8[NUM_8BIT_AXIS];
uint16_t axis16[NUM_16BIT_AXIS];
} usbd_duke_out_t;

typedef struct __attribute__((packed)) usbd_duke_in
{
uint8_t startByte; // 0x00
uint8_t bLength; // 0x06
uint16_t lValue; // Left Rumble
uint16_t hValue; // Right Rumble
} usbd_duke_in_t;

void ogx360_acc_toggle_fb(uint32_t wired_id, uint16_t left_motor, uint16_t right_motor);


void ogx360_meta_init(struct generic_ctrl *ctrl_data) {
memset((void *)ctrl_data, 0, sizeof(*ctrl_data)*4);

for (uint32_t i = 0; i < WIRED_MAX_DEV; i++) {
for (uint32_t j = 0; j < ADAPTER_MAX_AXES; j++) {
switch (config.out_cfg[i].dev_mode) {
case DEV_PAD_ALT:
ctrl_data[i].mask = ogx360_mask;
ctrl_data[i].desc = ogx360_desc;
ctrl_data[i].axes[j].meta = &ogx360_axes_meta[j];
break;
default:
ctrl_data[i].mask = ogx360_mask;
ctrl_data[i].desc = ogx360_desc;
ctrl_data[i].axes[j].meta = &ogx360_axes_meta[j];
break;
}
}
}
}


void ogx360_from_generic(int32_t dev_mode, struct generic_ctrl *ctrl_data, struct wired_data *wired_data) {
struct usbd_duke_out *duke_out = (struct usbd_duke_out*) wired_data->output;
struct usbd_duke_in *duke_in = (struct usbd_duke_in*) wired_data->output;

//Start Rumble
struct bt_data *bt_data = &bt_adapter.data[wired_data->index];
if ( bt_data->pids->type == BT_XBOX) // Rumble is hanging PS4 controllers, untested on the rest.
{
if (duke_in->startByte == 0x00 && duke_in->bLength == 6)
{
ogx360_acc_toggle_fb(wired_data->index, duke_in->lValue, duke_in->hValue);
}
else
{
ogx360_acc_toggle_fb(wired_data->index, 0, 0);
}
}

//Start output
duke_out->controllerType = 0xF1;
duke_out->startByte = 0;
duke_out->bLength = ( sizeof(struct usbd_duke_out) + 3 ) / 4; //Number of 4-byte blocks sent to Xbox

duke_out->wButtons = 0; // Digital buttons
for (int i=0;i<BUTTON_MASK_SIZE;i++)
{
if (ogx360_digital_btns_mask[i] != -1)
{
if ((ctrl_data->btns[0].value & BIT(i)) != 0)
{
duke_out->wButtons |= BIT(ogx360_digital_btns_mask[i]);
}
}
}

for (int i=0;i<BUTTON_MASK_SIZE;i++) // Analog buttons
{
if (ogx360_analog_btns_mask[i] != -1)
{
bool pressed = (ctrl_data->btns[0].value & BIT(i)) > 0;
if (pressed)
{
duke_out->analogButtons[ogx360_analog_btns_mask[i]] = 0xFF;
}
else
{
duke_out->analogButtons[ogx360_analog_btns_mask[i]] = 0x00;
}
}
}

for (int i=0;i<NUM_16BIT_AXIS;i++) // 16 bit axis
{
if (ctrl_data->axes[i].value > ctrl_data->axes[i].meta->size_max) {
duke_out->axis16[i] = ctrl_data->axes[i].meta->size_max;
}
else if (ctrl_data->axes[i].value < ctrl_data->axes[i].meta->size_min) {
duke_out->axis16[i] = ctrl_data->axes[i].meta->size_min;
}
else {
duke_out->axis16[i] = ctrl_data->axes[i].value;
}
}

for (int i=0;i<NUM_8BIT_AXIS;i++) // 8 bit axis
{
uint8_t axes_index = NUM_16BIT_AXIS + i;
if (ctrl_data->axes[axes_index].value > ctrl_data->axes[axes_index].meta->size_max) {
duke_out->axis8[i] = ctrl_data->axes[axes_index].meta->size_max;
}
else if (ctrl_data->axes[axes_index].value < ctrl_data->axes[axes_index].meta->size_min) {
duke_out->axis8[i] = ctrl_data->axes[axes_index].meta->size_min;
}
else {
duke_out->axis8[i] = ctrl_data->axes[axes_index].value;
}
}
ogx360_process(wired_data->index);
}

void ogx360_acc_toggle_fb(uint32_t wired_id, uint16_t left_motor, uint16_t right_motor) {
struct bt_dev *device = NULL;
struct bt_data *bt_data = NULL;
bt_host_get_dev_from_out_idx(wired_id, &device);
if (device) {
bt_data = &bt_adapter.data[device->ids.id];
if (bt_data) {
struct generic_fb fb_data = {0};
fb_data.wired_id = wired_id;
fb_data.type = FB_TYPE_RUMBLE;
fb_data.cycles = 0;
fb_data.start = 0;
fb_data.state = (left_motor || right_motor);
fb_data.left_motor = left_motor << 16 ;
fb_data.right_motor = right_motor << 16;
wireless_fb_from_generic(&fb_data, bt_data);
bt_hid_feedback(device, bt_data->output);
}
}
}
8 changes: 8 additions & 0 deletions main/adapter/wired/ogx360.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef _OGX360_H_
#define _OGX360_H_
#include "adapter/config.h"

void ogx360_meta_init(struct generic_ctrl *ctrl_data);
void ogx360_from_generic(int32_t dev_mode, struct generic_ctrl *ctrl_data, struct wired_data *wired_data);

#endif /* _OGX360_H_ */
5 changes: 5 additions & 0 deletions main/adapter/wired/wired.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "parallel_2p.h"
#include "sea.h"
#include "wii.h"
#include "ogx360.h"
#include "wired.h"

static from_generic_t from_generic_func[WIRED_MAX] = {
Expand Down Expand Up @@ -51,6 +52,7 @@ static from_generic_t from_generic_func[WIRED_MAX] = {
para_1p_from_generic, /* PARALLEL_1P_OD */
para_2p_from_generic, /* PARALLEL_2P_OD */
sea_from_generic, /* SEA_BOARD */
ogx360_from_generic, /* OGX360 */
};

static fb_to_generic_t fb_to_generic_func[WIRED_MAX] = {
Expand Down Expand Up @@ -78,6 +80,7 @@ static fb_to_generic_t fb_to_generic_func[WIRED_MAX] = {
NULL, /* PARALLEL_1P_OD */
NULL, /* PARALLEL_2P_OD */
NULL, /* SEA_BOARD */
NULL, /* OGX360 */
};

static meta_init_t meta_init_func[WIRED_MAX] = {
Expand Down Expand Up @@ -105,6 +108,7 @@ static meta_init_t meta_init_func[WIRED_MAX] = {
para_1p_meta_init, /* PARALLEL_1P_OD */
para_2p_meta_init, /* PARALLEL_2P_OD */
sea_meta_init, /* SEA_BOARD */
ogx360_meta_init, /* OGX360 */
};

static DRAM_ATTR buffer_init_t buffer_init_func[WIRED_MAX] = {
Expand Down Expand Up @@ -132,6 +136,7 @@ static DRAM_ATTR buffer_init_t buffer_init_func[WIRED_MAX] = {
para_1p_init_buffer, /* PARALLEL_1P_OD */
para_2p_init_buffer, /* PARALLEL_2P_OD */
sea_init_buffer, /* SEA_BOARD */
NULL, /* OGX360 */
};

int32_t wired_meta_init(struct wired_ctrl *ctrl_data) {
Expand Down
24 changes: 20 additions & 4 deletions main/adapter/wireless/ps.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,16 @@ static void ps4_fb_from_generic(struct generic_fb *fb_data, struct bt_data *bt_d
set_conf->leds = bt_ps4_ps5_led_dev_id_map[bt_data->base.pids->id];

if (fb_data->state) {
set_conf->r_rumble = 0x7F;
set_conf->l_rumble = 0x7F;
if (fb_data->left_motor || fb_data->right_motor)
{
set_conf->r_rumble = fb_data->right_motor >> 24;
set_conf->l_rumble = fb_data->left_motor >> 24;
}
else
{
set_conf->r_rumble = 0x3F;
set_conf->l_rumble = 0x3F;
}
}
}

Expand All @@ -240,8 +248,16 @@ static void ps5_fb_from_generic(struct generic_fb *fb_data, struct bt_data *bt_d
set_conf->conf0 = 0x02;
if (fb_data->state) {
set_conf->cmd = 0x03;
set_conf->r_rumble = 0x3F;
set_conf->l_rumble = 0x3F;
if (fb_data->left_motor || fb_data->right_motor)
{
set_conf->r_rumble = fb_data->right_motor >> 24;
set_conf->l_rumble = fb_data->left_motor >> 24;
}
else
{
set_conf->r_rumble = 0x3F;
set_conf->l_rumble = 0x3F;
}
}
}

Expand Down
12 changes: 11 additions & 1 deletion main/adapter/wireless/xbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,17 @@ int32_t xbox_to_generic(struct bt_data *bt_data, struct wireless_ctrl *ctrl_data
void xbox_fb_from_generic(struct generic_fb *fb_data, struct bt_data *bt_data) {
struct xb1_rumble *rumble = (struct xb1_rumble *)bt_data->base.output;

if (fb_data->state) {
if (fb_data->state == 1 && ( fb_data->left_motor || fb_data->right_motor )) {
struct xb1_rumble xb1_rumble_data = {
.enable = 0x03,
.mag_l = fb_data->left_motor >> 24,
.mag_r = fb_data->right_motor >> 24,
.duration = 0xFF,
.cnt = 0x00,
};
memcpy((void *)rumble, (void *)&xb1_rumble_data, sizeof(xb1_rumble_data));
}
else if (fb_data->state == 1) {
memcpy((void *)rumble, (void *)&xb1_rumble_on, sizeof(xb1_rumble_on));
}
else {
Expand Down
1 change: 1 addition & 0 deletions main/linker.lf
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ entries:
jag_io (noflash)
wii_i2c (noflash)
devcrypto (noflash)
ogx360_i2c (noflash)
1 change: 1 addition & 0 deletions main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ static void wired_init_task(void) {
memcpy(fb_data.data, sysname, fb_data.header.data_len);
adapter_q_fb(&fb_data);

ets_printf("wired_bare_init()");
if (wired_adapter.system_id < WIRED_MAX) {
wired_bare_init(chip_package);
}
Expand Down
3 changes: 3 additions & 0 deletions main/system/manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,9 @@ void sys_mgr_init(uint32_t package) {
case SEA_BOARD:
port_cnt = 1;
break;
case OGX360:
port_cnt = 4;
break;
default:
port_cnt = 2;
break;
Expand Down
Loading

0 comments on commit 4425812

Please sign in to comment.