From 0dc7e95c21e1435e09623170f51e5f1792929fe1 Mon Sep 17 00:00:00 2001 From: ashley Date: Mon, 18 Sep 2023 23:42:58 -0400 Subject: [PATCH] Use more accurate color ramp conversion method --- src/reskit/tileset.rs | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/reskit/tileset.rs b/src/reskit/tileset.rs index f9a5822..2a76cec 100644 --- a/src/reskit/tileset.rs +++ b/src/reskit/tileset.rs @@ -1,15 +1,45 @@ use crate::reskit::utility; -use std::error::Error; +use std::{error::Error, ops::RangeInclusive}; use std::fs; use std::fs::File; use std::io::Write; use image::{ GenericImageView, DynamicImage }; +/** + * Get a particular RGB component adjusted for the Mega Drive VDP colour ramp. + * See colour ramp at https://plutiedev.com/vdp-color-ramp + */ +fn rgb_component_to_ramp( component: u16 ) -> Result> { + let ramp: [(RangeInclusive, (u16,u16)); 7] = [ + (0..=52, (0x0, 0x2)), + (52..=87, (0x2, 0x4)), + (87..=116, (0x4, 0x6)), + (116..=144, (0x6, 0x8)), + (144..=172, (0x8, 0xA)), + (172..=206, (0xA, 0xC)), + (206..=255, (0xC, 0xE)) + ]; + + for i in 0..ramp.len() { + let ( ramp_range, ( cram_round_down, cram_round_up ) ) = &ramp[ i ]; + if ramp_range.contains( &component ) { + let range_midpoint = ramp_range.start() + ( ( ramp_range.end() - ramp_range.start() ) / 2 ); + return if component >= range_midpoint { + Ok( *cram_round_up ) + } else { + Ok( *cram_round_down ) + } + } + } + + Err( "rgb component not in range 0-255" )? +} + pub fn color_to_palette( r: u16, g: u16, b: u16, palette: &mut [u16; 16] ) -> Result> { let final_val = - ( ( r & 0x00F0 ) >> 4 ) | - ( g & 0x00F0 ) | - ( ( b & 0x00F0 ) << 4 ); + ( rgb_component_to_ramp( b )? << 8 ) | + ( rgb_component_to_ramp( g )? << 4 ) | + ( rgb_component_to_ramp( r )? ); // Does the color already exist? for i in 0..palette.len() {