mirror of
https://github.com/4yn/slidershim.git
synced 2024-11-27 15:00:49 +01:00
add brokestalgia controller
This commit is contained in:
parent
8fbb9e4d9f
commit
d89de5e6fc
@ -3,7 +3,9 @@ extern crate slider_io;
|
||||
use std::io;
|
||||
|
||||
use slider_io::{
|
||||
device::brokenithm::BrokenithmJob, shared::worker::AsyncHaltableWorker, state::SliderState,
|
||||
device::{brokenithm::BrokenithmJob, config::BrokenithmSpec},
|
||||
shared::worker::AsyncHaltableWorker,
|
||||
state::SliderState,
|
||||
};
|
||||
|
||||
#[tokio::main]
|
||||
@ -14,7 +16,10 @@ async fn main() {
|
||||
|
||||
let state = SliderState::new();
|
||||
|
||||
let _worker = AsyncHaltableWorker::new("brokenithm", BrokenithmJob::new(&state, &false, &false));
|
||||
let _worker = AsyncHaltableWorker::new(
|
||||
"brokenithm",
|
||||
BrokenithmJob::new(&state, &BrokenithmSpec::Nostalgia, &false),
|
||||
);
|
||||
let mut input = String::new();
|
||||
io::stdin().read_line(&mut input).unwrap();
|
||||
}
|
||||
|
@ -40,14 +40,14 @@ impl Context {
|
||||
match &config.device_mode {
|
||||
DeviceMode::None => (None, None, None),
|
||||
DeviceMode::Brokenithm {
|
||||
ground_only,
|
||||
spec,
|
||||
lights_enabled,
|
||||
} => (
|
||||
None,
|
||||
None,
|
||||
Some(AsyncHaltableWorker::new(
|
||||
"brokenithm",
|
||||
BrokenithmJob::new(&state, ground_only, lights_enabled),
|
||||
BrokenithmJob::new(&state, spec, lights_enabled),
|
||||
)),
|
||||
),
|
||||
DeviceMode::Hardware { spec, disable_air } => (
|
||||
|
File diff suppressed because one or more lines are too long
135
src-slider_io/src/device/brokenithm-www/index-ns.html
Normal file
135
src-slider_io/src/device/brokenithm-www/index-ns.html
Normal file
@ -0,0 +1,135 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>slidershim-brokenithm</title>
|
||||
<meta charset="utf8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||
/>
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<link rel="apple-touch-icon" sizes="192x192" href="/icon.png" />
|
||||
<style>
|
||||
#fullscreen {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
background: #000000;
|
||||
color: hotpink;
|
||||
}
|
||||
|
||||
.container {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
touch-action: none;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.air-container {
|
||||
/* display: flex; */
|
||||
display: none;
|
||||
flex-flow: column nowrap;
|
||||
align-items: stretch;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.touch-container {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: stretch;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.grow > * {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.key {
|
||||
flex: 1;
|
||||
border: 1px solid green;
|
||||
}
|
||||
|
||||
.key[data-active] {
|
||||
background-color: hotpink;
|
||||
}
|
||||
|
||||
.key.air[data-active] {
|
||||
background-color: skyblue;
|
||||
}
|
||||
|
||||
canvas {
|
||||
-ms-interpolation-mode: nearest-neighbor;
|
||||
image-rendering: crisp-edges;
|
||||
image-rendering: pixelated;
|
||||
touch-action: none;
|
||||
margin: 0px -1.5625vw;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="fullscreen">
|
||||
<!-- Offset for LED display -->
|
||||
<div class="container">
|
||||
<div class="air-container grow"></div>
|
||||
<div class="touch-container grow">
|
||||
<canvas id="canvas" width="33" height="1"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Hitbox Divs -->
|
||||
<div class="container" id="main">
|
||||
<div class="air-container grow">
|
||||
<div class="air key" data-air="1" data-kflag="5"></div>
|
||||
<div class="air key" data-air="1" data-kflag="4"></div>
|
||||
<div class="air key" data-air="1" data-kflag="3"></div>
|
||||
<div class="air key" data-air="1" data-kflag="2"></div>
|
||||
<div class="air key" data-air="1" data-kflag="1"></div>
|
||||
<div class="air key" data-air="1" data-kflag="0"></div>
|
||||
</div>
|
||||
<div class="touch-container grow">
|
||||
<div class="key" data-kflag="0"></div>
|
||||
<div class="key" data-kflag="1"></div>
|
||||
<div class="key" data-kflag="2"></div>
|
||||
<div class="key" data-kflag="3"></div>
|
||||
<div class="key" data-kflag="4"></div>
|
||||
<div class="key" data-kflag="5"></div>
|
||||
<div class="key" data-kflag="6"></div>
|
||||
<div class="key" data-kflag="7"></div>
|
||||
<div class="key" data-kflag="8"></div>
|
||||
<div class="key" data-kflag="9"></div>
|
||||
<div class="key" data-kflag="10"></div>
|
||||
<div class="key" data-kflag="11"></div>
|
||||
<div class="key" data-kflag="12"></div>
|
||||
<div class="key" data-kflag="13"></div>
|
||||
<div class="key" data-kflag="14"></div>
|
||||
<div class="key" data-kflag="15"></div>
|
||||
<div class="key" data-kflag="16"></div>
|
||||
<div class="key" data-kflag="17"></div>
|
||||
<div class="key" data-kflag="18"></div>
|
||||
<div class="key" data-kflag="19"></div>
|
||||
<div class="key" data-kflag="20"></div>
|
||||
<div class="key" data-kflag="21"></div>
|
||||
<div class="key" data-kflag="22"></div>
|
||||
<div class="key" data-kflag="23"></div>
|
||||
<div class="key" data-kflag="24"></div>
|
||||
<div class="key" data-kflag="25"></div>
|
||||
<div class="key" data-kflag="26"></div>
|
||||
<div class="key" data-kflag="27"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/config.js"></script>
|
||||
<script>
|
||||
var allAir = true;
|
||||
</script>
|
||||
<script src="/app.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -46,7 +46,7 @@ const compileKey = (key) => {
|
||||
almostLeft: !!prev ? key.offsetLeft + key.offsetWidth / 4 : -99999,
|
||||
almostRight: !!next ? key.offsetLeft + (key.offsetWidth * 3) / 4 : 99999,
|
||||
kflag: parseInt(key.dataset.kflag) + (parseInt(key.dataset.air) ? 32 : 0),
|
||||
isAir: parseInt(key.dataset.air) ? true : false,
|
||||
isAir: parseInt(key.dataset.air) ? true : window.allAir || false,
|
||||
prevKeyRef: prev,
|
||||
prevKeyKflag: prev
|
||||
? parseInt(prev.dataset.kflag) + (parseInt(prev.dataset.air) ? 32 : 0)
|
||||
@ -70,9 +70,9 @@ const compileKeys = () => {
|
||||
keys = document.getElementsByClassName("key");
|
||||
airKeys = [];
|
||||
touchKeys = [];
|
||||
for (var i = 0, key; i < keys.length; i++) {
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
const compiledKey = compileKey(keys[i]);
|
||||
if (!compiledKey.isAir) {
|
||||
if (compiledKey.kflag < 32) {
|
||||
touchKeys.push(compiledKey);
|
||||
} else {
|
||||
airKeys.push(compiledKey);
|
||||
@ -80,6 +80,38 @@ const compileKeys = () => {
|
||||
allKeys.push(compiledKey);
|
||||
}
|
||||
|
||||
touchKeys.memo = {};
|
||||
airKeys.memo = {};
|
||||
|
||||
touchKeys.getAxis = (x, y) => x;
|
||||
airKeys.getAxis = (x, y) => y;
|
||||
|
||||
var getKey = function (x, y) {
|
||||
var c = this.getAxis(x, y);
|
||||
var res = this.memo[c];
|
||||
if (res === undefined) {
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
if (isInside(x, y, this[i])) {
|
||||
res = this[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.memo[c] = res;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
touchKeys.getKey = getKey;
|
||||
airKeys.getKey = getKey;
|
||||
|
||||
for (var i = 0; i < window.outerWidth; i++) {
|
||||
touchKeys.getKey(i, touchKeys[0].top);
|
||||
}
|
||||
|
||||
for (var i = 0; i < window.outerHeight; i++) {
|
||||
airKeys.getKey(airKeys[0].left, i);
|
||||
}
|
||||
|
||||
if (!config.invert) {
|
||||
// Not inverted
|
||||
topKeys = airKeys;
|
||||
@ -95,15 +127,9 @@ const compileKeys = () => {
|
||||
|
||||
const getKey = (x, y) => {
|
||||
if (y < midline) {
|
||||
for (var i = 0; i < topKeys.length; i++) {
|
||||
if (isInside(x, y, topKeys[i])) return topKeys[i];
|
||||
}
|
||||
return topKeys.getKey(x, y);
|
||||
} else {
|
||||
for (var i = 0; i < bottomKeys.length; i++) {
|
||||
if (isInside(x, y, bottomKeys[i])) {
|
||||
return bottomKeys[i];
|
||||
}
|
||||
}
|
||||
return bottomKeys.getKey(x, y);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@ -241,9 +267,9 @@ const updateLed = (data) => {
|
||||
canvasData.data[i * 4 + 5] = buf[i * 3 + 1]; // g
|
||||
canvasData.data[i * 4 + 6] = buf[i * 3 + 2]; // b
|
||||
}
|
||||
canvasData.data[0] = buf[0]
|
||||
canvasData.data[1] = buf[1]
|
||||
canvasData.data[2] = buf[2]
|
||||
canvasData.data[0] = buf[0];
|
||||
canvasData.data[1] = buf[1];
|
||||
canvasData.data[2] = buf[2];
|
||||
canvasData.data[128] = buf[90];
|
||||
canvasData.data[129] = buf[91];
|
||||
canvasData.data[130] = buf[92];
|
||||
|
@ -18,7 +18,7 @@ use tokio::{
|
||||
use tokio_tungstenite::WebSocketStream;
|
||||
use tungstenite::{handshake, Message};
|
||||
|
||||
use crate::{shared::worker::AsyncHaltableJob, state::SliderState};
|
||||
use crate::{device::config::BrokenithmSpec, shared::worker::AsyncHaltableJob, state::SliderState};
|
||||
|
||||
// https://levelup.gitconnected.com/handling-websocket-and-http-on-the-same-port-with-rust-f65b770722c9
|
||||
|
||||
@ -36,6 +36,7 @@ async fn error_response() -> Result<Response<Body>, Infallible> {
|
||||
static BROKENITHM_STR_FILES: phf::Map<&'static str, (&'static str, &'static str)> = phf_map! {
|
||||
"app.js" => (include_str!("./brokenithm-www/app.js"), "text/javascript"),
|
||||
"config.js" => (include_str!("./brokenithm-www/config.js"), "text/javascript"),
|
||||
"index-ns.html" => (include_str!("./brokenithm-www/index-ns.html"), "text/html"),
|
||||
"index-go.html" => (include_str!("./brokenithm-www/index-go.html"), "text/html"),
|
||||
"index.html" => (include_str!("./brokenithm-www/index.html"), "text/html"),
|
||||
};
|
||||
@ -234,7 +235,7 @@ async fn handle_request(
|
||||
request: Request<Body>,
|
||||
remote_addr: SocketAddr,
|
||||
state: SliderState,
|
||||
ground_only: bool,
|
||||
spec: BrokenithmSpec,
|
||||
lights_enabled: bool,
|
||||
) -> Result<Response<Body>, Infallible> {
|
||||
let method = request.method();
|
||||
@ -252,9 +253,10 @@ async fn handle_request(
|
||||
request.uri().path(),
|
||||
request.headers().contains_key(header::UPGRADE),
|
||||
) {
|
||||
("/", false) | ("/index.html", false) => match ground_only {
|
||||
false => serve_file("index.html").await,
|
||||
true => serve_file("index-go.html").await,
|
||||
("/", false) | ("/index.html", false) => match spec {
|
||||
BrokenithmSpec::Basic => serve_file("index.html").await,
|
||||
BrokenithmSpec::GroundOnly => serve_file("index-go.html").await,
|
||||
BrokenithmSpec::Nostalgia => serve_file("index-ns.html").await,
|
||||
},
|
||||
(filename, false) => serve_file(&filename[1..]).await,
|
||||
("/ws", true) => handle_websocket(request, state, lights_enabled).await,
|
||||
@ -264,15 +266,15 @@ async fn handle_request(
|
||||
|
||||
pub struct BrokenithmJob {
|
||||
state: SliderState,
|
||||
ground_only: bool,
|
||||
spec: BrokenithmSpec,
|
||||
lights_enabled: bool,
|
||||
}
|
||||
|
||||
impl BrokenithmJob {
|
||||
pub fn new(state: &SliderState, ground_only: &bool, lights_enabled: &bool) -> Self {
|
||||
pub fn new(state: &SliderState, spec: &BrokenithmSpec, lights_enabled: &bool) -> Self {
|
||||
Self {
|
||||
state: state.clone(),
|
||||
ground_only: *ground_only,
|
||||
spec: spec.clone(),
|
||||
lights_enabled: *lights_enabled,
|
||||
}
|
||||
}
|
||||
@ -282,15 +284,17 @@ impl BrokenithmJob {
|
||||
impl AsyncHaltableJob for BrokenithmJob {
|
||||
async fn run<F: Future<Output = ()> + Send>(self, stop_signal: F) {
|
||||
let state = self.state.clone();
|
||||
let ground_only = self.ground_only;
|
||||
let spec = self.spec.clone();
|
||||
let lights_enabled = self.lights_enabled;
|
||||
let make_svc = make_service_fn(|conn: &AddrStream| {
|
||||
let remote_addr = conn.remote_addr();
|
||||
let make_svc_state = state.clone();
|
||||
let make_spec = spec.clone();
|
||||
async move {
|
||||
Ok::<_, Infallible>(service_fn(move |request: Request<Body>| {
|
||||
let svc_state = make_svc_state.clone();
|
||||
handle_request(request, remote_addr, svc_state, ground_only, lights_enabled)
|
||||
let spec = make_spec.clone();
|
||||
handle_request(request, remote_addr, svc_state, spec, lights_enabled)
|
||||
}))
|
||||
}
|
||||
});
|
||||
|
@ -7,6 +7,13 @@ pub enum HardwareSpec {
|
||||
Yuancon,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum BrokenithmSpec {
|
||||
Basic,
|
||||
GroundOnly,
|
||||
Nostalgia,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DeviceMode {
|
||||
None,
|
||||
@ -15,7 +22,7 @@ pub enum DeviceMode {
|
||||
disable_air: bool,
|
||||
},
|
||||
Brokenithm {
|
||||
ground_only: bool,
|
||||
spec: BrokenithmSpec,
|
||||
lights_enabled: bool,
|
||||
},
|
||||
DivaSlider {
|
||||
@ -45,13 +52,23 @@ impl DeviceMode {
|
||||
brightness: u8::try_from(v["divaBrightness"].as_i64()?).ok()?,
|
||||
},
|
||||
"brokenithm" => DeviceMode::Brokenithm {
|
||||
ground_only: v["disableAirStrings"].as_bool()?,
|
||||
spec: match v["disableAirStrings"].as_bool()? {
|
||||
false => BrokenithmSpec::Basic,
|
||||
true => BrokenithmSpec::GroundOnly,
|
||||
},
|
||||
lights_enabled: false,
|
||||
},
|
||||
"brokenithm-led" => DeviceMode::Brokenithm {
|
||||
ground_only: v["disableAirStrings"].as_bool()?,
|
||||
spec: match v["disableAirStrings"].as_bool()? {
|
||||
false => BrokenithmSpec::Basic,
|
||||
true => BrokenithmSpec::GroundOnly,
|
||||
},
|
||||
lights_enabled: true,
|
||||
},
|
||||
"brokenithm-nostalgia" => DeviceMode::Brokenithm {
|
||||
spec: BrokenithmSpec::Nostalgia,
|
||||
lights_enabled: false,
|
||||
},
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
@ -177,10 +177,11 @@
|
||||
<option value="diva">Slider over Serial</option>
|
||||
<option value="brokenithm">Brokenithm</option>
|
||||
<option value="brokenithm-led">Brokenithm + Led</option>
|
||||
<option value="brokenithm-nostalgia">Brokestalgia (28k)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{#if deviceMode.slice(0, 8) === "tasoller" || deviceMode.slice(0, 7) === "yuancon" || deviceMode.slice(0, 10) === "brokenithm"}
|
||||
{#if deviceMode.slice(0, 8) === "tasoller" || deviceMode.slice(0, 7) === "yuancon" || (deviceMode.slice(0, 10) === "brokenithm" && deviceMode !== "brokenithm-nostalgia")}
|
||||
<div class="row">
|
||||
<div class="label" />
|
||||
<div class="input">
|
||||
|
Loading…
Reference in New Issue
Block a user