Compare commits

...

17 Commits
v0.4.0 ... main

Author SHA1 Message Date
4yn 4f0db8e66e bump version 2025-03-22 21:43:16 +08:00
4yn 7cc6e46afe Merge branch 'sr1canskhsia-main' 2025-03-22 15:01:14 +08:00
sr1canskhsia 7b63ff3a1a Add Laverita v3 support 2025-03-22 00:27:46 -04:00
4yn 6124dee2db bump version number 2023-10-05 21:05:11 +08:00
4yn cbbfcdc99e Merge branch 'main' of github.com:4yn/slidershim 2023-10-05 20:27:31 +08:00
si yuan b77f5f105f
Merge pull request #13 from kokarare1212/main
WebSocket SSL Support
2023-10-05 20:26:07 +08:00
4yn 743424dc01 bump proc-macro2 dependency to work with latest nightly 2023-10-05 20:09:17 +08:00
碧舞すみほ 1b131d7ea7
Update src.js 2023-10-05 20:31:15 +09:00
碧舞すみほ df9ee3b57f
Update app.js 2023-10-05 20:30:47 +09:00
4yn 3bd7ee8586 yubideck v3 firmware support 2022-11-18 01:42:05 +08:00
4yn 828f480424 bump version and add readme 2022-08-08 23:00:53 +08:00
4yn e285bdb999 fix hid regression on yubideck 2022-08-08 22:58:24 +08:00
4yn 0b75d1c62e update readme and bump version 2022-07-29 19:49:04 +08:00
4yn b02e14ecdf fix hori slider output order 2022-07-29 19:46:34 +08:00
4yn f135c31904 bump version and update readme 2022-07-28 02:16:06 +08:00
4yn 396e77ac38 add tolerance to yuancon usb report 2022-07-28 02:12:28 +08:00
4yn 17cd942148 fix misplaced checkbox label 2022-07-28 02:11:58 +08:00
11 changed files with 202 additions and 24 deletions

View File

@ -12,9 +12,27 @@ Software adapter for various Chunithm slider controllers with a built-in Brokeni
## Changelog
- v0.6.0
- Support Laverita v3. Thanks @sr1canskhsia
- v0.5.1
- Support SSL/wss if brokenithm used with tunnelling. Thanks @kokarare1212
- v0.5.0
- Support for Yubideck 3.0 firmware
- v0.4.3
- Make Yubideck USB reports more flexible when reading data
- v0.4.2
- Fix HORI Project Diva gamepad slider output order
- v0.4.1
- Fix misplaced checkbox label (clicking on "use DirectInput" would check "disable air" instead)
- Make Yuancon USB reports more flexible when reading data
- v0.4.0
- Add DirectInput keyboard emulation using oblitum/Interception
- Add DirectInput keyboard emulation using [oblitum/Interception](https://github.com/oblitum/Interception)
- Add slide LED support for some controllers
<details>
<summary>Older changelog</summary>
- v0.3.1
- Fix wrong key in UMIGURI keyboard layout
- v0.3.0
@ -52,6 +70,8 @@ Software adapter for various Chunithm slider controllers with a built-in Brokeni
- v0.1.4
- Initial public release
</details>
## Setup Instructions
1. [Download here](https://github.com/4yn/slidershim/releases/latest)

File diff suppressed because one or more lines are too long

View File

@ -223,7 +223,7 @@ var ws = null;
var wsTimeout = 0;
var wsConnected = false;
const wsConnect = () => {
ws = new WebSocket("ws://" + location.host + "/ws");
ws = new WebSocket((location.protocol == "https:" ? "wss://" : "ws://") + location.host + "/ws");
ws.binaryType = "arraybuffer";
ws.onopen = () => {
ws.send("alive?");

View File

@ -5,7 +5,9 @@ pub enum HardwareSpec {
TasollerOne,
TasollerTwo,
Yuancon,
YuanconThree,
Yubideck,
YubideckThree,
}
#[derive(Debug, Clone)]
@ -49,10 +51,18 @@ impl DeviceMode {
spec: HardwareSpec::Yuancon,
disable_air: v["disableAirStrings"].as_bool()?,
},
"yuancon-three" => DeviceMode::Hardware {
spec: HardwareSpec::YuanconThree,
disable_air: v["disableAirStrings"].as_bool()?,
},
"yubideck" => DeviceMode::Hardware {
spec: HardwareSpec::Yubideck,
disable_air: v["disableAirStrings"].as_bool()?,
},
"yubideck-three" => DeviceMode::Hardware {
spec: HardwareSpec::YubideckThree,
disable_air: v["disableAirStrings"].as_bool()?,
},
"diva" => DeviceMode::DivaSlider {
port: v["divaSerialPort"].as_str()?.to_string(),
brightness: u8::try_from(v["divaBrightness"].as_i64()?).ok()?,

View File

@ -18,7 +18,7 @@ use crate::{
use super::config::HardwareSpec;
type HidReadCallback = fn(&Buffer, &mut SliderInput) -> ();
type HidLedCallback = fn(&mut Buffer, &SliderLights) -> ();
type HidLedCallback = fn(&mut Buffer, &mut Buffer, &SliderLights) -> ();
enum WriteType {
Bulk,
@ -41,6 +41,7 @@ pub struct HidJob {
led_write_type: WriteType,
led_callback: HidLedCallback,
led_buf: Buffer,
led_buf_two: Buffer,
handle: Option<DeviceHandle<GlobalContext>>,
}
@ -70,6 +71,7 @@ impl HidJob {
led_write_type: led_type,
led_callback,
led_buf: Buffer::new(),
led_buf_two: Buffer::new(),
handle: None,
}
}
@ -102,7 +104,7 @@ impl HidJob {
input.extra[0..2].copy_from_slice(&bits[26..28]);
},
WriteType::Bulk,
|buf, lights| {
|buf, _, lights| {
buf.len = 240;
buf.data[0] = 'B' as u8;
buf.data[1] = 'L' as u8;
@ -139,7 +141,7 @@ impl HidJob {
input.extra[0..2].copy_from_slice(&bits[6..8]);
},
WriteType::Bulk,
|buf, lights| {
|buf, _, lights| {
buf.len = 240;
buf.data[0] = 'B' as u8;
buf.data[1] = 'L' as u8;
@ -177,7 +179,7 @@ impl HidJob {
0x02,
*disable_air,
|buf, input| {
if buf.len != 34 {
if buf.len != 34 && buf.len != 35 {
return;
}
@ -190,7 +192,7 @@ impl HidJob {
}
},
WriteType::Interrupt,
|buf, lights| {
|buf, _, lights| {
buf.len = 31 * 2;
for (buf_chunk, state_chunk) in buf
.data
@ -203,6 +205,53 @@ impl HidJob {
}
},
),
HardwareSpec::YuanconThree => Self::new(
state.clone(),
0x0518,
0x2022,
0x83,
0x03,
*disable_air,
|buf, input| {
if buf.len != 46 { // real length is 46 but last 12 bytes are unused
return;
}
input.ground.copy_from_slice(&buf.data[2..34]);
input.flip_vert();
let bits: Vec<u8> = (0..8).map(|x| (buf.data[0] >> x) & 1).collect();
for i in 0..6 {
input.air[i ^ 1] = bits[i];
}
input.extra[0..2].copy_from_slice(&bits[6..8]);
},
WriteType::Interrupt,
|buf, buf_two, lights| {
buf.len = 61;
buf.data[0] = 0;
buf_two.len = 61;
buf_two.data[0] = 1;
for (buf_chunk, state_chunk) in buf.data[1..61]
.chunks_mut(3)
.zip(lights.ground.chunks(3).skip(11).take(20).rev())
{
buf_chunk[0] = state_chunk[0];
buf_chunk[1] = state_chunk[1];
buf_chunk[2] = state_chunk[2];
}
for (buf_chunk, state_chunk) in buf_two.data[1..34]
.chunks_mut(3)
.zip(lights.ground.chunks(3).take(11).rev())
{
buf_chunk[0] = state_chunk[0];
buf_chunk[1] = state_chunk[1];
buf_chunk[2] = state_chunk[2];
}
},
),
HardwareSpec::Yubideck => Self::new(
state.clone(),
0x1973,
@ -211,11 +260,12 @@ impl HidJob {
0x02, // Need to confirm
*disable_air,
|buf, input| {
if buf.len != 45 {
if buf.len != 45 && buf.len != 46 {
return;
}
input.ground.copy_from_slice(&buf.data[2..34]);
input.flip_vert();
for i in 0..6 {
input.air[i ^ 1] = (buf.data[0] >> i) & 1;
}
@ -224,7 +274,7 @@ impl HidJob {
}
},
WriteType::Interrupt,
|buf, lights| {
|buf, _, lights| {
buf.len = 62;
let lights_nibbles: Vec<u8> = lights
@ -251,6 +301,56 @@ impl HidJob {
}
},
),
HardwareSpec::YubideckThree => Self::new(
state.clone(),
0x1973,
0x2001,
0x81, // Need to confirm
0x02, // Need to confirm
*disable_air,
|buf, input| {
if buf.len != 45 && buf.len != 46 {
return;
}
input.ground.copy_from_slice(&buf.data[2..34]);
input.flip_vert();
for i in 0..6 {
input.air[i ^ 1] = (buf.data[0] >> i) & 1;
}
for i in 0..3 {
input.extra[2 - i] = (buf.data[1] >> i) & 1;
}
},
WriteType::Interrupt,
|buf, buf_two, lights| {
buf.len = 61;
buf.data[0] = 0;
buf_two.len = 61;
buf_two.data[0] = 1;
for (buf_chunk, state_chunk) in buf.data[1..61]
.chunks_mut(3)
.zip(lights.ground.chunks(3).skip(11).take(20).rev())
{
buf_chunk[0] = state_chunk[0];
buf_chunk[1] = state_chunk[1];
buf_chunk[2] = state_chunk[2];
}
for (buf_chunk, state_chunk) in buf_two.data[1..34]
.chunks_mut(3)
.zip(lights.ground.chunks(3).take(11).rev())
{
buf_chunk[0] = state_chunk[0];
buf_chunk[1] = state_chunk[1];
buf_chunk[2] = state_chunk[2];
}
buf_two.data[34..37].copy_from_slice(&lights.air_left[3..6]);
buf_two.data[37..40].copy_from_slice(&lights.air_right[3..6]);
},
),
}
}
@ -270,8 +370,15 @@ impl HidJob {
}
info!("Device setting configuration");
handle.set_active_configuration(1)?;
// A bit janky but Laverita v3 seems to require interface 3
info!("Device claiming interface");
handle.claim_interface(0)?;
if self.vid == 0x0518 && self.pid == 0x2022 {
handle.claim_interface(3)?;
} else {
handle.claim_interface(0)?;
}
self.handle = Some(handle);
Ok(())
}
@ -326,7 +433,11 @@ impl ThreadJob for HidJob {
{
let mut lights_handle = self.state.lights.lock();
if lights_handle.dirty {
(self.led_callback)(&mut self.led_buf, lights_handle.deref());
(self.led_callback)(
&mut self.led_buf,
&mut self.led_buf_two,
lights_handle.deref(),
);
lights_handle.dirty = false;
}
}
@ -348,6 +459,26 @@ impl ThreadJob for HidJob {
self.led_buf.len = 0;
}
}
if self.led_buf_two.len != 0 {
let res = (match self.led_write_type {
WriteType::Bulk => {
handle.write_bulk(self.led_endpoint, self.led_buf_two.slice(), TIMEOUT)
}
WriteType::Interrupt => {
handle.write_interrupt(self.led_endpoint, &self.led_buf_two.slice(), TIMEOUT)
}
})
.map_err(|e| {
// debug!("Device write error {}", e);
e
})
.unwrap_or(0);
if res == self.led_buf_two.len + 1 {
// work = true;
self.led_buf_two.len = 0;
}
}
}
work

View File

@ -91,7 +91,7 @@ impl OutputHandler for HoriOutput {
.fold(0, |axis, (idx, state)| {
axis
| match state {
true => 0b11 << ((15 - idx) * 2),
true => 0b11 << ((idx ^ 3) * 2),
false => 0,
}
})

8
src-tauri/Cargo.lock generated
View File

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4
[[package]]
name = "CoreFoundation-sys"
@ -2462,9 +2462,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro2"
version = "1.0.40"
version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
dependencies = [
"unicode-ident",
]
@ -2996,7 +2996,7 @@ dependencies = [
[[package]]
name = "slidershim"
version = "0.4.0"
version = "0.6.0"
dependencies = [
"env_logger",
"log",

View File

@ -1,6 +1,6 @@
[package]
name = "slidershim"
version = "0.4.0"
version = "0.6.0"
description = "slidershim"
authors = ["4yn"]
license = ""

View File

@ -2,13 +2,26 @@
___| (_) __| | ___ _ __ ___| |__ (_)_ __ ___
/ __| | |/ _` |/ _ \ '__/ __| '_ \| | '_ ` _ \
\__ \ | | (_| | __/ | \__ \ | | | | | | | | |
|___/_|_|\__,_|\___|_| |___/_| |_|_|_| |_| |_| v0.4.0
|___/_|_|\__,_|\___|_| |___/_| |_|_|_| |_| |_| v0.6.1
===============================================
https://github.com/4yn/slidershim
# Changelog
- v0.6.0
- Support Laverita v3. Thanks @sr1canskhsia
- v0.5.1
- Support SSL/wss if brokenithm used with tunnelling. Thanks @kokarare1212
- v0.5.0
- Support for Yubideck 3.0 firmware
- v0.4.3
- Make Yubideck USB reports more flexible when reading data
- v0.4.2
- Fix HORI Project Diva gamepad slider output order
- v0.4.1
- Fix misplaced checkbox label (clicking on "use DirectInput" would check "disable air" instead)
- Make Yuancon USB reports more flexible when reading data
- v0.4.0
- Add DirectInput keyboard emulation using oblitum/Interception
- Add slide LED support for some controllers

View File

@ -1,7 +1,7 @@
{
"package": {
"productName": "slidershim",
"version": "0.4.0"
"version": "0.6.0"
},
"build": {
"distDir": "../public",
@ -21,7 +21,9 @@
"icons/icon.icns",
"icons/icon.ico"
],
"resources": ["./README.txt"],
"resources": [
"./README.txt"
],
"externalBin": [],
"copyright": "© 4yn 2022",
"category": "DeveloperTool",
@ -74,4 +76,4 @@
"iconAsTemplate": true
}
}
}
}

View File

@ -196,7 +196,9 @@
<option value="tasoller-one">GAMO2 Tasoller, 1.0 HID Firmware</option>
<option value="tasoller-two">GAMO2 Tasoller, 2.0 HID Firmware</option>
<option value="yuancon">Yuancon Laverita, HID Firmware</option>
<option value="yubideck">大四 / Yubideck, HID Firmware</option>
<option value="yuancon-three">Yuancon Laverita v3, HID Firmware</option>
<option value="yubideck">大四 / Yubideck, HID Firmware 1.0</option>
<option value="yubideck-three">大四 / Yubideck, HID Firmware 3.0</option>
<option value="diva">Slider over Serial</option>
<option value="brokenithm">Brokenithm</option>
<option value="brokenithm-led">Brokenithm + Led</option>
@ -407,7 +409,7 @@
bind:checked={keyboardDirectInput}
on:change={markDirty}
/>
<label for="disable-air">Use DirectInput</label>
<label for="direct-input">Use DirectInput</label>
</span>
</div>
</div>