1
0
mirror of https://github.com/4yn/slidershim.git synced 2025-02-02 04:27:58 +01:00

qol and bugfix

This commit is contained in:
4yn 2022-02-06 17:56:50 +08:00
parent a8d72207a4
commit fcf80538b4
16 changed files with 225 additions and 49 deletions

View File

@ -54,6 +54,15 @@ body {
flex: 2 2 0;
}
.serverlist {
width: 100%;
max-height: 5rem;
overflow-x: auto;
}
.serverlist > pre {
font-size: 0.75em;
}
input,
select {
width: 100%;
@ -89,6 +98,24 @@ button.primary {
flex-flow: column nowrap;
align-items: stretch;
justify-content: flex-start;
/* border: 0.125rem solid white; */
}
.air {
height: 2rem;
display: flex;
flex-flow: column-reverse nowrap;
align-items: stretch;
justify-content: flex-start;
}
.air-data {
flex: 1 0;
}
.air-data-0 {
background: #000;
}
.air-data-1 {
background: #0aa;
}
.ground {
@ -143,3 +170,23 @@ button.primary {
padding: 0.1rem 0;
font-size: 0.8rem;
}
.extra {
height: 2rem;
display: flex;
flex-flow: row nowrap;
align-items: stretch;
justify-content: flex-start;
}
.extra-data {
width: 1rem;
height: 1rem;
border-radius: 1rem;
margin: 0.5rem;
}
.extra-data-0 {
background: #000;
}
.extra-data-1 {
background: #aaa;
}

2
src-tauri/Cargo.lock generated
View File

@ -2850,7 +2850,7 @@ checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
[[package]]
name = "slidershim"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"async-trait",
"directories",

View File

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

View File

@ -32,14 +32,9 @@ fn quit_app() {
fn main() {
// Setup logger
// env_logger::Builder::new()
// .filter_level(log::LevelFilter::Debug)
// .init();
simple_logging::log_to_file(
slider_io::Config::get_log_file_path().unwrap().as_path(),
log::LevelFilter::Debug,
)
.unwrap();
let log_file_path = slider_io::Config::get_log_file_path().unwrap();
simple_logging::log_to_file(log_file_path.as_path(), log::LevelFilter::Debug).unwrap();
// simple_logging::log_to_file("./log.txt", log::LevelFilter::Debug).unwrap();
let config = Arc::new(Mutex::new(Some(slider_io::Config::default())));
let manager = Arc::new(Mutex::new(slider_io::Manager::new()));
@ -114,6 +109,11 @@ fn main() {
if let Ok(ips) = ips {
app_handle.emit_all("listIps", &ips).unwrap();
}
let log_file_path = slider_io::Config::get_log_file_path().unwrap();
app_handle
.emit_all("updateLogPath", log_file_path.as_path().to_str().unwrap())
.unwrap();
});
// UI update event

View File

@ -0,0 +1,52 @@
// use serialport::SerialPort;
// use std::io::{BufRead, BufReader};
// struct ArcadeSlider {
// serial_port: BufReader<Box<dyn SerialPort>>,
// }
// impl ArcadeSlider {
// fn new() -> Self {
// let serial_port = serialport::new("COM1", 152000).open().unwrap();
// let serial_port_buf = BufReader::new(serial_port);
// Self {
// serial_port: serial_port_buf,
// }
// }
// fn recv(&mut self) {
// let mut consumed = 0;
// {
// let d = self.serial_port.fill_buf().unwrap();
// let mut packets = vec![];
// let mut packet = vec![];
// let mut bytes_taken = 0;
// let mut in_escape = 0;
// let mut checksum = 0;
// for b in d.iter() {
// bytes_taken += 1;
// match b {
// 0xff => {
// consumed += bytes_taken;
// bytes_taken = 0;
// in_escape = 0;
// }
// 0xfd => {
// in_escape = 1;
// }
// _ => {
// let b = b + in_escape;
// in_escape = 0;
// packet.push(b);
// }
// }
// }
// }
// self.serial_port.consume(consumed);
// }
// fn send(&mut self) {}
// }

View File

@ -1,5 +1,5 @@
use directories::ProjectDirs;
use log::info;
use log::{info, warn};
use serde_json::Value;
use std::{convert::TryFrom, fs, path::PathBuf};
@ -18,7 +18,12 @@ pub enum KeyboardLayout {
Yuancon,
Deemo,
Voltex,
GamepadVoltex,
}
#[derive(Debug, Clone, Copy)]
pub enum GamepadLayout {
Voltex,
Neardayo,
}
#[derive(Debug, Clone)]
@ -28,6 +33,10 @@ pub enum OutputMode {
layout: KeyboardLayout,
sensitivity: u8,
},
Gamepad {
layout: GamepadLayout,
sensitivity: u8,
},
Websocket {
url: String,
},
@ -97,8 +106,12 @@ impl Config {
layout: KeyboardLayout::Voltex,
sensitivity: u8::try_from(v["keyboardSensitivity"].as_i64()?).ok()?,
},
"gamepad-voltex" => OutputMode::Keyboard {
layout: KeyboardLayout::GamepadVoltex,
"gamepad-voltex" => OutputMode::Gamepad {
layout: GamepadLayout::Voltex,
sensitivity: u8::try_from(v["keyboardSensitivity"].as_i64()?).ok()?,
},
"gamepad-neardayo" => OutputMode::Gamepad {
layout: GamepadLayout::Neardayo,
sensitivity: u8::try_from(v["keyboardSensitivity"].as_i64()?).ok()?,
},
"websocket" => OutputMode::Websocket {
@ -185,7 +198,10 @@ impl Config {
pub fn default() -> Self {
Self::load_saved()
.or_else(|| Some(Self::factory()))
.or_else(|| {
warn!("Config loading from file failed, using default");
Some(Self::factory())
})
.unwrap()
}

View File

@ -32,6 +32,12 @@ impl ControllerState {
)
.collect()
}
pub fn flip_vert(&mut self) {
for i in 0..16 {
self.ground_state.swap(i * 2, i * 2 + 1);
}
}
}
pub struct LedState {
@ -81,6 +87,7 @@ impl FullState {
let controller_state_handle = self.controller_state.lock().unwrap();
buf.extend(controller_state_handle.ground_state);
buf.extend(controller_state_handle.air_state);
buf.extend(controller_state_handle.extra_state);
};
{
let led_state_handle = self.led_state.lock().unwrap();

View File

@ -85,9 +85,10 @@ impl HidDeviceJob {
for i in 0..32 {
controller_state.ground_state[i] = bits[34 + i] * 255;
}
controller_state.flip_vert();
controller_state.air_state.copy_from_slice(&bits[28..34]);
controller_state.extra_state.copy_from_slice(&bits[26..28]);
controller_state.extra_state[0..2].copy_from_slice(&bits[26..28]);
},
WriteType::Bulk,
|buf, led_state| {
@ -121,10 +122,11 @@ impl HidDeviceJob {
controller_state
.ground_state
.copy_from_slice(&buf.data[4..36]);
controller_state.flip_vert();
let bits: Vec<u8> = (0..8).map(|x| (buf.data[3] >> x) & 1).collect();
controller_state.air_state.copy_from_slice(&bits[2..8]);
controller_state.extra_state.copy_from_slice(&bits[2..8]);
controller_state.air_state.copy_from_slice(&bits[0..6]);
controller_state.extra_state[0..2].copy_from_slice(&bits[6..8]);
},
WriteType::Bulk,
|buf, led_state| {
@ -159,8 +161,7 @@ impl HidDeviceJob {
.ground_state
.copy_from_slice(&buf.data[2..34]);
for i in 0..6 {
controller_state.air_state[i ^ 1] = 0;
// controller_state.air_state[i ^ 1] = (buf.data[0] >> i) & 1;
controller_state.air_state[i ^ 1] = (buf.data[0] >> i) & 1;
}
for i in 0..3 {
controller_state.extra_state[i] = (buf.data[1] >> i) & 1;
@ -230,8 +231,13 @@ impl ThreadJob for HidDeviceJob {
{
let res = handle
.read_interrupt(self.read_endpoint, &mut self.read_buf.data, TIMEOUT)
.map_err(|e| {
// debug!("Device read error {}", &e);
e
})
.unwrap_or(0);
self.read_buf.len = res;
// debug!("{:?}", self.read_buf.slice());
if self.read_buf.len != 0 {
let mut controller_state_handle = self.state.controller_state.lock().unwrap();
(self.read_callback)(&self.read_buf, controller_state_handle.deref_mut());
@ -250,11 +256,15 @@ impl ThreadJob for HidDeviceJob {
if self.led_buf.len != 0 {
let res = (match self.led_write_type {
WriteType::Bulk => handle.write_bulk(self.led_endpoint, &self.led_buf.data, TIMEOUT),
WriteType::Bulk => handle.write_bulk(self.led_endpoint, self.led_buf.slice(), TIMEOUT),
WriteType::Interrupt => {
handle.write_interrupt(self.led_endpoint, &self.led_buf.data, TIMEOUT)
handle.write_interrupt(self.led_endpoint, &self.led_buf.slice(), TIMEOUT)
}
})
.map_err(|e| {
// debug!("Device write error {}", e);
e
})
.unwrap_or(0);
if res == self.led_buf.len + 1 {
self.led_buf.len = 0;

View File

@ -1,20 +1,26 @@
use vigem_client::{Client, TargetId, XButtons, XGamepad, Xbox360Wired};
use crate::slider_io::{output::OutputHandler, voltex::VoltexState};
use crate::slider_io::{config::GamepadLayout, output::OutputHandler, voltex::VoltexState};
pub struct GamepadOutput {
target: Xbox360Wired<Client>,
use_air: bool,
gamepad: XGamepad,
}
impl GamepadOutput {
pub fn new() -> Self {
pub fn new(layout: GamepadLayout) -> Self {
let client = Client::connect().unwrap();
let use_air = match layout {
GamepadLayout::Neardayo => true,
_ => false,
};
let mut target = Xbox360Wired::new(client, TargetId::XBOX360_WIRED);
target.plugin().unwrap();
target.wait_ready().unwrap();
Self {
target,
use_air,
gamepad: XGamepad::default(),
}
}
@ -48,18 +54,18 @@ impl OutputHandler for GamepadOutput {
}
});
let lx = (match voltex_state.laser[0] {
let lx = (match voltex_state.laser[0] || (self.use_air && flat_controller_state[34]) {
true => -30000,
false => 0,
} + match voltex_state.laser[1] {
} + match voltex_state.laser[1] || (self.use_air && flat_controller_state[35]) {
true => 30000,
false => 0,
});
let rx = (match voltex_state.laser[2] {
let rx = (match voltex_state.laser[2] || (self.use_air && flat_controller_state[36]) {
true => -30000,
false => 0,
} + match voltex_state.laser[3] {
} + match voltex_state.laser[3] || (self.use_air && flat_controller_state[37]) {
true => 30000,
false => 0,
});

View File

@ -78,7 +78,6 @@ impl KeyboardOutput {
KeyboardLayout::Yuancon => &YUANCON_KB_MAP,
KeyboardLayout::Deemo => &DEEMO_KB_MAP,
KeyboardLayout::Voltex => &VOLTEX_KB_MAP,
_ => panic!("Not implemented"),
};
let mut ground_to_idx = [0 as usize; 41];

View File

@ -5,6 +5,7 @@ mod worker;
mod controller_state;
mod voltex;
mod acio;
mod brokenithm;
mod gamepad;
mod keyboard;

View File

@ -1,11 +1,8 @@
use std::{thread, time::Duration};
use crate::slider_io::{
config::{KeyboardLayout, OutputMode},
controller_state::FullState,
gamepad::GamepadOutput,
keyboard::KeyboardOutput,
worker::ThreadJob,
config::OutputMode, controller_state::FullState, gamepad::GamepadOutput,
keyboard::KeyboardOutput, worker::ThreadJob,
};
pub trait OutputHandler: Send {
@ -28,10 +25,15 @@ impl OutputJob {
} => Self {
state: state.clone(),
sensitivity: *sensitivity,
handler: match layout {
KeyboardLayout::GamepadVoltex => Box::new(GamepadOutput::new()),
layout => Box::new(KeyboardOutput::new(layout.clone())),
},
handler: Box::new(KeyboardOutput::new(layout.clone())),
},
OutputMode::Gamepad {
layout,
sensitivity,
} => Self {
state: state.clone(),
sensitivity: *sensitivity,
handler: Box::new(GamepadOutput::new(layout.clone())),
},
_ => panic!("Not implemented"),
}

View File

@ -14,7 +14,7 @@ impl Buffer {
}
}
fn slice(&self) -> &[u8] {
pub fn slice(&self) -> &[u8] {
&self.data[0..self.len]
}
}

View File

@ -1,7 +1,7 @@
{
"package": {
"productName": "slidershim",
"version": "0.1.0"
"version": "0.1.1"
},
"build": {
"distDir": "../public",
@ -60,7 +60,7 @@
{
"title": "slidershim",
"width": 500,
"height": 500,
"height": 550,
"resizable": false,
"fullscreen": false
}

View File

@ -1,6 +1,7 @@
<script lang="ts">
import { onMount } from "svelte";
import { emit, listen } from "@tauri-apps/api/event";
import { open } from "@tauri-apps/api/shell";
import Link from "./Link.svelte";
import Preview from "./Preview.svelte";
@ -27,6 +28,7 @@
let polling = null;
let tick = 0;
let previewData = Array(131).fill(0);
let logfile = "";
function updatePolling(enabled) {
if (!!polling) {
@ -67,6 +69,10 @@
);
});
await listen("updateLogPath", (event) => {
logfile = event.payload as string;
});
await emit("ready", "");
updatePolling(true);
@ -106,6 +112,10 @@
async function quit() {
await emit("quit", "");
}
async function logs() {
await open(logfile);
}
</script>
<main class="main">
@ -138,10 +148,12 @@
<div class="row">
<div class="label" />
<div class="input">
Brokenithm open at:
<pre>
{ips.map((x) => `http://${x}:1606/`).join("\n")}
</pre>
<div class="serverlist">
Brokenithm open at:
<pre>
{ips.map((x) => `http://${x}:1606/`).join("\n")}
</pre>
</div>
</div>
</div>
{/if}
@ -156,6 +168,9 @@
<option value="kb-8-deemo">Keyboard 8-zone, Deemo Layout</option>
<option value="kb-voltex">Keyboard 10-zone, Voltex Layout</option>
<option value="gamepad-voltex">XBOX 360 Gamepad, Voltex Layout</option>
<option value="gamepad-neardayo"
>XBOX 360 Gamepad, Neardayo Layout</option
>
<!-- <option value="websocket">Websocket</option> -->
</select>
</div>
@ -299,6 +314,9 @@
>
<button on:click={async () => await hide()}>Hide</button>
<button on:click={async () => await quit()}>Quit</button>
{#if !!logfile.length}
<button on:click={async () => await logs()}>Logs</button>
{/if}
</div>
</main>

View File

@ -3,6 +3,8 @@
let topDatas = Array(16).fill(0);
let botDatas = Array(16).fill(0);
let airDatas = Array(6).fill(0);
let extraDatas = Array(3).fill(0);
let ledDatas = Array(31)
.fill(0)
.map((_, idx) => ({
@ -11,15 +13,22 @@
}));
$: {
if (data.length === 131) {
if (data.length === 134) {
// console.log(data);
for (let i = 0; i < 16; i++) {
topDatas[i] = data[i * 2 + 1];
botDatas[i] = data[i * 2];
}
for (let i = 0; i < 6; i++) {
airDatas[i] = data[32 + i];
}
for (let i = 0; i < 3; i++) {
extraDatas[i] = data[38 + i];
}
for (let i = 0; i < 31; i++) {
ledDatas[i].color = `rgb(${data[38 + i * 3]}, ${data[39 + i * 3]}, ${
data[40 + i * 3]
ledDatas[i].color = `rgb(${data[41 + i * 3]}, ${data[42 + i * 3]}, ${
data[43 + i * 3]
})`;
}
}
@ -27,7 +36,11 @@
</script>
<main class="preview">
<div class="air" />
<div class="air">
{#each airDatas as airData, idx (idx)}
<div class={`air-data air-data-${airData}`} />
{/each}
</div>
<div class="ground">
<div class="ground-led">
<div class="ground-row">
@ -54,4 +67,9 @@
</div>
</div>
</div>
<div class="extra">
{#each extraDatas as extraData, idx (idx)}
<div class={`extra-data extra-data-${extraData}`} />
{/each}
</div>
</main>