initial commit
This commit is contained in:
commit
5817fea9ad
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
163
Cargo.lock
generated
Normal file
163
Cargo.lock
generated
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[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 = "funty"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inherent"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c38228f24186d9cc68c729accb4d413be9eaed6ad07ff79e0270d9e56f3de13"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.21.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkg-config"
|
||||||
|
version = "0.3.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.95"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "radium"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||||
|
|
||||||
|
[[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 = "servicepoint"
|
||||||
|
version = "0.15.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2800caad491cb44f67e5dd5b8c61ece368eecfe588155d03c7d9864acbad6919"
|
||||||
|
dependencies = [
|
||||||
|
"bitvec",
|
||||||
|
"inherent",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"rust-lzma",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "servicepoint-idle"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"servicepoint",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.104"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
||||||
|
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.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vcpkg"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wyz"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
|
||||||
|
dependencies = [
|
||||||
|
"tap",
|
||||||
|
]
|
7
Cargo.toml
Normal file
7
Cargo.toml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[package]
|
||||||
|
name = "servicepoint-idle"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
servicepoint = "0.15.1"
|
27
flake.lock
Normal file
27
flake.lock
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1750969886,
|
||||||
|
"narHash": "sha256-zW/OFnotiz/ndPFdebpo3X0CrbVNf22n4DjN2vxlb58=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "a676066377a2fe7457369dd37c31fd2263b662f4",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-25.05",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
57
flake.nix
Normal file
57
flake.nix
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
description = "";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
{ self, nixpkgs }:
|
||||||
|
let
|
||||||
|
lib = nixpkgs.lib;
|
||||||
|
supported-systems = [
|
||||||
|
"x86_64-linux"
|
||||||
|
"aarch64-linux"
|
||||||
|
"aarch64-darwin"
|
||||||
|
"x86_64-darwin"
|
||||||
|
];
|
||||||
|
forAllSystems =
|
||||||
|
f:
|
||||||
|
lib.genAttrs supported-systems (
|
||||||
|
system:
|
||||||
|
f rec {
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
inherit system;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
devShells = forAllSystems (
|
||||||
|
{ pkgs, system }:
|
||||||
|
{
|
||||||
|
default = pkgs.mkShell rec {
|
||||||
|
packages = with pkgs; [
|
||||||
|
(pkgs.symlinkJoin {
|
||||||
|
name = "rust-toolchain";
|
||||||
|
paths = [
|
||||||
|
rustc
|
||||||
|
cargo
|
||||||
|
rustPlatform.rustcSrc
|
||||||
|
rustfmt
|
||||||
|
clippy
|
||||||
|
cargo-expand
|
||||||
|
];
|
||||||
|
})
|
||||||
|
|
||||||
|
gdb
|
||||||
|
xz
|
||||||
|
pkg-config
|
||||||
|
];
|
||||||
|
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
formatter = forAllSystems ({ pkgs, ... }: pkgs.nixfmt-rfc-style);
|
||||||
|
};
|
||||||
|
}
|
73
src/bar.rs
Normal file
73
src/bar.rs
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
use crate::command_queue::PacketQueue;
|
||||||
|
use crate::{Currency, GenerateCommands, Progressable};
|
||||||
|
use servicepoint::{Bitmap, BitmapCommand, Grid, Origin, TILE_SIZE, TILE_WIDTH, Tiles};
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Bar {
|
||||||
|
progress: f64,
|
||||||
|
speed: f64,
|
||||||
|
factor: f64,
|
||||||
|
origin: Origin<Tiles>,
|
||||||
|
width_tiles: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bar {
|
||||||
|
pub(crate) fn new(factor: f64, origin: Origin<Tiles>) -> Bar {
|
||||||
|
Self {
|
||||||
|
factor,
|
||||||
|
progress: 0f64,
|
||||||
|
speed: 0.01f64,
|
||||||
|
origin,
|
||||||
|
width_tiles: TILE_WIDTH / 2, // TODO: param
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Progressable for Bar {
|
||||||
|
fn progress(&self, delta: Duration) -> (Self, Currency) {
|
||||||
|
let extra_progress = delta.as_secs_f64() * self.speed;
|
||||||
|
let progress = self.progress + extra_progress;
|
||||||
|
let completions = progress.floor();
|
||||||
|
let progress = progress - completions;
|
||||||
|
let currency = completions * self.factor;
|
||||||
|
|
||||||
|
(Self { progress, ..*self }, currency)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GenerateCommands for Bar {
|
||||||
|
fn generate_commands(&self, q: &mut impl PacketQueue) {
|
||||||
|
let mut bitmap = Bitmap::new(self.width_tiles * TILE_SIZE, TILE_SIZE).unwrap();
|
||||||
|
|
||||||
|
// border top
|
||||||
|
let last_row = bitmap.height() - 1;
|
||||||
|
for x in 0..bitmap.width() {
|
||||||
|
bitmap.set(x, 0, true);
|
||||||
|
bitmap.set(x, last_row, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// border bottom
|
||||||
|
let last_col = bitmap.width() - 1;
|
||||||
|
for y in 0..bitmap.height() {
|
||||||
|
bitmap.set(0, y, true);
|
||||||
|
bitmap.set(last_col, y, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// progress fill
|
||||||
|
let fill_to = (bitmap.width() as f64 * self.progress) as usize;
|
||||||
|
for y in 0..bitmap.height() {
|
||||||
|
for x in 0..fill_to {
|
||||||
|
bitmap.set(x, y, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// to command
|
||||||
|
q.enqueue_command(BitmapCommand {
|
||||||
|
bitmap,
|
||||||
|
origin: Origin::from(&self.origin),
|
||||||
|
compression: Default::default(),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
20
src/command_queue.rs
Normal file
20
src/command_queue.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
use servicepoint::{Packet, UdpSocketExt};
|
||||||
|
use std::net::UdpSocket;
|
||||||
|
|
||||||
|
pub(crate) trait PacketQueue {
|
||||||
|
fn enqueue_command<P: TryInto<Packet>>(&mut self, packet: P) -> Result<bool, P::Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PacketQueue for Vec<Packet> {
|
||||||
|
fn enqueue_command<P: TryInto<Packet>>(&mut self, packet: P) -> Result<bool, P::Error> {
|
||||||
|
self.push(packet.try_into()?);
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PacketQueue for UdpSocket {
|
||||||
|
fn enqueue_command<P: TryInto<Packet>>(&mut self, packet: P) -> Result<bool, P::Error> {
|
||||||
|
let packet = packet.try_into()?;
|
||||||
|
Ok(self.send_command(packet).is_some())
|
||||||
|
}
|
||||||
|
}
|
39
src/game_state.rs
Normal file
39
src/game_state.rs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
use crate::bar::Bar;
|
||||||
|
use crate::command_queue::PacketQueue;
|
||||||
|
use crate::label::Label;
|
||||||
|
use crate::{Currency, GenerateCommands, Progressable};
|
||||||
|
use servicepoint::{Origin, TILE_WIDTH};
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct GameState {
|
||||||
|
pub(crate) currency: Currency,
|
||||||
|
pub(crate) first_step: Bar,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Progressable for GameState {
|
||||||
|
fn progress(&self, delta: Duration) -> (Self, Currency) {
|
||||||
|
let (first_step, first_currency) = self.first_step.progress(delta);
|
||||||
|
|
||||||
|
let currency = self.currency + first_currency;
|
||||||
|
|
||||||
|
(
|
||||||
|
Self {
|
||||||
|
currency,
|
||||||
|
first_step,
|
||||||
|
},
|
||||||
|
0f64,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GenerateCommands for GameState {
|
||||||
|
fn generate_commands(&self, queue: &mut impl PacketQueue) {
|
||||||
|
Label::new(Origin::ZERO, TILE_WIDTH, "Discordia Boot Procedure").generate_commands(queue);
|
||||||
|
|
||||||
|
self.first_step.generate_commands(queue);
|
||||||
|
Label::new(Origin::new(TILE_WIDTH / 2 + 1, 1), TILE_WIDTH / 2 - 1, "Power infrastructure")
|
||||||
|
.generate_commands(queue);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
35
src/label.rs
Normal file
35
src/label.rs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
use crate::GenerateCommands;
|
||||||
|
use crate::command_queue::PacketQueue;
|
||||||
|
use servicepoint::{CharGrid, CharGridCommand, Origin, Tiles};
|
||||||
|
|
||||||
|
pub(crate) struct Label<S: AsRef<str>> {
|
||||||
|
position: Origin<Tiles>,
|
||||||
|
text: S,
|
||||||
|
width_tiles: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Label<String> {
|
||||||
|
pub(crate) fn new<S: AsRef<str>>(position: Origin<Tiles>, width_tiles: usize, text: S) -> Self {
|
||||||
|
// TODO: those should be grapheme clusters
|
||||||
|
let text = text.as_ref().chars().take(width_tiles).collect::<String>();
|
||||||
|
Self {
|
||||||
|
position,
|
||||||
|
text,
|
||||||
|
width_tiles,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: AsRef<str>> GenerateCommands for Label<S> {
|
||||||
|
fn generate_commands(&self, queue: &mut impl PacketQueue) {
|
||||||
|
let mut grid = CharGrid::new(self.width_tiles, 1);
|
||||||
|
grid.set_row_str(0, self.text.as_ref()).unwrap();
|
||||||
|
|
||||||
|
queue
|
||||||
|
.enqueue_command(CharGridCommand {
|
||||||
|
grid: CharGrid::from(self.text.as_ref()),
|
||||||
|
origin: self.position,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
43
src/main.rs
Normal file
43
src/main.rs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
use crate::command_queue::PacketQueue;
|
||||||
|
use bar::Bar;
|
||||||
|
use game_state::GameState;
|
||||||
|
use servicepoint::{ClearCommand, Origin, UdpSocketExt};
|
||||||
|
use std::net::UdpSocket;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
mod bar;
|
||||||
|
mod command_queue;
|
||||||
|
mod game_state;
|
||||||
|
mod label;
|
||||||
|
|
||||||
|
type Currency = f64;
|
||||||
|
|
||||||
|
trait Progressable: Sized {
|
||||||
|
#[must_use]
|
||||||
|
fn progress(&self, delta: Duration) -> (Self, Currency);
|
||||||
|
}
|
||||||
|
|
||||||
|
trait GenerateCommands {
|
||||||
|
fn generate_commands(&self, queue: &mut impl PacketQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut state = GameState {
|
||||||
|
currency: 0f64,
|
||||||
|
first_step: Bar::new(1f64, Origin::new(0, 1)),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut connection = UdpSocket::bind_connect("127.0.0.1:2342").unwrap();
|
||||||
|
|
||||||
|
let mut last_refresh = Instant::now();
|
||||||
|
loop {
|
||||||
|
let current_time = Instant::now();
|
||||||
|
let delta = current_time - last_refresh;
|
||||||
|
last_refresh = current_time;
|
||||||
|
|
||||||
|
(state, _) = state.progress(delta);
|
||||||
|
|
||||||
|
connection.send_command(ClearCommand);
|
||||||
|
state.generate_commands(&mut connection);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue