1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//! PRNGs that aren't any kind of congruential generator.

/// The Super Mario 64 PRNG. Please, only use this as a joke.
///
/// [Watch the Youtube video](https://www.youtube.com/watch?v=MiuLeTE2MeQ)
pub fn sm64(mut input: u16) -> u16 {
  if input == 0x560A {
    input = 0;
  }
  let mut s0: u16 = input << 8;
  s0 ^= input;
  input = s0.rotate_left(8);
  s0 = ((s0 as u8) << 1) as u16 ^ input;
  let s1 = (s0 >> 1) ^ 0xFF80;
  if (s0 & 1) == 0 {
    if s1 == 0xAA55 {
      input = 0;
    } else {
      input = s1 ^ 0x1FF4;
    }
  } else {
    input = s1 ^ 0x8180;
  }
  input
}

/// As per `sm64`, but the main cycle doesn't end early.
///
/// Giving `0x560A` still jumps you back to the main cycle.
#[deprecated(since = "2.0.1", note = "sm64 is bad to use but faithful to a past game, this is just bad to use")]
pub fn sm64_longer(mut input: u16) -> u16 {
  if input == 0x560A {
    input = 0;
  }
  let mut s0: u16 = input << 8;
  s0 ^= input;
  input = s0.rotate_left(8);
  s0 = ((s0 as u8) << 1) as u16 ^ input;
  let s1 = (s0 >> 1) ^ 0xFF80;
  if (s0 & 1) == 0 {
    input = s1 ^ 0x1FF4;
  } else {
    input = s1 ^ 0x8180;
  }
  input
}