mirror of
https://github.com/brunocprado/PS5JB-JustDance-Control.git
synced 2026-10-17 18:00:23 +02:00
103 lines
3.8 KiB
C
103 lines
3.8 KiB
C
/*
|
|
protocol.h - PS5JustDance
|
|
Motion input protocols supported by the PS5 daemon:
|
|
1. JDM1 binary UDP packet (direct Joy-Con / Phone bridge, port 9052)
|
|
2. Cemuhook / DSU (DualShock UDP) protocol (BetterJoy, joycond-cemuhook,
|
|
DSUController Android/iOS, MotionSource)
|
|
3. JSON text packet over UDP or HTTP POST (built-in Phone Web Controller)
|
|
|
|
Licensed under the GNU Lesser General Public License version 2.1, or later.
|
|
*/
|
|
|
|
#ifndef PS5JD_PROTOCOL_H
|
|
#define PS5JD_PROTOCOL_H
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include "scemove.h"
|
|
|
|
#define JDM_UDP_MAGIC 0x314D444Au /* "JDM1" little-endian */
|
|
#define JDM_DEFAULT_PORT 9052
|
|
#define JDM_WEB_PORT 8080
|
|
#define DSU_DEFAULT_PORT 26760
|
|
|
|
/* Device orientation / source flags in jdm_packet_t::source_flags */
|
|
#define JDM_SOURCE_GENERIC 0x00 /* Already in PS Move frame (accel in G, gyro in rad/s) */
|
|
#define JDM_SOURCE_JOYCON_R 0x01 /* Switch Right Joy-Con raw/standard frame */
|
|
#define JDM_SOURCE_JOYCON_L 0x02 /* Switch Left Joy-Con raw/standard frame */
|
|
#define JDM_SOURCE_PHONE 0x03 /* Smartphone (accel in m/s^2, gyro in deg/s) */
|
|
|
|
/*
|
|
Native 36-byte binary UDP packet ("JDM1").
|
|
Little-endian layout:
|
|
offset 0: uint32_t magic (0x314D444A = "JDM1")
|
|
offset 4: uint8_t player_index (0..3)
|
|
offset 5: uint8_t source_flags (JDM_SOURCE_*)
|
|
offset 6: uint16_t buttons (SCE_MOVE_BUTTON_* mask)
|
|
offset 8: uint8_t trigger (0..255 analog T trigger)
|
|
offset 9: uint8_t reserved
|
|
offset 10: uint16_t pad_buttons (SCE_PAD_BUTTON_* mask for UI navigation)
|
|
offset 12: float accel[3] (X, Y, Z)
|
|
offset 24: float gyro[3] (X, Y, Z)
|
|
Total: 36 bytes.
|
|
*/
|
|
typedef struct __attribute__((packed)) jdm_packet {
|
|
uint32_t magic;
|
|
uint8_t player_index;
|
|
uint8_t source_flags;
|
|
uint16_t buttons;
|
|
uint8_t trigger;
|
|
uint8_t reserved;
|
|
uint16_t pad_buttons;
|
|
float accel[3];
|
|
float gyro[3];
|
|
} jdm_packet_t;
|
|
|
|
/* Normalized motion sample ready to be written into stub_controller_state_t */
|
|
typedef struct motion_sample {
|
|
int player_index; /* 0..3 */
|
|
float accel_g[3]; /* PS Move frame: X, Y, Z in G (1.0 = 9.80665 m/s^2) */
|
|
float gyro_rads[3]; /* PS Move frame: X, Y, Z in rad/s */
|
|
uint16_t buttons; /* SCE_MOVE_BUTTON_* */
|
|
uint16_t trigger; /* 0..255 */
|
|
uint32_t pad_buttons; /* SCE_PAD_BUTTON_* for UI navigation */
|
|
} motion_sample_t;
|
|
|
|
/* Cemuhook / DSU protocol constants */
|
|
#define DSU_MAGIC_SERVER 0x53555344u /* "DSUS" little-endian */
|
|
#define DSU_MAGIC_CLIENT 0x43555344u /* "DSUC" little-endian */
|
|
#define DSU_PROTOCOL_VERSION 1001
|
|
#define DSU_TYPE_VERSION_INFO 0x00100000u
|
|
#define DSU_TYPE_CONTROLLER_INFO 0x00100001u
|
|
#define DSU_TYPE_CONTROLLER_DATA 0x00100002u
|
|
|
|
/* Computes standard IEEE 802.3 CRC32 (used by DSU packets). */
|
|
uint32_t protocol_crc32(const uint8_t *data, size_t len);
|
|
|
|
/* Builds a 28-byte DSUC controller data subscription request packet for `slot` (0..3) or all slots (-1). */
|
|
size_t protocol_build_dsu_request(uint8_t *out_buf, size_t max_len, uint32_t client_id, int slot);
|
|
|
|
/*
|
|
Parses any supported incoming packet (JDM1 binary, DSUS Cemuhook, or JSON text)
|
|
and populates `out` in PS Move coordinates (G and rad/s).
|
|
Returns true if a valid controller motion sample was parsed.
|
|
*/
|
|
bool protocol_parse_packet(const uint8_t *buf, size_t len, float accel_scale, motion_sample_t *out);
|
|
|
|
/* Converts float to its raw IEEE-754 uint32_t representation. */
|
|
static inline uint32_t float_to_bits(float v) {
|
|
uint32_t bits;
|
|
__builtin_memcpy(&bits, &v, sizeof(bits));
|
|
return bits;
|
|
}
|
|
|
|
static inline float bits_to_float(uint32_t bits) {
|
|
float v;
|
|
__builtin_memcpy(&v, &bits, sizeof(v));
|
|
return v;
|
|
}
|
|
|
|
#endif
|