mirror of
https://github.com/kaesaecracker/servicepoint-simulator.git
synced 2025-01-18 10:30:14 +01:00
use parser from shared library
This commit is contained in:
parent
88409faa02
commit
bce0c48c4d
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -2151,7 +2151,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servicepoint2"
|
name = "servicepoint2"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/kaesaecracker/servicepoint.git#9eaa7462bccee02f698779b0fb4b9c1e9676bc60"
|
source = "git+https://github.com/kaesaecracker/servicepoint.git#c7456f0a67b5488cca777ea702144cd9996698c0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num",
|
"num",
|
||||||
"num-derive",
|
"num-derive",
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
mod font;
|
mod font;
|
||||||
mod gui;
|
mod gui;
|
||||||
mod protocol;
|
|
||||||
mod upd_loop;
|
mod upd_loop;
|
||||||
|
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
use num_derive::{FromPrimitive, ToPrimitive};
|
|
||||||
use servicepoint2::CommandCode;
|
|
||||||
use std::mem::size_of;
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct HdrWindow {
|
|
||||||
pub command: CommandCode,
|
|
||||||
pub x: u16,
|
|
||||||
pub y: u16,
|
|
||||||
pub w: u16,
|
|
||||||
pub h: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct HdrBitmap {
|
|
||||||
pub command: DisplayCommand,
|
|
||||||
pub offset: u16,
|
|
||||||
pub length: u16,
|
|
||||||
pub subcommand: DisplaySubcommand,
|
|
||||||
reserved: u16,
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#[repr(u16)]
|
|
||||||
#[derive(Debug, FromPrimitive, ToPrimitive)]
|
|
||||||
pub enum DisplaySubcommand {
|
|
||||||
SubCmdBitmapNormal = 0x0,
|
|
||||||
SubCmdBitmapCompressZ = 0x677a,
|
|
||||||
SubCmdBitmapCompressBz = 0x627a,
|
|
||||||
SubCmdBitmapCompressLz = 0x6c7a,
|
|
||||||
SubCmdBitmapCompressZs = 0x7a73,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum ReadHeaderError {
|
|
||||||
BufferTooSmall,
|
|
||||||
WrongCommandEndianness(u16, CommandCode),
|
|
||||||
InvalidCommand(u16),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HdrWindow {
|
|
||||||
pub fn from_buffer(buffer: &[u8]) -> Result<HdrWindow, ReadHeaderError> {
|
|
||||||
assert_eq!(size_of::<HdrWindow>(), 10, "invalid struct size");
|
|
||||||
|
|
||||||
if buffer.len() < size_of::<HdrWindow>() {
|
|
||||||
return Err(ReadHeaderError::BufferTooSmall);
|
|
||||||
}
|
|
||||||
|
|
||||||
let command_u16 = Self::read_beu16(&buffer[0..=1]);
|
|
||||||
return match CommandCode::from_primitive(command_u16) {
|
|
||||||
Some(command) => Ok(HdrWindow {
|
|
||||||
command,
|
|
||||||
x: Self::read_beu16(&buffer[2..=3]),
|
|
||||||
y: Self::read_beu16(&buffer[4..=5]),
|
|
||||||
w: Self::read_beu16(&buffer[6..=7]),
|
|
||||||
h: Self::read_beu16(&buffer[8..=9]),
|
|
||||||
}),
|
|
||||||
None => {
|
|
||||||
let maybe_command = CommandCode::from_primitive(u16::swap_bytes(command_u16));
|
|
||||||
return match maybe_command {
|
|
||||||
None => Err(ReadHeaderError::InvalidCommand(command_u16)),
|
|
||||||
Some(command) => Err(ReadHeaderError::WrongCommandEndianness(
|
|
||||||
command_u16,
|
|
||||||
command,
|
|
||||||
)),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_beu16(buffer: &[u8]) -> u16 {
|
|
||||||
let buffer: [u8; 2] = buffer
|
|
||||||
.try_into()
|
|
||||||
.expect("cannot read u16 from buffer with size != 2");
|
|
||||||
return u16::from_be_bytes(buffer);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +1,7 @@
|
||||||
use crate::font::BitmapFont;
|
use crate::font::BitmapFont;
|
||||||
use crate::protocol::{HdrWindow, ReadHeaderError};
|
|
||||||
use crate::DISPLAY;
|
use crate::DISPLAY;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use servicepoint2::{PixelGrid, PIXEL_WIDTH, TILE_SIZE, CommandCode};
|
use servicepoint2::{Command, Origin, Packet, PixelGrid, PIXEL_WIDTH, TILE_SIZE, Window, Size};
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
use std::net::{ToSocketAddrs, UdpSocket};
|
use std::net::{ToSocketAddrs, UdpSocket};
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
@ -47,7 +46,10 @@ impl UdpThread {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::handle_package(&mut buf[..amount], &font);
|
let vec = buf[..amount].to_vec();
|
||||||
|
let package = servicepoint2::Packet::from(vec);
|
||||||
|
|
||||||
|
Self::handle_package(package, &font);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -59,53 +61,29 @@ impl UdpThread {
|
||||||
self.thread.join().expect("could not wait on udp thread");
|
self.thread.join().expect("could not wait on udp thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_package(received: &mut [u8], font: &BitmapFont) {
|
fn handle_package(received: Packet, font: &BitmapFont) {
|
||||||
let header = match HdrWindow::from_buffer(&received[..10]) {
|
// TODO handle error case
|
||||||
Err(ReadHeaderError::BufferTooSmall) => {
|
let command = Command::try_from(received).unwrap();
|
||||||
error!("received a packet that is too small");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Err(ReadHeaderError::InvalidCommand(command_u16)) => {
|
|
||||||
error!("received invalid command {}", command_u16);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Err(ReadHeaderError::WrongCommandEndianness(command_u16, command_swapped)) => {
|
|
||||||
error!(
|
|
||||||
"The reversed byte order of {} matches command {:?}, you are probably sending the wrong endianness",
|
|
||||||
command_u16, command_swapped
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Ok(value) => value,
|
|
||||||
};
|
|
||||||
|
|
||||||
let payload = &received[10..];
|
match command {
|
||||||
|
Command::Clear => {
|
||||||
info!(
|
|
||||||
"received from {:?} (and {} bytes of payload)",
|
|
||||||
header,
|
|
||||||
payload.len()
|
|
||||||
);
|
|
||||||
|
|
||||||
match header.command {
|
|
||||||
CommandCode::Clear => {
|
|
||||||
info!("clearing display");
|
info!("clearing display");
|
||||||
for v in unsafe { DISPLAY.iter_mut() } {
|
for v in unsafe { DISPLAY.iter_mut() } {
|
||||||
*v = false;
|
*v = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CommandCode::HardReset => {
|
Command::HardReset => {
|
||||||
warn!("display shutting down");
|
warn!("display shutting down");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CommandCode::BitmapLinearWin => {
|
Command::BitmapLinearWin(Origin(x, y), pixels) => {
|
||||||
Self::print_bitmap_linear_win(&header, payload);
|
Self::print_pixel_grid(x as usize, y as usize, &pixels);
|
||||||
}
|
}
|
||||||
CommandCode::Cp437Data => {
|
Command::Cp437Data(window, payload) => {
|
||||||
Self::print_cp437_data(&header, payload, font);
|
Self::print_cp437_data(window, &payload, font);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
error!("command {:?} not implemented yet", header.command);
|
error!("command {:?} not implemented yet", command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,35 +101,18 @@ impl UdpThread {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_bitmap_linear_win(header: &HdrWindow, payload: &[u8]) {
|
fn print_cp437_data(window: Window, payload: &[u8], font: &BitmapFont) {
|
||||||
if !Self::check_payload_size(payload, header.w as usize * header.h as usize) {
|
let Window(Origin(x,y), Size(w, h)) = window;
|
||||||
|
if !UdpThread::check_payload_size(payload, (w * h) as usize) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let pixel_grid = PixelGrid::load(
|
for char_y in 0usize..h as usize {
|
||||||
header.w as usize * TILE_SIZE as usize,
|
for char_x in 0usize..w as usize {
|
||||||
header.h as usize,
|
let char_code = payload[char_y * w as usize + char_x];
|
||||||
payload,
|
|
||||||
);
|
|
||||||
|
|
||||||
Self::print_pixel_grid(
|
let tile_x = char_x + x as usize;
|
||||||
header.x as usize * TILE_SIZE as usize,
|
let tile_y = char_y + y as usize;
|
||||||
header.y as usize,
|
|
||||||
&pixel_grid,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_cp437_data(header: &HdrWindow, payload: &[u8], font: &BitmapFont) {
|
|
||||||
if !UdpThread::check_payload_size(payload, (header.w * header.h) as usize) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for char_y in 0usize..header.h as usize {
|
|
||||||
for char_x in 0usize..header.w as usize {
|
|
||||||
let char_code = payload[char_y * header.w as usize + char_x];
|
|
||||||
|
|
||||||
let tile_x = char_x + header.x as usize;
|
|
||||||
let tile_y = char_y + header.y as usize;
|
|
||||||
|
|
||||||
let bitmap = font.get_bitmap(char_code);
|
let bitmap = font.get_bitmap(char_code);
|
||||||
Self::print_pixel_grid(
|
Self::print_pixel_grid(
|
||||||
|
@ -164,7 +125,10 @@ impl UdpThread {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_pixel_grid(offset_x: usize, offset_y: usize, pixels: &PixelGrid) {
|
fn print_pixel_grid(offset_x: usize, offset_y: usize, pixels: &PixelGrid) {
|
||||||
debug!("printing {}x{} grid at {offset_x} {offset_y}", pixels.width, pixels.height);
|
debug!(
|
||||||
|
"printing {}x{} grid at {offset_x} {offset_y}",
|
||||||
|
pixels.width, pixels.height
|
||||||
|
);
|
||||||
for inner_y in 0..pixels.height {
|
for inner_y in 0..pixels.height {
|
||||||
for inner_x in 0..pixels.width {
|
for inner_x in 0..pixels.width {
|
||||||
let is_set = pixels.get(inner_x, inner_y);
|
let is_set = pixels.get(inner_x, inner_y);
|
||||||
|
|
Loading…
Reference in a new issue