Skip to content

Instantly share code, notes, and snippets.

View laevandus's full-sized avatar

Toomas Vahter laevandus

View GitHub Profile
void nrzi_encode(uint8_t* buf, uint8_t* output, uint16_t len)
{
uint8_t prev_nrzi_bit = 0;
uint8_t nrz_bit;
uint8_t nrzi_bit;
uint8_t i, j;
for (i=0; i<len; i++)
{
for (j=0; j<8; j++)
@laevandus
laevandus / Compute.metal
Created November 2, 2017 09:00
Metal kernel for multiplying input data.
kernel void processData(const device float *inVector [[ buffer(0) ]], device float *outVector [[ buffer(1) ]], uint id [[ thread_position_in_grid ]])
{
float input = inVector[id];
outVector[id] = input * 2.0;
}
@laevandus
laevandus / DataConverter.swift
Created November 2, 2017 09:05
Setting up compute pipeline state in Metal.
init()
{
guard let device = MTLCreateSystemDefaultDevice() else { fatalError("Metal device is not available.") }
self.device = device
guard let commandQueue = device.makeCommandQueue() else { fatalError("Failed creating Metal command queue.") }
self.commandQueue = commandQueue
guard let library = device.makeDefaultLibrary() else { fatalError("Failed creating Metal library.") }
guard let function = library.makeFunction(name: "processData") else { fatalError("Failed creating Metal function.") }
@laevandus
laevandus / DataConverter.swift
Last active November 2, 2017 18:25
Running Metal compute kernel.
func process(data: ContiguousArray<Float>) -> ContiguousArray<Float>
{
let dataBuffer = data.withUnsafeBytes { (bufferPointer) -> MTLBuffer? in
guard let baseAddress = bufferPointer.baseAddress else { return nil }
return device.makeBuffer(bytes: baseAddress, length: bufferPointer.count, options: .storageModeShared)
}
guard let inputBuffer = dataBuffer else { return [] }
guard let outputBuffer = device.makeBuffer(length: inputBuffer.length, options: .storageModeShared) else { return [] }
extension SKTexture
{
convenience init(radialGradientWithColors colors: [UIColor], locations: [CGFloat], size: CGSize)
{
let renderer = UIGraphicsImageRenderer(size: size)
let image = renderer.image { (context) in
let colorSpace = context.cgContext.colorSpace ?? CGColorSpaceCreateDeviceRGB()
let cgColors = colors.map({ $0.cgColor }) as CFArray
guard let gradient = CGGradient(colorsSpace: colorSpace, colors: cgColors, locations: UnsafePointer<CGFloat>(locations)) else {
fatalError("Failed creating gradient.")
@laevandus
laevandus / GameScene.swift
Last active December 5, 2017 15:16
Adding linear and radial gradients to SKScene.
final class GameScene: SKScene
{
override func didMove(to view: SKView)
{
let linearGradientSize = size
let linearGradientColors = [UIColor(red: 53.0 / 255.0, green: 92.0 / 255.0, blue: 125.0 / 255.0, alpha: 1.0),
UIColor(red: 108.0 / 255.0, green: 91.0 / 255.0, blue: 123.0 / 255.0, alpha: 1.0),
UIColor(red: 192.0 / 255.0, green: 108.0 / 255.0, blue: 132.0 / 255.0, alpha: 1.0)]
let linearGradientLocations: [CGFloat] = [0, 0.5, 1]
let textureCount = 8
@laevandus
laevandus / GameScene.swift
Created December 3, 2017 20:27
Keeping SKNode at the edge of a screen when scene is scaled.
private var initialSize: CGSize = .zero
private var presentedSize: CGSize { return scene?.view?.bounds.size ?? size }
private var presentedScaleFactor: CGFloat { return initialSize.width / presentedSize.width }
override func sceneDidLoad()
{
super.sceneDidLoad()
initialSize = size
}
let angleToCenter: CGFloat = .pi / 5
let angleToGridPoint: CGFloat = .pi / 3
// 1.0471975511966
let allowedRange = (angleToCenter - .pi / 8)...(angleToCenter + .pi / 8)
let angle = angleToGridPoint.clamped(to: allowedRange)
// 1.02101761241668
extension FloatingPoint {
func clamped(to range: ClosedRange<Self>) -> Self {
return max(min(self, range.upperBound), range.lowerBound)
}
}
let clamped = 5.4.clamped(to: 5.6...6.1)
let clamped = 10.5.clamped(to: 5...7)
extension BinaryInteger {
func clamped(to range: ClosedRange<Self>) -> Self {
return max(min(self, range.upperBound), range.lowerBound)
}
}
let clamped = 10.clamped(to: 5...7)