This commit is contained in:
Able 2022-01-18 06:15:51 -06:00
parent 91c249ce2a
commit 139f5243f3
31 changed files with 16347 additions and 115 deletions

View file

@ -11,9 +11,13 @@ Install [Qemu](https://www.qemu.org/)
`cargo install bootimage`
## Srange workarounds
- arm/build.rs has to move main.rs
- conditional dependencies for bootloader are broken
## Running
repbuild can be used to run and build docs for able os
`cargo repbuild doc`
`cargo repbuild run`
## Testing on real hardware
I recommend using an old x86_64 computer
* `cargo run --release` to generate a binary image that is bootable

17
ableos/Cargo.lock generated
View file

@ -36,7 +36,6 @@ dependencies = [
"log",
"pic8259",
"pretty-hex",
"qoi_rs",
"shadeable",
"spin",
"uart_16550",
@ -78,9 +77,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bootloader"
version = "0.9.20"
version = "0.9.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b0718f186cd449b21f044683933284ed90fb83f3e13949ff0e03b0b6f02e38e"
checksum = "a62c8f6168cd106687ee36a2b71a46c4144d73399f72814104d33094b8092fd2"
[[package]]
name = "cfg-if"
@ -333,12 +332,6 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "qoi_rs"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7ac44f12a8cec33865a699b2257e8454499fb4c3b13835710ff35c66bb65669"
[[package]]
name = "quote"
version = "1.0.14"
@ -386,7 +379,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
name = "shadeable"
version = "0.1.0"
dependencies = [
"libm",
"rhai",
"vga",
]
[[package]]
@ -453,9 +448,9 @@ checksum = "4ccbe8381883510b6a2d8f1e32905bddd178c11caef8083086d0c0c9ab0ac281"
[[package]]
name = "uart_16550"
version = "0.2.15"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65ad019480ef5ff8ffe66d6f6a259cd87cf317649481394981db1739d844f374"
checksum = "af81448a9a53c7b0f66198381f80912fd18f2c8965f9da4319e6f92e740bca5b"
dependencies = [
"bitflags",
"x86_64",

View file

@ -13,6 +13,9 @@ run-args = [
"stdio",
"-smp",
"cores=2",
# "-device",
# "virtio-gpu",
"-device",
"virtio-blk-pci,drive=drive0,id=virtblk0,num-queues=4",
"-drive",
@ -28,13 +31,16 @@ test-args = [
[dependencies]
linked_list_allocator = "0.9.0"
lliw = "0.2.0"
qoi_rs = "*"
# qoi_rs = "*"
spin = "0.5.2"
vga = "*"
pretty-hex = "0.2.1"
log= "*"
[dependencies.shadeable]
pretty-hex = "0.2.1"
[dependencies.shadeable]
path = "../shadeable"

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

17
ableos/notes/pci_tree.md Normal file
View file

@ -0,0 +1,17 @@
VGA
pcie
gpu
amd
ati
set_red
ssd

View file

@ -28,7 +28,7 @@ pub fn start(boot_info: &'static BootInfo) -> ! {
}
allocator::init_heap(&mut mapper, &mut frame_allocator).expect("heap initialization failed");
// info!("{:?}", boot_info);
crate::kmain::kernel_main();
}

View file

@ -2,6 +2,8 @@ use crate::{
arch::drivers::vga::{set_vga_color, Color},
kprint,
};
// TODO improve tokenizer/parser
pub fn colorify(eval: &str) {
let y = eval.split("$");
for z in y {

View file

@ -0,0 +1,73 @@
use alloc::{boxed::Box, vec, vec::Vec};
use shadeable::pixel_format::{new_rgba64, Rgba64};
use vga::{colors::Color16, writers::GraphicsWriter};
use crate::vga_e::VGAE;
#[derive(Debug)]
pub struct ScreenSize {
pub x: usize,
pub y: usize,
}
impl ScreenSize {
pub fn new(x: usize, y: usize) -> Self {
Self { x, y }
}
}
pub enum GraphicsReturn {
Ok,
ImproperScreenSize,
}
pub struct ScreenBuffer {
pub size: ScreenSize,
pub clear_color: Rgba64,
pub buff: Box<[Rgba64]>, // Vec<Rgba64>,
}
impl ScreenBuffer {
// Add optional size later
pub fn new(x: usize, y: usize) -> Self {
Self {
size: ScreenSize::new(x, y),
clear_color: 0,
buff: vec![0u64; x * y].into_boxed_slice(),
}
}
#[inline]
pub fn set_pixel(&mut self, x: usize, y: usize, color: Rgba64) {
self.buff[y * self.size.y + x] = color;
}
pub fn clear(&mut self) {
self.buff = vec![0u64; self.buff.len()].into_boxed_slice();
}
pub fn blit(&mut self, _width: usize, _height: usize) {}
}
pub trait VgaBuffer {
fn copy_to_buffer(&self) -> GraphicsReturn;
}
impl VgaBuffer for ScreenBuffer {
fn copy_to_buffer(&self) -> GraphicsReturn {
let mode = VGAE.lock();
/*
if self.size.y * 640 + self.size.x > 640 * 480 {
return GraphicsReturn::ImproperScreenSize;
}
*/
for y in 0..self.size.y {
for x in 0..self.size.x {
use shadeable::pixel_format::into_vga_16;
let vga_color = into_vga_16(self.buff[y * self.size.y + x]);
mode.set_pixel(x, y, vga_color);
}
}
GraphicsReturn::Ok
}
}

View file

@ -1,13 +1,15 @@
#![allow(clippy::empty_loop)]
use alloc::{fmt, format};
use shadeable::rhai_test;
// use std::println;
use alloc::format;
use shadeable::pixel_format::{into_vga_16, new_rgba64};
use vga::{colors::Color16, writers::GraphicsWriter};
use crate::{
logger,
relib::network::socket::SocketReturns,
unicode_utils,
graphics::VgaBuffer,
relib::network::socket::{SimpleSock, SocketReturns},
vga_e::{self, VGAE},
};
@ -21,6 +23,8 @@ use {
info::master,
systeminfo::{KERNEL_VERSION, RELEASE_TYPE},
},
graphics::ScreenBuffer,
// log::LOG_STATE,
relib::math::rand::RAND_HANDLE,
relib::network::socket::Socket,
@ -51,34 +55,27 @@ lazy_static! {
pub fn kernel_main() -> ! {
init::init();
log::set_max_level(LevelFilter::Info);
log::set_max_level(LevelFilter::Trace);
// crate::wasm::evaluate();
{
let mut a_thread = Thread::new();
let mut abcde = ScreenBuffer::new(480, 640);
// abcde.clear();
// abcde.copy_to_buffer();
VGAE.lock().clear_screen(Color16::Black);
a_thread.new_task(test_fn);
a_thread.new_task(test_fn);
THREAD_LIST.lock().push(a_thread);
GraphicsBuffer::draw();
GraphicsBuffer::hide_cursor();
}
trace!("length of screen buffer {}", abcde.buff.len());
trace!("Screen size {:?}", abcde.size);
crate::wasm::evaluate();
{
info!("{} v{}", RELEASE_TYPE, KERNEL_VERSION);
info!(
"Brand String: {:?}",
master().unwrap().brand_string().unwrap()
);
if false {
println!("$PINK$Hi$RED$ from$GREEN$ able!$RESET$");
println!("$RED$hi$RESET$");
abcde.set_pixel(10, 10, new_rgba64(255, 0, 0, 255));
for y in 30..60 {
for x in 1..=639 {
abcde.set_pixel(x, y, new_rgba64(255, 255, 8, 255));
}
}
// info!("{:?}", abcde.buff);
abcde.copy_to_buffer();
{
use crate::relib::network::socket::SimpleSock;
let mut xyz = SimpleSock::new();
xyz.peek();
@ -90,8 +87,6 @@ pub fn kernel_main() -> ! {
info!("{:?}", &xyz.read(4).unwrap());
println!("{:?}", &xyz.peek().unwrap());
match &xyz.peek() {
SocketReturns::ReadOk(strr) => {
let out = String::from_utf8_lossy(strr);
@ -103,28 +98,33 @@ pub fn kernel_main() -> ! {
}
}
println!("$GREEN$able$RESET$@$LIGHTBLUE$stAble$ $RED$->$RESET$");
let mut sock_print_id = SimpleSock::new();
{
// sock_print_id.write(format!("原 画 フ ァ イ ル 集").into());
sock_print_id.write(format!("simple sockets are based").into());
sock_print_id.write(format!("🤯 🍆 💦").into());
// sock_print_id.write(format!("1....2....3....4....5....6....7....8....9").into());
}
// crate::relib::image::mono_bitmap::bruh();
if false {
VGAE.lock().clear_screen(Color16::Black);
let xyz = format!("\u{e100}ableOS");
for x in xyz.chars().enumerate() {
for x in (*String::from_utf8_lossy(&sock_print_id.peek().unwrap()))
.chars()
.enumerate()
{
vga_e::draw_char(x.1, x.0);
}
}
for y in 0..480 {
for x in 0..640 {
// info!("{x}");
VGAE.lock().set_pixel(x, y, Color16::Blue)
}
if false {
draw_filled_circle(400, 350, 99, Color16::Black);
// let _ = shadeable::evaluate_shader(1);
}
let _ = rhai_test();
// abcde.clear();
// abcde.copy_to_buffer();
println!("hi");
// vga_e::test_it_fucko();
// stack_overflow();
sloop()
@ -143,3 +143,35 @@ pub fn tick() {
pub fn key_entropy(key: u8) {
RAND_HANDLE.lock().seed_entropy_keyboard(key);
}
pub fn test_threads() {
let mut a_thread = Thread::new();
a_thread.new_task(test_fn);
a_thread.new_task(test_fn);
THREAD_LIST.lock().push(a_thread);
}
fn draw_filled_circle(cx: i32, cy: i32, radius: usize, color: Color16) {
let vga = VGAE.lock();
let r = radius as i32 * 2;
for y in 0..640 {
for x in 0..480 {
let dx = cx - x as i32 * 2 - 1;
let dy = cy - y as i32 * 2 - 1;
if dx * dx + dy * dy <= r * r {
vga.set_pixel(x, y, color);
};
}
}
}
pub fn log_version_data() {
info!("{} v{}", RELEASE_TYPE, KERNEL_VERSION);
info!(
"Brand String: {:?}",
master().unwrap().brand_string().unwrap()
);
}

View file

@ -12,6 +12,7 @@
llvm_asm,
naked_functions
)]
#![feature(exclusive_range_pattern)]
#[cfg(target_arch = "aarch64")]
#[path = "arch/aarch64/mod.rs"]
@ -28,19 +29,13 @@ pub mod arch;
#[macro_use]
pub mod print;
/*
#[macro_use]
pub mod log;
*/
// pub use log2;
#[macro_use]
pub extern crate log;
pub mod allocator;
pub mod driver_traits;
pub mod experiments;
pub mod graphics;
pub mod keyboard;
pub mod kmain;
pub mod logger;

View file

@ -1,7 +1,4 @@
use {
crate::{arch::sloop, println},
core::panic::PanicInfo,
};
use {crate::arch::sloop, core::panic::PanicInfo};
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {

22
ableos/src/pci.rs Normal file
View file

@ -0,0 +1,22 @@
pub fn pciConfigReadWord(bus: u8, slot: u8, func: u8, offset: u8) {}
/*
uint16_t pciConfigReadWord(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) {
uint32_t address;
uint32_t lbus = (uint32_t)bus;
uint32_t lslot = (uint32_t)slot;
uint32_t lfunc = (uint32_t)func;
uint16_t tmp = 0;
// Create configuration address as per Figure 1
address = (uint32_t)((lbus << 16) | (lslot << 11) |
(lfunc << 8) | (offset & 0xFC) | ((uint32_t)0x80000000));
// Write out the address
outl(0xCF8, address);
// Read in the data
// (offset & 2) * 8) = 0 will choose the first word of the 32-bit register
tmp = (uint16_t)((inl(0xCFC) >> ((offset & 2) * 8)) & 0xFFFF);
return tmp;
}
*/

View file

@ -0,0 +1 @@
pub mod rle;

View file

@ -0,0 +1,48 @@
use alloc::vec;
use alloc::vec::Vec;
pub fn encode(bytes: &[u8]) -> Vec<u8> {
let mut encoding;
if bytes.first().is_none() {
return vec![];
} else {
encoding = vec![*bytes.first().unwrap()];
}
let mut occurrences = 1;
for byte in bytes.iter().skip(1) {
if byte == encoding.last().unwrap() && occurrences < 255 {
occurrences += 1;
} else {
encoding.extend(&[occurrences, *byte]);
occurrences = 1;
}
}
encoding.push(occurrences);
encoding
}
/// Read a run-length encoding and return its decoded contents.
///
/// * `bytes` - The bytes to be decoded.
pub fn decode(bytes: &[u8]) -> Vec<u8> {
let mut decoding = Vec::<u8>::new();
for (i, byte) in bytes.iter().enumerate() {
if i % 2 != 0 {
continue;
}
// Repeat bytes[i], bytes[i+1] times in a row.
// e.g.: "!!" equals to 33 times "!" ("!" value in ASCII).
for _j in 0..bytes[i + 1] {
decoding.push(*byte)
}
}
decoding
}

View file

@ -1,2 +1,3 @@
#[allow(unused_imports)]
use qoi_rs;
pub mod mono_bitmap;
pub mod stupid_simple_image;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,6 @@
/*
r[255,0,0]
g[0,0,0]
b[0,0,0]
a[0,0,0]
*/

View file

@ -1,8 +1,10 @@
pub mod clparse;
pub mod encoding;
pub mod image;
pub mod math;
pub mod network;
pub mod time;
pub struct VectorTwo {
pub x: i32,
pub y: i32,

View file

@ -66,6 +66,9 @@ impl SimpleSock {
id: sock_lock.len() - 1,
}
}
pub fn regrab_sock(id: usize) -> SocketID {
SocketID { id }
}
}
impl Socket for SimpleSock {

View file

@ -1,18 +1,19 @@
use ab_glyph::{Font, FontRef, Glyph};
use alloc::string::String;
use vga::{
use {
ab_glyph::{Font, FontRef, Glyph},
vga::{
colors::Color16,
writers::{Graphics640x480x16, GraphicsWriter},
},
};
lazy_static::lazy_static! {
pub static ref VGAE: spin::Mutex<Graphics640x480x16> = {
let xyz = Graphics640x480x16::new();
xyz.set_mode();
spin::Mutex::new(xyz)
};
pub static ref VGAE_BUFF_OFFSET_X: spin::Mutex<u8> = spin::Mutex::new(0);
pub static ref VGAE_BUFF_OFFSET_Y: spin::Mutex<u8> = spin::Mutex::new(0);
}
pub fn test_it_fucko() {
@ -47,35 +48,66 @@ pub trait GraphicsAPI {
fn add_shader() {}
}
pub struct Buffer {
pub label: String,
pub resolution: (u64, u64),
}
// #[deprecated(note = "Deprecated because you should use the damn graphics api")]
pub fn draw_char(character: char, offset: usize) {
pub fn draw_char(character: char, _offset: usize) {
let mode = *VGAE.lock();
let mut offset_x = VGAE_BUFF_OFFSET_X.lock();
let mut offset_y = VGAE_BUFF_OFFSET_Y.lock();
if *offset_x == 39 {
*offset_x = 0;
*offset_y += 1;
}
let font = FontRef::try_from_slice(include_bytes!(
"../../ableos/assets/fonts/MesloLGS NF Regular.ttf"
"../../ableos/assets/fonts/unifont-14.0.01.ttf"
))
.unwrap();
// Get a glyph for 'q' with a scale & position.
let q_glyph: Glyph = font.glyph_id(character).with_scale(20.0);
let font2 = FontRef::try_from_slice(include_bytes!(
"../../ableos/assets/fonts/unifont_upper-14.0.01.ttf"
))
.unwrap();
// Draw it.
if let Some(q) = font.outline_glyph(q_glyph) {
let scale = q.glyph().scale;
let mut has_char = false;
for x in font.codepoint_ids() {
if x.1 == character {
has_char = true;
break;
}
}
let used_font;
match has_char {
true => used_font = font,
false => used_font = font2,
}
let font_scale = 1.6;
match character {
'\n' => {}
_ => {
let q_glyph: Glyph = used_font.glyph_id(character).with_scale_and_position(
20.0 * font_scale,
ab_glyph::point(
*offset_x as f32 * (10.0 * font_scale),
*offset_y as f32 + (18.0 * font_scale),
),
);
if let Some(q) = used_font.outline_glyph(q_glyph) {
q.draw(|x, y, c| {
if c > 0.2 {
if c > 0.015 {
let corner = q.px_bounds().min;
mode.set_pixel(
x as usize + (offset * scale.y as usize / 2),
//
y as usize,
Color16::LightGreen,
x as usize + corner.x as usize,
y as usize + corner.y as usize,
Color16::Green,
);
}
});
}
*offset_x += 1;
}
}
}

View file

@ -1,12 +1,11 @@
use alloc::string::String;
use wasmi::TrapKind;
use {
alloc::format,
wasm_sys::SysCall,
wasmi::{
Error, Externals, FuncInstance, FuncRef, ImportsBuilder, ModuleImportResolver,
ModuleInstance, RuntimeArgs, RuntimeValue, Signature, Trap, ValueType,
ModuleInstance, RuntimeArgs, RuntimeValue, Signature, Trap, TrapKind, ValueType,
},
};

0
data.txt Normal file
View file

90
shadeable/Cargo.lock generated
View file

@ -20,12 +20,39 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bit_field"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "conquer-once"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c6d3a9775a69f6d1fe2cc888999b67ed30257d3da4d2af91984e722f2ec918a"
dependencies = [
"conquer-util",
]
[[package]]
name = "conquer-util"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e763eef8846b13b380f37dfecda401770b0ca4e56e95170237bd7c25c7db3582"
[[package]]
name = "const-random"
version = "0.1.13"
@ -63,6 +90,12 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "font8x8"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "875488b8711a968268c7cf5d139578713097ca4635a76044e8fe8eedf831d07e"
[[package]]
name = "getrandom"
version = "0.2.4"
@ -101,6 +134,15 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
[[package]]
name = "lock_api"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
dependencies = [
"scopeguard",
]
[[package]]
name = "no-std-compat"
version = "0.4.1"
@ -175,11 +217,19 @@ dependencies = [
"syn",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "shadeable"
version = "0.1.0"
dependencies = [
"libm",
"rhai",
"vga",
]
[[package]]
@ -197,6 +247,15 @@ dependencies = [
"static_assertions",
]
[[package]]
name = "spinning_top"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75adad84ee84b521fb2cca2d4fd0f1dab1d8d026bda3c5bea4ca63b5f9f9293c"
dependencies = [
"lock_api",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
@ -235,8 +294,39 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "vga"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67cbcb7bfff998d176ffb8f2c3dfd6cb0fe62740e36dee6c64fc3928c01001bf"
dependencies = [
"bitflags",
"conquer-once",
"font8x8",
"num-traits",
"spinning_top",
"x86_64",
]
[[package]]
name = "volatile"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4c2dbd44eb8b53973357e6e207e370f0c1059990df850aca1eca8947cf464f0"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "x86_64"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb611915c917c6296d11e23f71ff1ecfe49c5766daba92cd3df52df6b58285b6"
dependencies = [
"bit_field",
"bitflags",
"volatile",
]

View file

@ -7,7 +7,8 @@ edition = "2021"
[dependencies]
vga = "*"
libm = "*"
[dependencies.rhai]
version = "*"

View file

@ -2,13 +2,13 @@
extern crate alloc;
use alloc::{boxed::Box, vec, vec::Vec};
use engine_internals::engine_startup;
use pixel_format::RGBA;
use pixel_format::{Rgba64, RGBA};
// use core::fmt::Result;
use core::result::Result;
use rhai::{EvalAltResult, Scope};
mod engine_internals;
mod pixel_format;
pub mod pixel_format;
pub const SHADER: &str = include_str!("../shaders/simple.shade");
@ -66,3 +66,16 @@ pub fn rhai_test() -> Result<Vec<RGBA>, Box<EvalAltResult>>
// Done!
Ok(result_rgba)
}
pub fn evaluate_shader(pixel: u8) -> Result<Rgba64, Box<EvalAltResult>> {
let engine = engine_startup();
let ast = engine.compile(SHADER)?;
let mut scope = Scope::new();
scope.push("PIXEL_RGBA", pixel);
let result: RGBA = engine.call_fn(&mut scope, &ast, "main", ())?;
Ok(8)
}

View file

@ -1,5 +1,7 @@
use rhai::INT;
#![feature(exclusive_range_pattern)]
use rhai::INT;
use vga::colors::Color16;
pub type Rgba64 = u64;
pub fn get_r(rgba: Rgba64) -> u8 {
@ -37,20 +39,20 @@ pub fn set_r(rgba: Rgba64, r: u8) -> Rgba64 {
return z | y;
}
pub fn set_g(rgba: Rgba64, r: u8) -> Rgba64 {
let z = (r as Rgba64) << 16;
pub fn set_g(rgba: Rgba64, g: u8) -> Rgba64 {
let z = (g as Rgba64) << 16;
let y = rgba & 0xffffff;
return z | y;
}
pub fn set_b(rgba: Rgba64, r: u8) -> Rgba64 {
let z = (r as Rgba64) << 26 - 16;
pub fn set_b(rgba: Rgba64, b: u8) -> Rgba64 {
let z = (b as Rgba64) << 26 - 16;
let y = rgba & 0xffffff;
return z | y;
}
pub fn set_a(rgba: Rgba64, r: u8) -> Rgba64 {
let z = (r as Rgba64) << 8;
pub fn set_a(rgba: Rgba64, a: u8) -> Rgba64 {
let z = (a as Rgba64) << 8;
let y = rgba & 0xffffff;
return z | y;
}
@ -85,7 +87,6 @@ pub fn rgba_div(a: Rgba64, b: Rgba64) -> Rgba64 {
return fin;
}
pub fn rgba_mult(a: RGBA, b: RGBA) -> RGBA {
RGBA {
r: a.r * b.r,
@ -111,3 +112,133 @@ pub fn rgba_sub(a: RGBA, b: RGBA) -> RGBA {
}
}
//
pub fn new_rgba64(r: u8, g: u8, b: u8, a: u8) -> Rgba64 {
let mut x = 0;
x |= set_r(x, r);
x |= set_g(x, g);
x |= set_b(x, b);
x |= set_a(x, a);
x
}
pub fn into_vga_16(rgba_64: Rgba64) -> Color16 {
let mut fourbit: u8 = 0;
fourbit |= match get_r(rgba_64) {
85..=170 => 0b0100,
171..=255 => 0b1100,
_ => 0,
};
fourbit |= match get_g(rgba_64) {
85..=170 => 0b0010,
171..=255 => 0b1010,
_ => 0,
};
fourbit |= match get_b(rgba_64) {
85..=170 => 0b0001,
171..=255 => 0b1001,
_ => 0,
};
use Color16::*;
match fourbit {
0 => Black,
1 => Blue,
2 => Green,
3 => Cyan,
4 => Red,
5 => Magenta,
6 => Brown,
7 => LightGrey,
8 => DarkGrey,
9 => LightBlue,
10 => LightGreen,
11 => LightCyan,
12 => LightRed,
13 => Pink,
14 => Yellow,
15 => White,
_ => Green,
}
}
pub fn from_vga_16(color: Color16) -> Rgba64 {
match color {
Color16::Black => new_rgba64(0, 0, 0, 0),
Color16::Blue => new_rgba64(0, 0, 255, 0),
Color16::Green => new_rgba64(0, 255, 0, 0),
Color16::Cyan => new_rgba64(0, 255, 255, 0),
Color16::Red => new_rgba64(255, 0, 0, 0),
Color16::Magenta => new_rgba64(255, 0, 255, 0),
Color16::Brown => new_rgba64(165, 42, 42, 0),
Color16::Pink => new_rgba64(255, 105, 180, 0),
Color16::LightGrey => new_rgba64(211, 211, 211, 0),
Color16::DarkGrey => new_rgba64(105, 105, 105, 0),
Color16::Yellow => new_rgba64(255, 255, 0, 0),
Color16::White => new_rgba64(255, 255, 255, 0),
// To be colored
Color16::LightBlue => new_rgba64(0, 255, 255, 0),
Color16::LightGreen => new_rgba64(0, 255, 255, 0),
Color16::LightCyan => new_rgba64(0, 255, 255, 0),
Color16::LightRed => new_rgba64(0, 255, 255, 0),
}
}
use libm::sqrt;
fn euclideand(c1: (u8, u8, u8), c2: (u8, u8, u8)) -> u8 {
let (r1, g1, b1) = c1;
let (r2, g2, b2) = c2;
let (rd, gd, bd) = (r2 - r1, g2 - g1, b2 - b1);
sqrt((rd * rd + gd * gd + bd * bd) as f64) as u8
}
fn get_color16(c: (u8, u8, u8)) -> Color16 {
let palette: [(u8, u8, u8); 16] = [
(0, 0, 0),
(0, 0, 255),
(128, 128, 128),
(128, 128, 128),
(128, 128, 128),
(128, 128, 128),
(128, 128, 128),
(128, 128, 128),
(128, 128, 128),
(128, 128, 128),
(128, 128, 128),
(128, 128, 128),
(128, 128, 128),
(128, 128, 128),
(128, 128, 128),
(128, 128, 128),
];
let mut minc = euclideand(c, palette[0]);
let mut retval = 0;
for i in 1..16 {
let eucd = euclideand(c, palette[i]);
if eucd < minc {
retval = i;
minc = eucd
}
}
match retval {
0 => Color16::Black,
1 => Color16::Red,
2 => Color16::Red,
3 => Color16::Red,
4 => Color16::Red,
5 => Color16::Red,
6 => Color16::Red,
7 => Color16::Red,
8 => Color16::Red,
9 => Color16::Red,
10 => Color16::Blue,
11 => Color16::Blue,
12 => Color16::Blue,
13 => Color16::Blue,
14 => Color16::Blue,
15 => Color16::Blue,
_ => Color16::Pink,
}
}