
Quake
Fast Inverse Square Root
A Quake III Algorithm
Learning from Open Source
This webpage cannot succeed without volunteer effort. Your help in improving existing or adding new articles is very welcome. Simply contact via e-mail any article you think we should add.
float Q_rsqrt( float number )
{
long i; // 32-bit number
float x2, y; // 32-bit decimal number
const float threehalfs = 1.5F; // 1.5 (also 32-Bit)
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit hack
i = 0x5f3759df - ( i >> 1 ); // what the fuck?
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2st iteration, can be removed
return y;
}
According to the live activity documentation, we can only detect whether the device supports Live activity, but we don't know if the device has dynamic island
But there is a workaround for you to check for dynamic island. Currently dynamic island only available on iPhone 14 Pro and iPhone 14 Pro Max. So just need to check this both device.
Thanks to this link for type model, the model type name of iPhone 14 Pro and iPhone 14 Pro Max is iPhone15,2 and iPhone15,3 so we just need to check for these.
extension UIDevice {
func checkIfHasDynamicIsland() -> Bool {
if let simulatorModelIdentifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
let nameSimulator = simulatorModelIdentifier
return nameSimulator == "iPhone15,2" || nameSimulator == "iPhone15,3" ? true : false
}
var sysinfo = utsname()
uname(&sysinfo) // ignore return value
let name = String(bytes: Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN)), encoding: .ascii)!.trimmingCharacters(in: .controlCharacters)
return name == "iPhone15,2" || name == "iPhone15,3" ? true : false
}
}
let value = UIDevice().checkIfHasDynamicIsland()
print("value: ", value)
Another solution is to use the window safeAreaInsets value to detect dynamic island. when the device orientation is portrait, safeAreaInsets.top is equal to 59(Display Zoom Default), or 51(Display Zoom Large Text).
This is likely to support the iPhone15 Pro/iPhone15 Pro Max and later models.
extension UIDevice {
// Get this value after sceneDidBecomeActive
static var hasDynamicIsland: Bool {
// 1. dynamicIsland only support iPhone
guard UIDevice.current.userInterfaceIdiom == .phone else {
return false
}
// 2. Get key window, working after sceneDidBecomeActive
guard let window = (UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }.flatMap { $0.windows }.first { $0.isKeyWindow}) else {
print("Do not found key window")
return false
}
// 3.It works properly when the device orientation is portrait
return window.safeAreaInsets.top >= 51
}
}
if UIDevice.current.hasDynamicIsland == true {
...
}
void set_bit( unsigned char *byte, unsigned char n ) {
*byte |= 1 << n;
}
unsigned char get_bit( unsigned char byte, unsigned char n ) {
return (byte >> n) & 1;
}
void swap_using_xor( unsigned int *x, unsigned int *y )
{
*x = *x ^ *y; // x = x ^ y
*y = *x ^ *y; // y = (x ^ y) ^ y wich means now y = original x
*x = *x ^ *y; // x = (x ^ y) ^ y but since y is now original x then
// it is really x = (x ^ y) ^ x, so x = original y
}
RGBA stands for red green blue alpha. While it is sometimes described as a color space, ... On a little endian architecture this is equivalent to ABGR32.
uint32_t alpha_blend(uint32_t source, uint32_t background)
{
// Alpha blending the source and background RGBA colors : ABGR32 (little endian)
uint32_t alpha = (source >> 24);
uint32_t bxrx = (((source & 0x00ff00ff) * alpha) +
((background & 0x00ff00ff) * (0xff - alpha))) &
0xff00ff00;
uint32_t axgx = ((((source >> 8) & 0x00ff00ff) * alpha) +
(((background >> 8) & 0x00ff00ff) * (0xff - alpha))) &
0xff00ff00;
return ((bxrx >> 8) | axgx);
}
Render a UIImage with a gradient layer. Assign the gradient image to an SKTexture object. Assign the texture object to an SKSpriteNode and add the sprite as a child to the scene.
To render gradient images, we need to extend the base class of UIImage.
Basically, this extended behavior does is that it lets us configure a gradient layer, and then render a UIImage using the gradient layer.
extension UIImage {
static func gradientImage(withBounds: CGRect, startPoint: CGPoint, endPoint: CGPoint , colors: [CGColor]) -> UIImage {
// Configure the gradient layer based on input
let gradientLayer = CAGradientLayer()
gradientLayer.frame = withBounds
gradientLayer.colors = colors
gradientLayer.startPoint = startPoint
gradientLayer.endPoint = endPoint
// Render the image using the gradient layer
UIGraphicsBeginImageContext(gradientLayer.bounds.size)
gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
Feel free to use any colors (and remember to transform them into cgColor).
let color1: CGColor = UIColor(red: 0, green: 0, blue: 192/255, alpha: 1).cgColor
let color2: CGColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1).cgColor
let color3: CGColor = UIColor(red: 192/255, green: 0, blue: 0, alpha: 1).cgColor
Gradient layer has properties startPoint and endPoint. These are defined in the gradient layer’s unit coordinate space, regardless of whether the gradient layer is drawn on a square or a rectangle. The direction of a linear gradient is from startPoint towards the endPoint. This might be confusing, but basically, the direction of the gradient is the direction in which the color changes most rapidly.
(0, 0)
End Point
(1, 1)
(0, 0)
Start Point
(1, 1)
(1, 0)
Start Point
(0, 1)
(1, 0)
End Point
(0, 1)
(0.5, 0 )
Start Point
(0.5, 1)
(0.5, 0)
End Point
(0.5, 1)
(0, 0.5)
Start Point
(1, 0.5)
(0, 0.5)
End Point
(1, 0.5)
Feel free to choose any direction you like. I’m going to use the top left gradient in this example:
let startPoint = CGPoint(x: 0, y: 0)
let endPoint = CGPoint(x: 1, y: 1)
Now inside e.g. didMove function, create a gradient image with the scene’s frame as the boundaries of it, and use the colors defined above + set the start and the end points of the gradient to define its direction.
let image: UIImage = UIImage.gradientImage(withBounds: self.frame, startPoint: startPoint, endPoint: endPoint, colors: [color1, color2, color3])
Then create a texture using the gradient image. Create a gradient node using the texture and finally add it as the child of the scene.
let gradientTexture = SKTexture(image: image)
let gradientNode = SKSpriteNode(texture: gradientTexture)
self.addChild(gradientNode)
Now if you run the app you should see a nice gradient in the view.
In the gradient hides all the other sprites in the scene, you need to adjust the gradient layer’s z-position by changing gradientNode.zPosition to have e.g. the smallest value among all the other nodes if you want the gradient to be in the background.
Transforms the user coordinate system in a context such that the y-axis is flipped.
/*
Copyright © 2023 Insoft. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
extension CGContext {
/// Transforms the user coordinate system in a context
/// such that the y-axis is flipped.
func flipYAxis() {
concatenate(CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty:
CGFloat(height)/abs(userSpaceToDeviceSpaceTransform.d)))
}
}
A colection of extensions for CGFloat
/*
Copyright © 2023 Insoft. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
extension CGFloat {
static let scale = UIScreen.main.scale
static let nativeScale = UIScreen.main.nativeScale
static var width: CGFloat {
return UIScreen.main.bounds.size.width
}
static var nativeWidth: CGFloat {
return UIScreen.main.nativeBounds.size.width
}
static var height: CGFloat {
return UIScreen.main.bounds.size.height
}
static var nativeHight: CGFloat {
return UIScreen.main.nativeBounds.size.height
}
static let margin: CGFloat = 18.0
static let scaleFactor = UIDevice.current.userInterfaceIdiom == .pad ? 1.5 * UIScreen.main.scale : UIScreen.main.scale
static func degrees(_ angle: CGFloat) -> CGFloat {
return angle * .pi/180
}
static let earthGravity: CGFloat = 9.8;
}
A colection of extensions for CGImage
/*
Copyright © 2023 Insoft. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
import CoreGraphics
#if canImport(UniformTypeIdentifiers)
import UniformTypeIdentifiers
#endif
#if canImport(MobileCoreServices)
import MobileCoreServices
#endif
extension CGImage {
static func create(fromPixelData pixelData:UnsafePointer<UInt8>, ofSize size:CGSize) -> CGImage? {
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
let provider = CGDataProvider(data: CFDataCreate(nil, pixelData, Int(size.width) * Int(size.height) * 4))
CGImageSourceCreateWithDataProvider(provider!, nil)
let cgimg = CGImage(
width: Int(size.width),
height: Int(size.height),
bitsPerComponent: Int(8),
bitsPerPixel: Int(32),
bytesPerRow: Int(size.width) * Int(4),
space: colorSpace,
bitmapInfo: bitmapInfo,
provider: provider!,
decode: nil,
shouldInterpolate: true,
intent: CGColorRenderingIntent.defaultIntent
)
return cgimg
}
@discardableResult func write(to destinationURL: URL) -> Bool {
if #available(iOS 14.0, *) {
guard let destination = CGImageDestinationCreateWithURL(destinationURL as CFURL, UTType.png.identifier as CFString, 1, nil) else { return false }
CGImageDestinationAddImage(destination, self, nil)
return CGImageDestinationFinalize(destination)
} else {
// Fallback on earlier versions
guard let destination = CGImageDestinationCreateWithURL(destinationURL as CFURL, kUTTypePNG, 1, nil) else { return false }
CGImageDestinationAddImage(destination, self, nil)
return CGImageDestinationFinalize(destination)
}
}
}
// MARK: - Objective-C
@objc class _CGImage: NSObject {
@objc static func create(fromPixelData pixelData:UnsafePointer<UInt8>, ofSize size:CGSize) -> CGImage? {
return CGImage.create(fromPixelData: pixelData, ofSize: size)
}
@objc func write(cgimage: CGImage, to destinationURL: URL) -> Bool {
return cgimage.write(to: destinationURL)
}
}
A colection of extensions for UIApplication
/*
Copyright © 2023 Insoft. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
import Foundation
extension UIApplication {
@objc static var rootViewController: UIViewController? {
if #available(iOS 15, *) {
// WTF! Apple
return (UIApplication.shared.connectedScenes.first as? UIWindowScene)?.windows.first?.rootViewController
} else {
return UIApplication.shared.windows.first?.rootViewController
}
}
}