nonogamer9

OC-NICCC old version

Jan 31st, 2025
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.94 KB | None | 0 0
  1. local component = require("component")
  2. local gpu = component.gpu
  3. local internet = require("internet")
  4. local fs = require("filesystem")
  5. local computer = require("computer")
  6.  
  7. local SCREEN_WIDTH, SCREEN_HEIGHT = gpu.getResolution()
  8. local ASCII_CHARS = " .'`^\",:;Il!i><~+_-?][}{1)(|/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$"
  9. local SCENE_URL = "https://github.com/dabadab/st-niccc-2000-html5/raw/master/scene1.bin"
  10. local SCENE_FILE = "scene1.bin"
  11. local TARGET_FPS = 30
  12.  
  13. gpu.setResolution(SCREEN_WIDTH, SCREEN_HEIGHT)
  14.  
  15. local backBuffer = {}
  16. for y = 1, SCREEN_HEIGHT do
  17. backBuffer[y] = string.rep(" ", SCREEN_WIDTH)
  18. end
  19.  
  20. local function downloadFile(url, filename)
  21. print("OC-NICCC: ST-NICCC 2000 Port For OpenComputers Created By nonogamer9")
  22. print("THIS IS")
  23. print("*NOT*")
  24. print("AN COMPUTERCRAFT DEMO")
  25. print("Downloading " .. filename .. "...")
  26. local result = ""
  27. for chunk in internet.request(url) do
  28. result = result .. chunk
  29. end
  30. local file = io.open(filename, "wb")
  31. file:write(result)
  32. file:close()
  33. print("Download complete! Enjoy The Demo!")
  34. end
  35.  
  36. local function readBinaryFile(filename)
  37. local file = io.open(filename, "rb")
  38. if not file then return nil end
  39. local content = file:read("*all")
  40. file:close()
  41. return content
  42. end
  43.  
  44. local function decode(raw)
  45. raw = raw & 0xF
  46. local bits = (raw >> 3) & 1
  47. bits = bits | ((raw << 1) & 0xE)
  48. return bits * 17
  49. end
  50.  
  51. local function colorToAscii(r, g, b)
  52. local intensity = (0.299 * r + 0.587 * g + 0.114 * b) / 255
  53. local index = math.floor(intensity * (#ASCII_CHARS - 1)) + 1
  54. return ASCII_CHARS:sub(index, index)
  55. end
  56.  
  57. local function clearBackBuffer()
  58. for y = 1, SCREEN_HEIGHT - 1 do
  59. backBuffer[y] = string.rep(" ", SCREEN_WIDTH)
  60. end
  61. end
  62.  
  63. local function flushBackBuffer()
  64. for y = 1, SCREEN_HEIGHT - 1 do
  65. gpu.set(1, y, backBuffer[y])
  66. end
  67. end
  68.  
  69. local function renderFrame(dataStream, colors)
  70. local align = false
  71. local flags = string.byte(dataStream:read(1))
  72.  
  73. if flags & 2 > 0 then
  74. local colorsData = dataStream:read(2)
  75. local colorsValue = (string.byte(colorsData, 1) << 8) | string.byte(colorsData, 2)
  76. for i = 0, 15 do
  77. if colorsValue & (1 << (15 - i)) > 0 then
  78. local colorData = dataStream:read(2)
  79. local colorValue = (string.byte(colorData, 1) << 8) | string.byte(colorData, 2)
  80. colors[i + 1] = {
  81. red = decode(colorValue),
  82. green = decode(colorValue >> 4),
  83. blue = decode(colorValue >> 8)
  84. }
  85. end
  86. end
  87. end
  88.  
  89. if flags & 1 > 0 then
  90. clearBackBuffer()
  91. end
  92.  
  93. local function drawLine(x1, y1, x2, y2, char)
  94. local dx = math.abs(x2 - x1)
  95. local dy = math.abs(y2 - y1)
  96. local sx = x1 < x2 and 1 or -1
  97. local sy = y1 < y2 and 1 or -1
  98. local err = dx - dy
  99.  
  100. while true do
  101. if x1 >= 1 and x1 <= SCREEN_WIDTH and y1 >= 1 and y1 <= SCREEN_HEIGHT - 1 then
  102. local row = backBuffer[y1]
  103. backBuffer[y1] = row:sub(1, x1 - 1) .. char .. row:sub(x1 + 1)
  104. end
  105. if x1 == x2 and y1 == y2 then break end
  106. local e2 = 2 * err
  107. if e2 > -dy then
  108. err = err - dy
  109. x1 = x1 + sx
  110. end
  111. if e2 < dx then
  112. err = err + dx
  113. y1 = y1 + sy
  114. end
  115. end
  116. end
  117.  
  118. local function drawPolygon(polygon, char)
  119. for i = 1, #polygon do
  120. local p1 = polygon[i]
  121. local p2 = polygon[i % #polygon + 1]
  122. local x1, y1 = math.floor(p1.x * SCREEN_WIDTH / 320), math.floor(p1.y * (SCREEN_HEIGHT - 1) / 200)
  123. local x2, y2 = math.floor(p2.x * SCREEN_WIDTH / 320), math.floor(p2.y * (SCREEN_HEIGHT - 1) / 200)
  124. drawLine(x1, y1, x2, y2, char)
  125. end
  126. end
  127.  
  128. if flags & 4 > 0 then
  129. local verticesCount = string.byte(dataStream:read(1))
  130. local points = {}
  131. for i = 1, verticesCount do
  132. local x = string.byte(dataStream:read(1))
  133. local y = string.byte(dataStream:read(1))
  134. points[i] = {x = x, y = y}
  135. end
  136. while true do
  137. local bits = string.byte(dataStream:read(1))
  138. if bits == 0xFF then
  139. align = false
  140. break
  141. elseif bits == 0xFE then
  142. align = true
  143. break
  144. elseif bits == 0xFD then
  145. return false
  146. else
  147. local polygon = {}
  148. for i = 1, (bits & 0xF) do
  149. local index = string.byte(dataStream:read(1))
  150. table.insert(polygon, points[index + 1])
  151. end
  152. local color = colors[(bits >> 4) + 1]
  153. local char = colorToAscii(color.red, color.green, color.blue)
  154. drawPolygon(polygon, char)
  155. end
  156. end
  157. else
  158. while true do
  159. local bits = string.byte(dataStream:read(1))
  160. if bits == 0xFF then
  161. align = false
  162. break
  163. elseif bits == 0xFE then
  164. align = true
  165. break
  166. elseif bits == 0xFD then
  167. return false
  168. else
  169. local polygon = {}
  170. for i = 1, (bits & 0xF) do
  171. local x = string.byte(dataStream:read(1))
  172. local y = string.byte(dataStream:read(1))
  173. table.insert(polygon, {x = x, y = y})
  174. end
  175. local color = colors[(bits >> 4) + 1]
  176. local char = colorToAscii(color.red, color.green, color.blue)
  177. drawPolygon(polygon, char)
  178. end
  179. end
  180. end
  181.  
  182. if align then
  183. local position = dataStream:seek("cur", 0)
  184. position = (position + 0xFFFF) & ~0xFFFF
  185. dataStream:seek("set", position)
  186. end
  187.  
  188. return true
  189. end
  190.  
  191. local function main()
  192. if not fs.exists(SCENE_FILE) then
  193. downloadFile(SCENE_URL, SCENE_FILE)
  194. end
  195.  
  196. local sceneData = readBinaryFile(SCENE_FILE)
  197. if not sceneData then
  198. print("Failed to read " .. SCENE_FILE)
  199. return
  200. end
  201.  
  202. local dataStream = {
  203. data = sceneData,
  204. position = 1,
  205. read = function(self, count)
  206. local result = self.data:sub(self.position, self.position + count - 1)
  207. self.position = self.position + count
  208. return result
  209. end,
  210. seek = function(self, whence, offset)
  211. if whence == "set" then
  212. self.position = offset + 1
  213. elseif whence == "cur" then
  214. self.position = self.position + offset
  215. end
  216. return self.position - 1
  217. end
  218. }
  219.  
  220. local colors = {}
  221. for i = 1, 16 do
  222. colors[i] = {red = 0, green = 0, blue = 0}
  223. end
  224.  
  225. local frameCount = 0
  226. local lastTime = computer.uptime()
  227. local fpsUpdateInterval = 0.1
  228. local lastFpsUpdate = lastTime
  229. local frameTime = 1 / TARGET_FPS
  230. local currentFps = 0
  231.  
  232. while renderFrame(dataStream, colors) do
  233. frameCount = frameCount + 1
  234. local currentTime = computer.uptime()
  235. if currentTime - lastFpsUpdate >= fpsUpdateInterval then
  236. currentFps = frameCount / (currentTime - lastFpsUpdate)
  237. frameCount = 0
  238. lastFpsUpdate = currentTime
  239. gpu.fill(1, SCREEN_HEIGHT, SCREEN_WIDTH, 1, " ")
  240. gpu.set(1, SCREEN_HEIGHT, string.format("FPS: %.1f", currentFps))
  241. end
  242. flushBackBuffer()
  243. local frameDuration = computer.uptime() - currentTime
  244. if frameDuration < frameTime then
  245. os.sleep(frameTime - frameDuration)
  246. end
  247. end
  248. end
  249.  
  250. main()
Add Comment
Please, Sign In to add comment