aboutsummaryrefslogblamecommitdiffstats
path: root/src/render.rs
blob: bd17e2b237efc54713306db65c75586c512226fc (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                                                                  
              






                                                    
























                                                                                  




                                                  





                                                  
 

                                                 


                                                
                                                                          
 



















                                                                 
         









                                                                                                    
              
                                                            
        















                                                                      
 




                                             
 

                                                           


               
                                                                    

                      



                                                          



                                   





                                                                                                   
 

                         

                               














                                                                       
           
               
          























                                                                                             
       
 
                                                                                      
 

























                                                                                                  

   
use crate::font::BakedFont;
use crate::generated::fonts::{FONT_CHERRY_BOMB_ONE, FONT_GALMURI};
use rand::Rng;
use sdl2::pixels::{Color, PixelFormatEnum};
use sdl2::rect::Rect;
use sdl2::render::{Canvas, Texture, TextureCreator};
use sdl2::surface::Surface;
use sdl2::video::{Window, WindowContext};
use std::ops::DerefMut;

fn dvd_logo_offset(t: f64, screen_size_x: f64, screen_size_y: f64) -> (f64, f64) {
  let offset_x = t % (screen_size_x * 2.0);
  let offset_x = if offset_x > screen_size_x {
    screen_size_x * 2.0 - offset_x
  } else {
    offset_x
  };

  let offset_y = t % (screen_size_y * 2.0);
  let offset_y = if offset_y > screen_size_y {
    screen_size_y * 2.0 - offset_y
  } else {
    offset_y
  };

  (offset_x, offset_y)
}

const START_UWUSPACE: f64 = 0.0;
const START_BOUNCE: f64 = 0.5;
const START_SIN: f64 = 1.5;
const START_COMETOCOSIN: f64 = 2.5;
const SCENE_GREETINGS: f64 = 20.0;
const JUST_DVD: f64 = 70.0;

pub fn render(
  canvas: &mut Canvas<Window>,
  texture_creator: &TextureCreator<WindowContext>,
  time_seconds: f64,
) {
  let i = ((time_seconds * 60.0) % 510.0).round();
  let i = if i > 255.0 {
    (255.0 - (i - 255.0)) as u8
  } else {
    i as u8
  };

  let win_size = canvas.window().drawable_size();

  canvas.set_draw_color(Color::RGB(12, 12, 12));
  canvas.clear();

  let is_dvd = time_seconds < SCENE_GREETINGS || time_seconds >= JUST_DVD;

  if is_dvd {
    let time_seconds = if time_seconds >= JUST_DVD {
      time_seconds - JUST_DVD + 15.0
    } else {
      time_seconds
    };
    if time_seconds >= START_UWUSPACE {
      let bounce_speed = 90.0;
      let padding_x = 16.0;
      let padding_y = 16.0;
      let (offset_x, offset_y) = if time_seconds > START_BOUNCE {
        let mut uwu_width = padding_x;
        let mut uwu_height: f32 = padding_y;
        for c in "UwU-Space".chars() {
          let char = FONT_CHERRY_BOMB_ONE.get_char(c);
          uwu_width += char.advance_width;
          let nh = f32::from(char.height) + padding_y;
          if nh > uwu_height {
            uwu_height = nh;
          }
        }
        let virtual_screen_size = (
          f64::from(win_size.0) - (uwu_width + padding_x),
          f64::from(win_size.1) - f64::from(uwu_height + padding_y),
        );
        let t = (time_seconds - START_BOUNCE) * bounce_speed;
        let (offset_x, offset_y) = dvd_logo_offset(t, virtual_screen_size.0, virtual_screen_size.1);
        (
          (padding_x + offset_x).round() as i32,
          (f64::from(padding_y) + offset_y).round() as i32,
        )
      } else {
        (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(i, 64, 255 - i))
              .unwrap(),
            None,
            char.to_rect(offset as i32 + offset_x, offset_y),
          )
          .unwrap();
        offset += char.advance_width;
      }
    }
  }

  if time_seconds >= JUST_DVD {
    //
  } else if time_seconds >= SCENE_GREETINGS {
    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(i, 64, 255 - i))
            .unwrap(),
          None,
          char.to_rect(
            offset as i32 + 18 + rng.gen_range(-2..2),
            win_size.1 as i32 - 24 + rng.gen_range(-2..2),
          ),
        )
        .unwrap();
      offset += char.advance_width;
    }
  } else {
    if time_seconds >= START_SIN {
      let time_seconds = time_seconds - START_SIN;
      let base_sin_offset = time_seconds * 0.1;
      let sin_offset = base_sin_offset - 0.75;
      let mut sin_surface = Surface::new(win_size.0, win_size.1, PixelFormatEnum::RGBA32).unwrap();

      let w = win_size.0;
      let h = win_size.1;
      let f64_w = f64::from(w);
      let f64_h = f64::from(h);
      let f = &mut sin_surface.deref_mut().without_lock_mut().unwrap();

      let min_x_pos = (if base_sin_offset > 1.0 {
        0.0
      } else {
        1.0 - base_sin_offset
      }) * f64_w;

      for x in 0..w {
        let f64_x = f64::from(x);
        let out_of_frame = f64_x < min_x_pos;
        let sin_x = {
          let mut sin_x = f64_x + (sin_offset * f64_w);
          if sin_x > f64_w {
            sin_x -= f64_w;
          }
          sin_x
        };
        let sin_y =
          ((f64::sin(sin_x * (3.141 * 2.0) / f64_w) + 1.0) * (f64_h / 2.0)).floor() as usize;
        // let sin_idx = (sin_y * w as usize + x as usize) * 4;

        for y in 0..h {
          let idx = (y * w + x) as usize * 4;
          let cx = x * 512 / w;
          f[idx] = (122 - (cx / 8)) as u8;
          f[idx + 1] = (255 - (cx / 2)) as u8;
          f[idx + 2] = (cx / 2) as u8;
          f[idx + 3] = if out_of_frame {
            0
          } else if sin_y < y as usize {
            let v: u16 = if idx % 5 == 0 { 255 } else { 122 };
            let v = if (sin_y + 3) < (y as usize) {
              v
            } else {
              v * 2 / 3
            };
            v as u8
          } else {
            0
          };
        }
      }

      let sin_texture = Texture::from_surface(&sin_surface, texture_creator).unwrap();

      canvas
        .copy(&sin_texture, None, Rect::new(0, 0, win_size.0, win_size.1))
        .unwrap();
    }
    if time_seconds >= START_COMETOCOSIN {
      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);
        canvas
          .copy(
            &char
              .to_texture(texture_creator, Color::RGB(i, 64, 255 - i))
              .unwrap(),
            None,
            char.to_rect(offset as i32, win_size.1 as i32 - 32),
          )
          .unwrap();
        offset += char.advance_width;
        if offset > wrap_width {
          offset -= wrap_width;
        }
      }
    }
  }
}