1
0

swift_splash.swift 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. import Foundation
  2. #if canImport(Glibc)
  3. import Glibc
  4. #endif
  5. // ── Framebuffer structs ──
  6. struct fb_bitfield {
  7. var offset: UInt32 = 0
  8. var length: UInt32 = 0
  9. var msb_right: UInt32 = 0
  10. }
  11. struct fb_var_screeninfo {
  12. var xres: UInt32 = 0
  13. var yres: UInt32 = 0
  14. var xres_virtual: UInt32 = 0
  15. var yres_virtual: UInt32 = 0
  16. var xoffset: UInt32 = 0
  17. var yoffset: UInt32 = 0
  18. var bits_per_pixel: UInt32 = 0
  19. var grayscale: UInt32 = 0
  20. var red: fb_bitfield = fb_bitfield()
  21. var green: fb_bitfield = fb_bitfield()
  22. var blue: fb_bitfield = fb_bitfield()
  23. var transp: fb_bitfield = fb_bitfield()
  24. var nonstd: UInt32 = 0
  25. var activate: UInt32 = 0
  26. var height: UInt32 = 0
  27. var width: UInt32 = 0
  28. var accel_flags: UInt32 = 0
  29. var pixclock: UInt32 = 0
  30. var left_margin: UInt32 = 0
  31. var right_margin: UInt32 = 0
  32. var upper_margin: UInt32 = 0
  33. var lower_margin: UInt32 = 0
  34. var hsync_len: UInt32 = 0
  35. var vsync_len: UInt32 = 0
  36. var sync: UInt32 = 0
  37. var vmode: UInt32 = 0
  38. var reserved: (UInt32, UInt32, UInt32, UInt32, UInt32, UInt32) = (0, 0, 0, 0, 0, 0)
  39. }
  40. struct fb_fix_screeninfo {
  41. var id: (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8,
  42. Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8) =
  43. (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  44. var smem_start: UInt = 0
  45. var smem_len: UInt32 = 0
  46. var type: UInt32 = 0
  47. var type_aux: UInt32 = 0
  48. var visual: UInt32 = 0
  49. var xpanstep: UInt16 = 0
  50. var ypanstep: UInt16 = 0
  51. var ywrapstep: UInt16 = 0
  52. var line_length: UInt32 = 0
  53. var mmio_start: UInt = 0
  54. var mmio_len: UInt32 = 0
  55. var accel: UInt32 = 0
  56. var reserved: (UInt16, UInt16, UInt16) = (0, 0, 0)
  57. }
  58. @_silgen_name("get_vinfo")
  59. func get_vinfo(_ fd: Int32, _ vinfo: UnsafeMutableRawPointer) -> Int32
  60. @_silgen_name("get_finfo")
  61. func get_finfo(_ fd: Int32, _ finfo: UnsafeMutableRawPointer) -> Int32
  62. @_silgen_name("pan_display")
  63. func pan_display(_ fd: Int32, _ vinfo: UnsafeMutableRawPointer) -> Int32
  64. // ══════════════════════════════════════════════════════════════════
  65. // Anti-Aliased High-Resolution Back-Buffered Renderer
  66. // ══════════════════════════════════════════════════════════════════
  67. let AW = 600
  68. let AH = 600
  69. let AC = 300
  70. let ABUFSZ = AW * AH * 4
  71. // Geometry
  72. let NUC_R = 28
  73. let INNER_R = 120
  74. let OUTER_R = 200
  75. let ELEC_R = 12
  76. let RING_T = 2.0
  77. // Draw filled disk with anti-aliasing (smooth corners)
  78. func diskAA(_ p: UnsafeMutablePointer<UInt8>, _ cx: Double, _ cy: Double, _ r: Double, _ val: UInt8) {
  79. let y0 = max(0, Int(cy - r - 2))
  80. let y1 = min(AH - 1, Int(cy + r + 2))
  81. let x0 = max(0, Int(cx - r - 2))
  82. let x1 = min(AW - 1, Int(cx + r + 2))
  83. let rInner = r - 0.5
  84. let rInnerSq = rInner * rInner
  85. let rOuter = r + 0.5
  86. let rOuterSq = rOuter * rOuter
  87. let fVal = Double(val)
  88. for y in y0...y1 {
  89. let dy = Double(y) - cy
  90. let dySq = dy * dy
  91. let rowBase = y * AW * 4
  92. for x in x0...x1 {
  93. let dx = Double(x) - cx
  94. let distSq = dx * dx + dySq
  95. if distSq < rInnerSq {
  96. let off = rowBase + x * 4
  97. p[off] = max(p[off], val)
  98. p[off + 1] = max(p[off + 1], val)
  99. p[off + 2] = max(p[off + 2], val)
  100. } else if distSq < rOuterSq {
  101. let dist = sqrt(distSq)
  102. let alpha = rOuter - dist
  103. let v = UInt8(fVal * alpha)
  104. let off = rowBase + x * 4
  105. p[off] = max(p[off], v)
  106. p[off + 1] = max(p[off + 1], v)
  107. p[off + 2] = max(p[off + 2], v)
  108. }
  109. }
  110. }
  111. }
  112. // Draw ring outline with anti-aliasing (smooth curves)
  113. func ringAA(_ p: UnsafeMutablePointer<UInt8>, _ cx: Double, _ cy: Double, _ r: Double, _ t: Double, _ val: UInt8) {
  114. let scan = r + t + 2
  115. let y0 = max(0, Int(cy - scan))
  116. let y1 = min(AH - 1, Int(cy + scan))
  117. let x0 = max(0, Int(cx - scan))
  118. let x1 = min(AW - 1, Int(cx + scan))
  119. let rInMin = r - t - 0.5
  120. let rInMax = r - t + 0.5
  121. let rOutMin = r + t - 0.5
  122. let rOutMax = r + t + 0.5
  123. let rInMinSq = rInMin * rInMin
  124. let rInMaxSq = rInMax * rInMax
  125. let rOutMinSq = rOutMin * rOutMin
  126. let rOutMaxSq = rOutMax * rOutMax
  127. let tOuter = t + 0.5
  128. let fVal = Double(val)
  129. for y in y0...y1 {
  130. let dy = Double(y) - cy
  131. let dySq = dy * dy
  132. let rowBase = y * AW * 4
  133. for x in x0...x1 {
  134. let dx = Double(x) - cx
  135. let d = dx * dx + dySq
  136. if d >= rInMaxSq && d <= rOutMinSq {
  137. // Fully inside the ring
  138. let off = rowBase + x * 4
  139. p[off] = max(p[off], val)
  140. p[off + 1] = max(p[off + 1], val)
  141. p[off + 2] = max(p[off + 2], val)
  142. } else if (d >= rInMinSq && d < rInMaxSq) || (d > rOutMinSq && d <= rOutMaxSq) {
  143. // On the inner or outer edge
  144. let dist = sqrt(d)
  145. let diff = abs(dist - r)
  146. let alpha = tOuter - diff
  147. let v = UInt8(fVal * alpha)
  148. let off = rowBase + x * 4
  149. p[off] = max(p[off], v)
  150. p[off + 1] = max(p[off + 1], v)
  151. p[off + 2] = max(p[off + 2], v)
  152. }
  153. }
  154. }
  155. }
  156. // Blit buffer to framebuffer
  157. func blit(_ src: UnsafeMutablePointer<UInt8>,
  158. _ fbp: UnsafeMutablePointer<UInt8>,
  159. _ sx: Int, _ sy: Int,
  160. _ lineLen: Int, _ scrH: Int,
  161. _ fd: Int32, _ vinfo: UnsafeMutableRawPointer) {
  162. for y in 0..<AH {
  163. let fy = sy + y
  164. if fy < 0 || fy >= scrH { continue }
  165. memcpy(fbp + fy * lineLen + sx * 4,
  166. src + y * AW * 4,
  167. AW * 4)
  168. }
  169. _ = pan_display(fd, vinfo)
  170. }
  171. // ── Isolated IPC Client (talks to arkrt daemon) ──
  172. func queryIPC(cmdId: UInt16, payload: String = "") -> String {
  173. let fd = socket(AF_UNIX, 1, 0)
  174. if fd < 0 { return "ERROR" }
  175. defer { close(fd) }
  176. var addr = sockaddr_un()
  177. addr.sun_family = sa_family_t(AF_UNIX)
  178. let socketPath = "/dev/arkrt.sock"
  179. let pathBytes = socketPath.utf8CString
  180. withUnsafeMutablePointer(to: &addr.sun_path) { sunPathPtr in
  181. let rawPtr = UnsafeMutableRawPointer(sunPathPtr).assumingMemoryBound(to: CChar.self)
  182. for i in 0..<min(pathBytes.count, 108) {
  183. rawPtr[i] = pathBytes[i]
  184. }
  185. }
  186. let addrSize = MemoryLayout<sockaddr_un>.size
  187. let connectResult = withUnsafePointer(to: &addr) { addrPtr in
  188. addrPtr.withMemoryRebound(to: sockaddr.self, capacity: 1) { saPtr in
  189. connect(fd, saPtr, socklen_t(addrSize))
  190. }
  191. }
  192. if connectResult < 0 {
  193. return "OFFLINE"
  194. }
  195. // Construct strict binary request header
  196. let payloadData = payload.data(using: .utf8) ?? Data()
  197. var request = Data()
  198. var bigEndianCmd = cmdId.bigEndian
  199. var bigEndianLen = UInt32(payloadData.count).bigEndian
  200. withUnsafeBytes(of: &bigEndianCmd) { request.append(contentsOf: $0) }
  201. withUnsafeBytes(of: &bigEndianLen) { request.append(contentsOf: $0) }
  202. request.append(payloadData)
  203. // Send request
  204. request.withUnsafeBytes { reqBytes in
  205. _ = write(fd, reqBytes.baseAddress, reqBytes.count)
  206. }
  207. // Read response
  208. let bufSize = 4096
  209. let respBuf = UnsafeMutablePointer<UInt8>.allocate(capacity: bufSize)
  210. defer { respBuf.deallocate() }
  211. let bytesRead = read(fd, respBuf, bufSize)
  212. if bytesRead < 6 {
  213. return "ERROR_RESP"
  214. }
  215. let responseBuffer = UnsafeRawBufferPointer(start: respBuf, count: bytesRead)
  216. let respCmd = responseBuffer.load(fromByteOffset: 0, as: UInt16.self).bigEndian
  217. let respLen = responseBuffer.load(fromByteOffset: 2, as: UInt32.self).bigEndian
  218. if respCmd == cmdId && bytesRead >= 6 + Int(respLen) {
  219. let respPayloadBytes = UnsafeRawBufferPointer(rebasing: responseBuffer[6..<(6 + Int(respLen))])
  220. return String(decoding: respPayloadBytes, as: UTF8.self)
  221. }
  222. return "INVALID_DATA"
  223. }
  224. // ══════════════════════════════════════════════════════════════════
  225. func drawSwiftSplash() {
  226. let fd = open("/dev/fb0", O_RDWR)
  227. if fd < 0 { print("Error: Cannot open /dev/fb0"); return }
  228. var vinfo = fb_var_screeninfo()
  229. if get_vinfo(fd, &vinfo) < 0 { close(fd); return }
  230. var finfo = fb_fix_screeninfo()
  231. if get_finfo(fd, &finfo) < 0 { close(fd); return }
  232. let scrW = Int(vinfo.xres)
  233. let scrH = Int(vinfo.yres)
  234. let bpp = Int(vinfo.bits_per_pixel) / 8
  235. let lineLen = Int(finfo.line_length)
  236. let scrSz = Int(finfo.smem_len)
  237. let fb_ptr = mmap(nil, scrSz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)
  238. if fb_ptr == MAP_FAILED { close(fd); return }
  239. let fbp = fb_ptr!.bindMemory(to: UInt8.self, capacity: scrSz)
  240. // ── Clear entire screen to BLACK immediately ──
  241. memset(fbp, 0, scrSz)
  242. // Allocate raw pointer buffers
  243. let tpl = UnsafeMutablePointer<UInt8>.allocate(capacity: ABUFSZ) // template
  244. let work = UnsafeMutablePointer<UInt8>.allocate(capacity: ABUFSZ) // workspace
  245. // Centered coordinates
  246. let sx = (scrW - AW) / 2
  247. let sy = (scrH - AH) / 2
  248. // ── Pre-render static nucleus template ──
  249. memset(tpl, 0, ABUFSZ)
  250. diskAA(tpl, Double(AC), Double(AC), Double(NUC_R), 255)
  251. // ── Phase 1: Spawn & Orbit Expansion (35 frames) ──
  252. for frame in 0..<35 {
  253. memset(work, 0, ABUFSZ)
  254. let t = Double(frame) / 34.0
  255. let easeOut = 1.0 - pow(1.0 - t, 3.0)
  256. let curInnerR = Double(INNER_R) * easeOut
  257. let curOuterR = Double(OUTER_R) * easeOut
  258. let curElR = max(1.0, Double(ELEC_R) * easeOut)
  259. let ringBright = UInt8(60.0 * easeOut)
  260. diskAA(work, Double(AC), Double(AC), Double(NUC_R), 255)
  261. if curInnerR > Double(NUC_R) {
  262. ringAA(work, Double(AC), Double(AC), curInnerR, RING_T, ringBright)
  263. }
  264. if curOuterR > Double(NUC_R) {
  265. ringAA(work, Double(AC), Double(AC), curOuterR, RING_T, ringBright)
  266. }
  267. let angle = Double(frame) * 0.10
  268. for i in 0..<2 {
  269. let a = angle + Double(i) * Double.pi
  270. let ex = Double(AC) + cos(a) * curInnerR
  271. let ey = Double(AC) + sin(a) * curInnerR
  272. diskAA(work, ex, ey, curElR, 255)
  273. }
  274. for i in 0..<2 {
  275. let a = -angle * 0.6 + Double(i) * Double.pi
  276. let ex = Double(AC) + cos(a) * curOuterR
  277. let ey = Double(AC) + sin(a) * curOuterR
  278. diskAA(work, ex, ey, curElR, 255)
  279. }
  280. blit(work, fbp, sx, sy, lineLen, scrH, fd, &vinfo)
  281. usleep(16666)
  282. }
  283. // ── Pre-render static stable orbit template for Phase 2 ──
  284. memset(tpl, 0, ABUFSZ)
  285. diskAA(tpl, Double(AC), Double(AC), Double(NUC_R), 255)
  286. ringAA(tpl, Double(AC), Double(AC), Double(INNER_R), RING_T, 60)
  287. ringAA(tpl, Double(AC), Double(AC), Double(OUTER_R), RING_T, 60)
  288. // ── Phase 2: Stable Orbiting (150 frames ≈ 2.5 seconds at 60fps) ──
  289. for frame in 0..<150 {
  290. memcpy(work, tpl, ABUFSZ)
  291. let angle = (35.0 * 0.10) + Double(frame) * 0.05
  292. for i in 0..<2 {
  293. let a = angle + Double(i) * Double.pi
  294. let ex = Double(AC) + cos(a) * Double(INNER_R)
  295. let ey = Double(AC) + sin(a) * Double(INNER_R)
  296. diskAA(work, ex, ey, Double(ELEC_R), 255)
  297. }
  298. for i in 0..<2 {
  299. let a = -angle * 0.6 + Double(i) * Double.pi
  300. let ex = Double(AC) + cos(a) * Double(OUTER_R)
  301. let ey = Double(AC) + sin(a) * Double(OUTER_R)
  302. diskAA(work, ex, ey, Double(ELEC_R), 255)
  303. }
  304. blit(work, fbp, sx, sy, lineLen, scrH, fd, &vinfo)
  305. usleep(16666)
  306. }
  307. // ── Phase 3: Spiral Inward & Crash (30 frames) ──
  308. let baseAngle = (35.0 * 0.10) + (150.0 * 0.05)
  309. for frame in 0..<30 {
  310. memset(work, 0, ABUFSZ)
  311. let t = Double(frame) / 29.0
  312. let easeIn = t * t
  313. let curInner = Double(INNER_R) * (1.0 - easeIn)
  314. let curOuter = Double(OUTER_R) * (1.0 - easeIn)
  315. let curElR = max(1.0, Double(ELEC_R) * (1.0 - easeIn))
  316. let nucG = Double(NUC_R) + easeIn * 20.0
  317. diskAA(work, Double(AC), Double(AC), nucG, 255)
  318. if curInner > nucG + 2.0 {
  319. ringAA(work, Double(AC), Double(AC), curInner, RING_T, UInt8(60.0 * (1.0 - t)))
  320. }
  321. if curOuter > nucG + 2.0 {
  322. ringAA(work, Double(AC), Double(AC), curOuter, RING_T, UInt8(60.0 * (1.0 - t)))
  323. }
  324. let angle = baseAngle + t * Double.pi * 6.0
  325. if curElR > 1.0 {
  326. for i in 0..<2 {
  327. let a = angle + Double(i) * Double.pi
  328. diskAA(work, Double(AC) + cos(a) * curInner,
  329. Double(AC) + sin(a) * curInner, curElR, 255)
  330. }
  331. for i in 0..<2 {
  332. let a = -angle * 0.6 + Double(i) * Double.pi
  333. diskAA(work, Double(AC) + cos(a) * curOuter,
  334. Double(AC) + sin(a) * curOuter, curElR, 255)
  335. }
  336. }
  337. blit(work, fbp, sx, sy, lineLen, scrH, fd, &vinfo)
  338. usleep(16666)
  339. }
  340. // ── Phase 4: Flash & Fade to Black (20 frames) ──
  341. let finalNucG = Double(NUC_R) + 20.0
  342. for frame in 0..<20 {
  343. memset(work, 0, ABUFSZ)
  344. let t = Double(frame) / 19.0
  345. let flashR = min(Double(AC - 1), finalNucG + t * 240.0)
  346. let bright = UInt8(max(0.0, 255.0 * (1.0 - t)))
  347. if bright > 0 {
  348. diskAA(work, Double(AC), Double(AC), flashR, bright)
  349. }
  350. blit(work, fbp, sx, sy, lineLen, scrH, fd, &vinfo)
  351. usleep(16666)
  352. }
  353. // ── Clear to BLACK ──
  354. memset(fbp, 0, scrSz)
  355. _ = pan_display(fd, &vinfo)
  356. // ── Splash screen ──
  357. print("\u{1B}[0;40m\u{1B}[2J\u{1B}[H", terminator: "")
  358. print("""
  359. SSSS W W IIIII FFFFF TTTTT
  360. S W W I F T
  361. SSS W W W I FFF T
  362. S WW WW I F T
  363. SSSS W W IIIII F T
  364. """)
  365. print("\nArkOS Initialized. Drawing 'Swift' via native Swift runtime!\n")
  366. // Draw gradient below text
  367. for y in 200..<scrH {
  368. for x in 0..<scrW {
  369. let off = (x + Int(vinfo.xoffset)) * bpp +
  370. (y + Int(vinfo.yoffset)) * lineLen
  371. fbp[off] = UInt8((x * 255) / scrW)
  372. fbp[off + 1] = UInt8((y * 255) / scrH)
  373. fbp[off + 2] = 255 - UInt8((x * 255) / scrW)
  374. fbp[off + 3] = 0
  375. }
  376. }
  377. _ = pan_display(fd, &vinfo)
  378. tpl.deallocate()
  379. work.deallocate()
  380. munmap(fb_ptr, scrSz)
  381. close(fd)
  382. // Query system info from the background system service daemon (arkrt)
  383. let ip = queryIPC(cmdId: 102)
  384. let battery = queryIPC(cmdId: 103)
  385. let sysTime = queryIPC(cmdId: 101)
  386. print("──────────────────────────────────────────────────────")
  387. print(" ArkOS Service Framework Status (Via Isolated IPC):")
  388. print(" - Interface IP : \(ip)")
  389. print(" - System Time : \(sysTime)")
  390. print(" - Battery Level : \(battery)")
  391. print("──────────────────────────────────────────────────────\n")
  392. while true {
  393. usleep(500_000)
  394. }
  395. }
  396. drawSwiftSplash()