mirror of
				https://github.com/GayPizzaSpecifications/voxelotl-engine.git
				synced 2025-11-04 02:59:37 +00:00 
			
		
		
		
	use arc4random to seed non-csprng, fleshes out random subsystem
This commit is contained in:
		@ -13,7 +13,9 @@ add_executable(Voxelotl MACOSX_BUNDLE
 | 
				
			|||||||
  Color.swift
 | 
					  Color.swift
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Random/RandomProvider.swift
 | 
					  Random/RandomProvider.swift
 | 
				
			||||||
 | 
					  Random/RandomRange.swift
 | 
				
			||||||
  Random/Arc4Random.swift
 | 
					  Random/Arc4Random.swift
 | 
				
			||||||
 | 
					  Random/DarwinRandom.swift
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  NSImageLoader.swift
 | 
					  NSImageLoader.swift
 | 
				
			||||||
  Renderer.swift
 | 
					  Renderer.swift
 | 
				
			||||||
 | 
				
			|||||||
@ -25,18 +25,21 @@ class Game: GameDelegate {
 | 
				
			|||||||
  var player = Player()
 | 
					  var player = Player()
 | 
				
			||||||
  var projection: matrix_float4x4 = .identity
 | 
					  var projection: matrix_float4x4 = .identity
 | 
				
			||||||
  var chunk = Chunk(position: .zero)
 | 
					  var chunk = Chunk(position: .zero)
 | 
				
			||||||
  var random = Arc4Random.instance
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init() {
 | 
					  init() {
 | 
				
			||||||
    player.position = SIMD3(0.5, Float(Chunk.chunkSize) + 0.5, 0.5)
 | 
					    self.player.position = SIMD3(0.5, Float(Chunk.chunkSize) + 0.5, 0.5)
 | 
				
			||||||
    player.rotation = .init(.pi, 0)
 | 
					    self.player.rotation = .init(.pi, 0)
 | 
				
			||||||
 | 
					    self.generateWorld()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private func generateWorld() {
 | 
				
			||||||
 | 
					    var random = DarwinRandom(seed: Arc4Random.instance.next(in: DarwinRandom.max))
 | 
				
			||||||
    let colors: [Color<UInt8>] = [
 | 
					    let colors: [Color<UInt8>] = [
 | 
				
			||||||
      .white,
 | 
					      .white,
 | 
				
			||||||
      .red, .blue, .green,
 | 
					      .red, .blue, .green,
 | 
				
			||||||
      .magenta, .yellow, .cyan
 | 
					      .magenta, .yellow, .cyan
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    chunk.fill(allBy: {
 | 
					    self.chunk.fill(allBy: {
 | 
				
			||||||
      if (random.next() & 0x1) == 0x1 {
 | 
					      if (random.next() & 0x1) == 0x1 {
 | 
				
			||||||
        .solid(colors[random.next(in: 0..<colors.count)])
 | 
					        .solid(colors[random.next(in: 0..<colors.count)])
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
@ -59,19 +62,25 @@ class Game: GameDelegate {
 | 
				
			|||||||
    if let pad = GameController.current?.state {
 | 
					    if let pad = GameController.current?.state {
 | 
				
			||||||
      // Delete block underneath player
 | 
					      // Delete block underneath player
 | 
				
			||||||
      if pad.pressed(.south) {
 | 
					      if pad.pressed(.south) {
 | 
				
			||||||
        chunk.setBlock(at: SIMD3(player.position + .down * 0.2), type: .air)
 | 
					        self.chunk.setBlock(at: SIMD3(player.position + .down * 0.2), type: .air)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Player reset
 | 
					      // Player reset
 | 
				
			||||||
      if pad.pressed(.back) {
 | 
					      if pad.pressed(.back) {
 | 
				
			||||||
        player.position = .init(repeating: 0.5) + .init(0, Float(Chunk.chunkSize), 0)
 | 
					        self.player.position = .init(repeating: 0.5) + .init(0, Float(Chunk.chunkSize), 0)
 | 
				
			||||||
        player.velocity = .zero
 | 
					        self.player.velocity = .zero
 | 
				
			||||||
        player.rotation = .init(.pi, 0)
 | 
					        self.player.rotation = .init(.pi, 0)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Regenerate
 | 
				
			||||||
 | 
					      if pad.pressed(.start) {
 | 
				
			||||||
 | 
					        self.generateWorld()
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    player.update(deltaTime: deltaTime, chunk: chunk)
 | 
					    self.player.update(deltaTime: deltaTime, chunk: chunk)
 | 
				
			||||||
    camera.position = player.eyePosition
 | 
					    self.camera.position = player.eyePosition
 | 
				
			||||||
    camera.rotation = player.eyeRotation
 | 
					    self.camera.rotation = player.eyeRotation
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  func draw(_ renderer: Renderer, _ time: GameTime) {
 | 
					  func draw(_ renderer: Renderer, _ time: GameTime) {
 | 
				
			||||||
 | 
				
			|||||||
@ -17,8 +17,12 @@ public class Arc4Random: RandomProvider {
 | 
				
			|||||||
    arc4random()
 | 
					    arc4random()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public func next(in bound: Range<Int>) -> Int {
 | 
					  public func next(in bound: Int) -> Int {
 | 
				
			||||||
    assert(bound.upperBound <= Self.max)
 | 
					    assert(bound <= Self.max)
 | 
				
			||||||
    return bound.lowerBound + Int(arc4random_uniform(UInt32(bound.upperBound)))
 | 
					    return Int(arc4random_uniform(UInt32(bound)))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public func next(in range: Range<Int>) -> Int {
 | 
				
			||||||
 | 
					    return range.lowerBound + next(in: range.upperBound - range.lowerBound)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										33
									
								
								Sources/Voxelotl/Random/DarwinRandom.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								Sources/Voxelotl/Random/DarwinRandom.swift
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					public struct DarwinRandom: RandomProvider {
 | 
				
			||||||
 | 
					  public typealias Output = Int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public static var min: Int { 0x00000000 }
 | 
				
			||||||
 | 
					  public static var max: Int { 0x7FFFFFFF }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private var state: Int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  init() {
 | 
				
			||||||
 | 
					    self.state = 0
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public init(seed: Int) {
 | 
				
			||||||
 | 
					    self.state = seed
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mutating public func seed(with seed: Int) {
 | 
				
			||||||
 | 
					    self.state = seed
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mutating public func next() -> Int {
 | 
				
			||||||
 | 
					    if self.state == 0 {
 | 
				
			||||||
 | 
					      self.state = 123459876
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    let hi = self.state / 127773
 | 
				
			||||||
 | 
					    let lo = self.state - hi * 127773
 | 
				
			||||||
 | 
					    self.state = 16807 * lo - 2836 * hi
 | 
				
			||||||
 | 
					    if self.state < 0 {
 | 
				
			||||||
 | 
					      self.state += Self.max
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return self.state % (Self.max + 1)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								Sources/Voxelotl/Random/RandomRange.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Sources/Voxelotl/Random/RandomRange.swift
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					public extension RandomProvider where Output: BinaryInteger {
 | 
				
			||||||
 | 
					  mutating func next(in range: Range<Int>) -> Int {
 | 
				
			||||||
 | 
					    range.lowerBound + self.next(in: range.upperBound - range.lowerBound)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mutating func next(in range: ClosedRange<Int>) -> Int {
 | 
				
			||||||
 | 
					    range.lowerBound + self.next(in: range.upperBound - range.lowerBound + 1)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mutating func next(in bound: Int) -> Int {
 | 
				
			||||||
 | 
					    assert(Self.min == 0)
 | 
				
			||||||
 | 
					    assert(Self.max >= bound)
 | 
				
			||||||
 | 
					    let threshold = Int(Self.max % Output(bound))
 | 
				
			||||||
 | 
					    var result: Int
 | 
				
			||||||
 | 
					    repeat {
 | 
				
			||||||
 | 
					      result = Int(truncatingIfNeeded: self.next())
 | 
				
			||||||
 | 
					    } while result < threshold
 | 
				
			||||||
 | 
					    return result % bound
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -358,7 +358,7 @@ public class Renderer {
 | 
				
			|||||||
    let instancesBytes = numInstances * MemoryLayout<VertexShaderInstance>.stride
 | 
					    let instancesBytes = numInstances * MemoryLayout<VertexShaderInstance>.stride
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // (Re)create instance buffer if needed
 | 
					    // (Re)create instance buffer if needed
 | 
				
			||||||
    if self._instances[self.currentFrame] == nil || numInstances > self._instances[self.currentFrame]!.length {
 | 
					    if self._instances[self.currentFrame] == nil || instancesBytes > self._instances[self.currentFrame]!.length {
 | 
				
			||||||
      guard let instanceBuffer = self.device.makeBuffer(
 | 
					      guard let instanceBuffer = self.device.makeBuffer(
 | 
				
			||||||
        length: instancesBytes,
 | 
					        length: instancesBytes,
 | 
				
			||||||
        options: .storageModeManaged)
 | 
					        options: .storageModeManaged)
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user