internal import CPlaydate /// Internal C-string helpers shared by the wrappers. /// /// Passing strings to C goes through the standard `withCString`, which hands /// out a pointer to the string's own null-terminated storage without copying. extension String { /// Creates a string from a nullable C string, or `nil` if the pointer is null. init?(playdateCString pointer: UnsafePointer?) { guard let pointer else { return nil } self.init(cString: pointer) } /// Copies the string into a newly allocated null-terminated C string. /// The caller owns the memory and must free it with `deallocate()`. func copiedPlaydateCString() -> UnsafeMutablePointer { withCString { cString in let count = utf8.count + 1 let buffer = UnsafeMutablePointer.allocate(capacity: count) buffer.initialize(from: cString, count: count) return buffer } } } #if hasFeature(Embedded) && !os(macOS) /// The Embedded Swift runtime allocates through `posix_memalign(3)`, which /// the Playdate device C library does not provide. Memory comes from /// `malloc`, which the SDK's setup code routes to the firmware allocator. /// The pointer is later released with plain `free`, so it cannot be offset /// to adjust alignment; the firmware allocator's natural alignment has to /// satisfy the request, which the precondition asserts. @c(posix_memalign) public func posix_memalign( _ memptr: UnsafeMutablePointer, _ alignment: Int, _ size: Int ) -> CInt { guard let allocation = malloc(size) else { fatalError() } precondition(Int(bitPattern: allocation) % alignment == 0) memptr.pointee = allocation return 0 } #endif