DraRex368

ROBCO Stargate OS

Feb 8th, 2026 (edited)
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 20.70 KB | None | 0 0
  1. --[[
  2. ROBCO SGC DIALING COMPUTER
  3. Single-file CC:Tweaked script for a 2x4 advanced monitor
  4.  
  5. Features:
  6. - Boot animation
  7. - Gate diagram + status
  8. - Address book (dial/add/delete)
  9. - Virtual DHD (manual address entry)
  10. - Iris control
  11. - Persistent audit log
  12. - Touchscreen UI
  13. - Designed to integrate with Stargate Journey mod
  14.  
  15. NOTE:
  16. - Adjust peripheral names in CONFIG section as needed.
  17. - Adapt STARGATE JOURNEY ADAPTER methods to match your mod version.
  18. ]]--
  19.  
  20. -------------------------
  21. -- CONFIG
  22. -------------------------
  23. local CONFIG = {
  24.     monitorSide     = "top",      -- 2x4 advanced monitor
  25.     stargateSide    = "back",     -- Stargate Journey peripheral
  26.     logFile         = "sgc_audit.log",
  27.     addressBookFile = "sgc_address_book.json",
  28.     theme = {
  29.         bg          = colors.black,
  30.         fg          = colors.green,
  31.         accent      = colors.lime,
  32.         warning     = colors.red,
  33.         inactive    = colors.gray,
  34.         title       = colors.cyan,
  35.     }
  36. }
  37.  
  38. -------------------------
  39. -- PERIPHERALS
  40. -------------------------
  41. local mon = peripheral.wrap(CONFIG.monitorSide)
  42. if not mon then error("Monitor not found on "..CONFIG.monitorSide) end
  43. mon.setTextScale(0.5)
  44. local w, h = mon.getSize()
  45.  
  46. local sg = peripheral.wrap(CONFIG.stargateSide)
  47. if not sg then error("Stargate peripheral not found on "..CONFIG.stargateSide) end
  48.  
  49. -------------------------
  50. -- STATE
  51. -------------------------
  52. local state = {
  53.     currentScreen = "main", -- main | address_book | add_address | delete_address | dhd
  54.     selectedEntry = nil,
  55.     manualAddress = "",
  56.     manualName    = "",
  57.     manualType    = "MW",   -- MW | PG | SD (Milky Way, Pegasus, Same Dimension)
  58.     addressBook   = {},
  59.     gateStatus    = "UNKNOWN",
  60.     irisState     = "UNKNOWN",
  61.     lastEvent     = "",
  62. }
  63.  
  64. -------------------------
  65. -- UTIL
  66. -------------------------
  67. local function centerText(y, text, color)
  68.     mon.setCursorPos(1, y)
  69.     mon.setTextColor(color or CONFIG.theme.fg)
  70.     local x = math.floor((w - #text) / 2) + 1
  71.     mon.setCursorPos(x, y)
  72.     mon.write(text)
  73. end
  74.  
  75. local function clear(bg)
  76.     mon.setBackgroundColor(bg or CONFIG.theme.bg)
  77.     mon.clear()
  78.     mon.setCursorPos(1,1)
  79. end
  80.  
  81. local function drawBox(x1, y1, x2, y2, bg, fg, label)
  82.     mon.setBackgroundColor(bg or CONFIG.theme.bg)
  83.     mon.setTextColor(fg or CONFIG.theme.fg)
  84.     for y = y1, y2 do
  85.         mon.setCursorPos(x1, y)
  86.         mon.write(string.rep(" ", x2 - x1 + 1))
  87.     end
  88.     if label then
  89.         local lx = x1 + math.floor(((x2 - x1 + 1) - #label) / 2)
  90.         local ly = math.floor((y1 + y2) / 2)
  91.         mon.setCursorPos(lx, ly)
  92.         mon.write(label)
  93.     end
  94. end
  95.  
  96. local function logEvent(msg)
  97.     local f = fs.open(CONFIG.logFile, "a")
  98.     if f then
  99.         f.writeLine(os.date("%Y-%m-%d %H:%M:%S").." | "..msg)
  100.         f.close()
  101.     end
  102.     state.lastEvent = msg
  103. end
  104.  
  105. -------------------------
  106. -- PERSISTENCE
  107. -------------------------
  108. local function loadAddressBook()
  109.     if not fs.exists(CONFIG.addressBookFile) then
  110.         state.addressBook = {}
  111.         return
  112.     end
  113.     local f = fs.open(CONFIG.addressBookFile, "r")
  114.     if not f then return end
  115.     local content = f.readAll()
  116.     f.close()
  117.     local ok, data = pcall(textutils.unserializeJSON, content)
  118.     if ok and type(data) == "table" then
  119.         state.addressBook = data
  120.     else
  121.         state.addressBook = {}
  122.     end
  123. end
  124.  
  125. local function saveAddressBook()
  126.     local f = fs.open(CONFIG.addressBookFile, "w")
  127.     if not f then return end
  128.     f.write(textutils.serializeJSON(state.addressBook))
  129.     f.close()
  130. end
  131.  
  132. -------------------------
  133. -- STARGATE JOURNEY ADAPTER
  134. -- Adjust these to match your mod’s API
  135. -------------------------
  136. local function sg_getStatus()
  137.     -- Example: adapt to your API
  138.     -- return sg.getGateStatus() or "UNKNOWN"
  139.     local ok, status = pcall(sg.getGateStatus)
  140.     if ok and status then return status end
  141.     return "UNKNOWN"
  142. end
  143.  
  144. local function sg_getIrisState()
  145.     local ok, iris = pcall(sg.getIrisState)
  146.     if ok and iris then return iris end
  147.     return "UNKNOWN"
  148. end
  149.  
  150. local function sg_openIris()
  151.     pcall(sg.openIris)
  152.     logEvent("Iris opened")
  153. end
  154.  
  155. local function sg_closeIris()
  156.     pcall(sg.closeIris)
  157.     logEvent("Iris closed")
  158. end
  159.  
  160. local function sg_disconnect()
  161.     pcall(sg.disconnect)
  162.     logEvent("Gate disconnected")
  163. end
  164.  
  165. local function sg_dial(address)
  166.     -- address: string, e.g. "ABC-DEF-GHI"
  167.     logEvent("Dialing "..address)
  168.     pcall(sg.dial, address)
  169. end
  170.  
  171. -------------------------
  172. -- BOOT ANIMATION
  173. -------------------------
  174. local function bootAnimation()
  175.     clear()
  176.     mon.setTextColor(CONFIG.theme.title)
  177.     centerText(3, "ROBCO INDUSTRIES UNIFIED OPERATING SYSTEM")
  178.     centerText(4, "STARGATE COMMAND DIALING COMPUTER")
  179.     sleep(1.0)
  180.  
  181.     local lines = {
  182.         "[BOOT] Initializing ROBCO SGC Subsystems...",
  183.         "[BOOT] Linking to Stargate Journey Interface...",
  184.         "[BOOT] Loading Address Book...",
  185.         "[BOOT] Mounting Persistent Audit Log...",
  186.         "[BOOT] Calibrating Gate Status Sensors...",
  187.         "[BOOT] Verifying Iris Control Circuits...",
  188.         "[OK]   System Ready."
  189.     }
  190.  
  191.     mon.setTextColor(CONFIG.theme.fg)
  192.     local y = 6
  193.     for _, line in ipairs(lines) do
  194.         mon.setCursorPos(2, y)
  195.         mon.write(line)
  196.         y = y + 1
  197.         sleep(0.4)
  198.     end
  199.  
  200.     sleep(0.8)
  201. end
  202.  
  203. -------------------------
  204. -- GATE DIAGRAM
  205. -------------------------
  206. local function drawGateDiagram(x, y, radius, status)
  207.     -- Simple ASCII-ish ring
  208.     local ringChar = "O"
  209.     local activeColor = CONFIG.theme.accent
  210.     local idleColor   = CONFIG.theme.inactive
  211.     local warnColor   = CONFIG.theme.warning
  212.  
  213.     local color = idleColor
  214.     if status == "CONNECTED" or status == "DIALING" or status == "OPEN" then
  215.         color = activeColor
  216.     elseif status == "ERROR" then
  217.         color = warnColor
  218.     end
  219.  
  220.     mon.setTextColor(color)
  221.     -- crude circle
  222.     for dx = -radius, radius do
  223.         for dy = -radius, radius do
  224.             if dx*dx + dy*dy >= (radius-1)^2 and dx*dx + dy*dy <= (radius+1)^2 then
  225.                 local px = x + dx
  226.                 local py = y + dy
  227.                 if px >= 1 and px <= w and py >= 1 and py <= h then
  228.                     mon.setCursorPos(px, py)
  229.                     mon.write(ringChar)
  230.                 end
  231.             end
  232.         end
  233.     end
  234.  
  235.     -- center
  236.     mon.setTextColor(CONFIG.theme.fg)
  237.     mon.setCursorPos(x-1, y)
  238.     mon.write("SG")
  239. end
  240.  
  241. -------------------------
  242. -- MAIN SCREEN UI
  243. -------------------------
  244. -- Button layout (for 2x4 monitor, typically 32x16 chars):
  245. -- Top: title
  246. -- Left: gate diagram
  247. -- Right: status + iris
  248. -- Bottom: buttons row
  249.  
  250. local buttons = {}
  251.  
  252. local function registerButton(id, x1, y1, x2, y2, label, screen)
  253.     buttons[id] = {
  254.         x1=x1, y1=y1, x2=x2, y2=y2,
  255.         label=label,
  256.         screen=screen or "any"
  257.     }
  258. end
  259.  
  260. local function drawButton(id, bg, fg)
  261.     local b = buttons[id]
  262.     if not b then return end
  263.     drawBox(b.x1, b.y1, b.x2, b.y2, bg, fg, b.label)
  264. end
  265.  
  266. local function findButtonAt(x, y)
  267.     for id, b in pairs(buttons) do
  268.         if (b.screen == "any" or b.screen == state.currentScreen) and
  269.            x >= b.x1 and x <= b.x2 and y >= b.y1 and y <= b.y2 then
  270.             return id
  271.         end
  272.     end
  273.     return nil
  274. end
  275.  
  276. local function drawMainScreen()
  277.     clear()
  278.     mon.setTextColor(CONFIG.theme.title)
  279.     centerText(1, "ROBCO SGC DIALING COMPUTER")
  280.  
  281.     state.gateStatus = sg_getStatus()
  282.     state.irisState  = sg_getIrisState()
  283.  
  284.     -- Gate diagram on left
  285.     drawGateDiagram(math.floor(w*0.25), math.floor(h*0.45), 5, state.gateStatus)
  286.  
  287.     -- Status on right
  288.     mon.setTextColor(CONFIG.theme.fg)
  289.     mon.setCursorPos(math.floor(w*0.5), 3)
  290.     mon.write("Gate: "..state.gateStatus)
  291.     mon.setCursorPos(math.floor(w*0.5), 4)
  292.     mon.write("Iris: "..state.irisState)
  293.     mon.setCursorPos(math.floor(w*0.5), 5)
  294.     mon.write("Last: "..(state.lastEvent or ""))
  295.  
  296.     -- Buttons bottom row
  297.     local rowY = h-3
  298.     registerButton("dial",        2, rowY,      8, rowY+2,  "DIAL",        "main")
  299.     registerButton("hangup",      10, rowY,    16, rowY+2,  "HANG UP",     "main")
  300.     registerButton("iris",        18, rowY,    24, rowY+2,  "IRIS",        "main")
  301.     registerButton("addr_book",   26, rowY,    32, rowY+2,  "ADDRESSES",   "main")
  302.     registerButton("dhd",         2, rowY-4,   16, rowY-2,  "VIRTUAL DHD", "main")
  303.     registerButton("logs_hint",   18, rowY-4,  32, rowY-2,  "LOG: "..CONFIG.logFile, "main")
  304.  
  305.     drawButton("dial",      CONFIG.theme.accent,  CONFIG.theme.bg)
  306.     drawButton("hangup",    CONFIG.theme.warning, CONFIG.theme.bg)
  307.     drawButton("iris",      CONFIG.theme.title,   CONFIG.theme.bg)
  308.     drawButton("addr_book", CONFIG.theme.title,   CONFIG.theme.bg)
  309.     drawButton("dhd",       CONFIG.theme.accent,  CONFIG.theme.bg)
  310.     drawButton("logs_hint", CONFIG.theme.inactive,CONFIG.theme.bg)
  311. end
  312.  
  313. -------------------------
  314. -- ADDRESS BOOK SCREENS
  315. -------------------------
  316. local function drawAddressBookScreen()
  317.     clear()
  318.     state.currentScreen = "address_book"
  319.     mon.setTextColor(CONFIG.theme.title)
  320.     centerText(1, "ADDRESS BOOK")
  321.  
  322.     -- List entries
  323.     mon.setTextColor(CONFIG.theme.fg)
  324.     local y = 3
  325.     for i, entry in ipairs(state.addressBook) do
  326.         if y > h-4 then break end
  327.         mon.setCursorPos(2, y)
  328.         mon.write(string.format("%2d) %-10s %-3s %s", i, entry.name or "NONAME", entry.type or "?", entry.address or ""))
  329.         y = y + 1
  330.     end
  331.  
  332.     -- Buttons
  333.     local rowY = h-3
  334.     registerButton("addr_back",  2, rowY,    8, rowY+2,   "BACK",   "address_book")
  335.     registerButton("addr_add",   10, rowY,  16, rowY+2,   "ADD",    "address_book")
  336.     registerButton("addr_del",   18, rowY,  24, rowY+2,   "DELETE", "address_book")
  337.     registerButton("addr_dial",  26, rowY,  32, rowY+2,   "DIAL",   "address_book")
  338.  
  339.     drawButton("addr_back", CONFIG.theme.warning, CONFIG.theme.bg)
  340.     drawButton("addr_add",  CONFIG.theme.accent,  CONFIG.theme.bg)
  341.     drawButton("addr_del",  CONFIG.theme.title,   CONFIG.theme.bg)
  342.     drawButton("addr_dial", CONFIG.theme.accent,  CONFIG.theme.bg)
  343.  
  344.     mon.setCursorPos(2, h-5)
  345.     mon.write("Tap entry number area to select.")
  346. end
  347.  
  348. local function drawAddAddressScreen()
  349.     clear()
  350.     state.currentScreen = "add_address"
  351.     mon.setTextColor(CONFIG.theme.title)
  352.     centerText(1, "ADD ADDRESS")
  353.  
  354.     mon.setTextColor(CONFIG.theme.fg)
  355.     mon.setCursorPos(2,3); mon.write("Name: "..state.manualName)
  356.     mon.setCursorPos(2,4); mon.write("Addr: "..state.manualAddress)
  357.     mon.setCursorPos(2,5); mon.write("Type: "..state.manualType.." (MW/PG/SD)")
  358.  
  359.     registerButton("add_save",  2, h-3,  8, h-1, "SAVE",  "add_address")
  360.     registerButton("add_cancel",10, h-3, 16, h-1, "CANCEL","add_address")
  361.     registerButton("add_type",  18, h-3, 24, h-1, "TYPE", "add_address")
  362.     registerButton("add_name",  2, 3,   20, 3,   "EDIT NAME", "add_address")
  363.     registerButton("add_addr",  2, 4,   20, 4,   "EDIT ADDR", "add_address")
  364.  
  365.     drawButton("add_save",   CONFIG.theme.accent,  CONFIG.theme.bg)
  366.     drawButton("add_cancel", CONFIG.theme.warning, CONFIG.theme.bg)
  367.     drawButton("add_type",   CONFIG.theme.title,   CONFIG.theme.bg)
  368. end
  369.  
  370. local function drawDeleteAddressScreen()
  371.     clear()
  372.     state.currentScreen = "delete_address"
  373.     mon.setTextColor(CONFIG.theme.title)
  374.     centerText(1, "DELETE ADDRESS")
  375.  
  376.     mon.setTextColor(CONFIG.theme.fg)
  377.     mon.setCursorPos(2,3); mon.write("Tap entry number to delete.")
  378.     mon.setCursorPos(2,4); mon.write("BACK to cancel.")
  379.  
  380.     local y = 6
  381.     for i, entry in ipairs(state.addressBook) do
  382.         if y > h-4 then break end
  383.         mon.setCursorPos(2, y)
  384.         mon.write(string.format("%2d) %-10s %-3s %s", i, entry.name or "NONAME", entry.type or "?", entry.address or ""))
  385.         y = y + 1
  386.     end
  387.  
  388.     registerButton("del_back", 2, h-3, 8, h-1, "BACK", "delete_address")
  389.     drawButton("del_back", CONFIG.theme.warning, CONFIG.theme.bg)
  390. end
  391.  
  392. -------------------------
  393. -- VIRTUAL DHD SCREEN
  394. -------------------------
  395. local function drawDhdScreen()
  396.     clear()
  397.     state.currentScreen = "dhd"
  398.     mon.setTextColor(CONFIG.theme.title)
  399.     centerText(1, "VIRTUAL DHD")
  400.  
  401.     mon.setTextColor(CONFIG.theme.fg)
  402.     mon.setCursorPos(2,3); mon.write("Addr: "..state.manualAddress)
  403.     mon.setCursorPos(2,4); mon.write("Type: "..state.manualType.." (MW/PG/SD)")
  404.  
  405.     -- Simple keypad: we treat address as free-form string, but
  406.     -- you can enforce 7/8/9 length based on type if you want.
  407.     local keys = {
  408.         {"A","B","C","D","E","F","G","H"},
  409.         {"I","J","K","L","M","N","O","P"},
  410.         {"Q","R","S","T","U","V","W","X"},
  411.         {"Y","Z","-","DEL","CLR","OK","BK",""}
  412.     }
  413.  
  414.     local startY = 6
  415.     local cellW = math.floor(w / 8)
  416.     for row=1,#keys do
  417.         for col=1,#keys[row] do
  418.             local label = keys[row][col]
  419.             if label ~= "" then
  420.                 local x1 = (col-1)*cellW + 1
  421.                 local x2 = col*cellW
  422.                 local y1 = startY + (row-1)*2
  423.                 local y2 = y1 + 1
  424.                 local id = "key_"..label
  425.                 registerButton(id, x1, y1, x2, y2, label, "dhd")
  426.                 drawButton(id, CONFIG.theme.accent, CONFIG.theme.bg)
  427.             end
  428.         end
  429.     end
  430. end
  431.  
  432. -------------------------
  433. -- INPUT HELPERS
  434. -------------------------
  435. local function readLinePrompt(prompt)
  436.     -- crude text input using term, not monitor
  437.     term.clear()
  438.     term.setCursorPos(1,1)
  439.     term.write(prompt..": ")
  440.     return read()
  441. end
  442.  
  443. local function cycleType(current)
  444.     if current == "MW" then return "PG"
  445.     elseif current == "PG" then return "SD"
  446.     else return "MW" end
  447. end
  448.  
  449. local function enforceAddressLength(addr, t)
  450.     local len = #addr:gsub("-", "")
  451.     if t == "MW" and len ~= 7 then
  452.         return false, "Milky Way addresses must have 7 symbols."
  453.     elseif t == "PG" and len ~= 8 then
  454.         return false, "Pegasus addresses must have 8 symbols."
  455.     elseif t == "SD" and len ~= 9 then
  456.         return false, "Same-dimension addresses must have 9 symbols."
  457.     end
  458.     return true
  459. end
  460.  
  461. -------------------------
  462. -- BUTTON HANDLERS
  463. -------------------------
  464. local function handleMainButton(id)
  465.     if id == "dial" then
  466.         -- If we have a selected entry, dial it; otherwise go to DHD
  467.         if state.selectedEntry and state.addressBook[state.selectedEntry] then
  468.             local e = state.addressBook[state.selectedEntry]
  469.             local ok, err = enforceAddressLength(e.address, e.type or "MW")
  470.             if not ok then
  471.                 logEvent("Dial failed: "..err)
  472.             else
  473.                 sg_dial(e.address)
  474.             end
  475.         else
  476.             state.manualAddress = ""
  477.             state.manualType = "MW"
  478.             drawDhdScreen()
  479.         end
  480.     elseif id == "hangup" then
  481.         sg_disconnect()
  482.     elseif id == "iris" then
  483.         if state.irisState == "OPEN" then
  484.             sg_closeIris()
  485.         else
  486.             sg_openIris()
  487.         end
  488.     elseif id == "addr_book" then
  489.         drawAddressBookScreen()
  490.     elseif id == "dhd" then
  491.         state.manualAddress = ""
  492.         state.manualType = "MW"
  493.         drawDhdScreen()
  494.     end
  495. end
  496.  
  497. local function handleAddressBookTap(x, y)
  498.     -- detect which entry row was tapped
  499.     local rowStart = 3
  500.     local index = y - rowStart + 1
  501.     if index >= 1 and index <= #state.addressBook then
  502.         state.selectedEntry = index
  503.         logEvent("Selected entry "..index)
  504.         drawAddressBookScreen()
  505.     end
  506. end
  507.  
  508. local function handleAddressBookButton(id, x, y)
  509.     if id == "addr_back" then
  510.         state.currentScreen = "main"
  511.         drawMainScreen()
  512.     elseif id == "addr_add" then
  513.         state.manualName = ""
  514.         state.manualAddress = ""
  515.         state.manualType = "MW"
  516.         drawAddAddressScreen()
  517.     elseif id == "addr_del" then
  518.         drawDeleteAddressScreen()
  519.     elseif id == "addr_dial" then
  520.         if state.selectedEntry and state.addressBook[state.selectedEntry] then
  521.             local e = state.addressBook[state.selectedEntry]
  522.             local ok, err = enforceAddressLength(e.address, e.type or "MW")
  523.             if not ok then
  524.                 logEvent("Dial failed: "..err)
  525.             else
  526.                 sg_dial(e.address)
  527.                 state.currentScreen = "main"
  528.                 drawMainScreen()
  529.             end
  530.         else
  531.             logEvent("No entry selected")
  532.         end
  533.     else
  534.         -- maybe tapped list area
  535.         handleAddressBookTap(x, y)
  536.     end
  537. end
  538.  
  539. local function handleDeleteAddressTap(x, y)
  540.     local rowStart = 6
  541.     local index = y - rowStart + 1
  542.     if index >= 1 and index <= #state.addressBook then
  543.         local e = state.addressBook[index]
  544.         logEvent("Deleted entry "..(e.name or "NONAME"))
  545.         table.remove(state.addressBook, index)
  546.         saveAddressBook()
  547.         drawDeleteAddressScreen()
  548.     end
  549. end
  550.  
  551. local function handleDeleteAddressButton(id, x, y)
  552.     if id == "del_back" then
  553.         drawAddressBookScreen()
  554.     else
  555.         handleDeleteAddressTap(x, y)
  556.     end
  557. end
  558.  
  559. local function handleAddAddressButton(id)
  560.     if id == "add_cancel" then
  561.         drawAddressBookScreen()
  562.     elseif id == "add_type" then
  563.         state.manualType = cycleType(state.manualType)
  564.         drawAddAddressScreen()
  565.     elseif id == "add_name" then
  566.         state.manualName = readLinePrompt("Enter name")
  567.         drawAddAddressScreen()
  568.     elseif id == "add_addr" then
  569.         state.manualAddress = readLinePrompt("Enter address (e.g. ABC-DEF-GHI)")
  570.         drawAddAddressScreen()
  571.     elseif id == "add_save" then
  572.         if state.manualName == "" or state.manualAddress == "" then
  573.             logEvent("Cannot save: missing name or address")
  574.             return
  575.         end
  576.         local ok, err = enforceAddressLength(state.manualAddress, state.manualType)
  577.         if not ok then
  578.             logEvent("Cannot save: "..err)
  579.             return
  580.         end
  581.         table.insert(state.addressBook, {
  582.             name    = state.manualName,
  583.             address = state.manualAddress,
  584.             type    = state.manualType
  585.         })
  586.         saveAddressBook()
  587.         logEvent("Saved address "..state.manualName)
  588.         drawAddressBookScreen()
  589.     end
  590. end
  591.  
  592. local function handleDhdKey(label)
  593.     if label == "DEL" then
  594.         state.manualAddress = state.manualAddress:sub(1, #state.manualAddress-1)
  595.     elseif label == "CLR" then
  596.         state.manualAddress = ""
  597.     elseif label == "OK" then
  598.         local ok, err = enforceAddressLength(state.manualAddress, state.manualType)
  599.         if not ok then
  600.             logEvent("Dial failed: "..err)
  601.         else
  602.             sg_dial(state.manualAddress)
  603.             state.currentScreen = "main"
  604.             drawMainScreen()
  605.         end
  606.     elseif label == "BK" then
  607.         state.currentScreen = "main"
  608.         drawMainScreen()
  609.     else
  610.         state.manualAddress = state.manualAddress..label
  611.     end
  612.     if state.currentScreen == "dhd" then
  613.         drawDhdScreen()
  614.     end
  615. end
  616.  
  617. local function handleDhdButton(id)
  618.     local label = id:match("^key_(.+)$")
  619.     if label then
  620.         handleDhdKey(label)
  621.     end
  622. end
  623.  
  624. -------------------------
  625. -- MAIN EVENT LOOP
  626. -------------------------
  627. local function main()
  628.     loadAddressBook()
  629.     bootAnimation()
  630.     state.currentScreen = "main"
  631.     drawMainScreen()
  632.  
  633.     while true do
  634.         local e, p1, p2, p3 = os.pullEvent()
  635.         if e == "monitor_touch" then
  636.             local side, x, y = p1, p2, p3
  637.             if side ~= CONFIG.monitorSide then
  638.                 -- ignore other monitors
  639.             else
  640.                 local id = findButtonAt(x, y)
  641.                 if state.currentScreen == "main" then
  642.                     if id then handleMainButton(id) end
  643.                 elseif state.currentScreen == "address_book" then
  644.                     handleAddressBookButton(id, x, y)
  645.                 elseif state.currentScreen == "add_address" then
  646.                     if id then handleAddAddressButton(id) end
  647.                 elseif state.currentScreen == "delete_address" then
  648.                     handleDeleteAddressButton(id, x, y)
  649.                 elseif state.currentScreen == "dhd" then
  650.                     if id then handleDhdButton(id) end
  651.                 end
  652.             end
  653.         elseif e == "timer" or e == "rednet_message" or e == "stargate_status" then
  654.             -- You can expand here to react to gate events if the mod fires them.
  655.             -- For now, periodically refresh main screen when on it.
  656.             if state.currentScreen == "main" then
  657.                 drawMainScreen()
  658.             end
  659.         end
  660.     end
  661. end
  662.  
  663. main()
  664.  
Advertisement
Add Comment
Please, Sign In to add comment