Advertisement
VGToolBox

Projector

Sep 4th, 2012
770
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.85 KB | None | 0 0
  1. local debugMode = false
  2. local slideShowLoc = "disk/slides.txt"
  3.  
  4. --Utility functions-\/-----------------------------------------------------------------------------
  5. function getPeripheral(periph)
  6.  
  7.     sides = {"left","right","front","back","top","bottom"}
  8.     for i, v in ipairs(sides) do
  9.         if peripheral.isPresent(v) then
  10.             if peripheral.getType(v) == periph then
  11.                 return peripheral.wrap(v)
  12.             end
  13.         end
  14.     end
  15.     return nil
  16.  
  17. end
  18.  
  19.  
  20. function slowWriteAt(x,y,str,speed)
  21.     speed = speed or 60
  22.     term.setCursorPos(x ,y)
  23.     debug("Slow write at x: "..x)
  24.     textutils.slowWrite(str,speed)
  25. end
  26.  
  27. function writeAt(x,y,str)
  28.     local oldx, oldy = term.getCursorPos()
  29.     term.setCursorPos(x ,y);
  30.     term.write(str);
  31.     term.setCursorPos(oldx, oldy)
  32. end
  33.  
  34. function drawAllBoxes(boxes)
  35.  
  36.     for i, v in ipairs(boxes) do
  37.         v:draw()
  38.     end
  39.  
  40. end
  41.  
  42. function writeAllText(texts, slow)
  43.  
  44.     for i, v in ipairs(texts) do
  45.         if not slow then
  46.             v:write()
  47.         else
  48.             v:slowWrite()
  49.         end
  50.     end
  51.  
  52. end
  53.  
  54. function pulseOutput(sColour, n)
  55.  
  56.     for i = 1, n do
  57.  
  58.         rs.setBundledOutput("bottom", colors.combine(rs.getBundledOutput("bottom"), sColour))
  59.         sleep(0.45)
  60.         rs.setBundledOutput("bottom", colors.subtract(rs.getBundledOutput("bottom"), sColour))
  61.         sleep(0.45)
  62.  
  63.     end
  64. end
  65.  
  66. local loadingChars = {"/","|","\\","-"}
  67. local loadingPos = {x = 0, y = 0,active = false}
  68.  
  69. function showLoading()
  70.  
  71.     local i = 1
  72.     if loadingPos.active then
  73.         error("Something is already loading")
  74.     end
  75.  
  76.     loadingPos.active = true
  77.  
  78.     if loadingPos.x < 1 or loadingPos.y < 1 then
  79.         error("loadingPos not set")
  80.     end
  81.  
  82.     repeat
  83.         term.setCursorPos(loadingPos.x, loadingPos.y)
  84.         print(loadingChars[i])
  85.         i = (i < #loadingChars) and i + 1 or 1
  86.         sleep(0.2)
  87.     until not loadingPos.active
  88.  
  89.     term.setCursorPos(loadingPos.x, loadingPos.y)
  90.     print(" ")
  91.     loadingPos.x, loadingPos.y = 0, 0
  92.  
  93.  
  94. end
  95.  
  96. function stopLoading()
  97.  
  98.     loadingPos.active = false
  99.  
  100. end
  101.  
  102. function debug(val)
  103.  
  104.     if debugMode then
  105.  
  106.         oldx, oldy = term.getCursorPos()
  107.         term.restore()
  108.         --term.setCursorPos(6, consoleHeight)
  109.         print(val)
  110.         --sleep(3)
  111.         term.redirect(monitor)
  112.         term.setCursorPos(oldx, oldy)
  113.     end
  114. end
  115.  
  116. --Utility functions-/\-----------------------------------------------------------------------------
  117. --Class constructors-\/----------------------------------------------------------------------------
  118.  
  119. function newBox(x, y, width, height)
  120.  
  121.     --creates a box with drawing and erasing methods
  122.  
  123.     local function drawBox(box)
  124.  
  125.         --renders a box onscreen at correct location and size, accepts box "class" as argument
  126.         local hChar = "|"
  127.         local vChar = "-"
  128.         local cornerChar = "O"
  129.         local currentChar = ""
  130.  
  131.         if not box.x or not box.y or not box.width or not box.height then
  132.  
  133.         --exit without attempting to render the box
  134.         return 0
  135.         end
  136.  
  137.         --print("y is "..y)
  138.  
  139.         for i = box.x, x + box.width do
  140.  
  141.             if i == x or i == x + width then
  142.                 currentChar = cornerChar
  143.             else
  144.                 currentChar = vChar
  145.             end
  146.  
  147.             writeAt(i, y, currentChar)
  148.             writeAt(i, y + height, currentChar)
  149.         end
  150.  
  151.         for i = y + 1, y + box.height - 1 do
  152.  
  153.             currentChar = hChar
  154.             writeAt(x, i, currentChar)
  155.             writeAt(x + width, i, currentChar)
  156.         end
  157.  
  158.     end
  159.  
  160.     local function eraseBox(box)
  161.  
  162.         --clears the area that box sits in. Can be used to create a box in negative space
  163.  
  164.         if not box.x or not box.y or not box.width or not box.height then
  165.  
  166.             --exit without attempting to render the box
  167.             return 0
  168.         end
  169.  
  170.         for i = box.x, x + box.width do
  171.             writeAt(i, y, "")
  172.             writeAt(i, y + height, "")
  173.         end
  174.  
  175.         for i = y + 1, y + box.hight - 1 do
  176.             writeAt(x, i, "")
  177.             writeAt(x + width, i, "")
  178.         end
  179.  
  180.     end
  181.  
  182.     local box = {x = x, y = y, width = width, height = height, draw = drawBox, erase = eraseBox}
  183.  
  184.     return box
  185.  
  186. end
  187.  
  188.  
  189. function newText(string, x, y, alignment, renderImmediate)
  190.  
  191.     local function renderText(text)
  192.         --renders text onscreen at correct alignment, accepts text "class" as argument
  193.         text.alignment = text.alignment or "left"
  194.  
  195.         if text.alignment == "left" then
  196.             writeAt(text.x,text.y,text.string)
  197.  
  198.         elseif alignment == "centre" then
  199.             writeAt(text.x - #text.string * 0.5, text.y, text.string)
  200.  
  201.         elseif alignment == "right" then
  202.             writeAt(text.x - #text.string, text.y, text.string)
  203.  
  204.         else
  205.  
  206.             error(text.alignment..' alignment for string "'..text.string..'" is not a valid alignment')
  207.         end
  208.     end
  209.  
  210.     local function slowRenderText(text,speed)
  211.  
  212.         --slow renders text onscreen at correct alignment, accepts text "class" as argument
  213.         text.alignment = text.alignment or "left"
  214.  
  215.         if text.alignment == "left" then
  216.             slowWriteAt(text.x,text.y,text.string, speed)
  217.  
  218.         elseif alignment == "centre" then
  219.             slowWriteAt(text.x - #text.string * 0.5, text.y, text.string, speed)
  220.  
  221.         elseif alignment == "right" then
  222.             slowWriteAt(text.x - #text.string, text.y, text.string, speed)
  223.  
  224.         else
  225.  
  226.             error(text.alignment..' alignment for string "'..text.string..'" is not a valid alignment')
  227.         end
  228.  
  229.     end
  230.  
  231.     local function deleteText(text)
  232.  
  233.         text.alignment = text.alignment or "left"
  234.         text.string = string.rep(" ", #text.string)
  235.  
  236.         if text.alignment == "left" then
  237.             writeAt(text.x,text.y,text.string)
  238.  
  239.         elseif alignment == "centre" then
  240.             writeAt(text.x - #text.string * 0.5, text.y, text.string)
  241.  
  242.         elseif alignment == "right" then
  243.             writeAt(text.x - #text.string, text.y, text.string)
  244.  
  245.         else
  246.  
  247.             error(text.alignment..' alignment for string "'..text.string..'" is not a valid alignment')
  248.         end
  249.  
  250.     end
  251.  
  252.     local function slowDeleteText(text)
  253.  
  254.         text.alignment = text.alignment or "left"
  255.         text.string = string.rep(" ", #text.string)
  256.  
  257.         if text.alignment == "left" then
  258.             slowWriteAt(text.x,text.y,text.string)
  259.  
  260.         elseif alignment == "centre" then
  261.             slowWriteAt(text.x - #text.string * 0.5, text.y, text.string)
  262.  
  263.         elseif alignment == "right" then
  264.             slowWriteAt(text.x - #text.string, text.y, text.string)
  265.  
  266.         else
  267.  
  268.             error(text.alignment..' alignment for string "'..text.string..'" is not a valid alignment')
  269.         end
  270.  
  271.     end
  272.  
  273.     local function getLength(text)
  274.  
  275.         return #text.string
  276.  
  277.     end
  278.  
  279.  
  280.     renderImmediate = renderImmediate or "false"
  281.  
  282.     local text = {}
  283.     text.alignment = alignment or "left"
  284.     text.string = string or "blank"
  285.     text.x = x or 1
  286.     text.y = y or 1
  287.     text.write = renderText
  288.     text.slowWrite = slowRenderText
  289.     text.delete = deleteText
  290.     text.slowDelete = slowDeleteText
  291.     text.length = getLength
  292.  
  293.     if renderImmediate == "now" then
  294.         text:write()
  295.     elseif renderImmediate == "slow" then
  296.         text:slowWrite()
  297.     end
  298.  
  299.     return text
  300.  
  301. end
  302.  
  303. --Class constructors-/\----------------------------------------------------------------------------
  304.  
  305. local function showSlides(width, height)
  306.  
  307.     local diskDrive = getPeripheral("drive")
  308.     local slideShow = {}
  309.     local alignment = "left"
  310.     local style = "normal"
  311.     local bullet = 1
  312.     local newPage = false
  313.     local currentHeader = nil
  314.     local y = 1
  315.     local x = 1
  316.  
  317.     local printableText = ""
  318.  
  319.     slideShow = getSlides(diskDrive)
  320.  
  321.     if not slideShow then
  322.         return 1
  323.     end
  324.  
  325.     i = 1
  326.  
  327.     while slideShow[i] do
  328.  
  329.         if slideShow[i]:sub(1,1) == "[" then
  330.  
  331.             if slideShow[i]:sub(2,2) == "h" then
  332.                 style = "header"
  333.  
  334.             elseif slideShow[i]:sub(2,2) == "b" then
  335.                 style = "bullet"
  336.  
  337.             elseif slideShow[i]:sub(2,2) == "r" then
  338.                 alignment = "right"
  339.  
  340.             elseif slideShow[i]:sub(2,2) == "c" then
  341.                 alignment = "centre"
  342.  
  343.             elseif slideShow[i]:sub(2,2) == "n" then
  344.                 newPage = true
  345.                 currentHeader = nil
  346.  
  347.             elseif slideShow[i]:sub(2,3) == "/b" then
  348.                 style = "normal"
  349.                 bullet = 1
  350.  
  351.             elseif slideShow[i]:sub(2,3) == "/r" or slideShow[i]:sub(2,3) == "/c" then
  352.                 alignment = "left"
  353.  
  354.             end
  355.  
  356.             if slideShow[i]:sub(3,3) == "]" then
  357.                 printableText = slideShow[i]:sub(4)
  358.  
  359.             else
  360.                 printableText = slideShow[i]:sub(5)
  361.  
  362.             end
  363.         else
  364.  
  365.             printableText = slideShow[i]
  366.  
  367.         end
  368.  
  369.         if y >= height - 1 or newPage then
  370.             term.clear()
  371.             y = 1
  372.             if currentHeader then
  373.                 currentHeader:write()
  374.                 y = y + 2
  375.             end
  376.         end
  377.  
  378.  
  379.         if printableText ~= "" then
  380.  
  381.             local tempAlignment = alignment
  382.             local tempY = y
  383.             local tempX = x
  384.  
  385.             if style == "bullet" then
  386.                 printableText = bullet..". "..printableText
  387.                 tempAlignment = "left"
  388.  
  389.             elseif style == "header" then
  390.                 printableText = printableText:upper()
  391.                 tempAlignment = "centre"
  392.                 tempY = 1
  393.                 tempX = width * 0.5
  394.             end
  395.  
  396.             local tempText = newText(printableText, tempX, tempY, tempAlignment)
  397.             tempText:slowWrite(40)
  398.  
  399.             if style == "header" then
  400.                 currentHeader = tempText
  401.                 style = "normal"
  402.  
  403.             elseif style == "bullet" then
  404.                 bullet = bullet + 1
  405.             end
  406.  
  407.             y = y + 2
  408.  
  409.             while true do
  410.  
  411.                 event, p1 = os.pullEventRaw()
  412.                 if event == "disk_eject" then
  413.                     return 2
  414.                 elseif event == "redstone" then
  415.                     if rs.getInput("left") or rs.getInput("right") then
  416.                         break
  417.                     end
  418.                 elseif event == "terminate" then
  419.                     return 0
  420.                 end
  421.  
  422.             end
  423.  
  424.         end
  425.  
  426.         i = i + 1
  427.  
  428.        
  429.  
  430.     end
  431.  
  432.     return 0
  433.  
  434. end
  435.  
  436.  
  437. function getSlides(diskDrive)
  438.  
  439.     local slideShow = {}
  440.  
  441.     debug("getting slides")
  442.  
  443.     if diskDrive then
  444.  
  445.         if fs.exists(slideShowLoc) then
  446.  
  447.             --Check to see if save file exists and open it to save out all of the current saved statuses
  448.  
  449.             local hRead = assert(fs.open(slideShowLoc, "r")) --Will crash the program if the file cannot be opened
  450.  
  451.             local i = 1
  452.  
  453.             while true do
  454.  
  455.                 slideShow[i] = hRead.readLine()
  456.  
  457.                 if not slideShow[i] then
  458.                     break
  459.                 end
  460.  
  461.                 i = i + 1
  462.  
  463.             end
  464.  
  465.             hRead.close()
  466.         else
  467.             slideShow = nil
  468.         end
  469.     end
  470.  
  471.     return slideShow
  472. end
  473.  
  474. local function main()
  475.  
  476.     if not monitor then
  477.         error("Monitor not found\nA monitor is required to run this program")
  478.     end
  479.  
  480.     print("running projection on monitor")
  481.  
  482.     term.redirect(monitor)
  483.  
  484.     while true do
  485.         event, p1 = os.pullEvent("redstone")
  486.         if rs.getInput("left") or rs.getInput("right") then
  487.             break
  488.         end
  489.     end
  490.  
  491.  
  492.     monitor.clear()
  493.  
  494.     monitor.setTextScale(3)
  495.  
  496.     local width, height = monitor.getSize()
  497.  
  498.     local startupScreen = newText("B.A.M.", math.ceil((width ) * 0.5)+ 1, math.ceil((height) * 0.5), "centre")
  499.     startupScreen:slowWrite(2)
  500.     sleep(3)
  501.  
  502.     monitor.clear()
  503.  
  504.     sleep(1)
  505.     monitor.setTextScale(1)
  506.  
  507.     width, height = monitor.getSize()
  508.  
  509.  
  510.     while true do
  511.  
  512.         monitor.clear()
  513.  
  514.         local outcome = showSlides(width, height)
  515.  
  516.         monitor.clear()
  517.  
  518.         if outcome == 1 then
  519.             local diskWrong = newText("Disk does not contain\nappropriate information or\ndisk drive can be found.\nPlease insert a new disk", 1, 1, "left")
  520.             diskWrong:slowWrite(40)
  521.             os.pullEvent("disk")
  522.  
  523.         elseif outcome == 2 then
  524.             local diskOut = newText("Disk has been Removed,\nplease insert disk to\nbegin presentation", 1, 1, "left")
  525.             diskOut:slowWrite(40)
  526.             os.pullEvent("disk")
  527.  
  528.         elseif outcome == 0 then
  529.             break
  530.         end
  531.     end
  532.  
  533.     monitor.clear()
  534.     term.restore()
  535. end
  536.  
  537. monitor = getPeripheral("monitor")
  538.  
  539. while true do
  540.     main()
  541. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement