Skip to main content

steel_registry/data_components/components/
rgb_color.rs

1//! Shared codec helpers for Vanilla RGB color components.
2
3use simdnbt::owned::NbtTag;
4use steel_utils::nbt::{NbtNumeric as _, nbt_collection_values};
5
6pub(super) fn decode_rgb_color(tag: &NbtTag) -> Option<i32> {
7    if let Some(color) = tag.codec_i32() {
8        return Some(color);
9    }
10    let channels = nbt_collection_values(tag)?;
11    let [red, green, blue] = channels.as_slice() else {
12        return None;
13    };
14    Some(rgb_from_floats(
15        red.codec_f32()?,
16        green.codec_f32()?,
17        blue.codec_f32()?,
18    ))
19}
20
21fn rgb_from_floats(red: f32, green: f32, blue: f32) -> i32 {
22    let red = java_floor(red * 255.0) & 0xff;
23    let green = java_floor(green * 255.0) & 0xff;
24    let blue = java_floor(blue * 255.0) & 0xff;
25    (0xff00_0000_u32 | ((red as u32) << 16) | ((green as u32) << 8) | blue as u32) as i32
26}
27
28fn java_floor(value: f32) -> i32 {
29    let truncated = value as i32;
30    if value < truncated as f32 {
31        truncated.wrapping_sub(1)
32    } else {
33        truncated
34    }
35}