From ce194993be192233e82889c2d1542e5ebcaaed95 Mon Sep 17 00:00:00 2001
From: Vinzenz Schroeter <vinzenz.f.s@gmail.com>
Date: Fri, 2 May 2025 13:15:02 +0200
Subject: [PATCH] update to new (unreleased) servicepoint version

---
 Cargo.lock   | 146 +++++++++++++++++++++++++++++++++++++--------------
 Cargo.toml   |  12 +++--
 src/game.rs  |  21 +++-----
 src/main.rs  |  46 +++++++---------
 src/rules.rs |   2 -
 5 files changed, 143 insertions(+), 84 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index a397605..c7227be 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -72,6 +72,18 @@ version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
 
+[[package]]
+name = "bitvec"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
+dependencies = [
+ "funty",
+ "radium",
+ "tap",
+ "wyz",
+]
+
 [[package]]
 name = "cfg-if"
 version = "1.0.0"
@@ -172,6 +184,12 @@ dependencies = [
  "log",
 ]
 
+[[package]]
+name = "funty"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
+
 [[package]]
 name = "getrandom"
 version = "0.2.15"
@@ -241,6 +259,12 @@ dependencies = [
  "windows-sys 0.48.0",
 ]
 
+[[package]]
+name = "once_cell"
+version = "1.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+
 [[package]]
 name = "parking_lot"
 version = "0.12.2"
@@ -264,6 +288,12 @@ dependencies = [
  "windows-targets 0.52.5",
 ]
 
+[[package]]
+name = "pkg-config"
+version = "0.3.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
+
 [[package]]
 name = "ppv-lite86"
 version = "0.2.17"
@@ -272,9 +302,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.82"
+version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
 dependencies = [
  "unicode-ident",
 ]
@@ -289,21 +319,27 @@ dependencies = [
 ]
 
 [[package]]
-name = "rand"
-version = "0.9.0-alpha.1"
+name = "radium"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d31e63ea85be51c423e52ba8f2e68a3efd53eed30203ee029dd09947333693e"
+checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
 dependencies = [
+ "libc",
  "rand_chacha",
  "rand_core",
- "zerocopy",
 ]
 
 [[package]]
 name = "rand_chacha"
-version = "0.9.0-alpha.1"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78674ef918c19451dbd250f8201f8619b494f64c9aa6f3adb28fd8a0f1f6da46"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
 dependencies = [
  "ppv-lite86",
  "rand_core",
@@ -311,12 +347,11 @@ dependencies = [
 
 [[package]]
 name = "rand_core"
-version = "0.9.0-alpha.1"
+version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc89dffba8377c5ec847d12bb41492bda235dba31a25e8b695cd0fe6589eb8c9"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
 dependencies = [
  "getrandom",
- "zerocopy",
 ]
 
 [[package]]
@@ -357,12 +392,35 @@ version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
 
+[[package]]
+name = "rust-lzma"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d62915608f6cee1d7f2fc00f28b4f058ff79d6e4ec3c2fe0006b09b52437c84"
+dependencies = [
+ "pkg-config",
+ "vcpkg",
+]
+
 [[package]]
 name = "scopeguard"
 version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
 
+[[package]]
+name = "servicepoint"
+version = "0.14.0"
+source = "git+https://git.berlin.ccc.de/servicepoint/servicepoint/?branch=next#8ddbaeaaa64a4abb8ffb8b08a3a84cc1135e312f"
+dependencies = [
+ "bitvec",
+ "log",
+ "once_cell",
+ "rand",
+ "rust-lzma",
+ "thiserror",
+]
+
 [[package]]
 name = "servicepoint-life"
 version = "0.1.0"
@@ -372,16 +430,7 @@ dependencies = [
  "env_logger",
  "log",
  "rand",
- "servicepoint2",
-]
-
-[[package]]
-name = "servicepoint2"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94d9aecc4d31a71578481de6c6d64383d374126c38469c9689067579c1d910fd"
-dependencies = [
- "log",
+ "servicepoint",
 ]
 
 [[package]]
@@ -428,15 +477,41 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
 
 [[package]]
 name = "syn"
-version = "2.0.64"
+version = "2.0.101"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ad3dee41f36859875573074334c200d1add8e4a87bb37113ebd31d926b7b11f"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
 dependencies = [
  "proc-macro2",
  "quote",
  "unicode-ident",
 ]
 
+[[package]]
+name = "tap"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
+
+[[package]]
+name = "thiserror"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "unicode-ident"
 version = "1.0.12"
@@ -449,6 +524,12 @@ version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
 
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
 [[package]]
 name = "wasi"
 version = "0.11.0+wasi-snapshot-preview1"
@@ -617,21 +698,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
 
 [[package]]
-name = "zerocopy"
-version = "0.8.0-alpha.6"
+name = "wyz"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db678a6ee512bd06adf35c35be471cae2f9c82a5aed2b5d15e03628c98bddd57"
+checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
 dependencies = [
- "zerocopy-derive",
-]
-
-[[package]]
-name = "zerocopy-derive"
-version = "0.8.0-alpha.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "201585ea96d37ee69f2ac769925ca57160cef31acb137c16f38b02b76f4c1e62"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "tap",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index 9b88435..a2dc836 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,9 +4,15 @@ version = "0.1.0"
 edition = "2021"
 
 [dependencies]
-clap = { version = "4.5.4", features = ["derive"] }
-rand = "0.9.0-alpha.1"
+clap = { version = "4.5", features = ["derive"] }
+rand = "0.8"
 env_logger = "0.11.3"
-servicepoint2 = { version = "0.4.2", default-features = false }
 crossterm = "0.27.0"
 log = "0.4.21"
+
+[dependencies.servicepoint]
+package = "servicepoint"
+version = "0.14.0"
+features = ["rand"]
+git = "https://git.berlin.ccc.de/servicepoint/servicepoint/"
+branch = "next"
diff --git a/src/game.rs b/src/game.rs
index 308440d..7dd344c 100644
--- a/src/game.rs
+++ b/src/game.rs
@@ -1,29 +1,24 @@
-use servicepoint2::Grid;
+use servicepoint::{Grid, Value, ValueGrid};
 
 use crate::rules::Rules;
 
-pub(crate) struct Game<TState, TGrid, TKernel, const KERNEL_SIZE: usize>
+pub(crate) struct Game<TState, TKernel, const KERNEL_SIZE: usize>
 where
-    TGrid: Grid<TState>,
-    TState: Copy + PartialEq,
-    TKernel: Copy,
+    TState: Value + PartialEq,
+    TKernel: Value,
 {
-    pub field: TGrid,
+    pub field: ValueGrid<TState>,
     pub rules: Rules<TState, TKernel, KERNEL_SIZE>,
 }
 
-impl<TState, TGrid, TKernel, const KERNEL_SIZE: usize> Game<TState, TGrid, TKernel, KERNEL_SIZE>
-where
-    TGrid: Grid<TState>,
-    TState: Copy + PartialEq,
-    TKernel: Copy,
+impl<TState: Value + PartialEq, TKernel: Value, const KERNEL_SIZE: usize> Game<TState, TKernel, KERNEL_SIZE>
 {
     pub fn step(&mut self) {
         self.field = self.field_iteration();
     }
 
-    fn field_iteration(&self) -> TGrid {
-        let mut next = TGrid::new(self.field.width(), self.field.height());
+    fn field_iteration(&self) -> ValueGrid<TState> {
+        let mut next = ValueGrid::new(self.field.width(), self.field.height());
         for x in 0..self.field.width() {
             for y in 0..self.field.height() {
                 let old_state = self.field.get(x, y);
diff --git a/src/main.rs b/src/main.rs
index 02e8bda..3ce1c2e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,5 @@
 use std::io::stdout;
+use std::net::UdpSocket;
 use std::num::Wrapping;
 use std::thread;
 use std::time::{Duration, Instant};
@@ -12,12 +13,7 @@ use crossterm::terminal::{
 use log::LevelFilter;
 use rand::distributions::{Distribution, Standard};
 use rand::Rng;
-use servicepoint2::{
-    ByteGrid, CompressionCode, Connection, FRAME_PACING, Grid, Origin, PixelGrid, TILE_HEIGHT,
-    TILE_WIDTH,
-};
-use servicepoint2::Command::{BitmapLinearWin, CharBrightness};
-
+use servicepoint::{FRAME_PACING, Grid, TILE_HEIGHT, TILE_WIDTH, Bitmap, UdpSocketExt, BitmapCommand, SendCommandExt, BrightnessGridCommand, BrightnessGrid, Brightness, ValueGrid, PIXEL_WIDTH, PIXEL_HEIGHT, ByteGrid};
 use crate::game::Game;
 use crate::print::{println_debug, println_info, println_warning};
 use crate::rules::{generate_bb3, generate_u8b3};
@@ -37,11 +33,11 @@ fn main() {
 
     let mut left_pixels = Game {
         rules: generate_bb3(),
-        field: PixelGrid::max_sized(),
+        field: ValueGrid::new(PIXEL_WIDTH, PIXEL_HEIGHT),
     };
     let mut right_pixels = Game {
         rules: generate_bb3(),
-        field: PixelGrid::max_sized(),
+        field: ValueGrid::new(PIXEL_WIDTH, PIXEL_HEIGHT),
     };
     let mut left_luma = Game {
         rules: generate_u8b3(),
@@ -57,8 +53,8 @@ fn main() {
     randomize(&mut right_luma.field);
     randomize(&mut right_pixels.field);
 
-    let mut pixels = PixelGrid::max_sized();
-    let mut luma = ByteGrid::new(TILE_WIDTH, TILE_HEIGHT);
+    let mut pixels = Bitmap::max_sized();
+    let mut luma = BrightnessGrid::new(TILE_WIDTH, TILE_HEIGHT);
 
     let mut split_pixel = 0;
     let mut split_speed: i32 = 1;
@@ -222,7 +218,7 @@ impl TryFrom<Event> for AppEvent {
     }
 }
 
-fn draw_pixels(pixels: &mut PixelGrid, left: &PixelGrid, right: &PixelGrid, split_index: usize) {
+fn draw_pixels(pixels: &mut Bitmap, left: &ValueGrid<bool>, right: &ValueGrid<bool>, split_index: usize) {
     for x in 0..pixels.width() {
         let left_or_right = if x < split_index { left } else { right };
         for y in 0..pixels.height() {
@@ -232,28 +228,22 @@ fn draw_pixels(pixels: &mut PixelGrid, left: &PixelGrid, right: &PixelGrid, spli
     }
 }
 
-fn draw_luma(luma: &mut ByteGrid, left: &ByteGrid, right: &ByteGrid, split_tile: usize) {
+fn draw_luma(luma: &mut BrightnessGrid, left: &ByteGrid, right: &ByteGrid, split_tile: usize) {
     for x in 0..luma.width() {
         let left_or_right = if x < split_tile { left } else { right };
         for y in 0..luma.height() {
-            let set = u8::max(48, left_or_right.get(x, y));
-
-            let set = set as f32 / u8::MAX as f32 * 12f32;
-
-            luma.set(x, y, set as u8);
+            let set: u8 = left_or_right.get(x, y) / u8::MAX * u8::from(Brightness::MAX);
+            let set = Brightness::try_from(set).unwrap();
+            luma.set(x, y, set);
         }
     }
 }
 
-fn send_to_screen(connection: &Connection, pixels: &PixelGrid, luma: &ByteGrid) {
-    let pixel_cmd = BitmapLinearWin(Origin(0, 0), pixels.clone(), CompressionCode::Uncompressed);
-    connection
-        .send(pixel_cmd.into())
-        .expect("could not send pixels");
-
-    connection
-        .send(CharBrightness(Origin(0, 0), luma.clone()).into())
-        .expect("could not send brightness");
+fn send_to_screen(connection: &UdpSocket, pixels: &Bitmap, luma: &BrightnessGrid) {
+    let cmd: BitmapCommand = pixels.clone().try_into().unwrap();
+    _ = connection.send_command(cmd);
+    let cmd: BrightnessGridCommand = luma.clone().try_into().unwrap();
+    _ = connection.send_command(cmd);
 }
 
 fn randomize<TGrid, TValue>(field: &mut TGrid)
@@ -270,7 +260,7 @@ fn randomize<TGrid, TValue>(field: &mut TGrid)
     }
 }
 
-fn init() -> Connection {
+fn init() -> UdpSocket {
     env_logger::builder()
         .filter_level(LevelFilter::Info)
         .parse_default_env()
@@ -280,7 +270,7 @@ fn init() -> Connection {
         .expect("could not enter alternate screen");
     enable_raw_mode().expect("could not enable raw terminal mode");
 
-    Connection::open(Cli::parse().destination)
+    UdpSocket::bind_connect(Cli::parse().destination)
         .expect("Could not connect. Did you forget `--destination`?")
 }
 
diff --git a/src/rules.rs b/src/rules.rs
index 6156a5d..e506fad 100644
--- a/src/rules.rs
+++ b/src/rules.rs
@@ -3,8 +3,6 @@ use rand::{thread_rng, Rng};
 
 use crate::print::println_info;
 
-const MAX_BRIGHTNESS: u8 = 12;
-
 pub struct Rules<TState, TKernel, const KERNEL_SIZE: usize>
 where
     TState: Copy + PartialEq,