From d694a954175de13e0a354f8576d65dde7e125e8e Mon Sep 17 00:00:00 2001 From: memdmp Date: Sun, 16 Feb 2025 02:29:24 +0100 Subject: feat: improve text rendering --- src/render.rs | 328 +++++++++++++++++++++++++++------------------------------- 1 file changed, 154 insertions(+), 174 deletions(-) (limited to 'src/render.rs') diff --git a/src/render.rs b/src/render.rs index 9e80307..08b17be 100644 --- a/src/render.rs +++ b/src/render.rs @@ -1,5 +1,6 @@ use crate::font::BakedFont; use crate::generated::fonts::{FONT_CHERRY_BOMB_ONE, FONT_GALMURI}; +use rand::distributions::uniform::SampleRange; use rand::Rng; use sdl2::pixels::{Color, PixelFormatEnum}; use sdl2::rect::Rect; @@ -26,6 +27,59 @@ fn dvd_logo_offset(t: f64, screen_size_x: f64, screen_size_y: f64) -> (f64, f64) (offset_x, offset_y) } +fn render_chars_with_rng( + canvas: &mut Canvas, + texture_creator: &TextureCreator, + str: impl Iterator, + font: impl BakedFont, + range_x: &R, + range_y: &R, + offset_x: &mut f64, + offset_y: &i32, + colour: Color, + rng: &mut impl Rng, +) where + R: SampleRange + Clone, +{ + let mut rng = rng; + for c in str { + let char = font.get_char(c); + canvas + .copy( + &char.to_texture(texture_creator, colour).unwrap(), + None, + char.to_rect( + offset_x.clone() as i32 + rng.gen_range(range_x.clone()), + offset_y.clone() + rng.gen_range(range_y.clone()), + ), + ) + .unwrap(); + *offset_x += char.advance_width; + } +} + +fn render_chars_without_rng( + canvas: &mut Canvas, + texture_creator: &TextureCreator, + str: impl Iterator, + font: impl BakedFont, + offset_x: &mut f64, + offset_y: &i32, + colour: Color, +) { + for c in str { + let char = font.get_char(c); + canvas + .copy( + &char.to_texture(texture_creator, colour).unwrap(), + None, + char.to_rect(offset_x.clone() as i32, offset_y.clone()), + ) + .unwrap(); + *offset_x += char.advance_width; + } +} + pub const START_UWUSPACE: f64 = 0.0; pub const START_BOUNCE: f64 = 0.5; pub const START_SIN: f64 = 12.0; @@ -104,22 +158,15 @@ pub fn render( (padding_x.round() as i32, padding_y.round() as i32) }; let mut offset: f64 = 0.0; - for c in "UwU-Space".chars() { - let char = FONT_CHERRY_BOMB_ONE.get_char(c); - canvas - .copy( - &char - .to_texture( - texture_creator, - Color::RGB(colourthing, 64, 255 - colourthing), - ) - .unwrap(), - None, - char.to_rect(offset as i32 + offset_x, offset_y), - ) - .unwrap(); - offset += char.advance_width; - } + render_chars_without_rng( + canvas, + texture_creator, + "UwU-Space".chars(), + FONT_CHERRY_BOMB_ONE, + &mut f64::from(offset_x), + &offset_y, + Color::RGB(colourthing, 64, 255 - colourthing), + ); } } @@ -148,36 +195,30 @@ pub fn render( let mut i = 0.0; let strlen = 19; - let mut uwuoffset_x = 0.0; - for c in { + let mut uwuoffset_x = 18.0; + let str = { if time_seconds + 0.75 >= (SCENE_GREETINGS - SCENE_MOAR) { - "oh look a 64k rust demo".chars() + "oh look a 64k rust demo" } else { - "Have some scrollers: x3".chars() + "Have some scrollers: x3" } - } { - let char: crate::font::RenderableCharacter = FONT_GALMURI.get_char(c); - canvas - .copy( - &char - .to_texture( - texture_creator, - Color::RGB(colourthing, 64, 255 - colourthing), - ) - .unwrap(), - None, - char.to_rect( - uwuoffset_x as i32 + 18 + rng.gen_range(-2..2), - (24) + rng.gen_range(-3..3), - ), - ) - .unwrap(); - uwuoffset_x += char.advance_width; - i += 1.0; - if i > (time_seconds * (f64::from(strlen) / greeting_header_duration)).floor() { - break; - } - } + }; + let str = str.chars().collect::>(); + let str = &str[0..((time_seconds * (f64::from(strlen) / greeting_header_duration)).floor() + as usize) + .min(str.len())]; + render_chars_with_rng( + canvas, + texture_creator, + str.iter().map(|v| *v), + FONT_GALMURI, + &(-2..2), + &(-3..3), + &mut uwuoffset_x, + &24, + Color::RGB(colourthing, 64, 255 - colourthing), + &mut rng, + ); let mut offset_y = 36; for line in [ "Pls come to CoSin 2025 Credits", @@ -194,25 +235,7 @@ pub fn render( let mut offset_x: f64 = f64::from(win_size.0) - ((time_seconds - greeting_header_duration) * (f64::from(win_size.0) * 0.078125)); - for c in line.chars() { - let char = FONT_GALMURI.get_char(c); - canvas - .copy( - &char - .to_texture( - texture_creator, - Color::RGB(colourthing, 64, 255 - colourthing), - ) - .unwrap(), - None, - char.to_rect( - offset_x as i32 + rng.gen_range(-2..2), - offset_y + rng.gen_range(-2..2), - ), - ) - .unwrap(); - offset_x += char.advance_width; - } + render_chars_with_rng(canvas, texture_creator, line.chars(), FONT_GALMURI, &(-2..2), &(-2..2), &mut offset_x,&offset_y, Color::RGB(colourthing, 64, 255 - colourthing), &mut rng); } } } @@ -222,27 +245,31 @@ pub fn render( let time_seconds = time_seconds - SCENE_GREETINGS; // Greetings let greeting_header_duration = 4.0; + let colour = Color::RGB(colourthing, 64, 255 - colourthing); + let mut rng = rand::thread_rng(); { - let mut rng = rand::thread_rng(); - let mut i = 0.0; let strlen = 43; let mut uwuoffset_x = 0.0; - for c in "Greetings by UwU-Space to:".chars() { + let str = "Greetings by UwU-Space to:"; + let str = str.chars().collect::>(); + let str = &str[0..{ + let f = time_seconds * (f64::from(strlen) / greeting_header_duration); + let f = f.floor() as usize; + f.min(str.len()) + }]; + for c in str { + // we dont use the abstraction funcs due to the inline uwu-space let is_not_uwu = i <= 12.0 || i >= 22.0; + i += 1.0; let char = if is_not_uwu { - FONT_GALMURI.get_char(c) + FONT_GALMURI.get_char(*c) } else { - FONT_CHERRY_BOMB_ONE.get_char(c) + FONT_CHERRY_BOMB_ONE.get_char(*c) }; canvas .copy( - &char - .to_texture( - texture_creator, - Color::RGB(colourthing, 64, 255 - colourthing), - ) - .unwrap(), + &char.to_texture(texture_creator, colour).unwrap(), None, char.to_rect( uwuoffset_x as i32 + 18 + rng.gen_range(-2..2), @@ -251,10 +278,6 @@ pub fn render( ) .unwrap(); uwuoffset_x += char.advance_width; - i += 1.0; - if i > (time_seconds * (f64::from(strlen) / greeting_header_duration)).floor() { - break; - } } let mut offset_y = 36; let mut line_index = 0; @@ -265,105 +288,62 @@ pub fn render( vec!["Shana", "psykon", "Unlock"], ] { offset_y += 24; - let mut offset_x = (f64::from(line_index) * 90.0) + f64::from(win_size.0) - - ((time_seconds - greeting_header_duration) * (f64::from(win_size.0) * 0.078125)); + let mut offset_x = 18.0 + + ((f64::from(line_index) * 90.0) + f64::from(win_size.0) + - ((time_seconds - greeting_header_duration) * (f64::from(win_size.0) * 0.078125))); line_index += 1; - for c in line.join(" ").chars() { - let char = FONT_GALMURI.get_char(c); - canvas - .copy( - &char - .to_texture( - texture_creator, - Color::RGB(colourthing, 64, 255 - colourthing), - ) - .unwrap(), - None, - char.to_rect( - offset_x as i32 + 18 + rng.gen_range(-2..2), - offset_y + rng.gen_range(-2..2), - ), - ) - .unwrap(); - offset_x += char.advance_width; - } + render_chars_with_rng( + canvas, + texture_creator, + line.join(" ").chars(), + FONT_GALMURI, + &(-2..2), + &(-2..2), + &mut offset_x, + &offset_y, + colour, + &mut rng, + ); } } // We did most of this at mountainbytes - { - let mut offset = 0.0; - let mut rng = rand::thread_rng(); - - for c in "we did 90% onsite at mountainbytes 2025,".chars() { - let char = FONT_GALMURI.get_char(c); - canvas - .copy( - &char - .to_texture( - texture_creator, - Color::RGB(colourthing, 64, 255 - colourthing), - ) - .unwrap(), - None, - char.to_rect( - offset as i32 + 18 + rng.gen_range(-2..2), - win_size.1 as i32 - 64 + rng.gen_range(-2..2), - ), - ) - .unwrap(); - offset += char.advance_width; - } - } - { - let mut offset = 0.0; - let mut rng = rand::thread_rng(); - - for c in "the rest 2 months ago".chars() { - let char = FONT_GALMURI.get_char(c); - canvas - .copy( - &char - .to_texture( - texture_creator, - Color::RGB(colourthing, 64, 255 - colourthing), - ) - .unwrap(), - None, - char.to_rect( - offset as i32 + 24 + rng.gen_range(-2..2), - win_size.1 as i32 - 32 + rng.gen_range(-2..2), - ), - ) - .unwrap(); - offset += char.advance_width; - } - } - // Sorry for shit invite - { - let mut offset = 0.0; - let mut rng = rand::thread_rng(); - - for c in "sorry for shit invite we have adhd".chars() { - let char = FONT_GALMURI.get_char(c); - canvas - .copy( - &char - .to_texture( - texture_creator, - Color::RGB(colourthing, 64, 255 - colourthing), - ) - .unwrap(), - None, - char.to_rect( - offset as i32 + 18 + rng.gen_range(-2..2), - win_size.1 as i32 - 96 + rng.gen_range(-2..2), - ), - ) - .unwrap(); - offset += char.advance_width; - } - } + render_chars_with_rng( + canvas, + texture_creator, + "sorry for shit invite we have adhd".chars(), + FONT_GALMURI, + &(-2..2), + &(-2..2), + &mut 18.0, + &(win_size.1 as i32 - 96), + colour, + &mut rng, + ); + render_chars_with_rng( + canvas, + texture_creator, + "we did 90% onsite at mountainbytes 2025,".chars(), + FONT_GALMURI, + &(-2..2), + &(-2..2), + &mut 18.0, + &(win_size.1 as i32 - 64), + colour, + &mut rng, + ); + render_chars_with_rng( + canvas, + texture_creator, + "the rest 2 months ago".chars(), + FONT_GALMURI, + &(-2..2), + &(-2..2), + &mut 18.0, + &(win_size.1 as i32 - 32), + colour, + &mut rng, + ); } } else { if time_seconds >= START_SIN { @@ -430,9 +410,9 @@ pub fn render( let time_seconds = time_seconds - START_COMETOCOSIN; let wrap_width = f64::from(win_size.0); let mut offset = (18.0 + (time_seconds * 32.0)) % wrap_width; - // WARNING: we wrap this! if the text is wider than the window, this whole thing falls apart - for c in "Come to Cosin25 :3".chars() { - let char = FONT_GALMURI.get_char(c); + // World's shittiest marquee implementation + for char in "Come to Cosin25 :3".chars() { + let char = FONT_GALMURI.get_char(char); canvas .copy( &char -- cgit v1.2.3