Advertisement
Tag365

OpenComputers ComputerCraft emulator

Feb 19th, 2016
675
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.17 KB | None | 0 0
  1. local args = {...}
  2.  
  3. -- Configuration --
  4. local cc_directory = "/usr/cc"
  5. local cc_lua_directory = cc_directory.."/lua"
  6. local cc_save_directory = cc_directory.."/data"
  7.  
  8. -- OpenOS modules --
  9. local oc_computer = require("computer")
  10. local oc_component = require("component")
  11. local oc_filesystem = require("filesystem")
  12. local oc_term = require("term")
  13. local oc_event = require("event")
  14. local oc_keyboard = require("keyboard")
  15. local oc_sides = require("sides")
  16. local oc_bit32 = require("bit32")
  17. local oc_os = os
  18. local oc_io = io
  19.  
  20. local gpu = oc_component.gpu
  21. gpu.setResolution(51, 19)
  22.  
  23. ---------------------------
  24. -- ComputerCraft modules --
  25. ---------------------------
  26. local eventQueue = {{}}
  27. local timerList = {}
  28. local alarmList = {}
  29.  
  30. local ccEnv = {_VERSION = _VERSION}
  31. ccEnv._G = ccEnv
  32. ccEnv._ENV = setmetatable({}, {__index = ccEnv})
  33. ccEnv._CC_DISABLE_LUA51_FEATURES = true
  34. local os = {}
  35. local fs = {}
  36. local term = {}
  37. local parallel = {}
  38. local colors = {}
  39. local colours = {}
  40. local redstone = {}
  41. local rednet = {}
  42. local http
  43.  
  44. -- FS API --
  45. function fs.open(path, mode)
  46. while path:sub(1, 1) == "/" do path = path:sub(2) end
  47. local handle = {}
  48. --print(path, mode)
  49. local realHandle, errorMessage = oc_io.open(cc_save_directory.."/"..path, mode)
  50. if not realHandle then
  51. realHandle, errorMessage = oc_io.open(cc_lua_directory.."/"..path, mode)
  52. end
  53. if errorMessage then
  54. --print("Error: "..errorMessage)
  55. return nil, errorMessage
  56. end
  57.  
  58. function handle.close(...) return realHandle:close(...) end
  59. if mode == "w" or mode == "a" then
  60. function handle.write(...) return realHandle:write(...) end
  61. function handle.writeLine(data) return realHandle:write(data.."\n") end
  62. function handle.flush(...) return realHandle:flush(...) end
  63. elseif mode == "r" then
  64. --function handle.read(...) return realHandle:read(...) end
  65. function handle.readLine() return realHandle:read() end
  66. function handle.readAll() return realHandle:read("*a") end
  67. --function handle.seek(...) return realHandle:seek(...) end
  68. end
  69.  
  70. return handle
  71. end
  72.  
  73. -- Checks if a path refers to an existing file or directory.
  74. function fs.exists(path)
  75. while path:sub(1, 1) == "/" do path = path:sub(2) end
  76. return oc_filesystem.exists(cc_save_directory.."/"..path) or oc_filesystem.exists(cc_lua_directory.."/"..path)
  77. end
  78.  
  79. -- Checks if a path refers to an existing directory.
  80. function fs.isDir(path)
  81. while path:sub(1, 1) == "/" do path = path:sub(2) end
  82. return oc_filesystem.isDirectory(cc_save_directory.."/"..path) or oc_filesystem.isDirectory(cc_lua_directory.."/"..path)
  83. end
  84.  
  85. -- Checks if a path is read-only (i.e. cannot be modified).
  86. function fs.isReadOnly(path)
  87. while path:sub(1, 1) == "/" do path = path:sub(2) end
  88. if oc_filesystem.exists(cc_lua_directory.."/"..path) and path:sub(1, 5):find("rom/") then
  89. return true
  90. end
  91. return path:sub(1, 4):find("rom") and true or false
  92. end
  93.  
  94. -- Gets the final component of a pathname.
  95. function fs.getName(path)
  96. while path:sub(1, 1) == "/" do path = path:sub(2) end
  97. if path:sub(1, 5):find("rom/") then
  98. return oc_filesystem.name(cc_lua_directory.."/"..path)
  99. else
  100. return oc_filesystem.name(cc_save_directory.."/"..path)
  101. end
  102. end
  103. fs.name = fs.getName
  104.  
  105. -- Gets the size of a file in bytes.
  106. function fs.getSize(path)
  107. while path:sub(1, 1) == "/" do path = path:sub(2) end
  108. if oc_filesystem.exists(cc_lua_directory.."/"..path) and path:sub(1, 5):find("rom/") then
  109. return oc_filesystem.size(cc_lua_directory.."/"..path)
  110. end
  111. return oc_filesystem.size(cc_save_directory.."/"..path)
  112. end
  113.  
  114. -- Gets the remaining space on the drive containing the given directory.
  115. function fs.getFreeSpace(path)
  116. while path:sub(1, 1) == "/" do path = path:sub(2) end
  117. return oc_io.get(cc_save_directory.."/"..path).spaceFree()
  118. end
  119.  
  120. local listCache = {}
  121. -- Returns a list of all the files (including subdirectories but not their contents) contained in a directory,
  122. -- as a numerically indexed table.
  123. function fs.list(path)
  124. --print(cc_lua_directory.."/"..path)
  125. if listCache[path] then
  126. return listCache[path]
  127. end
  128. local items = {}
  129. if oc_filesystem.isDirectory(cc_lua_directory.."/"..path) then
  130. for value in oc_filesystem.list(cc_lua_directory.."/"..path) do
  131. items[#items + 1] = value
  132. end
  133. end
  134. if oc_filesystem.isDirectory(cc_save_directory.."/"..path) then
  135. for value in oc_filesystem.list(cc_save_directory.."/"..path) do
  136. items[#items + 1] = value
  137. end
  138. end
  139. listCache[path] = items
  140. return items
  141. end
  142.  
  143. -- Makes a directory.
  144. function fs.makeDir(path)
  145. while path:sub(1, 1) == "/" do path = path:sub(2) end
  146. oc_filesystem.makeDirectory(cc_save_directory.."/"..path)
  147. end
  148.  
  149. -- Moves a file or directory to a new location.
  150. function fs.move(fromPath, toPath)
  151. oc_filesystem.move(cc_save_directory.."/"..fromPath, cc_save_directory.."/"..toPath)
  152. end
  153.  
  154. -- Copies a file or directory to a new location.
  155. function fs.copy(fromPath, toPath)
  156. oc_filesystem.copy(cc_save_directory.."/"..fromPath, cc_save_directory.."/"..toPath)
  157. end
  158.  
  159. -- Deletes a file or directory.
  160. function fs.delete(path)
  161. while path:sub(1, 1) == "/" do path = path:sub(2) end
  162. oc_filesystem.remove(cc_save_directory.."/"..path)
  163. end
  164.  
  165. -- Combines two path components, returning a path consisting of the local path nested inside the base path.
  166. -- The resultant path consists of all the components of localPath inside all the components of basePath.
  167. -- Neither path needs to exist; this function only manipulates strings and does not touch the filesystem.
  168. function fs.combine(basePath, localPath)
  169. if #basePath > 0 and #localPath > 0 then
  170. return basePath.."/"..localPath
  171. elseif #basePath > 0 then
  172. return basePath
  173. elseif #localPath > 0 then
  174. return localPath
  175. end
  176. return ""
  177. end
  178.  
  179. -- Searches the computer's files using wildcards.
  180. function fs.find(wildcard)
  181. local items = {}
  182.  
  183. return items
  184. end
  185.  
  186. -- Term API --
  187. local nativeTerm = term
  188. local termColors = {
  189. [1] = 0xF0F0F0,
  190. [2] = 0xF2B233,
  191. [4] = 0xE57FD8,
  192. [8] = 0x99B2F2,
  193. [16] = 0xDEDE6C,
  194. [32] = 0x7FCC19,
  195. [64] = 0xF2B2CC,
  196. [128] = 0x4C4C4C,
  197. [256] = 0x999999,
  198. [512] = 0x4C99B2,
  199. [1024] = 0xB266E5,
  200. [2048] = 0x3366CC,
  201. [4096] = 0x7F664C,
  202. [8192] = 0x57A64E,
  203. [16384] = 0xCC4C4C,
  204. [32768] = 0x000000
  205. }
  206. local charToTermColor = {}
  207. for value = 0, 15 do
  208. if value < 10 then
  209. charToTermColor[tostring(value)] = 2^value
  210. else
  211. charToTermColor[value == 10 and "a" or value == 11 and "b" or value == 12 and "c" or value == 13 and "d" or value == 14 and "e" or value == 15 and "f"] = 2^value
  212. end
  213. end
  214. local textColor = 1
  215. local backgroundColor = 32768
  216. gpu.setForeground(termColors[textColor] or 0xFFFFFF)
  217. gpu.setBackground(termColors[backgroundColor] or 0x000000)
  218. oc_term.clear()
  219.  
  220. -- False functions in case it errors
  221. function term.native()
  222. return nativeTerm
  223. end
  224. function term.current()
  225. return nativeTerm
  226. end
  227. function term.redirect() end
  228.  
  229. -- Actual functions begin
  230. function term.isColor()
  231. return gpu.getDepth() > 1
  232. end
  233. term.isColour = term.isColor
  234.  
  235. function term.getTextColor()
  236. return textColor
  237. end
  238. function term.getBackgroundColor()
  239. return backgroundColor
  240. end
  241. function term.setTextColor(newColor)
  242. textColor = newColor
  243. gpu.setForeground(termColors[textColor] or 0xFFFFFF)
  244. end
  245. function term.setBackgroundColor(newColor)
  246. backgroundColor = newColor
  247. gpu.setBackground(termColors[backgroundColor] or 0x000000)
  248. end
  249. term.getTextColour = term.getTextColor
  250. term.getBackgroundColour = term.getBackgroundColor
  251. term.setTextColour = term.setTextColor
  252. term.setBackgroundColour = term.setBackgroundColor
  253.  
  254. local cursorX, cursorY = 1, 1
  255. function term.getSize()
  256. return gpu.getResolution()
  257. end
  258. function term.getCursorPos()
  259. return cursorX, cursorY
  260. end
  261. function term.setCursorPos(x, y)
  262. cursorX, cursorY = math.max(x, 1), y
  263. oc_term.setCursor(cursorX, cursorY)
  264. end
  265. function term.setCursorBlink(newValue)
  266. return oc_term.setCursorBlink(newValue)
  267. end
  268. function term.scroll()
  269. local width, height = gpu.getResolution()
  270. local foregroundColor, backgroundColor = gpu.getForeground(), gpu.getBackground()
  271. -- Color correct copying
  272. for x = 1, width do
  273. local character, pixelForegroundColor, pixelBackgroundColor = gpu.get(x, height)
  274. if backgroundColor ~= pixelBackgroundColor then
  275. gpu.setBackground(pixelBackgroundColor)
  276. backgroundColor = pixelBackgroundColor
  277. end
  278. if foregroundColor ~= pixelForegroundColor then
  279. gpu.setForeground(pixelForegroundColor)
  280. foregroundColor = pixelForegroundColor
  281. end
  282. gpu.set(x, 0, character)
  283. end
  284. gpu.fill(1, height, width, 1, " ")
  285. end
  286.  
  287. -- Writes text to the screen, using the current text and background colors.
  288. function term.write(text)
  289. gpu.set(cursorX, cursorY, text)
  290. cursorX = cursorX + #text
  291. oc_term.setCursor(cursorX, cursorY)
  292. end
  293.  
  294. -- Writes text to the screen using the specified text and background colors. Requires version 1.74 or newer.
  295. function term.blit(text, colors, backgroundColors)
  296. if not #text == #colors then
  297. error("bad argument #2 to 'blit' (length of 'colors' must equal length of 'text')")
  298. elseif not #text == #backgroundColors then
  299. error("bad argument #3 to 'blit' (length of 'backgroundColors' must equal length of 'text')")
  300. end
  301. local lastBGColor = backgroundColor
  302. local lastFGColor = textColor
  303. for char = 1, #text do
  304. if lastBGColor ~= charToTermColor[backgroundColors:sub(char, char)] then
  305. lastBGColor = charToTermColor[backgroundColors:sub(char, char)]
  306. gpu.setBackground(termColors[charToTermColor[backgroundColors:sub(char, char)]])
  307. end
  308. if lastFGColor ~= charToTermColor[colors:sub(char, char)] then
  309. lastFGColor = charToTermColor[colors:sub(char, char)]
  310. gpu.setForeground(termColors[charToTermColor[colors:sub(char, char)]])
  311. end
  312. gpu.set(cursorX + char - 1, cursorY, text:sub(char, char))
  313. end
  314. cursorX = cursorX + #text
  315. oc_term.setCursor(cursorX, cursorY)
  316. end
  317.  
  318.  
  319. -- Clears the entire screen.
  320. function term.clear()
  321. oc_term.clear()
  322. oc_term.setCursor(cursorX, cursorY)
  323. end
  324.  
  325. -- Clears the line the cursor is on.
  326. function term.clearLine()
  327. oc_term.clearLine()
  328. end
  329.  
  330. -- OS API --
  331. -- Returns the unique ID of this computer. os.computerID() also behaves exactly the same as os.getComputerID().
  332. function os.getComputerID()
  333. return 0
  334. end
  335.  
  336. --
  337. function os.getComputerLabel()
  338. return nil
  339. end
  340.  
  341. --
  342. function os.setComputerLabel(label)
  343.  
  344. end
  345.  
  346. -- Adds an event to the event queue with the name event and the given parameters.
  347. function os.queueEvent(...)
  348. eventQueue[#eventQueue + 1] = {...}
  349. end
  350.  
  351. -- Turns off the computer.
  352. function os.shutdown()
  353. oc_computer.shutdown(false)
  354. end
  355.  
  356. -- Reboots the computer.
  357. function os.reboot()
  358. oc_computer.shutdown(true)
  359. end
  360.  
  361. -- Queues an event to be triggered after a number of seconds (timeout).
  362. -- The ID of the timer is returned from this function to differentiate multiple timers.
  363. -- Timers are one-shot; once they have fired an event you will need to start another one if you need a recurring timer.
  364. function os.startTimer(timeout)
  365. local timerID = #timerList + 1
  366.  
  367. -- Create the new timer
  368. timerList[timerID] = {Start = oc_computer.uptime(), Timeout = timeout, Canceled = false}
  369.  
  370. return timerID
  371. end
  372.  
  373. -- Cancels a running timer, to prevent it throwing an event.
  374. function os.cancelTimer(timerID)
  375. if timerList[timerID] then
  376. timerList[timerID].Canceled = true
  377. end
  378. end
  379.  
  380. local getDayInGame = function()
  381. return math.floor(oc_os.time()/(60*60*24))
  382. end
  383. local getTimeInGame = function()
  384. return (oc_os.time()/(60*60))%24
  385. end
  386.  
  387. -- Queues an event to be triggered at the specified in-game time.
  388. function os.startAlarm(time)
  389. local alarmID = #alarmList + 1
  390.  
  391. -- Create the new alarm
  392. alarmList[alarmID] = {TimeOfDay = time, Canceled = false, FiredToday = getTimeInGame() > time}
  393.  
  394. return alarmID
  395. end
  396.  
  397. -- Cancels a pending alarm, to prevent it throwing an event.
  398. function os.cancelAlarm(alarmID)
  399.  
  400. end
  401.  
  402. -- Returns the amount of time since the in-game computer was started.
  403. function os.clock()
  404. return oc_computer.uptime()
  405. end
  406.  
  407. -- Return the current in-game day (the number of in-game days since the world was created).
  408. function os.day()
  409. return getDayInGame()
  410. end
  411.  
  412. -- Returns the current in-game time.
  413. function os.time()
  414. return getTimeInGame()
  415. end
  416.  
  417. -- Redstone API --
  418. -- Returns a table of possible sides.
  419. function redstone.getSides()
  420. if oc_component.isAvailable("redstone") then
  421. --local oc_redstone = oc_component.redstone
  422. return {"left", "right", "top", "bottom", "front", "back"}
  423. end
  424. return {}
  425. end
  426.  
  427. -- Returns the current redstone input signal state on side.
  428. function redstone.getInput(side)
  429. if oc_component.isAvailable("redstone") then
  430. local oc_redstone = oc_component.redstone
  431. if oc_sides[side] then
  432. local value = oc_redstone.getInput(oc_sides[side])
  433. return value > 0
  434. end
  435. end
  436. end
  437.  
  438. function redstone.getOutput(side)
  439. if oc_component.isAvailable("redstone") then
  440. local oc_redstone = oc_component.redstone
  441. if oc_sides[side] then
  442. local value = oc_redstone.getOutput(oc_sides[side])
  443. return value > 0
  444. end
  445. end
  446. end
  447.  
  448. function redstone.getOutput(side)
  449. if oc_component.isAvailable("redstone") then
  450. local oc_redstone = oc_component.redstone
  451. if oc_sides[side] then
  452. local value = oc_redstone.getOutput(oc_sides[side])
  453. return value > 0
  454. end
  455. end
  456. end
  457.  
  458. function redstone.setOutput(side, value)
  459. if oc_component.isAvailable("redstone") then
  460. local oc_redstone = oc_component.redstone
  461. if oc_sides[side] then
  462. pcall(oc_redstone.setOutput, oc_sides[side], 255)
  463. pcall(oc_redstone.setOutput, oc_sides[side], 15)
  464. end
  465. end
  466. end
  467.  
  468. function redstone.getAnalogInput(side)
  469. if oc_component.isAvailable("redstone") then
  470. local oc_redstone = oc_component.redstone
  471. if oc_sides[side] then
  472. return oc_redstone.getInput(oc_sides[side])
  473. end
  474. end
  475. end
  476.  
  477. function redstone.getAnalogOutput(side)
  478. if oc_component.isAvailable("redstone") then
  479. local oc_redstone = oc_component.redstone
  480. if oc_sides[side] then
  481. return oc_redstone.getOutput(oc_sides[side])
  482. end
  483. end
  484. end
  485.  
  486. function redstone.setAnalogOutput(side, value)
  487. if oc_component.isAvailable("redstone") then
  488. local oc_redstone = oc_component.redstone
  489. if oc_sides[side] then
  490. oc_redstone.setOutput(oc_sides[side], value)
  491. end
  492. end
  493. end
  494.  
  495. -- Rednet API --
  496. function rednet.run()
  497. while true do
  498. coroutine.yield()
  499. end
  500. end
  501.  
  502. -- HTTP API --
  503. if oc_component.isAvailable("internet") then
  504. if oc_component.internet.isHttpEnabled() then
  505. local internet = oc_component.internet
  506.  
  507. http = {}
  508.  
  509. function http.request(url, postData, headers)
  510. local realHandle = internet.request(url, postData)
  511.  
  512. local handle = {}
  513. function handle.close() realHandle:close() end
  514. function handle.readLine() return realHandle:read() end
  515. function handle.readAll() return realHandle:read("*a") end
  516. function handle.getResponseCode()
  517. local responseCode = realHandle:response()
  518. return responseCode
  519. end
  520.  
  521. eventQueue[#eventQueue + 1] = {"http_success", url, handle}
  522. end
  523.  
  524. function http.checkURL(url)
  525. return true
  526. end
  527. end
  528. end
  529.  
  530. -- A function useful for completing the envirornment
  531. local cloneTable
  532. cloneTable = function(tableToClone)
  533. local clonedTable = {}
  534. for key, value in pairs(tableToClone) do
  535. if type(value) == "table" then
  536. clonedTable[key] = cloneTable(value)
  537. else
  538. clonedTable[key] = value
  539. end
  540. end
  541. return clonedTable
  542. end
  543.  
  544. -- Complete the envirornment
  545. ccEnv.print = print
  546. ccEnv.load = load
  547. ccEnv.loadstring = load
  548. ccEnv.type = type
  549. ccEnv.select = select
  550. ccEnv.next = next
  551. ccEnv.pairs = pairs
  552. ccEnv.ipairs = ipairs
  553. ccEnv.assert = assert
  554. ccEnv.error = error
  555. ccEnv.getmetatable = getmetatable
  556. ccEnv.setmetatable = setmetatable
  557. ccEnv.pcall = pcall
  558. ccEnv.xpcall = xpcall
  559. ccEnv.tostring = tostring
  560. ccEnv.tonumber = tonumber
  561. ccEnv.setfenv = setfenv
  562. ccEnv.getfenv = getfenv
  563. ccEnv.unpack = table.unpack
  564.  
  565. if not ccEnv.setfenv then
  566. function ccEnv.setfenv(thisfunction, env)
  567. local oldFunction = thisfunction
  568. thisfunction = function(...)
  569. local _ENV = env
  570. return oldFunction(...)
  571. end
  572. return thisfunction
  573. end
  574. function ccEnv.getfenv(x)
  575. return _ENV
  576. end
  577. end
  578.  
  579. -- Add the APIs.
  580. ccEnv.fs = fs
  581. ccEnv.os = os
  582. ccEnv.term = term
  583. ccEnv.redstone = redstone
  584. ccEnv.rs = redstone
  585. ccEnv.rednet = rednet
  586. ccEnv.http = http
  587. ccEnv.bit = cloneTable(bit32)
  588. ccEnv.string = cloneTable(string)
  589. ccEnv.table = cloneTable(table)
  590. --ccEnv.table.unpack = nil
  591. ccEnv.math = cloneTable(math)
  592. ccEnv.coroutine = cloneTable(coroutine)
  593.  
  594. for key, value in pairs(ccEnv) do
  595. if key ~= "_G" or key ~= "_ENV" then
  596. ccEnv._G[key] = value
  597. ccEnv._ENV[key] = value
  598. end
  599. end
  600.  
  601. -- Install the character key to character converter
  602. local characterKeysString = "abcdefghijklmnopqrstuvwxyz1234567890"
  603. local characterKeyToString = {
  604. [oc_keyboard.keys.space] = " ",
  605. [oc_keyboard.keys.apostrophe] = "'",
  606. [oc_keyboard.keys.slash] = "/",
  607. [oc_keyboard.keys.backslash] = "\\",
  608. [oc_keyboard.keys.lbracket] = "[",
  609. [oc_keyboard.keys.rbracket] = "]",
  610. [oc_keyboard.keys.equals] = "=",
  611. [oc_keyboard.keys.minus] = "-",
  612. [oc_keyboard.keys.colon] = ";",
  613. [oc_keyboard.keys.comma] = ",",
  614. [oc_keyboard.keys.period] = ".",
  615. [oc_keyboard.keys.numpadsub] = "-",
  616. [oc_keyboard.keys.numpadadd] = "+",
  617. }
  618. for char = 1, #characterKeysString do
  619. characterKeyToString[oc_keyboard.keys[characterKeysString:sub(char,char)]] = characterKeysString:sub(char,char)
  620. end
  621. local characterKeyToStringUpper = {
  622. [oc_keyboard.keys["1"]] = "!",
  623. [oc_keyboard.keys["2"]] = "@",
  624. [oc_keyboard.keys["3"]] = "#",
  625. [oc_keyboard.keys["4"]] = "$",
  626. [oc_keyboard.keys["5"]] = "%",
  627. [oc_keyboard.keys["6"]] = "^",
  628. [oc_keyboard.keys["7"]] = "&",
  629. [oc_keyboard.keys["8"]] = "*",
  630. [oc_keyboard.keys["9"]] = "(",
  631. [oc_keyboard.keys["0"]] = ")",
  632. [oc_keyboard.keys.apostrophe] = "\"",
  633. [oc_keyboard.keys.slash] = "?",
  634. [oc_keyboard.keys.backslash] = "|",
  635. [oc_keyboard.keys.lbracket] = "{",
  636. [oc_keyboard.keys.rbracket] = "}",
  637. [oc_keyboard.keys.equals] = "+",
  638. [oc_keyboard.keys.minus] = "_",
  639. [oc_keyboard.keys.colon] = ":",
  640. [oc_keyboard.keys.comma] = ",",
  641. [oc_keyboard.keys.period] = ">",
  642. }
  643.  
  644. -- Run the bios script
  645. local biosScript = assert(loadfile(cc_lua_directory.."/bios.lua", ccEnv, ccEnv))
  646. local bios = function()
  647. local success, errorMessage = xpcall(function()
  648. local ccEnv = ccEnv
  649. local _ENV = ccEnv
  650. _G = ccEnv
  651. biosScript()
  652. end,
  653. function(errorMessage)
  654. return errorMessage.."\n"..debug.traceback()
  655. end)
  656. if not success then
  657. error(errorMessage, 0)
  658. end
  659. end
  660. local computerCoroutine = coroutine.create(bios)
  661. local computerOn = true
  662. local lastTimeInGame = getTimeInGame()
  663.  
  664. function os.shutdown()
  665. computerOn = false
  666. end
  667.  
  668. while computerOn do
  669. local oc_Signal = {oc_event.pull(0)}
  670.  
  671. -- Handle the OpenComputers signal
  672. if oc_Signal then
  673. if oc_Signal[1] == "key_down" then
  674. if characterKeyToString[oc_Signal[4]] then
  675. if oc_keyboard.isShiftDown() then
  676. if characterKeyToStringUpper[oc_Signal[4]] then
  677. eventQueue[#eventQueue + 1] = {"char", characterKeyToStringUpper[oc_Signal[4]]}
  678. else
  679. eventQueue[#eventQueue + 1] = {"char", string.upper(characterKeyToString[oc_Signal[4]])}
  680. end
  681. else
  682. eventQueue[#eventQueue + 1] = {"char", characterKeyToString[oc_Signal[4]]}
  683. end
  684. end
  685. eventQueue[#eventQueue + 1] = {"key", oc_Signal[4]}
  686. elseif oc_Signal[1] == "key_up" then
  687. eventQueue[#eventQueue + 1] = {"key_up", oc_Signal[4]}
  688. elseif oc_Signal[1] == "touch" then
  689. eventQueue[#eventQueue + 1] = {"mouse_click", oc_Signal[5], oc_Signal[3], oc_Signal[4]}
  690. elseif oc_Signal[1] == "drop" then
  691. eventQueue[#eventQueue + 1] = {"mouse_up", oc_Signal[5], oc_Signal[3], oc_Signal[4]}
  692. elseif oc_Signal[1] == "drag" then
  693. eventQueue[#eventQueue + 1] = {"mouse_drag", oc_Signal[5], oc_Signal[3], oc_Signal[4]}
  694. elseif oc_Signal[1] == "screen_resized" then
  695. eventQueue[#eventQueue + 1] = {"term_resize"}
  696. end
  697. end
  698.  
  699. -- Try to terminate anything
  700. if oc_keyboard.isControlDown() and oc_keyboard.isKeyDown(0x14) then
  701. table.insert(eventQueue, 1, {"terminate"})
  702. --table.insert(eventQueue, "terminate")
  703. end
  704.  
  705. -- Handle timers and alarms
  706. for timerID, timer in ipairs(timerList) do
  707. if not timer.Canceled then
  708. if oc_computer.uptime() > timer.Start + timer.Timeout then
  709. -- Trigger the timer event
  710. timer.Canceled = true -- Timers are one-shot, therfore it must be "canceled" after it fires.
  711. eventQueue[#eventQueue + 1] = {"timer", timerID}
  712. end
  713. end
  714. end
  715. if getTimeInGame() < lastTimeInGame then
  716. for alarmID, alarm in ipairs(alarmList) do
  717. if not alarm.Canceled then
  718. -- Untrigger the alarm event
  719. alarm.FiredToday = false
  720. end
  721. end
  722. end
  723. for alarmID, alarm in ipairs(alarmList) do
  724. if getTimeInGame() > alarm.Time and not alarm.Canceled and not alarm.FiredToday then
  725. -- Trigger the alarm event
  726. alarm.FiredToday = true
  727. eventQueue[#eventQueue + 1] = {"alarm", timerID}
  728. end
  729. end
  730.  
  731. -- Update the ComputerCraft emulation state
  732. if not eventQueue[1] then
  733. assert(coroutine.resume(computerCoroutine))
  734. else
  735. assert(coroutine.resume(computerCoroutine, eventQueue[1][1], eventQueue[1][2], eventQueue[1][3], eventQueue[1][4], eventQueue[1][5], eventQueue[1][6], eventQueue[1][7], eventQueue[1][8], eventQueue[1][9], eventQueue[1][10]))
  736. table.remove(eventQueue, 1)
  737. end
  738. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement