-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
41 changed files
with
2,076 additions
and
0 deletions.
There are no files selected for viewing
8 changes: 8 additions & 0 deletions
8
Examples/SwiftIOPlayground/13MoreProjects/Fireworks/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.DS_Store | ||
/.build | ||
/Packages | ||
xcuserdata/ | ||
DerivedData/ | ||
.swiftpm/configuration/registries.json | ||
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata | ||
.netrc |
28 changes: 28 additions & 0 deletions
28
Examples/SwiftIOPlayground/13MoreProjects/Fireworks/Package.mmp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# This is a MadMachine project file in TOML format | ||
# This file contains parameters that cannot be managed by SwiftPM | ||
# Editing this file will alter the behavior of the build/download process | ||
# Project files within dependent libraries will be IGNORED | ||
|
||
# Specify the board name below | ||
# Supported boards are listed as follows | ||
# "SwiftIOBoard" | ||
# "SwiftIOMicro" | ||
board = "SwiftIOMicro" | ||
|
||
# Specify the target triple below | ||
# Supported architectures are listed as follows | ||
# "thumbv7em-unknown-none-eabi" | ||
# "thumbv7em-unknown-none-eabihf" | ||
# "armv7em-none-none-eabi" | ||
triple = "armv7em-none-none-eabi" | ||
|
||
# Enable or disable hardware floating-point support below | ||
# If your code involves significant floating-point calculations, please set it to 'true' | ||
hard-float = true | ||
|
||
# Enable or disable float register below | ||
# If your code involves significant floating-point calculations, please set it to 'true' | ||
float-abi = false | ||
|
||
# Reserved for future use | ||
version = 1 |
28 changes: 28 additions & 0 deletions
28
Examples/SwiftIOPlayground/13MoreProjects/Fireworks/Package.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// swift-tools-version: 5.9 | ||
// The swift-tools-version declares the minimum version of Swift required to build this package. | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "Fireworks", | ||
dependencies: [ | ||
// Dependencies declare other packages that this package depends on. | ||
.package(url: "https://github.com/madmachineio/SwiftIO.git", branch: "develop"), | ||
.package(url: "https://github.com/madmachineio/MadBoards.git", branch: "develop"), | ||
.package(url: "https://github.com/madmachineio/MadDrivers.git", branch: "develop"), | ||
.package(url: "https://github.com/madmachineio/CFreeType", from: "2.13.0"), | ||
], | ||
targets: [ | ||
// Targets are the basic building blocks of a package, defining a module or a test suite. | ||
// Targets can depend on other targets in this package and products from dependencies. | ||
.executableTarget( | ||
name: "Fireworks", | ||
dependencies: [ | ||
"SwiftIO", | ||
"MadBoards", | ||
// Use specific library name rather than "MadDrivers" would speed up the build procedure. | ||
.product(name: "ST7789", package: "MadDrivers"), | ||
"CFreeType" | ||
]), | ||
] | ||
) |
Binary file added
BIN
+164 KB
Examples/SwiftIOPlayground/13MoreProjects/Fireworks/Resources/Fonts/Roboto-Regular.ttf
Binary file not shown.
Binary file added
BIN
+84.6 KB
Examples/SwiftIOPlayground/13MoreProjects/Fireworks/Resources/Sounds/boom.wav
Binary file not shown.
89 changes: 89 additions & 0 deletions
89
Examples/SwiftIOPlayground/13MoreProjects/Fireworks/Sources/Firework.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import MadGraphics | ||
import ST7789 | ||
import SwiftIO | ||
|
||
struct Firework { | ||
var particle: Particle | ||
var sparks: [Spark] = [] | ||
|
||
var exploded = false | ||
|
||
let color: Color | ||
let size = 2 | ||
|
||
// Create a firework at the bottom of the screen. | ||
init(color: Color, maxWidth: Int) { | ||
self.color = color | ||
|
||
let x = Array(0..<(maxWidth - 1)).shuffled().randomElement()! | ||
particle = Particle(pos: Point(x: x, y: maxWidth - 1)) | ||
} | ||
|
||
// Update firework's position. | ||
// If it explodes, it will return true to indicate it's time to play sound. | ||
mutating func update(_ layer: Layer) -> Bool { | ||
if exploded { | ||
for spark in sparks { | ||
layer.draw() { canvas in | ||
canvas.fillCircle(at: spark.pos, radius: size, data: Color.black.rawValue) | ||
} | ||
} | ||
|
||
updateSparks() | ||
|
||
for spark in sparks { | ||
let color = Color.blend(foreground: color.rawValue, background: Color.black.rawValue, mask: spark.lifespan) | ||
layer.draw() { canvas in | ||
canvas.fillCircle(at: spark.pos, radius: size, data: color.rawValue) | ||
} | ||
} | ||
} else { | ||
layer.draw() { canvas in | ||
canvas.fillCircle(at: particle.pos, radius: size, data: Color.black.rawValue) | ||
} | ||
|
||
let playSound = updateParticle() | ||
|
||
layer.draw() { canvas in | ||
canvas.fillCircle(at: particle.pos, radius: size, data: color.rawValue) | ||
} | ||
return playSound | ||
} | ||
|
||
return false | ||
} | ||
|
||
// Update sparks' position and speed over time. | ||
mutating func updateSparks() { | ||
for i in sparks.indices.reversed() { | ||
sparks[i].update() | ||
// If | ||
if sparks[i].done() { | ||
sparks.remove(at: i) | ||
} | ||
} | ||
} | ||
|
||
// Update particle's position and speed over time. | ||
mutating func updateParticle() -> Bool { | ||
particle.update() | ||
if particle.willExplode() { | ||
exploded = true | ||
explode() | ||
return true | ||
} | ||
|
||
return false | ||
} | ||
|
||
// Generate firework sparks after explosion. | ||
mutating func explode() { | ||
for _ in 0..<100 { | ||
sparks.append(Spark(pos: particle.pos)) | ||
} | ||
} | ||
|
||
func done() -> Bool { | ||
return exploded && sparks.count == 0 | ||
} | ||
} |
94 changes: 94 additions & 0 deletions
94
Examples/SwiftIOPlayground/13MoreProjects/Fireworks/Sources/Fireworks.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import SwiftIO | ||
import MadBoard | ||
import ST7789 | ||
import MadGraphics | ||
|
||
// Use lock to protect data from simultaneous access by multiple threads. | ||
let i2sLock = Mutex() | ||
// Whether the speaker will play sound. | ||
var playSound = false | ||
|
||
@main | ||
public struct Fireworks { | ||
public static func main() { | ||
// Initialize the SPI pin and the digital pins for the LCD. | ||
let bl = DigitalOut(Id.D2) | ||
let rst = DigitalOut(Id.D12) | ||
let dc = DigitalOut(Id.D13) | ||
let cs = DigitalOut(Id.D5) | ||
let spi = SPI(Id.SPI0, speed: 30_000_000) | ||
|
||
// Initialize the LCD using the pins above. Rotate the screen to keep the original at the upper left. | ||
let screen = ST7789(spi: spi, cs: cs, dc: dc, rst: rst, bl: bl, rotation: .angle90) | ||
var screenBuffer = [UInt16](repeating: 0, count: screen.width * screen.width) | ||
var frameBuffer = [UInt32](repeating: 0, count: screen.width * screen.width) | ||
|
||
var colorIndex = 0 | ||
let colors: [Color] = [ | ||
.pink, .red, .lime, .blue, .cyan, | ||
.purple, .magenta, .orange, .yellow | ||
] | ||
|
||
let layer = Layer(at: Point.zero, anchorPoint: UnitPoint.zero, width: screen.width, height: screen.height) | ||
|
||
|
||
let font = Font(path: "/lfs/Resources/Fonts/Roboto-Regular.ttf", pointSize: 10, dpi: 220) | ||
let text1 = TextLayer(at: Point(x: layer.bounds.size.halfWidth, y: 40), anchorPoint: UnitPoint.center, string: "Happy", font: font, foregroundColor: Color.red) | ||
let text2 = TextLayer(at: Point(x: layer.bounds.size.halfWidth, y: 80), anchorPoint: UnitPoint.center, string: "Christmas", font: font, foregroundColor: Color.red) | ||
|
||
layer.append(text1) | ||
layer.append(text2) | ||
|
||
var fireworks: [Firework] = [] | ||
var exploded = false | ||
|
||
createThread( | ||
name: "play_sound", | ||
priority: 3, | ||
stackSize: 1024 * 64, | ||
soundThread | ||
) | ||
|
||
sleep(ms: 10) | ||
|
||
while true { | ||
if Int.random(in: 0..<100) < 10 { | ||
fireworks.append(Firework(color: colors[colorIndex], maxWidth: layer.bounds.width)) | ||
// Update firwork's color. | ||
colorIndex += 1 | ||
if colorIndex == colors.count { | ||
colorIndex = 0 | ||
} | ||
} | ||
|
||
var i = 0 | ||
while i < fireworks.count { | ||
if fireworks[i].update(layer) { | ||
exploded = true | ||
} | ||
|
||
// If a all sparks of a firework disppear, remove the firework. | ||
if fireworks[i].done() { | ||
fireworks.remove(at: i) | ||
} else { | ||
i += 1 | ||
} | ||
} | ||
|
||
// If any firework has exploded, update the global variable. | ||
if exploded { | ||
i2sLock.lock() | ||
playSound = true | ||
i2sLock.unlock() | ||
|
||
exploded = false | ||
} | ||
|
||
layer.render(into: &frameBuffer, output: &screenBuffer, transform: Color.getRGB565LE) { dirty, data in | ||
screen.writeBitmap(x: dirty.x, y: dirty.y, width: dirty.width, height: dirty.height, data: data) | ||
} | ||
|
||
sleep(ms: 10) | ||
} | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
Examples/SwiftIOPlayground/13MoreProjects/Fireworks/Sources/Particle.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import MadGraphics | ||
|
||
// The firework before explosion. | ||
struct Particle { | ||
var pos: Point | ||
var velocity: (x: Float, y: Float) | ||
var acceleration: (x: Float, y: Float) | ||
|
||
// Create a particle with a random velocity and acceleration. | ||
init(pos: Point) { | ||
self.pos = pos | ||
velocity = (0, Float.random(in: (-14.0)...(-10.0))) | ||
acceleration = (0, Float.random(in: 0.3..<0.4)) | ||
} | ||
|
||
// Update the particle's position and velocity over time. | ||
mutating func update() { | ||
pos.x += Int(velocity.x) | ||
pos.y += Int(velocity.y) | ||
|
||
velocity.x += acceleration.x | ||
velocity.y += acceleration.y | ||
} | ||
|
||
// Whether the particle reaches its maximum height. | ||
func willExplode() -> Bool { | ||
return velocity.y > 0 | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
Examples/SwiftIOPlayground/13MoreProjects/Fireworks/Sources/SoundThread.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import SwiftIO | ||
import MadBoard | ||
|
||
func soundThread(_ a: UnsafeMutableRawPointer?, _ b: UnsafeMutableRawPointer?, _ c: UnsafeMutableRawPointer?) -> () { | ||
let speaker = I2S(Id.I2S0, rate: 44_100) | ||
|
||
// Read sound data from file. | ||
let sound = readSoundData(from: "/lfs/Resources/Sounds/boom.wav") | ||
var startPlay = false | ||
|
||
while true { | ||
sleep(ms: 100) | ||
|
||
// Check the global variable to see if the speaker need to play sound. | ||
i2sLock.lock() | ||
if playSound { | ||
startPlay = true | ||
} | ||
i2sLock.unlock() | ||
|
||
if startPlay { | ||
speaker.write(sound) | ||
startPlay = false | ||
|
||
// Update the global variable. | ||
i2sLock.lock() | ||
playSound = false | ||
i2sLock.unlock() | ||
} | ||
} | ||
|
||
func readSoundData(from path: String) -> [UInt8] { | ||
let headerSize = 0x2C | ||
var buffer = [UInt8]() | ||
|
||
do { | ||
let file = try FileDescriptor.open(path) | ||
try file.seek(offset: 0, from: FileDescriptor.SeekOrigin.end) | ||
let size = try file.tell() - headerSize | ||
|
||
buffer = [UInt8](repeating: 0, count: size) | ||
try file.read(fromAbsoluteOffest: headerSize, into: &buffer, count: size) | ||
try file.close() | ||
} catch { | ||
print("File \(path) handle error: \(error)") | ||
return [] | ||
} | ||
|
||
return buffer | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
Examples/SwiftIOPlayground/13MoreProjects/Fireworks/Sources/Spark.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import MadGraphics | ||
|
||
// The firework after explosion. | ||
struct Spark { | ||
var pos: Point | ||
var velocity: (x: Float, y: Float) | ||
var acceleration: (x: Float, y: Float) | ||
// How long the spark shows on the screen. | ||
var lifespan: UInt8 = 255 | ||
|
||
// Create a particle with a random velocity and acceleration. | ||
// Its initial position is the maximum height of the firework particle. | ||
init(pos: Point) { | ||
self.pos = pos | ||
|
||
// The speed of the spark at a random direction. | ||
velocity.x = Float(Array(-100..<100).shuffled().randomElement()!) / 50 | ||
velocity.y = Float(Array(-100..<100).shuffled().randomElement()!) / 50 | ||
velocity.x *= Float.random(in: 1...4) | ||
velocity.y *= Float.random(in: 1...4) | ||
|
||
acceleration = (0, Float.random(in: 0.3..<0.4)) | ||
} | ||
|
||
// Update the particle's position and velocity over time. | ||
mutating func update() { | ||
velocity.x *= 0.8 | ||
velocity.y *= 0.8 | ||
lifespan -= 5 | ||
|
||
pos.x += Int(velocity.x) | ||
pos.y += Int(velocity.y) | ||
|
||
velocity.x += acceleration.x | ||
velocity.y += acceleration.y | ||
} | ||
|
||
// Whether the spark will disappear. | ||
func done() -> Bool { | ||
return lifespan <= 0 | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
Examples/SwiftIOPlayground/13MoreProjects/HilbertCurve/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.DS_Store | ||
/.build | ||
/Packages | ||
xcuserdata/ | ||
DerivedData/ | ||
.swiftpm/configuration/registries.json | ||
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata | ||
.netrc |
Oops, something went wrong.