colour emulation

This commit is contained in:
Alex Janka 2023-04-23 09:20:59 +10:00
parent be11c6a596
commit 0a60629dad
4 changed files with 40 additions and 5 deletions

1
Cargo.lock generated
View file

@ -992,6 +992,7 @@ dependencies = [
"bytemuck", "bytemuck",
"futures", "futures",
"itertools", "itertools",
"num-traits",
"once_cell", "once_cell",
"rand", "rand",
"serde", "serde",

View file

@ -16,3 +16,4 @@ itertools = "0.10.5"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_with = "2.3.1" serde_with = "2.3.1"
bytemuck = "1.13" bytemuck = "1.13"
num-traits = "0.2"

View file

@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
processor::memory::addresses::{OamAddress, VramAddress}, processor::memory::addresses::{OamAddress, VramAddress},
util::{as_signed, get_bit}, util::{as_signed, get_bit, SaturatingCast},
}; };
use super::cgb::CgbPalette; use super::cgb::CgbPalette;
@ -117,10 +117,24 @@ impl From<Colour> for [u8; 4] {
} }
fn rgb_from_bytes(bytes: u16) -> Colour { fn rgb_from_bytes(bytes: u16) -> Colour {
let blue = (((bytes & (0b11111 << 10)) >> 10) << 3) as u8; let b = (bytes & (0b11111 << 10)) >> 10;
let green = (((bytes & (0b11111 << 5)) >> 5) << 3) as u8; let g = (bytes & (0b11111 << 5)) >> 5;
let red = ((bytes & 0b11111) << 3) as u8; let r = bytes & 0b11111;
Colour(red, green, blue) // direct colour emulation:
// let blue = (raw_blue << 3) | (raw_blue >> 2);
// let green = (raw_green << 3) | (raw_green >> 2);
// let red = (raw_red << 3) | (raw_red >> 2);
// colour emulation from
// https://web.archive.org/web/20200322151952/https://byuu.net/video/color-emulation
let blue = (r * 6 + g * 4 + b * 22).min(960) >> 2;
let green = (g * 24 + b * 8).min(960) >> 2;
let red = (r * 26 + g * 4 + b * 2).min(960) >> 2;
Colour(
red.saturating_cast(),
green.saturating_cast(),
blue.saturating_cast(),
)
} }
impl ColourInner { impl ColourInner {

View file

@ -1,3 +1,5 @@
use num_traits::{PrimInt, Unsigned};
use crate::processor::{memory::mmio::gpu::Colour, Direction}; use crate::processor::{memory::mmio::gpu::Colour, Direction};
use std::{io, mem::transmute}; use std::{io, mem::transmute};
@ -82,6 +84,23 @@ impl Nibbles for u8 {
} }
} }
pub trait SaturatingCast<T>
where
T: PrimInt + Unsigned,
{
fn saturating_cast(&self) -> T;
}
impl<F, T> SaturatingCast<T> for F
where
T: PrimInt + Unsigned + TryFrom<F>,
F: PrimInt + Unsigned,
{
fn saturating_cast(&self) -> T {
(*self).try_into().unwrap_or(T::max_value())
}
}
pub fn scale_buffer<T: From<Colour> + Copy>( pub fn scale_buffer<T: From<Colour> + Copy>(
buffer: &[T], buffer: &[T],
width: usize, width: usize,