Compare commits
41 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6f1e1fb3cf | ||
|
733693258c | ||
|
66429e6714 | ||
|
e159df38cc | ||
|
8e8f16646b | ||
|
7f77dddda9 | ||
|
52c7d86022 | ||
|
19d84a7c9a | ||
|
297c1aedb9 | ||
|
ea5efdcf69 | ||
|
ed640548a6 | ||
|
7ee23cd20d | ||
|
fa3bbfff58 | ||
|
4fc23d0a76 | ||
|
e2d0ce2e59 | ||
|
193817fda6 | ||
|
da8bc84c36 | ||
|
d036f6574b | ||
|
6bc7d0b94e | ||
|
fcf2df1c51 | ||
|
23a5432bc3 | ||
|
1232487f58 | ||
|
1d4d5f0520 | ||
|
4906e70f49 | ||
|
4b3bf5dc4b | ||
|
d1b289ff8e | ||
|
9feeb6782b | ||
|
b02247fbe6 | ||
|
30b77617e2 | ||
|
1e87c76689 | ||
|
2841625b15 | ||
|
4f74c2f8cd | ||
|
a1e8fb7aec | ||
|
b6acbc2484 | ||
|
c5bdc65923 | ||
|
c77fb9818f | ||
|
c334492ea9 | ||
|
78fb4ecbfc | ||
|
c280dbe716 | ||
|
d7b402c764 | ||
|
ec74203e70 |
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,3 +1,8 @@
|
||||
bin/*
|
||||
obj/*
|
||||
.vs
|
||||
|
||||
|
||||
# Added by cargo
|
||||
|
||||
/target
|
||||
|
338
Cargo.lock
generated
Normal file
338
Cargo.lock
generated
Normal file
@ -0,0 +1,338 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm_winapi"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lexopt"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baff4b617f7df3d896f97fe922b64817f6cd9a756bb81d40f8883f2f66dcb401"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nmsrust"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"crossterm",
|
||||
"lexopt",
|
||||
"libc",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-mio"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
18
Cargo.toml
Normal file
18
Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "nmsrust"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
lexopt = "0.3.0"
|
||||
libc = "0.2.147"
|
||||
atty = "0.2.14"
|
||||
rand = "0.8.5"
|
||||
crossterm = "0.27.0"
|
||||
|
16
Makefile
16
Makefile
@ -17,21 +17,21 @@ CFLAGS ?= -Wextra -Wall -O2
|
||||
|
||||
.PHONY: all install uninstall clean
|
||||
|
||||
nms: $(OBJ)/input.o $(OBJ)/error.o $(OBJ)/nmscharset.o $(OBJ)/nmstermio.o $(OBJ)/nmseffect.o $(OBJ)/nms.o | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $(BIN)/$@ $^
|
||||
nms: $(OBJ)/error.o $(OBJ)/nmstermio.o $(OBJ)/nmseffect.o $(OBJ)/nms.o | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $(BIN)/$@ $^ target/release/libnmsrust.a
|
||||
|
||||
sneakers: $(OBJ)/nmscharset.o $(OBJ)/nmstermio.o $(OBJ)/nmseffect.o $(OBJ)/sneakers.o | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $(BIN)/$@ $^
|
||||
sneakers: $(OBJ)/nmstermio.o $(OBJ)/nmseffect.o $(OBJ)/sneakers.o | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $(BIN)/$@ $^ target/release/libnmsrust.a
|
||||
|
||||
all: nms sneakers
|
||||
|
||||
all-ncurses: nms-ncurses sneakers-ncurses
|
||||
|
||||
nms-ncurses: $(OBJ)/input.o $(OBJ)/error.o $(OBJ)/nmscharset.o $(OBJ)/nmstermio_ncurses.o $(OBJ)/nmseffect.o $(OBJ)/nms.o | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $(BIN)/nms $^ -lncursesw
|
||||
nms-ncurses: $(OBJ)/error.o $(OBJ)/nmstermio_ncurses.o $(OBJ)/nmseffect.o $(OBJ)/nms.o | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $(BIN)/nms $^ -lncursesw target/release/libnmsrust.a
|
||||
|
||||
sneakers-ncurses: $(OBJ)/nmscharset.o $(OBJ)/nmstermio_ncurses.o $(OBJ)/nmseffect.o $(OBJ)/sneakers.o | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $(BIN)/sneakers $^ -lncursesw
|
||||
sneakers-ncurses: $(OBJ)/nmstermio_ncurses.o $(OBJ)/nmseffect.o $(OBJ)/sneakers.o | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $(BIN)/sneakers $^ -lncursesw target/release/libnmsrust.a
|
||||
|
||||
$(OBJ)/%.o: $(SRC)/%.c | $(OBJ)
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
29
justfile
Normal file
29
justfile
Normal file
@ -0,0 +1,29 @@
|
||||
default:
|
||||
just --list
|
||||
|
||||
|
||||
# Build from scratch
|
||||
build:
|
||||
cargo build --release
|
||||
make nms
|
||||
|
||||
# Build ncurses version
|
||||
build_ncurses:
|
||||
cargo build --release
|
||||
make nms-ncurses
|
||||
|
||||
build_sneakers:
|
||||
cargo build --release
|
||||
make sneakers
|
||||
|
||||
|
||||
# Clean all project files
|
||||
clean:
|
||||
rm -rf obj
|
||||
rm -rf bin
|
||||
cargo clean
|
||||
|
||||
|
||||
# A sample run of the program
|
||||
sample_run *args:
|
||||
cat Cargo.toml | ./bin/nms {{args}}
|
55
src/args.rs
Normal file
55
src/args.rs
Normal file
@ -0,0 +1,55 @@
|
||||
use std::ffi::OsString;
|
||||
|
||||
use lexopt::prelude::*;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) struct Args {
|
||||
pub(crate) version: bool,
|
||||
pub(crate) clear_screen: bool,
|
||||
|
||||
///Pass the 'color' argument to the nmstermio module where it will set the
|
||||
///foreground color of the unencrypted characters as they are
|
||||
///revealed. Valid arguments are "white", "yellow", "magenta", "blue",
|
||||
///"green", "red", and "cyan".
|
||||
pub(crate) foreground: Option<OsString>,
|
||||
|
||||
/// Set the autoDecrypt flag according to the true/false value of the
|
||||
/// 'setting' argument. When set to true, nmseffect_exec() will not
|
||||
/// require a key press to start the decryption effect.
|
||||
pub(crate) autodecrypt: bool,
|
||||
|
||||
/// Set the maskBlank flag according to the true/false value of the
|
||||
/// 'setting' argument. When set to true, blank spaces characters
|
||||
/// will be masked as well.
|
||||
pub(crate) mask_blanks: bool,
|
||||
}
|
||||
|
||||
pub(crate) fn parse_arguments() -> Result<Args, lexopt::Error> {
|
||||
let mut parser = lexopt::Parser::from_env();
|
||||
|
||||
let mut args = Args::default();
|
||||
|
||||
while let Some(arg) = parser.next()? {
|
||||
match arg {
|
||||
Short('a') => {
|
||||
args.autodecrypt = true;
|
||||
}
|
||||
Short('c') => {
|
||||
args.clear_screen = true;
|
||||
}
|
||||
Short('f') => {
|
||||
let foreground = parser.value()?;
|
||||
args.foreground = Some(foreground);
|
||||
}
|
||||
Short('s') => {
|
||||
args.mask_blanks = true;
|
||||
}
|
||||
Short('v') => {
|
||||
args.version = true;
|
||||
}
|
||||
_ => return Err(arg.unexpected()),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(args)
|
||||
}
|
225
src/charset.rs
Normal file
225
src/charset.rs
Normal file
@ -0,0 +1,225 @@
|
||||
// Total characters in charTable[] array.
|
||||
//#define CHAR_COUNT 218
|
||||
|
||||
// Character table representing the character set know as CP437 used by
|
||||
// the original IBM PC - https://en.wikipedia.org/wiki/Code_page_437
|
||||
pub(crate) const CHAR_TABLE: [&[u8]; 218] = [
|
||||
b"!\0",
|
||||
b"\"\0",
|
||||
b"#\0",
|
||||
b"$\0",
|
||||
b"%\0",
|
||||
b"&\0",
|
||||
b"'\0",
|
||||
b"(\0",
|
||||
b")\0",
|
||||
b"*\0",
|
||||
b"+\0",
|
||||
b",\0",
|
||||
b"-\0",
|
||||
b"~\0",
|
||||
b".\0",
|
||||
b"/\0",
|
||||
b":\0",
|
||||
b";\0",
|
||||
b"<\0",
|
||||
b"=\0",
|
||||
b">\0",
|
||||
b"?\0",
|
||||
b"[\0",
|
||||
b"\\\0",
|
||||
b"]\0",
|
||||
b"_\0",
|
||||
b"{\0",
|
||||
b"}\0",
|
||||
b"A\0",
|
||||
b"B\0",
|
||||
b"C\0",
|
||||
b"D\0",
|
||||
b"E\0",
|
||||
b"F\0",
|
||||
b"G\0",
|
||||
b"H\0",
|
||||
b"I\0",
|
||||
b"J\0",
|
||||
b"K\0",
|
||||
b"L\0",
|
||||
b"M\0",
|
||||
b"N\0",
|
||||
b"O\0",
|
||||
b"P\0",
|
||||
b"Q\0",
|
||||
b"R\0",
|
||||
b"S\0",
|
||||
b"T\0",
|
||||
b"U\0",
|
||||
b"V\0",
|
||||
b"W\0",
|
||||
b"X\0",
|
||||
b"Y\0",
|
||||
b"Z\0",
|
||||
b"a\0",
|
||||
b"b\0",
|
||||
b"c\0",
|
||||
b"d\0",
|
||||
b"e\0",
|
||||
b"f\0",
|
||||
b"g\0",
|
||||
b"h\0",
|
||||
b"i\0",
|
||||
b"j\0",
|
||||
b"k\0",
|
||||
b"l\0",
|
||||
b"m\0",
|
||||
b"n\0",
|
||||
b"o\0",
|
||||
b"p\0",
|
||||
b"q\0",
|
||||
b"r\0",
|
||||
b"s\0",
|
||||
b"t\0",
|
||||
b"u\0",
|
||||
b"v\0",
|
||||
b"w\0",
|
||||
b"x\0",
|
||||
b"y\0",
|
||||
b"z\0",
|
||||
b"0\0",
|
||||
b"1\0",
|
||||
b"2\0",
|
||||
b"3\0",
|
||||
b"4\0",
|
||||
b"5\0",
|
||||
b"6\0",
|
||||
b"7\0",
|
||||
b"8\0",
|
||||
b"9\0",
|
||||
b"\xc3\x87\0",
|
||||
b"\xc3\xbc\0",
|
||||
b"\xc3\xa9\0",
|
||||
b"\xc3\xa2\0",
|
||||
b"\xc3\xa4\0",
|
||||
b"\xc3\xa0\0",
|
||||
b"\xc3\xa5\0",
|
||||
b"\xc3\xa7\0",
|
||||
b"\xc3\xaa\0",
|
||||
b"\xc3\xab\0",
|
||||
b"\xc3\xa8\0",
|
||||
b"\xc3\xaf\0",
|
||||
b"\xc3\xae\0",
|
||||
b"\xc3\xac\0",
|
||||
b"\xc3\x84\0",
|
||||
b"\xc3\x85\0",
|
||||
b"\xc3\x89\0",
|
||||
b"\xc3\xa6\0",
|
||||
b"\xc3\x86\0",
|
||||
b"\xc3\xb4\0",
|
||||
b"\xc3\xb6\0",
|
||||
b"\xc3\xb2\0",
|
||||
b"\xc3\xbb\0",
|
||||
b"\xc3\xb9\0",
|
||||
b"\xc3\xbf\0",
|
||||
b"\xc3\x96\0",
|
||||
b"\xc3\x9c\0",
|
||||
b"\xc2\xa2\0",
|
||||
b"\xc2\xa3\0",
|
||||
b"\xc2\xa5\0",
|
||||
b"\xc6\x92\0",
|
||||
b"\xc3\xa1\0",
|
||||
b"\xc3\xad\0",
|
||||
b"\xc3\xb3\0",
|
||||
b"\xc3\xba\0",
|
||||
b"\xc3\xb1\0",
|
||||
b"\xc3\x91\0",
|
||||
b"\xc2\xaa\0",
|
||||
b"\xc2\xba\0",
|
||||
b"\xc2\xbf\0",
|
||||
b"\xc2\xac\0",
|
||||
b"\xc2\xbd\0",
|
||||
b"\xc2\xbc\0",
|
||||
b"\xc2\xa1\0",
|
||||
b"\xc2\xab\0",
|
||||
b"\xc2\xbb\0",
|
||||
b"\xce\xb1\0",
|
||||
b"\xc3\x9f\0",
|
||||
b"\xce\x93\0",
|
||||
b"\xcf\x80\0",
|
||||
b"\xce\xa3\0",
|
||||
b"\xcf\x83\0",
|
||||
b"\xc2\xb5\0",
|
||||
b"\xcf\x84\0",
|
||||
b"\xce\xa6\0",
|
||||
b"\xce\x98\0",
|
||||
b"\xce\xa9\0",
|
||||
b"\xce\xb4\0",
|
||||
b"\xcf\x86\0",
|
||||
b"\xce\xb5\0",
|
||||
b"\xc2\xb1\0",
|
||||
b"\xc3\xb7\0",
|
||||
b"\xc2\xb0\0",
|
||||
b"\xc2\xb7\0",
|
||||
b"\xc2\xb2\0",
|
||||
b"\xc2\xb6\0",
|
||||
b"\xe2\x8c\x90\0",
|
||||
b"\xe2\x82\xa7\0",
|
||||
b"\xe2\x96\x91\0",
|
||||
b"\xe2\x96\x92\0",
|
||||
b"\xe2\x96\x93\0",
|
||||
b"\xe2\x94\x82\0",
|
||||
b"\xe2\x94\xa4\0",
|
||||
b"\xe2\x95\xa1\0",
|
||||
b"\xe2\x95\xa2\0",
|
||||
b"\xe2\x95\x96\0",
|
||||
b"\xe2\x95\x95\0",
|
||||
b"\xe2\x95\xa3\0",
|
||||
b"\xe2\x95\x91\0",
|
||||
b"\xe2\x95\x97\0",
|
||||
b"\xe2\x95\x9d\0",
|
||||
b"\xe2\x95\x9c\0",
|
||||
b"\xe2\x95\x9b\0",
|
||||
b"\xe2\x94\x90\0",
|
||||
b"\xe2\x94\x94\0",
|
||||
b"\xe2\x94\xb4\0",
|
||||
b"\xe2\x94\xac\0",
|
||||
b"\xe2\x94\x9c\0",
|
||||
b"\xe2\x94\x80\0",
|
||||
b"\xe2\x94\xbc\0",
|
||||
b"\xe2\x95\x9e\0",
|
||||
b"\xe2\x95\x9f\0",
|
||||
b"\xe2\x95\x9a\0",
|
||||
b"\xe2\x95\x94\0",
|
||||
b"\xe2\x95\xa9\0",
|
||||
b"\xe2\x95\xa6\0",
|
||||
b"\xe2\x95\xa0\0",
|
||||
b"\xe2\x95\x90\0",
|
||||
b"\xe2\x95\xac\0",
|
||||
b"\xe2\x95\xa7\0",
|
||||
b"\xe2\x95\xa8\0",
|
||||
b"\xe2\x95\xa4\0",
|
||||
b"\xe2\x95\xa7\0",
|
||||
b"\xe2\x95\x99\0",
|
||||
b"\xe2\x95\x98\0",
|
||||
b"\xe2\x95\x92\0",
|
||||
b"\xe2\x95\x93\0",
|
||||
b"\xe2\x95\xab\0",
|
||||
b"\xe2\x95\xaa\0",
|
||||
b"\xe2\x94\x98\0",
|
||||
b"\xe2\x94\x8c\0",
|
||||
b"\xe2\x96\x88\0",
|
||||
b"\xe2\x96\x84\0",
|
||||
b"\xe2\x96\x8c\0",
|
||||
b"\xe2\x96\x90\0",
|
||||
b"\xe2\x96\x80\0",
|
||||
b"\xe2\x88\x9e\0",
|
||||
b"\xe2\x88\xa9\0",
|
||||
b"\xe2\x89\xa1\0",
|
||||
b"\xe2\x89\xa5\0",
|
||||
b"\xe2\x89\xa4\0",
|
||||
b"\xe2\x8c\xa0\0",
|
||||
b"\xe2\x8c\xa1\0",
|
||||
b"\xe2\x89\x88\0",
|
||||
b"\xe2\x88\x99\0",
|
||||
b"\xe2\x88\x9a\0",
|
||||
b"\xe2\x81\xbf\0",
|
||||
b"\xe2\x96\xa0\0",
|
||||
];
|
40
src/color.rs
Normal file
40
src/color.rs
Normal file
@ -0,0 +1,40 @@
|
||||
use std::{convert::TryFrom, ffi::OsString};
|
||||
|
||||
pub(crate) enum Color {
|
||||
Black = 0,
|
||||
Red = 1,
|
||||
Green = 2,
|
||||
Yellow = 3,
|
||||
Blue = 4,
|
||||
Magenta = 5,
|
||||
Cyan = 6,
|
||||
White = 7,
|
||||
}
|
||||
|
||||
impl Default for Color {
|
||||
fn default() -> Self {
|
||||
Color::Blue
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<OsString> for Color {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(s: OsString) -> Result<Self, ()> {
|
||||
let s = match s.to_str() {
|
||||
Some(s) => s,
|
||||
None => return Err(()),
|
||||
};
|
||||
Ok(match s {
|
||||
"black" => Color::Black,
|
||||
"red" => Color::Red,
|
||||
"green" => Color::Green,
|
||||
"yellow" => Color::Yellow,
|
||||
"blue" => Color::Blue,
|
||||
"magenta" => Color::Magenta,
|
||||
"cyan" => Color::Cyan,
|
||||
"white" => Color::White,
|
||||
_ => return Err(()),
|
||||
})
|
||||
}
|
||||
}
|
166
src/input.c
166
src/input.c
@ -1,166 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Brian Barto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GPL License. See LICENSE for more details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/select.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include "input.h"
|
||||
#include "error.h"
|
||||
|
||||
int input_get(unsigned char** dest, char *prompt)
|
||||
{
|
||||
int r, input_len;
|
||||
fd_set input_stream;
|
||||
struct timeval timeout;
|
||||
void *timeout_p;
|
||||
|
||||
FD_ZERO(&input_stream);
|
||||
input_len = 0;
|
||||
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
if (isatty(STDIN_FILENO))
|
||||
{
|
||||
timeout_p = NULL;
|
||||
if (prompt != NULL)
|
||||
{
|
||||
printf("%s", prompt);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timeout_p = &timeout;
|
||||
}
|
||||
|
||||
FD_SET(STDIN_FILENO, &input_stream);
|
||||
r = select(FD_SETSIZE, &input_stream, NULL, NULL, timeout_p);
|
||||
if (r < 0)
|
||||
{
|
||||
error_log("Error while waiting for input data. Errno: %i", errno);
|
||||
return -1;
|
||||
}
|
||||
if (r > 0)
|
||||
{
|
||||
r = ioctl(STDIN_FILENO, FIONREAD, &input_len);
|
||||
if (r < 0)
|
||||
{
|
||||
error_log("Could not determine length of input. Errno: %i", errno);
|
||||
return -1;
|
||||
}
|
||||
if (input_len > 0)
|
||||
{
|
||||
*dest = malloc(input_len);
|
||||
if (*dest == NULL)
|
||||
{
|
||||
error_log("Memory allocation error.");
|
||||
return -1;
|
||||
}
|
||||
r = read(STDIN_FILENO, *dest, input_len);
|
||||
if (r < 0)
|
||||
{
|
||||
error_log("Input read error. Errno: %i", errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FD_CLR(STDIN_FILENO, &input_stream);
|
||||
|
||||
return input_len;
|
||||
}
|
||||
|
||||
int input_get_str(char** dest, char *prompt)
|
||||
{
|
||||
int r, i, input_len;
|
||||
unsigned char *input;
|
||||
|
||||
r = input_get(&input, prompt);
|
||||
if (r < 0)
|
||||
{
|
||||
error_log("Could not get input.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (r > 0)
|
||||
{
|
||||
if (input[r - 1] == '\n')
|
||||
{
|
||||
--r;
|
||||
if (r > 0 && input[r - 1] == '\r')
|
||||
{
|
||||
--r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (r == 0)
|
||||
{
|
||||
error_log("No input provided.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
input_len = r;
|
||||
|
||||
*dest = malloc(input_len + 1);
|
||||
if (*dest == NULL)
|
||||
{
|
||||
error_log("Memory allocation error.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(*dest, 0, input_len + 1);
|
||||
|
||||
for (i = 0; i < input_len; ++i)
|
||||
{
|
||||
if (isascii(input[i]))
|
||||
{
|
||||
(*dest)[i] = input[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
error_log("Input contains non-ascii characters.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
free(input);
|
||||
|
||||
return input_len;
|
||||
}
|
||||
|
||||
int input_get_from_pipe(unsigned char** dest)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (isatty(STDIN_FILENO))
|
||||
{
|
||||
error_log("Input data from a piped or redirected source is required.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = input_get(dest, NULL);
|
||||
if (r < 0)
|
||||
{
|
||||
error_log("Could not get input.");
|
||||
return -1;
|
||||
}
|
||||
if (r == 0)
|
||||
{
|
||||
error_log("No input provided.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
15
src/input.h
15
src/input.h
@ -1,15 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Brian Barto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GPL License. See LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef INPUT_H
|
||||
#define INPUT_H 1
|
||||
|
||||
int input_get(unsigned char** dest, char *prompt);
|
||||
int input_get_str(char** dest, char *prompt);
|
||||
int input_get_from_pipe(unsigned char** dest);
|
||||
|
||||
#endif
|
116
src/lib.rs
Normal file
116
src/lib.rs
Normal file
@ -0,0 +1,116 @@
|
||||
mod args;
|
||||
mod charset;
|
||||
mod color;
|
||||
mod sneakers;
|
||||
|
||||
use libc::{c_char, c_int, c_void};
|
||||
use std::ffi::CString;
|
||||
use std::process;
|
||||
|
||||
use color::Color;
|
||||
|
||||
const VERSION: &str = "2.0.0";
|
||||
|
||||
extern "C" {
|
||||
fn nmstermio_set_clearscr(_: c_int);
|
||||
fn nmseffect_exec(
|
||||
input: *const c_char,
|
||||
len: c_int,
|
||||
autodecrypt_c: c_int,
|
||||
maskblank_c: c_int,
|
||||
clear_scr: c_int,
|
||||
) -> c_char;
|
||||
static mut foregroundColor: c_int;
|
||||
}
|
||||
|
||||
///Sleep for the number of milliseconds indicated by argument
|
||||
#[no_mangle]
|
||||
pub extern "C" fn nmseffect_sleep(t: c_int) {
|
||||
use std::time::Duration;
|
||||
|
||||
let dur = Duration::from_millis(t as u64);
|
||||
std::thread::sleep(dur);
|
||||
}
|
||||
|
||||
/// Return a random character from charTable[].
|
||||
#[no_mangle]
|
||||
pub extern "C" fn nmscharset_get_random() -> *const c_char {
|
||||
let table = charset::CHAR_TABLE;
|
||||
let idx: u16 = rand::random::<u16>();
|
||||
|
||||
let bytes = table[(idx as usize) % table.len()];
|
||||
bytes.as_ptr() as *const c_char
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rust_main() {
|
||||
println!("Hello from rust");
|
||||
|
||||
let args = match args::parse_arguments() {
|
||||
Ok(args) => args,
|
||||
Err(e) => {
|
||||
println!("{e}");
|
||||
process::exit(1);
|
||||
}
|
||||
};
|
||||
println!("{:?}", args);
|
||||
|
||||
if args.version {
|
||||
println!("nms version {VERSION}");
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
if let Some(color) = args.foreground {
|
||||
let color = Color::try_from(color).unwrap_or_default();
|
||||
let n = color as c_int;
|
||||
unsafe {
|
||||
foregroundColor = n;
|
||||
}
|
||||
}
|
||||
|
||||
if args.clear_screen {
|
||||
unsafe {
|
||||
nmstermio_set_clearscr(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let input = get_input("Enter input: ");
|
||||
if input.len() == 0 {
|
||||
eprintln!("Input is empty"); //TODO use error_log()/error_print() abstraction
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
exec_effect(input, args.autodecrypt, args.mask_blanks, args.clear_screen);
|
||||
}
|
||||
|
||||
pub(crate) fn exec_effect(input: String, autodecrypt: bool, maskblank: bool, clear_screen: bool) {
|
||||
|
||||
let maskblank_c = if maskblank { 1 } else { 0 };
|
||||
let autodecrypt_c = if autodecrypt { 1 } else { 0};
|
||||
|
||||
let output_cstring = CString::new(input).unwrap();
|
||||
let ptr = output_cstring.as_ptr();
|
||||
let len = output_cstring.as_bytes().len();
|
||||
let clear = if clear_screen { 1 } else { 0 };
|
||||
let _r = unsafe { nmseffect_exec(ptr, len as i32, autodecrypt_c, maskblank_c, clear) };
|
||||
|
||||
}
|
||||
|
||||
fn get_input(prompt: &str) -> String {
|
||||
use std::io::{Read, Write};
|
||||
|
||||
let mut stdin = std::io::stdin();
|
||||
let mut stdout = std::io::stdout();
|
||||
let mut buf = String::new();
|
||||
|
||||
if atty::is(atty::Stream::Stdin) {
|
||||
print!("{prompt}");
|
||||
stdout.flush().unwrap();
|
||||
stdin.read_line(&mut buf).unwrap();
|
||||
} else {
|
||||
stdin.read_to_string(&mut buf).unwrap();
|
||||
}
|
||||
|
||||
buf
|
||||
}
|
68
src/nms.c
68
src/nms.c
@ -4,74 +4,12 @@
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GPL License. See LICENSE for more details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include "nmseffect.h"
|
||||
#include "input.h"
|
||||
#include "error.h"
|
||||
|
||||
#define VERSION "1.0.1"
|
||||
extern void rust_main();
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main(void)
|
||||
{
|
||||
int r, o;
|
||||
unsigned char *input;
|
||||
|
||||
input = NULL;
|
||||
|
||||
while ((o = getopt(argc, argv, "f:ascv")) != -1)
|
||||
{
|
||||
switch (o)
|
||||
{
|
||||
case 'f':
|
||||
nmseffect_set_foregroundcolor(optarg);
|
||||
break;
|
||||
case 'a':
|
||||
nmseffect_set_autodecrypt(1);
|
||||
break;
|
||||
case 's':
|
||||
nmseffect_set_maskblank(1);
|
||||
break;
|
||||
case 'c':
|
||||
nmseffect_set_clearscr(1);
|
||||
break;
|
||||
case 'v':
|
||||
printf("nms version " VERSION "\n");
|
||||
return EXIT_SUCCESS;
|
||||
case '?':
|
||||
if (isprint(optopt))
|
||||
{
|
||||
error_log("Unknown option '-%c'.", optopt);
|
||||
}
|
||||
else
|
||||
{
|
||||
error_log("Unknown option character '\\x%x'.", optopt);
|
||||
}
|
||||
error_print();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
r = input_get(&input, "Enter input: ");
|
||||
if (r < 0)
|
||||
{
|
||||
error_log("Could not get input.");
|
||||
error_print();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else if (r == 0)
|
||||
{
|
||||
error_log("Input is empty.");
|
||||
error_print();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
r = nmseffect_exec(input, r);
|
||||
|
||||
free(input);
|
||||
|
||||
rust_main();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Brian Barto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GPL License. See LICENSE for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The nmscharset module defines the character set that is used to
|
||||
* represent encryption.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// Total characters in charTable[] array.
|
||||
#define CHAR_COUNT 218
|
||||
|
||||
// Character table representing the character set know as CP437 used by
|
||||
// the original IBM PC - https://en.wikipedia.org/wiki/Code_page_437
|
||||
static char *charTable[] = {
|
||||
"!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", "~",
|
||||
".", "/", ":", ";", "<", "=", ">", "?", "[", "\\", "]", "_", "{", "}",
|
||||
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
|
||||
"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
|
||||
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
|
||||
"n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
"\xc3\x87", "\xc3\xbc", "\xc3\xa9", "\xc3\xa2", "\xc3\xa4", "\xc3\xa0",
|
||||
"\xc3\xa5", "\xc3\xa7", "\xc3\xaa", "\xc3\xab", "\xc3\xa8", "\xc3\xaf",
|
||||
"\xc3\xae", "\xc3\xac", "\xc3\x84", "\xc3\x85", "\xc3\x89", "\xc3\xa6",
|
||||
"\xc3\x86", "\xc3\xb4", "\xc3\xb6", "\xc3\xb2", "\xc3\xbb", "\xc3\xb9",
|
||||
"\xc3\xbf", "\xc3\x96", "\xc3\x9c", "\xc2\xa2", "\xc2\xa3", "\xc2\xa5",
|
||||
"\xc6\x92", "\xc3\xa1", "\xc3\xad", "\xc3\xb3", "\xc3\xba", "\xc3\xb1",
|
||||
"\xc3\x91", "\xc2\xaa", "\xc2\xba", "\xc2\xbf", "\xc2\xac", "\xc2\xbd",
|
||||
"\xc2\xbc", "\xc2\xa1", "\xc2\xab", "\xc2\xbb", "\xce\xb1", "\xc3\x9f",
|
||||
"\xce\x93", "\xcf\x80", "\xce\xa3", "\xcf\x83", "\xc2\xb5", "\xcf\x84",
|
||||
"\xce\xa6", "\xce\x98", "\xce\xa9", "\xce\xb4", "\xcf\x86", "\xce\xb5",
|
||||
"\xc2\xb1", "\xc3\xb7", "\xc2\xb0", "\xc2\xb7", "\xc2\xb2", "\xc2\xb6",
|
||||
"\xe2\x8c\x90", "\xe2\x82\xa7", "\xe2\x96\x91", "\xe2\x96\x92",
|
||||
"\xe2\x96\x93", "\xe2\x94\x82", "\xe2\x94\xa4", "\xe2\x95\xa1",
|
||||
"\xe2\x95\xa2", "\xe2\x95\x96", "\xe2\x95\x95", "\xe2\x95\xa3",
|
||||
"\xe2\x95\x91", "\xe2\x95\x97", "\xe2\x95\x9d", "\xe2\x95\x9c",
|
||||
"\xe2\x95\x9b", "\xe2\x94\x90", "\xe2\x94\x94", "\xe2\x94\xb4",
|
||||
"\xe2\x94\xac", "\xe2\x94\x9c", "\xe2\x94\x80", "\xe2\x94\xbc",
|
||||
"\xe2\x95\x9e", "\xe2\x95\x9f", "\xe2\x95\x9a", "\xe2\x95\x94",
|
||||
"\xe2\x95\xa9", "\xe2\x95\xa6", "\xe2\x95\xa0", "\xe2\x95\x90",
|
||||
"\xe2\x95\xac", "\xe2\x95\xa7", "\xe2\x95\xa8", "\xe2\x95\xa4",
|
||||
"\xe2\x95\xa7", "\xe2\x95\x99", "\xe2\x95\x98", "\xe2\x95\x92",
|
||||
"\xe2\x95\x93", "\xe2\x95\xab", "\xe2\x95\xaa", "\xe2\x94\x98",
|
||||
"\xe2\x94\x8c", "\xe2\x96\x88", "\xe2\x96\x84", "\xe2\x96\x8c",
|
||||
"\xe2\x96\x90", "\xe2\x96\x80", "\xe2\x88\x9e", "\xe2\x88\xa9",
|
||||
"\xe2\x89\xa1", "\xe2\x89\xa5", "\xe2\x89\xa4", "\xe2\x8c\xa0",
|
||||
"\xe2\x8c\xa1", "\xe2\x89\x88", "\xe2\x88\x99", "\xe2\x88\x9a",
|
||||
"\xe2\x81\xbf", "\xe2\x96\xa0"
|
||||
};
|
||||
|
||||
/*
|
||||
* Return a random character from charTable[].
|
||||
*/
|
||||
char *nmscharset_get_random(void) {
|
||||
return charTable[rand() % CHAR_COUNT];
|
||||
}
|
@ -9,6 +9,6 @@
|
||||
#define NMSCHARSET_H 1
|
||||
|
||||
// Function prototypes
|
||||
char *nmscharset_get_random(void);
|
||||
extern char *nmscharset_get_random(void);
|
||||
|
||||
#endif
|
||||
|
@ -32,9 +32,7 @@
|
||||
#define REVEAL_LOOP_SPEED 50 // miliseconds between each reveal loop
|
||||
|
||||
// Behavior settings
|
||||
static int autoDecrypt = 0; // Auto-decrypt flag
|
||||
static int maskBlank = 0; // Mask blank spaces
|
||||
static int colorOn = 1; // Terminal color flag
|
||||
const int colorOn = 1; // Terminal color flag - nothing actually sets this to be false ever
|
||||
|
||||
// Character attribute structure, linked list. Keeps track of every
|
||||
// character's attributes required for rendering and decryption effect.
|
||||
@ -48,14 +46,14 @@ struct charAttr {
|
||||
};
|
||||
|
||||
// Static function prototypes
|
||||
static void nmseffect_sleep(int);
|
||||
extern void nmseffect_sleep(int);
|
||||
|
||||
/*
|
||||
* This function applies the data decryption effect to the character
|
||||
* string that is provided as an argument. It returns the last character
|
||||
* pressed by the user.
|
||||
*/
|
||||
char nmseffect_exec(unsigned char *string, int string_len) {
|
||||
char nmseffect_exec(unsigned char *string, int string_len, int autoDecrypt, int maskBlank, int clear_screen) {
|
||||
struct charAttr *list_pointer = NULL;
|
||||
struct charAttr *list_head = NULL;
|
||||
struct charAttr *list_temp = NULL;
|
||||
@ -72,7 +70,7 @@ char nmseffect_exec(unsigned char *string, int string_len) {
|
||||
// Initialize terminal
|
||||
nmstermio_init_terminal();
|
||||
|
||||
if (!nmstermio_get_clearscr()) {
|
||||
if (!clear_screen) {
|
||||
// Get current row position
|
||||
origRow = nmstermio_get_cursor_row();
|
||||
|
||||
@ -271,7 +269,7 @@ char nmseffect_exec(unsigned char *string, int string_len) {
|
||||
|
||||
nmstermio_clear_input();
|
||||
|
||||
if (nmstermio_get_clearscr()) {
|
||||
if (clear_screen) {
|
||||
nmstermio_get_char();
|
||||
}
|
||||
|
||||
@ -290,39 +288,6 @@ char nmseffect_exec(unsigned char *string, int string_len) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass the 'color' argument to the nmstermio module where it will set the
|
||||
* foreground color of the unencrypted characters as they are
|
||||
* revealed. Valid arguments are "white", "yellow", "magenta", "blue",
|
||||
* "green", "red", and "cyan".
|
||||
*/
|
||||
void nmseffect_set_foregroundcolor(char *color) {
|
||||
nmstermio_set_foregroundcolor(color);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the autoDecrypt flag according to the true/false value of the
|
||||
* 'setting' argument. When set to true, nmseffect_exec() will not
|
||||
* require a key press to start the decryption effect.
|
||||
*/
|
||||
void nmseffect_set_autodecrypt(int setting) {
|
||||
if (setting)
|
||||
autoDecrypt = 1;
|
||||
else
|
||||
autoDecrypt = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the maskBlank flag according to the true/false value of the
|
||||
* 'setting' argument. When set to true, blank spaces characters
|
||||
* will be masked as well.
|
||||
*/
|
||||
void nmseffect_set_maskblank(int setting) {
|
||||
if (setting)
|
||||
maskBlank = 1;
|
||||
else
|
||||
maskBlank = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass the 'setting' argument to the nmstermio module where it will set
|
||||
@ -332,29 +297,3 @@ void nmseffect_set_maskblank(int setting) {
|
||||
void nmseffect_set_clearscr(int setting) {
|
||||
nmstermio_set_clearscr(setting);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the 'colorOn' flag according to the true/false value of the 'setting'
|
||||
* argument. This flag tells nmseffect_exec() to use colors in it's output.
|
||||
* This is true by default, and meant to be used only for terminals that
|
||||
* do not support color. Though, compiling with ncurses support is perhaps
|
||||
* a better option, as it will detect color capabilities automatically.
|
||||
*/
|
||||
void nmseffect_set_color(int setting) {
|
||||
if (setting)
|
||||
colorOn = 1;
|
||||
else
|
||||
colorOn = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sleep for the number of milliseconds indicated by argument 't'.
|
||||
*/
|
||||
static void nmseffect_sleep(int t) {
|
||||
struct timespec ts;
|
||||
|
||||
ts.tv_sec = t / 1000;
|
||||
ts.tv_nsec = (t % 1000) * 1000000;
|
||||
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
|
@ -9,11 +9,8 @@
|
||||
#define NMSEFFECT_H 1
|
||||
|
||||
// Function prototypes
|
||||
char nmseffect_exec(unsigned char *, int string_len);
|
||||
void nmseffect_set_foregroundcolor(char *);
|
||||
char nmseffect_exec(unsigned char *, int string_len, int autoDecrypt, int maskblank, int clear_screen);
|
||||
void nmseffect_set_returnopts(char *);
|
||||
void nmseffect_set_autodecrypt(int);
|
||||
void nmseffect_set_maskblank(int);
|
||||
void nmseffect_set_clearscr(int);
|
||||
void nmseffect_use_color(int);
|
||||
void nmseffect_set_input_position(int, int);
|
||||
|
@ -50,7 +50,7 @@
|
||||
|
||||
// Terminal IO settings
|
||||
static int clearScr = 0; // clearScr flag
|
||||
static int foregroundColor = COLOR_BLUE; // Foreground color setting
|
||||
int foregroundColor = COLOR_BLUE; // Foreground color setting
|
||||
|
||||
// Function prototypes
|
||||
static void nmstermio_set_terminal(int);
|
||||
@ -206,14 +206,6 @@ void nmstermio_beep(void) {
|
||||
BEEP();
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the status of the clearScr flag. This is used by the nmseffect
|
||||
* module to make certain decisions based on its value.
|
||||
*/
|
||||
int nmstermio_get_clearscr(void) {
|
||||
return clearScr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the clearScr flag according to the true/false value of the 's' argument.
|
||||
*/
|
||||
@ -224,33 +216,6 @@ void nmstermio_set_clearscr(int s) {
|
||||
clearScr = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the desired foreground color of the unencrypted characters as they
|
||||
* are revealed by nmstermio_print_reveal_string(). Valid arguments are
|
||||
* "white", "yellow", "magenta", "blue", "green", "red", and "cyan".
|
||||
*/
|
||||
void nmstermio_set_foregroundcolor(char *c) {
|
||||
|
||||
if(strcmp("white", c) == 0)
|
||||
foregroundColor = COLOR_WHITE;
|
||||
else if(strcmp("yellow", c) == 0)
|
||||
foregroundColor = COLOR_YELLOW;
|
||||
else if(strcmp("black", c) == 0)
|
||||
foregroundColor = COLOR_BLACK;
|
||||
else if(strcmp("magenta", c) == 0)
|
||||
foregroundColor = COLOR_MAGENTA;
|
||||
else if(strcmp("blue", c) == 0)
|
||||
foregroundColor = COLOR_BLUE;
|
||||
else if(strcmp("green", c) == 0)
|
||||
foregroundColor = COLOR_GREEN;
|
||||
else if(strcmp("red", c) == 0)
|
||||
foregroundColor = COLOR_RED;
|
||||
else if(strcmp("cyan", c) == 0)
|
||||
foregroundColor = COLOR_CYAN;
|
||||
else
|
||||
foregroundColor = COLOR_BLUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get and returns the current row position of the cursor. This involves
|
||||
* sending the appropriate ANSI escape code to the terminal and
|
||||
|
@ -22,9 +22,7 @@ char nmstermio_get_char(void);
|
||||
void nmstermio_print_reveal_string(char *, int);
|
||||
void nmstermio_show_cursor(void);
|
||||
void nmstermio_beep(void);
|
||||
int nmstermio_get_clearscr(void);
|
||||
void nmstermio_set_clearscr(int);
|
||||
void nmstermio_set_foregroundcolor(char *);
|
||||
int nmstermio_get_cursor_row(void);
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
// Static settings
|
||||
static int clearScr = 1; // clearScr flag
|
||||
static int foregroundColor = COLOR_BLUE; // Foreground color setting
|
||||
int foregroundColor = COLOR_BLUE; // Foreground color setting
|
||||
|
||||
/*
|
||||
* Initialize and configure the terminal for output. This usually means
|
||||
@ -140,13 +140,6 @@ void nmstermio_beep(void) {
|
||||
beep();
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the status of the clearScr flag. This is used by the nmseffect
|
||||
* module to make certain decisions based on its value.
|
||||
*/
|
||||
int nmstermio_get_clearscr(void) {
|
||||
return clearScr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the clearScr flag according to the true/false value of the 's' argument.
|
||||
@ -158,33 +151,6 @@ void nmstermio_set_clearscr(int s) {
|
||||
clearScr = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the desired foreground color of the unencrypted characters as they
|
||||
* are revealed by nmstermio_print_reveal_string(). Valid arguments are
|
||||
* "white", "yellow", "magenta", "blue", "green", "red", and "cyan".
|
||||
*/
|
||||
void nmstermio_set_foregroundcolor(char *c) {
|
||||
|
||||
if(strcmp("white", c) == 0)
|
||||
foregroundColor = COLOR_WHITE;
|
||||
else if(strcmp("yellow", c) == 0)
|
||||
foregroundColor = COLOR_YELLOW;
|
||||
else if(strcmp("black", c) == 0)
|
||||
foregroundColor = COLOR_BLACK;
|
||||
else if(strcmp("magenta", c) == 0)
|
||||
foregroundColor = COLOR_MAGENTA;
|
||||
else if(strcmp("blue", c) == 0)
|
||||
foregroundColor = COLOR_BLUE;
|
||||
else if(strcmp("green", c) == 0)
|
||||
foregroundColor = COLOR_GREEN;
|
||||
else if(strcmp("red", c) == 0)
|
||||
foregroundColor = COLOR_RED;
|
||||
else if(strcmp("cyan", c) == 0)
|
||||
foregroundColor = COLOR_CYAN;
|
||||
else
|
||||
foregroundColor = COLOR_BLUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get and returns the current row position of the cursor.
|
||||
*/
|
||||
|
179
src/sneakers.c
179
src/sneakers.c
@ -11,184 +11,11 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include "nmseffect.h"
|
||||
|
||||
extern void rust_sneakers_effect();
|
||||
|
||||
int main(void) {
|
||||
int termCols, spaces = 0;
|
||||
unsigned char *display_uc = NULL;
|
||||
char *display = NULL;
|
||||
char *head1Left = "DATANET PROC RECORD: 45-3456-W-3452";
|
||||
char *head1Right = "Transnet on/xc-3";
|
||||
char *head2Center = "FEDERAL RESERVE TRANSFER NODE";
|
||||
char *head3Center = "National Headquarters";
|
||||
char *head4Center = "************ Remote Systems Network Input Station ************";
|
||||
char *head5Center = "================================================================";
|
||||
char *menu1 = "[1] Interbank Funds Transfer (Code Prog: 485-GWU)";
|
||||
char *menu2 = "[2] International Telelink Access (Code Lim: XRP-262)";
|
||||
char *menu3 = "[3] Remote Facsimile Send/Receive (Code Tran: 2LZP-517)";
|
||||
char *menu4 = "[4] Regional Bank Interconnect (Security Code: 47-B34)";
|
||||
char *menu5 = "[5] Update System Parameters (Entry Auth. Req.)";
|
||||
char *menu6 = "[6] Remote Operator Logon/Logoff";
|
||||
char *foot1Center = "================================================================";
|
||||
char *foot2Center = "[ ] Select Option or ESC to Abort";
|
||||
|
||||
// Get terminal dimentions (needed for centering)
|
||||
struct winsize w;
|
||||
// if not an interactive tty, w is not populated, resulting in UB
|
||||
if (ioctl(0, TIOCGWINSZ, &w) == -1) {
|
||||
perror("Input not from an interactive terminal");
|
||||
return 1;
|
||||
}
|
||||
termCols = w.ws_col;
|
||||
|
||||
// Allocate space for our display string
|
||||
if ((display = malloc(20 * termCols)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Memory Allocation Error. Quitting!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Allocate space for our display string
|
||||
if ((display_uc = malloc(20 * termCols)) == NULL)
|
||||
{
|
||||
free(display);
|
||||
fprintf(stderr, "Memory Allocation Error. Quitting!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(display, 0, 20 * termCols);
|
||||
memset(display_uc, 0, 20 * termCols);
|
||||
|
||||
// Start building the display string
|
||||
strcpy(display, head1Left);
|
||||
|
||||
spaces = termCols - strlen(head1Left) - strlen(head1Right);
|
||||
while (spaces > 0) {
|
||||
strcat(display, " ");
|
||||
--spaces;
|
||||
}
|
||||
strcat(display, head1Right);
|
||||
|
||||
strcat(display, "\n");
|
||||
|
||||
spaces = (termCols - strlen(head2Center)) / 2;
|
||||
while (spaces > 0) {
|
||||
strcat(display, " ");
|
||||
--spaces;
|
||||
}
|
||||
strcat(display, head2Center);
|
||||
|
||||
strcat(display, "\n");
|
||||
strcat(display, "\n");
|
||||
|
||||
spaces = (termCols - strlen(head3Center)) / 2;
|
||||
while (spaces > 0) {
|
||||
strcat(display, " ");
|
||||
--spaces;
|
||||
}
|
||||
strcat(display, head3Center);
|
||||
|
||||
strcat(display, "\n");
|
||||
strcat(display, "\n");
|
||||
|
||||
spaces = (termCols - strlen(head4Center)) / 2;
|
||||
while (spaces > 0) {
|
||||
strcat(display, " ");
|
||||
--spaces;
|
||||
}
|
||||
strcat(display, head4Center);
|
||||
|
||||
strcat(display, "\n");
|
||||
|
||||
spaces = (termCols - strlen(head5Center)) / 2;
|
||||
while (spaces > 0) {
|
||||
strcat(display, " ");
|
||||
--spaces;
|
||||
}
|
||||
strcat(display, head5Center);
|
||||
|
||||
strcat(display, "\n");
|
||||
strcat(display, "\n");
|
||||
|
||||
spaces = ((termCols - strlen(head5Center)) / 2) + 3;
|
||||
while (spaces > 0) {
|
||||
strcat(display, " ");
|
||||
--spaces;
|
||||
}
|
||||
strcat(display, menu1);
|
||||
|
||||
strcat(display, "\n");
|
||||
|
||||
spaces = ((termCols - strlen(head5Center)) / 2) + 3;
|
||||
while (spaces > 0) {
|
||||
strcat(display, " ");
|
||||
--spaces;
|
||||
}
|
||||
strcat(display, menu2);
|
||||
|
||||
strcat(display, "\n");
|
||||
|
||||
spaces = ((termCols - strlen(head5Center)) / 2) + 3;
|
||||
while (spaces > 0) {
|
||||
strcat(display, " ");
|
||||
--spaces;
|
||||
}
|
||||
strcat(display, menu3);
|
||||
|
||||
strcat(display, "\n");
|
||||
|
||||
spaces = ((termCols - strlen(head5Center)) / 2) + 3;
|
||||
while (spaces > 0) {
|
||||
strcat(display, " ");
|
||||
--spaces;
|
||||
}
|
||||
strcat(display, menu4);
|
||||
|
||||
strcat(display, "\n");
|
||||
|
||||
spaces = ((termCols - strlen(head5Center)) / 2) + 3;
|
||||
while (spaces > 0) {
|
||||
strcat(display, " ");
|
||||
--spaces;
|
||||
}
|
||||
strcat(display, menu5);
|
||||
|
||||
strcat(display, "\n");
|
||||
|
||||
spaces = ((termCols - strlen(head5Center)) / 2) + 3;
|
||||
while (spaces > 0) {
|
||||
strcat(display, " ");
|
||||
--spaces;
|
||||
}
|
||||
strcat(display, menu6);
|
||||
|
||||
strcat(display, "\n");
|
||||
strcat(display, "\n");
|
||||
|
||||
spaces = (termCols - strlen(foot1Center)) / 2;
|
||||
while (spaces > 0) {
|
||||
strcat(display, " ");
|
||||
--spaces;
|
||||
}
|
||||
strcat(display, foot1Center);
|
||||
|
||||
strcat(display, "\n");
|
||||
strcat(display, "\n");
|
||||
|
||||
spaces = (termCols - strlen(foot2Center)) / 2;
|
||||
while (spaces > 0) {
|
||||
strcat(display, " ");
|
||||
--spaces;
|
||||
}
|
||||
strcat(display, foot2Center);
|
||||
|
||||
nmseffect_set_clearscr(1);
|
||||
|
||||
memcpy(display_uc, display, 20 * termCols);
|
||||
|
||||
// Execute effect
|
||||
nmseffect_exec(display_uc, strlen(display));
|
||||
|
||||
free(display);
|
||||
free(display_uc);
|
||||
rust_sneakers_effect();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
75
src/sneakers.rs
Normal file
75
src/sneakers.rs
Normal file
@ -0,0 +1,75 @@
|
||||
|
||||
const head1Left: &str = "DATANET PROC RECORD: 45-3456-W-3452";
|
||||
const head1Right: &str = "Transnet on/xc-3";
|
||||
const head2Center: &str = "FEDERAL RESERVE TRANSFER NODE";
|
||||
const head3Center: &str = "National Headquarters";
|
||||
const head4Center: &str = "************ Remote Systems Network Input Station ************";
|
||||
const head5Center: &str = "================================================================";
|
||||
const menu1: &str = "[1] Interbank Funds Transfer (Code Prog: 485-GWU)";
|
||||
const menu2: &str = "[2] International Telelink Access (Code Lim: XRP-262)";
|
||||
const menu3: &str = "[3] Remote Facsimile Send/Receive (Code Tran: 2LZP-517)";
|
||||
const menu4: &str = "[4] Regional Bank Interconnect (Security Code: 47-B34)";
|
||||
const menu5: &str = "[5] Update System Parameters (Entry Auth. Req.)";
|
||||
const menu6: &str = "[6] Remote Operator Logon/Logoff";
|
||||
const foot1Center: &str = "================================================================";
|
||||
const foot2Center: &str = "[ ] Select Option or ESC to Abort";
|
||||
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rust_sneakers_effect() {
|
||||
use std::time::Duration;
|
||||
|
||||
|
||||
unsafe {
|
||||
crate::nmstermio_set_clearscr(1);
|
||||
}
|
||||
|
||||
let (term_width, _term_height) = crossterm::terminal::size().expect("Error reading terminal size");
|
||||
let term_width = term_width as usize;
|
||||
let mut buf = String::new();
|
||||
|
||||
buf.push_str(head1Left);
|
||||
let spaces = term_width - head1Left.len() - head1Right.len();
|
||||
buf.push_str(&" ".repeat(spaces));
|
||||
buf.push_str(head1Right);
|
||||
buf.push('\n');
|
||||
|
||||
for text in [head2Center, head3Center].iter(){
|
||||
let spaces = ((term_width - text.len()) / 2);
|
||||
buf.push_str(&" ".repeat(spaces));
|
||||
buf.push_str(text);
|
||||
buf.push_str("\n\n");
|
||||
};
|
||||
|
||||
for text in [head4Center, head5Center].iter(){
|
||||
let spaces = ((term_width - text.len()) / 2);
|
||||
buf.push_str(&" ".repeat(spaces));
|
||||
buf.push_str(text);
|
||||
buf.push('\n');
|
||||
};
|
||||
|
||||
buf.push('\n');
|
||||
|
||||
for text in [menu1, menu2, menu3, menu4, menu5, menu6].iter() {
|
||||
let spaces = ((term_width - head5Center.len()) / 2) + 3;
|
||||
buf.push_str(&" ".repeat(spaces));
|
||||
buf.push_str(text);
|
||||
buf.push('\n');
|
||||
}
|
||||
|
||||
for text in [foot1Center, foot2Center].iter() {
|
||||
let spaces = ((term_width - text.len()) / 2);
|
||||
buf.push('\n');
|
||||
buf.push_str(&" ".repeat(spaces));
|
||||
buf.push_str(text);
|
||||
buf.push('\n');
|
||||
};
|
||||
|
||||
// println!("{}", buf);
|
||||
|
||||
// let dur = Duration::from_millis(2000);
|
||||
// std::thread::sleep(dur);
|
||||
|
||||
crate::exec_effect(buf, false, false, true);
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user