Skip to content

Commit

Permalink
Store a matrix object in server state and draw data to it
Browse files Browse the repository at this point in the history
  • Loading branch information
saltire committed Nov 10, 2020
1 parent 2790a62 commit 898617b
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 77 deletions.
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod matrix;
mod server;

fn main() {
matrix::usb();
let anime = matrix::Matrix::new().unwrap();

server::start();
server::start(anime);
}
146 changes: 81 additions & 65 deletions src/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,89 +93,105 @@ const PANE2_ROWS: [(usize, usize); 35] = [
const PANE2_Y_OFFSET: usize = 20;
const PANE2_X_OFFSET: usize = 3;

fn send(buf: &[u8], device_handle: &DeviceHandle<GlobalContext>, timeout: &Duration) {
let mut buffer = [0u8; 640];
for x in 0..buf.len() {
buffer[x] = buf[x];
}
// println!("{:02X?}", buffer);

match device_handle.write_control(REQUEST_TYPE, REQUEST, VALUE, 0, &buffer, *timeout) {
Ok(_) => {},
Err(e) => println!("Error: {}", e)
}
pub struct Matrix {
device_handle: DeviceHandle<GlobalContext>,
timeout: Duration,
}

fn send_pixels(pixels: Vec<Vec<u8>>, device_handle: &DeviceHandle<GlobalContext>, timeout: &Duration) {
let mut pane1 = [0u8; 640];
for x in 0..7 {
pane1[x] = PANE1_HEADER[x];
}
for (r, (index, width)) in PANE1_ROWS.iter().enumerate() {
for x in 0..*width {
pane1[index + x] = pixels[r][x];
impl Matrix {
fn send(&self, buf: &[u8]) {
let mut buffer = [0u8; 640];
for x in 0..buf.len() {
buffer[x] = buf[x];
}
}
// println!("{:02X?}", buffer);

let mut pane2 = [0u8; 640];
for x in 0..7 {
pane2[x] = PANE2_HEADER[x];
match self.device_handle.write_control(REQUEST_TYPE, REQUEST, VALUE, 0, &buffer, self.timeout) {
Ok(_) => {},
Err(e) => println!("Error: {}", e)
}
}
for (r, (index, width)) in PANE2_ROWS.iter().enumerate() {
let x_offset = if r == 0 { PANE2_X_OFFSET } else { 0 };
for x in 0..*width {
pane2[index + x] = pixels[r + PANE2_Y_OFFSET][x + x_offset];

pub fn send_pixels(&self, pixels: &Vec<Vec<u8>>) {
let mut pane1 = [0u8; 640];
for x in 0..7 {
pane1[x] = PANE1_HEADER[x];
}
for (r, (index, width)) in PANE1_ROWS.iter().enumerate() {
for x in 0..*width {
pane1[index + x] = pixels[r][x];
}
}

let mut pane2 = [0u8; 640];
for x in 0..7 {
pane2[x] = PANE2_HEADER[x];
}
for (r, (index, width)) in PANE2_ROWS.iter().enumerate() {
let x_offset = if r == 0 { PANE2_X_OFFSET } else { 0 };
for x in 0..*width {
pane2[index + x] = pixels[r + PANE2_Y_OFFSET][x + x_offset];
}
}

self.send(&pane1);
self.send(&pane2);
self.send(&FLUSH);
}

send(&pane1, &device_handle, &timeout);
send(&pane2, &device_handle, &timeout);
send(&FLUSH, &device_handle, &timeout);
}
pub fn new() -> Option<Matrix> {
// let tick = Duration::new(0, 500 * 1000000);
// let timeout = Duration::new(5, 0);

pub fn usb() {
// let tick = Duration::new(0, 500 * 1000000);
let timeout = Duration::new(5, 0);
for device in rusb::devices().unwrap().iter() {
let device_desc = device.device_descriptor().unwrap();

for device in rusb::devices().unwrap().iter() {
let device_desc = device.device_descriptor().unwrap();
if device_desc.vendor_id() == VENDOR_ID && device_desc.product_id() == PRODUCT_ID {
let mut device_handle = device.open().unwrap(); // sends GET_DESCRIPTOR_FROM_DEVICE x2

if device_desc.vendor_id() == VENDOR_ID && device_desc.product_id() == PRODUCT_ID {
let mut device_handle = device.open().unwrap(); // sends GET_DESCRIPTOR_FROM_DEVICE x2
// This device has 1 config, 1 interface, 1 endpoint.
let config = device.active_config_descriptor().unwrap();
let interface = config.interfaces().next().unwrap();

// This device has 1 config, 1 interface, 1 endpoint.
let config = device.active_config_descriptor().unwrap();
let interface = config.interfaces().next().unwrap();
// device_handle.reset().unwrap();

// device_handle.reset().unwrap();
device_handle.claim_interface(interface.number()).unwrap();

device_handle.claim_interface(interface.number()).unwrap();
let matrix = Matrix {
device_handle,
timeout: Duration::new(5, 0),
};

send(&INIT_HEADER, &device_handle, &timeout);
// send(&INIT_01, &device_handle, &timeout);
// send(&INIT_02, &device_handle, &timeout);
matrix.send(&INIT_HEADER);
// send(&INIT_01, &device_handle, &timeout);
// send(&INIT_02, &device_handle, &timeout);

for buf in [INIT1, INIT2, INIT3].iter() {
send(buf, &device_handle, &timeout);
}
for buf in [INIT1, INIT2, INIT3].iter() {
matrix.send(buf);
}

let mut widths = vec![];
for (_index, width) in PANE1_ROWS.iter() {
widths.push(*width);
}
for (r, (_index, width)) in PANE2_ROWS.iter().enumerate() {
let last_width = if r == 0 { widths.pop().unwrap() } else { 0 };
widths.push(last_width + width);
}
let mut pixels = vec![];
for width in widths {
let mut row = vec![0u8; width];
row[0] = 255;
row[width - 1] = 255;
pixels.push(row);
}
// let mut widths = vec![];
// for (_index, width) in PANE1_ROWS.iter() {
// widths.push(*width);
// }
// for (r, (_index, width)) in PANE2_ROWS.iter().enumerate() {
// let last_width = if r == 0 { widths.pop().unwrap() } else { 0 };
// widths.push(last_width + width);
// }
// let mut pixels = vec![];
// for width in widths {
// let mut row = vec![0u8; width];
// row[0] = 255;
// row[width - 1] = 255;
// pixels.push(row);
// }

// matrix.send_pixels(&pixels);

send_pixels(pixels, &device_handle, &timeout);
return Some(matrix);
}
}

None
}
}
10 changes: 7 additions & 3 deletions src/server.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
use serde::Deserialize;
use rocket::State;
use rocket_contrib::json::Json;
use rocket_contrib::serve::StaticFiles;

use super::matrix::Matrix;


#[derive(Deserialize)]
struct Data {
rows: Vec<Vec<u8>>,
}

#[post("/post", format = "json", data = "<data>")]
fn post(data: Json<Data>) -> () {
println!("{:?}", data.rows);
fn post(data: Json<Data>, matrix: State<Matrix>) -> () {
matrix.send_pixels(&data.rows);
}

pub fn start() {
pub fn start(matrix: Matrix) {
rocket::ignite()
.manage(matrix)
.mount("/", StaticFiles::from("web"))
.mount("/", routes![post])
.launch();
Expand Down
16 changes: 9 additions & 7 deletions web/web.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ const widths = [
26, 26, 25, 25, 24, 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18,
17, 17, 16, 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9,
];
const size = 10;
const canvaswidth = (Math.max(...widths) + 0.5) * size;
const canvasheight = ((widths.length / 2) + 0.5) * size;
const xsize = 30;
const ysize = 20;
const canvaswidth = (Math.max(...widths) + 0.5) * xsize;
const canvasheight = ((widths.length / 2) + 0.5) * ysize;

grid.setAttribute('viewBox', `0 0 ${canvaswidth} ${canvasheight}`);

Expand All @@ -22,7 +23,7 @@ const map = {};

const drawDiamond = (x, y) => {
const poly = document.createElementNS(ns, 'polygon');
const ox = x + (y % 2 ? 0.5 : 0);
const ox = x + (y % 2 ? 0 : 0.5);
const oy = y / 2;
poly.setAttribute('points',
[
Expand All @@ -31,7 +32,7 @@ const drawDiamond = (x, y) => {
[ox + 0.5, oy + 1],
[ox, oy + 0.5],
]
.map(point => point.map(v => v * size).join(','))
.map(([px, py]) => [px * xsize, py * ysize].join(','))
.join(' '));
poly.setAttribute('fill', '#000000');
grid.appendChild(poly);
Expand All @@ -52,8 +53,9 @@ const drawDiamond = (x, y) => {

widths.forEach((width, y) => {
for (let x = 0; x < width; x++) {
// Shift thr first row right by one.
map[`${x},${y}`] = drawDiamond(y === 0 ? x + 1 : x, y);
// Shift the first row left by one.
const offset = 33 - width - (y === 0 ? 1 : 0);
map[`${x},${y}`] = drawDiamond(offset + x, y);
}
});

Expand Down

0 comments on commit 898617b

Please sign in to comment.