diff --git a/Examples/SwiftBreak/Package.swift b/Examples/SwiftBreak/Package.swift index 3c81195..2b27bd3 100644 --- a/Examples/SwiftBreak/Package.swift +++ b/Examples/SwiftBreak/Package.swift @@ -9,13 +9,12 @@ guard let home = Context.environment["HOME"] else { } let swiftSettingsSimulator: [SwiftSetting] = [ - .enableExperimentalFeature("Embedded"), .enableExperimentalFeature("NoncopyableGenerics"), .unsafeFlags([ "-Xfrontend", "-disable-objc-interop", - "-Xfrontend", "-disable-stack-protector", - "-Xfrontend", "-function-sections", - "-Xfrontend", "-gline-tables-only", + // "-Xfrontend", "-disable-stack-protector", + // "-Xfrontend", "-function-sections", + // "-Xfrontend", "-gline-tables-only", "-Xcc", "-DTARGET_EXTENSION", "-Xcc", "-I", "-Xcc", "\(gccIncludePrefix)/include", "-Xcc", "-I", "-Xcc", "\(gccIncludePrefix)/include-fixed", @@ -27,17 +26,19 @@ let swiftSettingsSimulator: [SwiftSetting] = [ let package = Package( name: "SwiftBreak", products: [ - .library(name: "SwiftBreak", targets: ["SwiftBreak"]) + .library(name: "SwiftBreak", type: .dynamic, targets: ["SwiftBreak"]), ], dependencies: [ .package(path: "../..") ], targets: [ .target( - name: "SwiftBreak", - dependencies: [ - .product(name: "Playdate", package: "swift-playdate-examples") - ], - swiftSettings: swiftSettingsSimulator) + name: "SwiftBreak", + dependencies: [ + .product(name: "Playdate", package: "swift-playdate-examples"), + ], + path: "Sources", + swiftSettings: swiftSettingsSimulator + ) ], swiftLanguageVersions: [.version("6"), .v5]) diff --git a/Examples/SwiftBreak/Sources/Entry.swift b/Examples/SwiftBreak/Sources/Entry.swift index b1117b8..91dfe6f 100644 --- a/Examples/SwiftBreak/Sources/Entry.swift +++ b/Examples/SwiftBreak/Sources/Entry.swift @@ -10,7 +10,9 @@ nonisolated(unsafe) var game = Game() @_cdecl("update") func update(pointer: UnsafeMutableRawPointer?) -> Int32 { - game.updateGame() + if game.updateGame() { + Sprite.updateAndDrawSprites() + } return 1 } diff --git a/Examples/SwiftBreak/Sources/Game.swift b/Examples/SwiftBreak/Sources/Game.swift index 9b936ba..9b24e10 100644 --- a/Examples/SwiftBreak/Sources/Game.swift +++ b/Examples/SwiftBreak/Sources/Game.swift @@ -53,9 +53,10 @@ struct Game: ~Copyable { } extension Game { - mutating func updateGame() { + mutating func updateGame() -> Bool { let pushed = System.buttonState.pushed - switch self.state { + let state = self.state + switch state { case .loading: if pushed == .a { self.startNewGame() @@ -89,8 +90,8 @@ extension Game { self.startNewGame() } } - - Sprite.updateAndDrawSprites() + + return true } mutating func startNewGame() { diff --git a/Examples/SwiftBreak/simbuild b/Examples/SwiftBreak/simbuild new file mode 100755 index 0000000..13c61ce --- /dev/null +++ b/Examples/SwiftBreak/simbuild @@ -0,0 +1,4 @@ +#!/bin/sh +swift build +cp .build/arm64-apple-macosx/debug/libSwiftBreak.dylib Source/pdex.dylib +${HOME}/Developer/PlaydateSDK/bin/pdc Source SwiftBreak.pdx diff --git a/Package.swift b/Package.swift index 18c2e19..bd7ff0f 100644 --- a/Package.swift +++ b/Package.swift @@ -9,12 +9,14 @@ guard let home = Context.environment["HOME"] else { } let swiftSettingsSimulator: [SwiftSetting] = [ - .enableExperimentalFeature("Embedded"), + // .enableExperimentalFeature("Embedded"), .unsafeFlags([ + "-g", "-Onone", + "-Xfrontend", "-Onone", "-Xfrontend", "-disable-objc-interop", "-Xfrontend", "-disable-stack-protector", "-Xfrontend", "-function-sections", - "-Xfrontend", "-gline-tables-only", + // "-Xfrontend", "-gline-tables-only", "-Xcc", "-DTARGET_EXTENSION", "-Xcc", "-I", "-Xcc", "\(gccIncludePrefix)/include", "-Xcc", "-I", "-Xcc", "\(gccIncludePrefix)/include-fixed", @@ -26,6 +28,7 @@ let swiftSettingsSimulator: [SwiftSetting] = [ let cSettingsSimulator: [CSetting] = [ .unsafeFlags([ "-DTARGET_EXTENSION", + "-nostdlib", "-I", "\(gccIncludePrefix)/include", "-I", "\(gccIncludePrefix)/include-fixed", "-I", "\(gccIncludePrefix)/../../../../arm-none-eabi/include", @@ -36,8 +39,8 @@ let cSettingsSimulator: [CSetting] = [ let package = Package( name: "swift-playdate-examples", products: [ - .library(name: "Playdate", targets: ["Playdate"]), - .library(name: "CPlaydate", targets: ["CPlaydate"]), + .library(name: "Playdate", type: .static, targets: ["Playdate"]), + .library(name: "CPlaydate", type: .static, targets: ["CPlaydate"]), ], targets: [ .target( diff --git a/Sources/Playdate/Sprite.swift b/Sources/Playdate/Sprite.swift index 2d79cc6..354d066 100644 --- a/Sources/Playdate/Sprite.swift +++ b/Sources/Playdate/Sprite.swift @@ -361,7 +361,11 @@ extension Sprite { let rawCollisions = spriteAPI.checkCollisions.unsafelyUnwrapped(self.pointer, goalX, goalY, &actualX, &actualY, &count) let collisions = UnsafeBufferPointer(start: rawCollisions, count: Int(count)) - defer { rawCollisions?.deallocate() } + defer { + if let rawCollisions { + System.free(pointer: rawCollisions) + } + } return body(actualX, actualY, collisions) } @@ -397,7 +401,7 @@ extension Sprite { let rawCollisions = spriteAPI.moveWithCollisions.unsafelyUnwrapped(self.pointer, goalX, goalY, &actualX, &actualY, &count) let collisions = UnsafeBufferPointer(start: rawCollisions, count: Int(count)) - defer { rawCollisions?.deallocate() } + defer { rawCollisions.flatMap(System.free) } return body(actualX, actualY, collisions) } @@ -407,7 +411,7 @@ extension Sprite { var count: Int32 = 0 let rawSprites = spriteAPI.querySpritesAtPoint.unsafelyUnwrapped(x, y, &count) let sprites = UnsafeBufferPointer(start: rawSprites, count: Int(count)) - defer { rawSprites?.deallocate() } + defer { rawSprites.flatMap(System.free) } return body(sprites) } @@ -417,7 +421,7 @@ extension Sprite { var count: Int32 = 0 let rawSprites = spriteAPI.querySpritesInRect.unsafelyUnwrapped(x, y, width, height, &count) let sprites = UnsafeBufferPointer(start: rawSprites, count: Int(count)) - defer { rawSprites?.deallocate() } + defer { rawSprites.flatMap(System.free) } return body(sprites) } @@ -427,7 +431,7 @@ extension Sprite { var count: Int32 = 0 let rawSprites = spriteAPI.querySpritesAlongLine.unsafelyUnwrapped(x1, y1, x2, y2, &count) let sprites = UnsafeBufferPointer(start: rawSprites, count: Int(count)) - defer { rawSprites?.deallocate() } + defer { rawSprites.flatMap(System.free) } return body(sprites) } @@ -439,7 +443,7 @@ extension Sprite { var count: Int32 = 0 let rawSprites = spriteAPI.querySpriteInfoAlongLine.unsafelyUnwrapped(x1, y1, x2, y2, &count) let sprites = UnsafeBufferPointer(start: rawSprites, count: Int(count)) - defer { rawSprites?.deallocate() } + defer { rawSprites.flatMap(System.free) } return body(sprites) } @@ -452,7 +456,7 @@ extension Sprite { var count: Int32 = 0 let rawSprites = spriteAPI.allOverlappingSprites.unsafelyUnwrapped(&count) let sprites = UnsafeBufferPointer(start: rawSprites, count: Int(count)) - defer { rawSprites?.deallocate() } + defer { rawSprites.flatMap(System.free) } return body(sprites) } } diff --git a/Sources/Playdate/System.swift b/Sources/Playdate/System.swift index b111d9e..73d6a87 100644 --- a/Sources/Playdate/System.swift +++ b/Sources/Playdate/System.swift @@ -151,4 +151,16 @@ extension System { public static func clearICache() { systemAPI.clearICache.unsafelyUnwrapped() } + + /// Reallocates a pointer. + /// If `pointer == nil`, and `size > 0`, allocates a new pointer. + /// If `pointer != nil` and `size == 0` deallocates the pointer. + public static func realloc(pointer: UnsafeMutableRawPointer?, size: size_t) -> UnsafeMutableRawPointer? { + systemAPI.realloc.unsafelyUnwrapped(pointer, size) + } + + /// Frees a pointer previously allocated with `realloc()`. + public static func free(pointer: UnsafeMutablePointer) { + let _ = systemAPI.realloc.unsafelyUnwrapped(pointer, 0) + } }