Compare commits
4 Commits
Author | SHA1 | Date |
---|---|---|
jinsoul | 9f521e3b25 | |
jinsoul | 47459136b9 | |
jinsoul | 4be2d972bb | |
jinsoul | d699defa0b |
|
@ -1,6 +1,8 @@
|
|||
# chuniio-yubideck
|
||||
ChuniIO driver for YubiDeck FW 3.0.
|
||||
|
||||
This fork adds support for the RPunithm, an HID device that is compatible with the YubiDeck protocol.
|
||||
|
||||
Thanks to:
|
||||
- [hlcm0](https://github.com/hlcm0/yubideck-io-firmware/blob/main/code/pico_yubideck_emu/report.h) and [4yn](https://github.com/4yn/slidershim/blob/main/src-slider_io/src/device/hid.rs#L257)
|
||||
for YubiDeck protocol information
|
||||
|
@ -18,6 +20,9 @@ path64=chuniio_yubideck_amdaemon.dll
|
|||
;; For CHUNITHM PARADISE and older
|
||||
path=chuniio_yubideck.dll
|
||||
|
||||
;; For RPunithm
|
||||
rpunithm=1
|
||||
|
||||
[io3]
|
||||
test=0x31
|
||||
service=0x32
|
||||
|
@ -26,8 +31,9 @@ coin=0x33
|
|||
|
||||
## USB Protocol
|
||||
USB device: `1973:2001`, interface 0
|
||||
Note: On the RPunithm, the slider is exposed on interface 2 as the device is reported as a composite device with multiple interfaces
|
||||
|
||||
- Endpoint IN Interrupt (0x81)
|
||||
- Endpoint IN Interrupt (0x81) (Note: Endpoint is 0x83 on the RPunithm)
|
||||
- Data length: 45 bytes
|
||||
- `data[0]`: bits 0-5: beam {2, 1, 4, 3, 6, 5}
|
||||
- `data[1]`: bits 0-2 for the 3 buttons (1 = pressed)
|
||||
|
|
|
@ -4,3 +4,8 @@ pub struct Configuration {
|
|||
pub service_key: u32,
|
||||
pub coin_key: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct DeviceConfiguration {
|
||||
pub rpunithm: u32
|
||||
}
|
||||
|
|
|
@ -31,6 +31,11 @@ cfg_if::cfg_if! {
|
|||
if #[cfg(any(chuni, chusanapp))] {
|
||||
use std::{sync::{atomic::AtomicBool, RwLock}, thread};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use winapi::um::{winbase::GetPrivateProfileIntA};
|
||||
|
||||
use create::configuration::DeviceConfiguration;
|
||||
|
||||
use anyhow::Result;
|
||||
use ::log::info;
|
||||
use rusb::{DeviceHandle, GlobalContext};
|
||||
|
@ -41,6 +46,26 @@ cfg_if::cfg_if! {
|
|||
|
||||
static DEVICE: RwLock<Option<DeviceHandle<GlobalContext>>> = RwLock::new(None);
|
||||
static SLIDER_ACTIVE: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
lazy_static! {
|
||||
static ref CONFIGURATION: DeviceConfiguration = {
|
||||
let chuniio = CString::new("chuniio").unwrap();
|
||||
let rpunithm = CString::new("rpunithm").unwrap();
|
||||
let cfg_file = CString::new(".\\segatools.ini").unwrap();
|
||||
|
||||
unsafe {
|
||||
DeviceConfiguration {
|
||||
rpunithm: GetPrivateProfileIntA(
|
||||
chuniio.as_ptr(),
|
||||
rpunithm.as_ptr(),
|
||||
// default always 0, just in-case a regular yubideck user uses this chuniio and has no idea what a rpunithm is
|
||||
0,
|
||||
cfg_file.as_ptr(),
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -376,8 +401,15 @@ fn yubideck_init() -> Result<()> {
|
|||
continue;
|
||||
};
|
||||
|
||||
device.set_active_configuration(1)?;
|
||||
device.claim_interface(0)?;
|
||||
// the rpunithm exposes the slider interface on interface 2, as opposed to interface 0 on the yubideck
|
||||
if CONFIGURATION.rpunithm == 1 {
|
||||
device.set_active_configuration(1)?;
|
||||
device.claim_interface(2)?;
|
||||
}
|
||||
else {
|
||||
device.set_active_configuration(1)?;
|
||||
device.claim_interface(0)?;
|
||||
};
|
||||
|
||||
let mut global_device = DEVICE.write().unwrap();
|
||||
*global_device = Some(device);
|
||||
|
@ -413,8 +445,10 @@ fn input_thread_proc() {
|
|||
};
|
||||
let usb_out = unsafe { output_shmem.as_slice_mut() };
|
||||
|
||||
let endpoint = if CONFIGURATION.rpunithm == 1 {0x83} else {0x81};
|
||||
|
||||
loop {
|
||||
if let Err(e) = device.read_interrupt(0x81, usb_in, TIMEOUT) {
|
||||
if let Err(e) = device.read_interrupt(endpoint, usb_in, TIMEOUT) {
|
||||
match e {
|
||||
rusb::Error::NoDevice | rusb::Error::Io => {
|
||||
error!("Controller disconnected.");
|
||||
|
|
Loading…
Reference in New Issue