forked from AbleOS/ableos
254 lines
5.3 KiB
Rust
254 lines
5.3 KiB
Rust
#![feature(exclusive_range_pattern)]
|
|
|
|
use rhai::INT;
|
|
use vga::colors::Color16;
|
|
pub type Rgba64 = u64;
|
|
|
|
pub fn get_r(rgba: Rgba64) -> u8 {
|
|
let x: u64 = rgba;
|
|
|
|
let y = x >> 24;
|
|
|
|
return (y & 0xff).try_into().unwrap();
|
|
}
|
|
pub fn get_g(rgba: Rgba64) -> u8 {
|
|
let x: u64 = rgba;
|
|
|
|
let y = x >> 16;
|
|
|
|
return (y & 0xff).try_into().unwrap();
|
|
}
|
|
pub fn get_b(rgba: Rgba64) -> u8 {
|
|
let x: u64 = rgba;
|
|
|
|
let y = x >> (24 - 16);
|
|
|
|
return (y & 0xff).try_into().unwrap();
|
|
}
|
|
pub fn get_a(rgba: Rgba64) -> u8 {
|
|
let x = rgba;
|
|
|
|
let y = x >> (24 - 16 - 8);
|
|
|
|
return (y & 0xff).try_into().unwrap();
|
|
}
|
|
|
|
pub fn set_r(rgba: Rgba64, r: u8) -> Rgba64 {
|
|
let z = (r as Rgba64) << 24;
|
|
let y = rgba & 0xffffff;
|
|
return z | y;
|
|
}
|
|
|
|
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, b: u8) -> Rgba64 {
|
|
let z = (b as Rgba64) << 26 - 16;
|
|
let y = rgba & 0xffffff;
|
|
return z | y;
|
|
}
|
|
|
|
pub fn set_a(rgba: Rgba64, a: u8) -> Rgba64 {
|
|
let z = (a as Rgba64) << 8;
|
|
let y = rgba & 0xffffff;
|
|
return z | y;
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct RGBA {
|
|
pub r: INT,
|
|
pub g: INT,
|
|
pub b: INT,
|
|
pub a: INT,
|
|
}
|
|
impl RGBA {
|
|
pub fn new(r: INT, g: INT, b: INT, a: INT) -> Self {
|
|
Self { r, g, b, a }
|
|
}
|
|
}
|
|
|
|
pub fn rgba_div(a: Rgba64, b: Rgba64) -> Rgba64 {
|
|
let mut fin: Rgba64 = 0;
|
|
|
|
// println!("{}", fin);
|
|
fin = set_r(fin, get_r(a) / get_r(b));
|
|
// println!("{}", fin);
|
|
|
|
fin = set_g(fin, get_g(a) / get_g(b));
|
|
/*
|
|
|
|
get_b(a) / get_b(b);
|
|
|
|
get_a(a) / get_a(b);
|
|
*/
|
|
|
|
return fin;
|
|
}
|
|
pub fn rgba_mult(a: RGBA, b: RGBA) -> RGBA {
|
|
RGBA {
|
|
r: a.r * b.r,
|
|
g: a.g * b.g,
|
|
b: a.b * b.b,
|
|
a: a.a * b.a,
|
|
}
|
|
}
|
|
pub fn rgba_add(a: RGBA, b: RGBA) -> RGBA {
|
|
RGBA {
|
|
r: a.r + b.r,
|
|
g: a.g + b.g,
|
|
b: a.b + b.b,
|
|
a: a.a + b.a,
|
|
}
|
|
}
|
|
pub fn rgba_sub(a: RGBA, b: RGBA) -> RGBA {
|
|
RGBA {
|
|
r: a.r - b.r,
|
|
g: a.g - b.g,
|
|
b: a.b - b.b,
|
|
a: a.a - b.a,
|
|
}
|
|
}
|
|
//
|
|
|
|
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 {
|
|
use Color16::*;
|
|
match color {
|
|
Black => new_rgba64(0, 0, 0, 0),
|
|
DarkGrey => new_rgba64(105, 105, 105, 0),
|
|
LightGrey => new_rgba64(211, 211, 211, 0),
|
|
//
|
|
Blue => new_rgba64(0, 0, 255, 0),
|
|
Green => new_rgba64(0, 255, 0, 0),
|
|
Red => new_rgba64(255, 0, 0, 0),
|
|
//
|
|
Yellow => new_rgba64(255, 255, 0, 0),
|
|
Cyan => new_rgba64(0, 255, 255, 0),
|
|
Magenta => new_rgba64(255, 0, 255, 0),
|
|
|
|
Brown => new_rgba64(165, 42, 42, 0),
|
|
Pink => new_rgba64(255, 105, 180, 0),
|
|
White => new_rgba64(255, 255, 255, 0),
|
|
|
|
LightBlue => new_rgba64(173, 216, 230, 0),
|
|
LightGreen => new_rgba64(144, 238, 144, 0),
|
|
LightCyan => new_rgba64(88, 100, 100, 0),
|
|
LightRed => new_rgba64(255, 204, 203, 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
|
|
}
|
|
pub fn get_color16(c: Rgba64) -> Color16 {
|
|
let r = get_r(c);
|
|
let g = get_g(c);
|
|
let b = get_b(c);
|
|
|
|
let c = (r, g, b);
|
|
let palette: [(u8, u8, u8); 16] = [
|
|
(0, 0, 0),
|
|
(105, 105, 105),
|
|
(211, 211, 211),
|
|
(0, 0, 255),
|
|
(0, 255, 0),
|
|
(255, 0, 0),
|
|
(255, 255, 0),
|
|
(0, 255, 255),
|
|
(255, 0, 255),
|
|
(165, 42, 42),
|
|
(255, 105, 180),
|
|
(255, 255, 255),
|
|
(173, 216, 230),
|
|
(144, 238, 144),
|
|
(88, 100, 100),
|
|
(255, 204, 203),
|
|
];
|
|
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
|
|
}
|
|
}
|
|
use Color16::*;
|
|
match retval {
|
|
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,
|
|
}
|
|
}
|