Advertisement
TheRockettek

Untitled

Feb 13th, 2017
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 43.58 KB | None | 0 0
  1. --[[
  2.  
  3. PAIN picture editor for ComputerCraft
  4.  
  5. Get it with
  6.  
  7. pastebin get wJQ7jav0 pain
  8.  
  9. std pb wJQ7jav0 pain
  10.  
  11. std ld pain pain
  12.  
  13.  
  14.  
  15. This is a stable release. You fool!
  16.  
  17. --]]
  18.  
  19.  
  20.  
  21. local displayHelp = function()
  22.  
  23. local progname = fs.getName(shell.getRunningProgram())
  24.  
  25. print(progname.." <filename>")
  26.  
  27. print("Press F1 in program for more.")
  28.  
  29. end
  30.  
  31.  
  32.  
  33. local pMode = 0
  34.  
  35.  
  36.  
  37. local tArg = {...}
  38.  
  39. if (not tArg[1]) and shell then
  40.  
  41. return displayHelp()
  42.  
  43. end
  44.  
  45.  
  46.  
  47. if tArg[2] == "view" then
  48.  
  49. pMode = 1
  50.  
  51. elseif tArg[2] == "moo" then
  52.  
  53. return print("This PAIN does not have Super Cow Powers.")
  54.  
  55. end
  56.  
  57.  
  58.  
  59. local fileName
  60.  
  61. if not term.isColor() then
  62.  
  63. error("Only for Advanced computers")
  64.  
  65. end
  66.  
  67. local barmsg = "Press F1 for help."
  68.  
  69. local tse = textutils.serialise
  70.  
  71. local tun = textutils.unserialise
  72.  
  73. local paintEncoded
  74.  
  75. local lastPaintEncoded
  76.  
  77. local frame = 1
  78.  
  79. local doRender = false
  80.  
  81. local metaHistory = {}
  82.  
  83. local bepimode = false --this is a family-friendly program! now stand still while I murder you
  84.  
  85. local evenDrawGrid = true --will you evenDraw(the)Grid ?
  86.  
  87. local renderBlittle = false --whether or not to render all in blittle
  88.  
  89. local firstTerm, blittleTerm = term.current()
  90.  
  91. local firstBG = term.getBackgroundColor()
  92.  
  93. local firstTX = term.getTextColor()
  94.  
  95.  
  96.  
  97. local grid
  98.  
  99.  
  100.  
  101. local yield = function()
  102.  
  103. os.queueEvent("yield")
  104.  
  105. os.pullEvent("yield")
  106.  
  107. end
  108.  
  109.  
  110.  
  111. local paint = {
  112.  
  113. scrollX = 0,
  114.  
  115. scrollY = 0,
  116.  
  117. t = colors.gray,
  118.  
  119. b = colors.white,
  120.  
  121. m = 1, --in case you want to use PAIN as a level editor or something
  122.  
  123. c = " ",
  124.  
  125. doGray = false,
  126.  
  127. }
  128.  
  129.  
  130.  
  131. local scr_x, scr_y = term.getSize()
  132.  
  133. local scrollX, scrollY = 0, 0
  134.  
  135.  
  136.  
  137. local keysDown = {}
  138.  
  139. local miceDown = {}
  140.  
  141.  
  142.  
  143. local doRenderBar = 1 -- 1 and 0. Not true or false
  144.  
  145.  
  146.  
  147. local fixstr = function(str)
  148.  
  149. return str:gsub("\\(%d%d%d)",string.char)
  150.  
  151. end
  152.  
  153.  
  154.  
  155. local choice = function(input,breakkeys)
  156.  
  157. repeat
  158.  
  159. event, key = os.pullEvent("key")
  160.  
  161. if type(key) == "number" then key = keys.getName(key) end
  162.  
  163. if key == nil then key = " " end
  164.  
  165. if type(breakkeys) == "table" then
  166.  
  167. for a = 1, #breakkeys do
  168.  
  169. if key == breakkeys[a] then
  170.  
  171. return ""
  172.  
  173. end
  174.  
  175. end
  176.  
  177. end
  178.  
  179. until string.find(input, key)
  180.  
  181. return key
  182.  
  183. end
  184.  
  185. local explode = function(div,str)
  186.  
  187. if (div=='') then return false end
  188.  
  189. local pos,arr = 0,{}
  190.  
  191. for st,sp in function() return string.find(str,div,pos,true) end do
  192.  
  193. table.insert(arr,str:sub(pos,st-1))
  194.  
  195. pos = sp + 1
  196.  
  197. end
  198.  
  199. table.insert(arr,str:sub(pos))
  200.  
  201. return arr
  202.  
  203. end
  204.  
  205.  
  206.  
  207. local function cutString(max_line_length, str) --from stack overflow
  208.  
  209. local lines = {}
  210.  
  211. local line
  212.  
  213. str:gsub('(%s*)(%S+)',
  214.  
  215. function(spc, word)
  216.  
  217. if not line or #line + #spc + #word > max_line_length then
  218.  
  219. table.insert(lines, line)
  220.  
  221. line = word
  222.  
  223. else
  224.  
  225. line = line..spc..word
  226.  
  227. end
  228.  
  229. end
  230.  
  231. )
  232.  
  233. table.insert(lines, line)
  234.  
  235. return lines
  236.  
  237. end
  238.  
  239.  
  240.  
  241. local cutUp = function(len,tbl)
  242.  
  243. local output = {}
  244.  
  245. local e = 0
  246.  
  247. local s
  248.  
  249. for a = 1, #tbl do
  250.  
  251. if #(tbl[a]:gsub(" ","")) == 0 then
  252.  
  253. s = {""}
  254.  
  255. else
  256.  
  257. s = cutString(len,tbl[a])
  258.  
  259. end
  260.  
  261. for b = 1, #s do
  262.  
  263. table.insert(output,s[b])
  264.  
  265. end
  266.  
  267. end
  268.  
  269. return output
  270.  
  271. end
  272.  
  273.  
  274.  
  275. local getEvents = function(...)
  276.  
  277. local output
  278.  
  279. while true do
  280.  
  281. output = {os.pullEvent()}
  282.  
  283. for a = 1, #arg do
  284.  
  285. if type(arg[a]) == "boolean" then
  286.  
  287. if doRender == arg[a] then
  288.  
  289. return {}
  290.  
  291. end
  292.  
  293. elseif output[1] == arg[a] then
  294.  
  295. return unpack(output)
  296.  
  297. end
  298.  
  299. end
  300.  
  301. end
  302.  
  303. end
  304.  
  305.  
  306.  
  307. local sanitize = function(sani,tize)
  308.  
  309. local _,x = string.find(sani,tize)
  310.  
  311. if x then
  312.  
  313. return sani:sub(x+1)
  314.  
  315. else
  316.  
  317. return sani
  318.  
  319. end
  320.  
  321. end
  322.  
  323. local ro = function(input, max)
  324.  
  325. return math.floor(input % max)
  326.  
  327. end
  328.  
  329.  
  330.  
  331. local guiHelp = function()
  332.  
  333. term.redirect(firstTerm)
  334.  
  335. scr_x, scr_y = term.current().getSize()
  336.  
  337. local _helpText = [[
  338.  
  339.  
  340.  
  341. 'PAIN' Help Page
  342.  
  343. Programmed by LDDestroier/EldidiStroyrr
  344.  
  345.  
  346.  
  347. (use UP/DOWN or scrollwheel, exit with Q)
  348.  
  349. If you want to use PAIN to its full capacity, then READ EVERYTHING HERE! It's not TOO long, and it's completely worth it!
  350.  
  351.  
  352.  
  353. Syntax:
  354.  
  355. >pain <filename> [view]
  356.  
  357.  
  358.  
  359. [view]: disable all writing capability to view a file
  360.  
  361.  
  362.  
  363. You can see what colors are selected based on the word "PAIN" on the hotbar.
  364.  
  365.  
  366.  
  367. Hotkeys:
  368.  
  369. left/right ctrl: toggle the menu
  370.  
  371.  
  372.  
  373. left click:
  374.  
  375. +shift = drag and let go to make a line
  376.  
  377. -alone = place pixel
  378.  
  379.  
  380.  
  381. right click: delete pixel
  382.  
  383.  
  384.  
  385. middle click OR "t": place text down with current colors
  386.  
  387.  
  388.  
  389. "[" or mouse scroll down:
  390.  
  391. +shift = change to previous text color
  392.  
  393. -alone = change to previous background color
  394.  
  395.  
  396.  
  397. "]" or mouse scroll up:
  398.  
  399. +shift = change to next text color
  400.  
  401. -alone = change to next background color
  402.  
  403.  
  404.  
  405. spacebar:
  406.  
  407. +shift = toggle grid
  408.  
  409. -alone = toggle bar visibility
  410.  
  411.  
  412.  
  413. arrowkeys:
  414.  
  415. +shift = move entire picture
  416.  
  417. +tab = move one pixel at a time
  418.  
  419. -alone = looks around the canvas smoothly
  420.  
  421.  
  422.  
  423. "+" (or equals):
  424.  
  425. +left alt = swap the current frame with the next frame
  426.  
  427. -alone = change to next frame
  428.  
  429.  
  430.  
  431. "-":
  432.  
  433. +left alt = swap the current frame with the previous frame
  434.  
  435. -alone = change to previous frame
  436.  
  437.  
  438.  
  439. "a": set the coordinates to 0,0
  440.  
  441.  
  442.  
  443. "b": toggle redirect to blittle, to preview in teletext characters
  444.  
  445.  
  446.  
  447. "c": input coordinates to move the canvas to
  448.  
  449.  
  450.  
  451. "g": toggle grayscale mode. everything is in shades of gray. if you Save, it saves in grayscale.
  452.  
  453.  
  454.  
  455. "f":
  456.  
  457. +shift = fill all empty pixels with background color
  458.  
  459. -alone = absolutely nothing
  460.  
  461.  
  462.  
  463. "m": set metadata for pixels (for game makers, otherwise safe to ignore)
  464.  
  465.  
  466.  
  467.  
  468.  
  469. Le Menu (access with CTRL):
  470.  
  471.  
  472.  
  473. -left click on a menu item to select it.
  474.  
  475. -if you click on the menubar, let go on an option to select it.
  476.  
  477.  
  478.  
  479. "Save"
  480.  
  481. Saves all frames to a specially formatted PAIN paint file. The format PAIN uses is very inefficient despite my best efforts, so Export if you don't use text or multiple frame.
  482.  
  483.  
  484.  
  485. "Export"
  486.  
  487. Exports current frame to the basic paint format, which doesn't save text, but is WAY more space-efficient. Specify a path, too.
  488.  
  489.  
  490.  
  491. "Del. Frame"
  492.  
  493. Deletes the current frame. Tells you off if you try to delete the only frame.
  494.  
  495.  
  496.  
  497. "Clear"
  498.  
  499. Deletes all pixels on the current frame.
  500.  
  501.  
  502.  
  503. "Exit"
  504.  
  505. Durr I dunno, I think it exits.
  506.  
  507.  
  508.  
  509.  
  510.  
  511. I hope my PAIN causes you joy.
  512.  
  513. ]]
  514.  
  515. _helpText = explode("\n",_helpText)
  516.  
  517. helpText = cutUp(scr_x,_helpText)
  518.  
  519. local helpscroll = 0
  520.  
  521. term.setBackgroundColor(colors.gray)
  522.  
  523. term.setTextColor(colors.white)
  524.  
  525. term.clear()
  526.  
  527. local evt, key
  528.  
  529. while true do
  530.  
  531. term.clear()
  532.  
  533. for a = 1, scr_y do
  534.  
  535. term.setCursorPos(1,a)
  536.  
  537. term.clearLine()
  538.  
  539. term.write(helpText[a-helpscroll] or "")
  540.  
  541. end
  542.  
  543. repeat
  544.  
  545. evt,key = os.pullEvent()
  546.  
  547. until evt == "key" or evt == "mouse_scroll"
  548.  
  549. if evt == "key" then
  550.  
  551. if key == keys.up then
  552.  
  553. helpscroll = helpscroll + 1
  554.  
  555. elseif key == keys.down then
  556.  
  557. helpscroll = helpscroll - 1
  558.  
  559. elseif key == keys.pageUp then
  560.  
  561. helpscroll = helpscroll + scr_y
  562.  
  563. elseif key == keys.pageDown then
  564.  
  565. helpscroll = helpscroll - scr_y
  566.  
  567. elseif (key == keys.q) or (key == keys.space) then
  568.  
  569. doRender = true
  570.  
  571. if renderBlittle then term.redirect(blittleTerm) end
  572.  
  573. scr_x, scr_y = term.current().getSize()
  574.  
  575. return
  576.  
  577. end
  578.  
  579. elseif evt == "mouse_scroll" then
  580.  
  581. helpscroll = helpscroll - key
  582.  
  583. end
  584.  
  585. if helpscroll > 0 then
  586.  
  587. helpscroll = 0
  588.  
  589. elseif helpscroll < -(#helpText-(scr_y-3)) then
  590.  
  591. helpscroll = -(#helpText-(scr_y-3))
  592.  
  593. end
  594.  
  595. end
  596.  
  597. end
  598.  
  599.  
  600.  
  601. local tableRemfind = function(tbl, str)
  602.  
  603. local out = tbl
  604.  
  605. for a = 1, #tbl do
  606.  
  607. if tbl[a] == str then
  608.  
  609. table.remove(out,a)
  610.  
  611. return out,a
  612.  
  613. end
  614.  
  615. end
  616.  
  617. return {}
  618.  
  619. end
  620.  
  621.  
  622.  
  623. local stringShift = function(str,amt)
  624.  
  625. return str:sub(ro(amt-1,#str)+1)..str:sub(1,ro(amt-1,#str))
  626.  
  627. end
  628.  
  629.  
  630.  
  631. local deepCopy
  632.  
  633. deepCopy = function(obj)
  634.  
  635. if type(obj) ~= 'table' then return obj end
  636.  
  637. local res = {}
  638.  
  639. for k, v in pairs(obj) do res[deepCopy(k)] = deepCopy(v) end
  640.  
  641. return res
  642.  
  643. end
  644.  
  645.  
  646.  
  647. local renderBottomBar = function(txt)
  648.  
  649. term.setCursorPos(1,scr_y)
  650.  
  651. term.setBackgroundColor(colors.lightGray)
  652.  
  653. term.setTextColor(colors.black)
  654.  
  655. term.clearLine()
  656.  
  657. term.write(txt)
  658.  
  659. end
  660.  
  661.  
  662.  
  663. local bottomPrompt = function(txt,history,cho,breakkeys)
  664.  
  665. renderBottomBar(txt)
  666.  
  667. local out
  668.  
  669. sleep(0)
  670.  
  671. if cho then
  672.  
  673. out = choice(cho,breakkeys)
  674.  
  675. else
  676.  
  677. out = read(_,history)
  678.  
  679. end
  680.  
  681. return out
  682.  
  683. end
  684.  
  685.  
  686.  
  687. local getDotsInLine = function( startX, startY, endX, endY ) --stolen from the paintutils API...hehehe
  688.  
  689. local out = {}
  690.  
  691.  
  692.  
  693. startX = math.floor(startX)
  694.  
  695. startY = math.floor(startY)
  696.  
  697. endX = math.floor(endX)
  698.  
  699. endY = math.floor(endY)
  700.  
  701.  
  702.  
  703. if startX == endX and startY == endY then
  704.  
  705. out = {{x=startX,y=startY}}
  706.  
  707. return out
  708.  
  709. end
  710.  
  711.  
  712.  
  713. local minX = math.min( startX, endX )
  714.  
  715. if minX == startX then
  716.  
  717. minY = startY
  718.  
  719. maxX = endX
  720.  
  721. maxY = endY
  722.  
  723. else
  724.  
  725. minY = endY
  726.  
  727. maxX = startX
  728.  
  729. maxY = startY
  730.  
  731. end
  732.  
  733.  
  734.  
  735. local xDiff = maxX - minX
  736.  
  737. local yDiff = maxY - minY
  738.  
  739.  
  740.  
  741. if xDiff > math.abs(yDiff) then
  742.  
  743. local y = minY
  744.  
  745. local dy = yDiff / xDiff
  746.  
  747. for x=minX,maxX do
  748.  
  749. table.insert(out,{x=x,y=math.floor(y+0.5)})
  750.  
  751. y = y + dy
  752.  
  753. end
  754.  
  755. else
  756.  
  757. local x = minX
  758.  
  759. local dx = xDiff / yDiff
  760.  
  761. if maxY >= minY then
  762.  
  763. for y=minY,maxY do
  764.  
  765. table.insert(out,{x=math.floor(x+0.5),y=y})
  766.  
  767. x = x + dx
  768.  
  769. end
  770.  
  771. else
  772.  
  773. for y=minY,maxY,-1 do
  774.  
  775. table.insert(out,{x=math.floor(x+0.5),y=y})
  776.  
  777. x = x - dx
  778.  
  779. end
  780.  
  781. end
  782.  
  783. end
  784.  
  785. return out
  786.  
  787. end
  788.  
  789.  
  790.  
  791. local movePaintEncoded = function(pe,xdiff,ydiff)
  792.  
  793. local outpootis = deepCopy(pe)
  794.  
  795. for a = 1, #outpootis do
  796.  
  797. outpootis[a].x = outpootis[a].x+xdiff
  798.  
  799. outpootis[a].y = outpootis[a].y+ydiff
  800.  
  801. end
  802.  
  803. return outpootis
  804.  
  805. end
  806.  
  807.  
  808.  
  809. local clearRedundant = function(dots)
  810.  
  811. local input = {}
  812.  
  813. local pheight = 0
  814.  
  815. local pwidth = 0
  816.  
  817. for a = 1, #dots do
  818.  
  819. if dots[a].y > pheight then
  820.  
  821. pheight = dots[a].y
  822.  
  823. end
  824.  
  825. if dots[a].x > pwidth then
  826.  
  827. pwidth = dots[a].x
  828.  
  829. end
  830.  
  831. end
  832.  
  833. for a = 1, #dots do
  834.  
  835. if not input[dots[a].y] then input[dots[a].y] = {} end
  836.  
  837. input[dots[a].y][dots[a].x] = dots[a]
  838.  
  839. end
  840.  
  841. local output = {}
  842.  
  843. local frame = 0
  844.  
  845. for y = 1, pheight do
  846.  
  847. for x = 1, pwidth do
  848.  
  849. if input[y] then
  850.  
  851. if input[y][x] then
  852.  
  853. table.insert(output,input[y][x])
  854.  
  855. end
  856.  
  857. end
  858.  
  859. if frame >= 50 then
  860.  
  861. --yield()
  862.  
  863. frame = 0
  864.  
  865. end
  866.  
  867. end
  868.  
  869. end
  870.  
  871. return output
  872.  
  873. end
  874.  
  875.  
  876.  
  877. local grayOut = function(color)
  878.  
  879. local c = deepCopy(_G.colors)
  880.  
  881. local grays = {
  882.  
  883. [c.white] = c.white,
  884.  
  885. [c.orange] = c.lightGray,
  886.  
  887. [c.magenta] = c.lightGray,
  888.  
  889. [c.lightBlue] = c.lightGray,
  890.  
  891. [c.yellow] = c.white,
  892.  
  893. [c.lime] = c.lightGray,
  894.  
  895. [c.pink] = c.lightGray,
  896.  
  897. [c.gray] = c.gray,
  898.  
  899. [c.lightGray] = c.lightGray,
  900.  
  901. [c.cyan] = c.lightGray,
  902.  
  903. [c.purple] = c.gray,
  904.  
  905. [c.blue] = c.gray,
  906.  
  907. [c.brown] = c.gray,
  908.  
  909. [c.green] = c.lightGray,
  910.  
  911. [c.red] = c.gray,
  912.  
  913. [c.black] = c.black,
  914.  
  915. }
  916.  
  917. local newColor = grays[color] or 1
  918.  
  919. return newColor
  920.  
  921. end
  922.  
  923.  
  924.  
  925. local getOnscreenCoords = function(tbl,_x,_y)
  926.  
  927. local screenTbl = {}
  928.  
  929. for a = 1, #tbl do
  930.  
  931. if tbl[a].x+paint.scrollX > 0 and tbl[a].x+paint.scrollX <= scr_x then
  932.  
  933. if tbl[a].y+paint.scrollY > 0 and tbl[a].y+paint.scrollY <= scr_y then
  934.  
  935. table.insert(screenTbl,{tbl[a].x+paint.scrollX,tbl[a].y+paint.scrollY})
  936.  
  937. end
  938.  
  939. end
  940.  
  941. end
  942.  
  943. if not _x and _y then
  944.  
  945. return screenTbl
  946.  
  947. else
  948.  
  949. for a = 1, #screenTbl do
  950.  
  951. if screenTbl[a][1] == _x and screenTbl[a][2] == _y then
  952.  
  953. return true
  954.  
  955. end
  956.  
  957. end
  958.  
  959. return false
  960.  
  961. end
  962.  
  963. end
  964.  
  965.  
  966.  
  967. local fillTool = function(info,cx,cy,color,layer) --takes a frame, not the whole paintEncoded
  968.  
  969. local x,y
  970.  
  971. local output = {}
  972.  
  973. for a = 1, #info do
  974.  
  975. if (info[a].x == cx) and (info[a].y == cy) then
  976.  
  977. x = cx
  978.  
  979. y = cy
  980.  
  981. replaceColor = info[a].b
  982.  
  983. break
  984.  
  985. end
  986.  
  987. end
  988.  
  989. if not x and y then
  990.  
  991. return
  992.  
  993. end
  994.  
  995. if color == replaceColor then
  996.  
  997. return
  998.  
  999. end
  1000.  
  1001. table.insert(output,{
  1002.  
  1003. ["x"] = x,
  1004.  
  1005. ["y"] = y,
  1006.  
  1007. ["b"] = color,
  1008.  
  1009. ["t"] = color,
  1010.  
  1011. ["c"] = " ",
  1012.  
  1013. ["m"] = paint.m
  1014.  
  1015. })
  1016.  
  1017. local loops = 0
  1018.  
  1019. local tAffectedPoints = {
  1020.  
  1021. [1] = {
  1022.  
  1023. x = x+tTerm.scroll.x,
  1024.  
  1025. z = z+tTerm.scroll.z
  1026.  
  1027. }
  1028.  
  1029. }
  1030.  
  1031. while #tAffectedPoints > 0 do
  1032.  
  1033. if loops%200 == 0 then
  1034.  
  1035. sleep(0.05)
  1036.  
  1037. end
  1038.  
  1039. for i=-1,1,2 do
  1040.  
  1041. local x = tAffectedPoints[1]["x"]+i
  1042.  
  1043. local z = tAffectedPoints[1]["z"]
  1044.  
  1045. if tBlueprint[layer][x][z] == replaceColor and x >= tTerm.viewable.sX and x <= tTerm.viewable.eX and z >= tTerm.viewable.sZ and z <= tTerm.viewable.eZ then
  1046.  
  1047. drawPoint(x,z,color,layer,true,true)
  1048.  
  1049. table.insert(tAffectedPoints,{["x"] = x,["z"] = z})
  1050.  
  1051. end
  1052.  
  1053. x = tAffectedPoints[1]["x"]
  1054.  
  1055. z = tAffectedPoints[1]["z"]+i
  1056.  
  1057. if tBlueprint[layer][x][z] == replaceColor and x >= tTerm.viewable.sX and x <= tTerm.viewable.eX and z >= tTerm.viewable.sZ and z <= tTerm.viewable.eZ then
  1058.  
  1059. drawPoint(x,z,color,layer,true,true)
  1060.  
  1061. table.insert(tAffectedPoints,{["x"] = x,["z"] = z})
  1062.  
  1063. end
  1064.  
  1065. end
  1066.  
  1067. table.remove(tAffectedPoints,1)
  1068.  
  1069. loops = loops+1
  1070.  
  1071. end
  1072.  
  1073. end
  1074.  
  1075.  
  1076.  
  1077. local saveFile = function(path,info)
  1078.  
  1079. local output = {}
  1080.  
  1081. for a = 1, #info do
  1082.  
  1083. output[a] = clearRedundant(info[a])
  1084.  
  1085. if a % 8 == 0 then yield() end
  1086.  
  1087. end
  1088.  
  1089. local fileout = textutils.serialize(output):gsub(" ",""):gsub("\n",""):gsub(" = ","="):gsub(",}","}")
  1090.  
  1091. if #fileout >= fs.getFreeSpace(fs.getDir(path)) then
  1092.  
  1093. barmsg = "Not enough space."
  1094.  
  1095. return
  1096.  
  1097. end
  1098.  
  1099. local file = fs.open(path,"w")
  1100.  
  1101. file.write(fileout)
  1102.  
  1103. file.close()
  1104.  
  1105. end
  1106.  
  1107. local renderBar = function(msg,dontSetVisible)
  1108.  
  1109. local tsv = term.current().setVisible
  1110.  
  1111. if (doRenderBar == 0) or renderBlittle then return end
  1112.  
  1113. if tsv and (not dontSetVisible) then tsv(false) end
  1114.  
  1115. term.setCursorPos(1,scr_y)
  1116.  
  1117. term.setBackgroundColor(colors.lightGray)
  1118.  
  1119. term.setTextColor(colors.black)
  1120.  
  1121. term.clearLine()
  1122.  
  1123. term.setBackgroundColor(paint.b)
  1124.  
  1125. term.setTextColor(paint.t)
  1126.  
  1127. term.setCursorPos(2,scr_y)
  1128.  
  1129. term.write("PAIN")
  1130.  
  1131. term.setBackgroundColor(colors.lightGray)
  1132.  
  1133. term.setTextColor(colors.black)
  1134.  
  1135. term.setCursorPos(7,scr_y)
  1136.  
  1137. term.write(msg.." Frame: "..frame.."/"..#paintEncoded)
  1138.  
  1139. term.write(" (X:"..paint.scrollX.." Y:"..paint.scrollY..")")
  1140.  
  1141. if tsv and (not dontSetVisible) then tsv(true) end
  1142.  
  1143. end
  1144.  
  1145.  
  1146.  
  1147. local rendback = {
  1148.  
  1149. b = colors.black,
  1150.  
  1151. t = colors.gray,
  1152.  
  1153. }
  1154.  
  1155.  
  1156.  
  1157. local getTablePaint = function(pe)
  1158.  
  1159. local output = {}
  1160.  
  1161. for a = 1, #pe do
  1162.  
  1163. if not output[pe[a].y] then output[pe[a].y] = {} end
  1164.  
  1165. output[pe[a].y][pe[a].x] = pe[a]
  1166.  
  1167. end
  1168.  
  1169. return output
  1170.  
  1171. end
  1172.  
  1173.  
  1174.  
  1175. local renderPainyThings = function(xscroll,yscroll,doGrid)
  1176.  
  1177. if bepimode then
  1178.  
  1179. grid = {
  1180.  
  1181. "Bepis",
  1182.  
  1183. "episB",
  1184.  
  1185. "pisBe",
  1186.  
  1187. "isBep",
  1188.  
  1189. "sBepi",
  1190.  
  1191. }
  1192.  
  1193. else
  1194.  
  1195. grid = {
  1196.  
  1197. "%%..",
  1198.  
  1199. "%%..",
  1200.  
  1201. "%%..",
  1202.  
  1203. "..%%",
  1204.  
  1205. "..%%",
  1206.  
  1207. "..%%",
  1208.  
  1209. }
  1210.  
  1211. end
  1212.  
  1213. term.setBackgroundColor(rendback.b)
  1214.  
  1215. term.setTextColor(rendback.t)
  1216.  
  1217. local badchar = "/"
  1218.  
  1219. local blittlelabel = "blittle max"
  1220.  
  1221. local screenlabel = "screen max"
  1222.  
  1223. if doGrid then
  1224.  
  1225. for y = 1, scr_y-(renderBlittle and 0 or doRenderBar) do
  1226.  
  1227. term.setCursorPos(1,y)
  1228.  
  1229. --the single most convoluted line I've ever written that works, and I love it
  1230.  
  1231. term.write(stringShift(grid[ro(y+(yscroll+2),#grid)+1],xscroll+1):rep(math.ceil(scr_x/#grid[ro(y+(yscroll+2),#grid)+1])):sub(1,scr_x))
  1232.  
  1233. term.setCursorPos(1,y)
  1234.  
  1235. if ((scr_y+1)-yscroll) == y then --regular limit
  1236.  
  1237. term.write( (string.rep("@", ( (scr_x) ) - (#screenlabel+2) ) ..screenlabel:gsub(" ","@"):upper().."@@"):sub(xscroll>0 and xscroll or 0) )
  1238.  
  1239. elseif (((scr_y*3)+1)-yscroll) == y then --blittle limit
  1240.  
  1241. term.write( (string.rep("@", ( ((scr_x*2)) ) - (#blittlelabel+2) )..blittlelabel:gsub(" ","@"):upper().."@@"):sub(xscroll>0 and xscroll or 0) )
  1242.  
  1243. end
  1244.  
  1245. --Stupid easter eggs, ho!--
  1246.  
  1247. if 1000-yscroll == y then
  1248.  
  1249. term.setCursorPos(1000-xscroll,y)
  1250.  
  1251. term.write(" What ARE you doing? Stop messing around! ")
  1252.  
  1253. end
  1254.  
  1255. if 2016-yscroll == y then
  1256.  
  1257. term.setCursorPos(200-xscroll,y)
  1258.  
  1259. term.write(" MOTHER 3 is the best RPG ever. ")
  1260.  
  1261. end
  1262.  
  1263. if 2017-yscroll == y then
  1264.  
  1265. term.setCursorPos(200-xscroll,y)
  1266.  
  1267. term.write(" Wouldn't you agree? ")
  1268.  
  1269. end
  1270.  
  1271. if 800-yscroll == y then
  1272.  
  1273. term.setCursorPos(1700-xscroll,y)
  1274.  
  1275. term.write(" Which would you say is better? ")
  1276.  
  1277. end
  1278.  
  1279. if 801-yscroll == y then
  1280.  
  1281. term.setCursorPos(1700-xscroll,y)
  1282.  
  1283. term.write(" Cave Story or Braid? ")
  1284.  
  1285. end
  1286.  
  1287. if 802-yscroll == y then
  1288.  
  1289. term.setCursorPos(1700-xscroll,y)
  1290.  
  1291. term.write(" It depends what you're looking for. ")
  1292.  
  1293. end
  1294.  
  1295. --Is this the end?--
  1296.  
  1297. if (xscroll > scr_x) and (xscroll < (scr_x*2)+1) then --blittle limit
  1298.  
  1299. for y = 1, scr_y do
  1300.  
  1301. if y+yscroll <= (scr_y*3) then
  1302.  
  1303. if not (y == scr_y and doRenderBar == 1) then
  1304.  
  1305. term.setCursorPos((scr_x+1)-(xscroll-scr_x),y)
  1306.  
  1307. term.write("@")
  1308.  
  1309. end
  1310.  
  1311. end
  1312.  
  1313. end
  1314.  
  1315. elseif (xscroll > 0) then --regular limit
  1316.  
  1317. for y = 1, scr_y do
  1318.  
  1319. if y+yscroll <= scr_y then
  1320.  
  1321. if not (y == scr_y and doRenderBar == 1) then
  1322.  
  1323. term.setCursorPos((scr_x+1)-xscroll,y)
  1324.  
  1325. term.write("@")
  1326.  
  1327. end
  1328.  
  1329. end
  1330.  
  1331. end
  1332.  
  1333. end
  1334.  
  1335. end
  1336.  
  1337. --render areas that won't save
  1338.  
  1339. if xscroll < 0 then
  1340.  
  1341. for y = 1, scr_y do
  1342.  
  1343. if not (y == scr_y and doRenderBar == 1) then
  1344.  
  1345. term.setCursorPos(1,y)
  1346.  
  1347. term.write(badchar:rep(-xscroll))
  1348.  
  1349. end
  1350.  
  1351. end
  1352.  
  1353. end
  1354.  
  1355. if yscroll < 0 then
  1356.  
  1357. for y = 1, -yscroll do
  1358.  
  1359. if not (y == scr_y and doRenderBar == 1) then
  1360.  
  1361. term.setCursorPos(1,y)
  1362.  
  1363. term.write(badchar:rep(scr_x))
  1364.  
  1365. end
  1366.  
  1367. end
  1368.  
  1369. end
  1370.  
  1371. else
  1372.  
  1373. term.clear()
  1374.  
  1375. end
  1376.  
  1377. end
  1378.  
  1379.  
  1380.  
  1381. renderPAIN = function(dots,xscroll,yscroll,doPain)
  1382.  
  1383. local tsv = term.current().setVisible
  1384.  
  1385. if tsv then tsv(false) end
  1386.  
  1387. local beforeTX,beforeBG = term.getTextColor(), term.getBackgroundColor()
  1388.  
  1389. local cx,cy = term.getCursorPos()
  1390.  
  1391. local FUCK, SHIT = pcall(function()
  1392.  
  1393. if doPain then
  1394.  
  1395. renderPainyThings(xscroll,yscroll,evenDrawGrid)
  1396.  
  1397. renderBar(barmsg,true)
  1398.  
  1399. end
  1400.  
  1401. for a = 1, #dots do
  1402.  
  1403. local d = dots[a]
  1404.  
  1405. if doPain then
  1406.  
  1407. if not ((d.y-yscroll >= 1 and d.y-yscroll <= scr_y-(renderBlittle and 0 or (doRenderBar or 0))) and (d.x-xscroll >= 1 and d.x-xscroll <= scr_x)) then
  1408.  
  1409. d = nil
  1410.  
  1411. end
  1412.  
  1413. end
  1414.  
  1415. if d then
  1416.  
  1417. term.setCursorPos(d.x-(xscroll or 0),d.y-(yscroll or 0))
  1418.  
  1419. term.setTextColor((paint.doGray and grayOut(d.t)) or d.t)
  1420.  
  1421. term.setBackgroundColor((paint.doGray and grayOut(d.b)) or d.b)
  1422.  
  1423. term.write(d.c)
  1424.  
  1425. end
  1426.  
  1427. end
  1428.  
  1429. end)
  1430.  
  1431. term.setBackgroundColor(beforeBG)
  1432.  
  1433. term.setTextColor(beforeTX)
  1434.  
  1435. term.setCursorPos(cx,cy)
  1436.  
  1437. if tsv then tsv(true) end
  1438.  
  1439. if not FUCK then error(SHIT) end --GODDAMN IT
  1440.  
  1441. end
  1442.  
  1443.  
  1444.  
  1445. renderPAINFS = function(filename,xscroll,yscroll,frameNo,doPain)
  1446.  
  1447. local tun, tse = textutils.unserialize, textutils.serialize
  1448.  
  1449. local file = fs.open(filename,"r")
  1450.  
  1451. local contents = file.readAll()
  1452.  
  1453. local amntFrames
  1454.  
  1455. file.close()
  1456.  
  1457. local tcontents = tun(contents)
  1458.  
  1459. if type(tcontents) ~= "table" then
  1460.  
  1461. tcontents = importFromNFP(contents)
  1462.  
  1463. else
  1464.  
  1465. amntFrames = #tcontents
  1466.  
  1467. tcontents = tcontents[frameNo or 1]
  1468.  
  1469. end
  1470.  
  1471. renderPAIN(tcontents,xscroll,yscroll,doPain)
  1472.  
  1473. return amntFrames
  1474.  
  1475. end
  1476.  
  1477.  
  1478.  
  1479. local getBlittle = function()
  1480.  
  1481. if not blittle then
  1482.  
  1483. local geet = http.get("http://pastebin.com/raw/ujchRSnU")
  1484.  
  1485. if not geet then
  1486.  
  1487. return false
  1488.  
  1489. else
  1490.  
  1491. geet = geet.readAll()
  1492.  
  1493. local file = fs.open("/.templittle/blittle","w")
  1494.  
  1495. file.write(geet)
  1496.  
  1497. file.close()
  1498.  
  1499. os.loadAPI("/.templittle/blittle")
  1500.  
  1501. fs.delete("/.templittle/")
  1502.  
  1503. if not blittleTerm then
  1504.  
  1505. blittleTerm = blittle.createWindow()
  1506.  
  1507. end
  1508.  
  1509. return blittleTerm, firstTerm
  1510.  
  1511. end
  1512.  
  1513. else
  1514.  
  1515. if not blittleTerm then
  1516.  
  1517. blittleTerm = blittle.createWindow()
  1518.  
  1519. end
  1520.  
  1521. return blittleTerm, firstTerm
  1522.  
  1523. end
  1524.  
  1525. end
  1526.  
  1527.  
  1528.  
  1529. local putDownText = function(x,y)
  1530.  
  1531. term.setCursorPos(x,y)
  1532.  
  1533. term.setTextColor((paint.doGray and grayOut(paint.t)) or paint.t)
  1534.  
  1535. term.setBackgroundColor((paint.doGray and grayOut(paint.b)) or paint.b)
  1536.  
  1537. local msg = read()
  1538.  
  1539. if #msg > 0 then
  1540.  
  1541. for a = 1, #msg do
  1542.  
  1543. table.insert(paintEncoded[frame],{x=a+(x+paint.scrollX)-1,y=y+paint.scrollY,t=paint.t,b=paint.b,c=msg:sub(a,a),m=paint.m})
  1544.  
  1545. end
  1546.  
  1547. end
  1548.  
  1549. end
  1550.  
  1551.  
  1552.  
  1553. local deleteDot = function(x,y)
  1554.  
  1555. local good = false
  1556.  
  1557. for a = #paintEncoded[frame],1,-1 do
  1558.  
  1559. local b = paintEncoded[frame][a]
  1560.  
  1561. if (x == b.x) and (y == b.y) then
  1562.  
  1563. table.remove(paintEncoded[frame],a)
  1564.  
  1565. good = true
  1566.  
  1567. end
  1568.  
  1569. end
  1570.  
  1571. return good
  1572.  
  1573. end
  1574.  
  1575.  
  1576.  
  1577. CTB = function(_color) --Color To Blit
  1578.  
  1579. local blitcolors = {
  1580.  
  1581. [0] = " ",
  1582.  
  1583. [colors.white] = "0",
  1584.  
  1585. [colors.orange] = "1",
  1586.  
  1587. [colors.magenta] = "2",
  1588.  
  1589. [colors.lightBlue] = "3",
  1590.  
  1591. [colors.yellow] = "4",
  1592.  
  1593. [colors.lime] = "5",
  1594.  
  1595. [colors.pink] = "6",
  1596.  
  1597. [colors.gray] = "7",
  1598.  
  1599. [colors.lightGray] = "8",
  1600.  
  1601. [colors.cyan] = "9",
  1602.  
  1603. [colors.purple] = "a",
  1604.  
  1605. [colors.blue] = "b",
  1606.  
  1607. [colors.brown] = "c",
  1608.  
  1609. [colors.green] = "d",
  1610.  
  1611. [colors.red] = "e",
  1612.  
  1613. [colors.black] = "f",
  1614.  
  1615. }
  1616.  
  1617. return blitcolors[_color] or "f"
  1618.  
  1619. end
  1620.  
  1621.  
  1622.  
  1623. BTC = function(_color) --Blit To Color
  1624.  
  1625. local blitcolors = {
  1626.  
  1627. [" "] = 0,
  1628.  
  1629. ["0"] = colors.white,
  1630.  
  1631. ["1"] = colors.orange,
  1632.  
  1633. ["2"] = colors.magenta,
  1634.  
  1635. ["3"] = colors.lightBlue,
  1636.  
  1637. ["4"] = colors.yellow,
  1638.  
  1639. ["5"] = colors.lime,
  1640.  
  1641. ["6"] = colors.pink,
  1642.  
  1643. ["7"] = colors.gray,
  1644.  
  1645. ["8"] = colors.lightGray,
  1646.  
  1647. ["9"] = colors.cyan,
  1648.  
  1649. ["a"] = colors.purple,
  1650.  
  1651. ["b"] = colors.blue,
  1652.  
  1653. ["c"] = colors.brown,
  1654.  
  1655. ["d"] = colors.green,
  1656.  
  1657. ["e"] = colors.red,
  1658.  
  1659. ["f"] = colors.black,
  1660.  
  1661. }
  1662.  
  1663. return blitcolors[_color]
  1664.  
  1665. end
  1666.  
  1667.  
  1668.  
  1669. exportToNFP = function(input)
  1670.  
  1671. local doop = {}
  1672.  
  1673. local p = input
  1674.  
  1675. local pheight = 0
  1676.  
  1677. local pwidth = 0
  1678.  
  1679. for a = 1, #p do
  1680.  
  1681. if p[a].y > pheight then
  1682.  
  1683. pheight = p[a].y
  1684.  
  1685. end
  1686.  
  1687. if p[a].x > pwidth then
  1688.  
  1689. pwidth = p[a].x
  1690.  
  1691. end
  1692.  
  1693. end
  1694.  
  1695. for k,v in pairs(p) do
  1696.  
  1697. if not doop[v.y] then doop[v.y] = {} end
  1698.  
  1699. doop[v.y][v.x] = CTB(v.b)
  1700.  
  1701. end
  1702.  
  1703. for y = 1, pheight do
  1704.  
  1705. if doop[y] then
  1706.  
  1707. for x = 1, pwidth do
  1708.  
  1709. if doop[y][x] then
  1710.  
  1711. nfpoutput = nfpoutput..doop[y][x]
  1712.  
  1713. else
  1714.  
  1715. nfpoutput = nfpoutput.." "
  1716.  
  1717. end
  1718.  
  1719. end
  1720.  
  1721. end
  1722.  
  1723. nfpoutput = nfpoutput.."\n"
  1724.  
  1725. end
  1726.  
  1727. return nfpoutput
  1728.  
  1729. end
  1730.  
  1731.  
  1732.  
  1733. importFromNFP = function(theInput)
  1734.  
  1735. local output = {}
  1736.  
  1737. local input = explode("\n",theInput)
  1738.  
  1739. for a = 1, #input do
  1740.  
  1741. line = input[a]
  1742.  
  1743. for b = 1, #line do
  1744.  
  1745. if (line:sub(b,b) ~= " ") and BTC(line:sub(b,b)) then
  1746.  
  1747. table.insert(output,{
  1748.  
  1749. x = b,
  1750.  
  1751. y = a,
  1752.  
  1753. t = colors.white,
  1754.  
  1755. b = BTC(line:sub(b,b)) or colors.black,
  1756.  
  1757. c = " ",
  1758.  
  1759. })
  1760.  
  1761. end
  1762.  
  1763. end
  1764.  
  1765. end
  1766.  
  1767. return output
  1768.  
  1769. end
  1770.  
  1771.  
  1772.  
  1773. local getTheDoots = function(pe)
  1774.  
  1775. local hasBadDots = false
  1776.  
  1777. local baddestX,baddestY = 1,1
  1778.  
  1779. barmsg = "Checking..."
  1780.  
  1781. for b = 1, #pe do
  1782.  
  1783. local doot = pe[b]
  1784.  
  1785. if doot.x <= 0 or doot.y <= 0 then
  1786.  
  1787. hasBadDots = true
  1788.  
  1789. if doot.x < baddestX then
  1790.  
  1791. baddestX = doot.x
  1792.  
  1793. end
  1794.  
  1795. if doot.y < baddestY then
  1796.  
  1797. baddestY = doot.y
  1798.  
  1799. end
  1800.  
  1801. end
  1802.  
  1803. if b % 64 == 0 then yield() end
  1804.  
  1805. end
  1806.  
  1807. return baddestX, baddestY
  1808.  
  1809. end
  1810.  
  1811.  
  1812.  
  1813. local function deepcompare(t1,t2,ignore_mt)
  1814.  
  1815. local ty1 = type(t1)
  1816.  
  1817. local ty2 = type(t2)
  1818.  
  1819. if ty1 ~= ty2 then return false end
  1820.  
  1821. -- non-table types can be directly compared
  1822.  
  1823. if ty1 ~= 'table' and ty2 ~= 'table' then return t1 == t2 end
  1824.  
  1825. -- as well as tables which have the metamethod __eq
  1826.  
  1827. local mt = getmetatable(t1)
  1828.  
  1829. if not ignore_mt and mt and mt.__eq then return t1 == t2 end
  1830.  
  1831. for k1,v1 in pairs(t1) do
  1832.  
  1833. local v2 = t2[k1]
  1834.  
  1835. if v2 == nil or not deepcompare(v1,v2) then return false end
  1836.  
  1837. end
  1838.  
  1839. for k2,v2 in pairs(t2) do
  1840.  
  1841. local v1 = t1[k2]
  1842.  
  1843. if v1 == nil or not deepcompare(v1,v2) then return false end
  1844.  
  1845. end
  1846.  
  1847. return true
  1848.  
  1849. end
  1850.  
  1851.  
  1852.  
  1853. local displayMenu = function()
  1854.  
  1855. menuOptions = {"Save","Export","Del.frame","Clear","Exit"}
  1856.  
  1857. local diss = " "..table.concat(menuOptions," ")
  1858.  
  1859. local cleary = scr_y-math.floor(#diss/scr_x)
  1860.  
  1861. for a = cleary,scr_y do
  1862.  
  1863. term.setCursorPos(1,a)
  1864.  
  1865. term.setBackgroundColor(colors.lightGray)
  1866.  
  1867. term.clearLine()
  1868.  
  1869. end
  1870.  
  1871. local menuPoses = {}
  1872.  
  1873. local menuFunctions = {
  1874.  
  1875. [1] = function() --Save
  1876.  
  1877. local hasBadDots = false
  1878.  
  1879. for a = 1, #paintEncoded do
  1880.  
  1881. local radx,rady = getTheDoots(paintEncoded[a])
  1882.  
  1883. if radx ~= 1 or rady ~= 1 then
  1884.  
  1885. hasBadDots = true
  1886.  
  1887. end
  1888.  
  1889. end
  1890.  
  1891. if hasBadDots then
  1892.  
  1893. local ting = bottomPrompt("Dot(s) are OoB! Save or fix? (Y/N/F)",_,"ynf",{keys.leftCtrl,keys.rightCtrl})
  1894.  
  1895. if ting == "f" then
  1896.  
  1897. for a = 1, #paintEncoded do
  1898.  
  1899. local baddestX, baddestY = getTheDoots(paintEncoded[a])
  1900.  
  1901. paintEncoded[a] = movePaintEncoded(paintEncoded[a],-(baddestX-1),-(baddestY-1))
  1902.  
  1903. end
  1904.  
  1905. elseif ting ~= "y" then
  1906.  
  1907. barmsg = ""
  1908.  
  1909. return false
  1910.  
  1911. end
  1912.  
  1913. end
  1914.  
  1915. local output = deepCopy(paintEncoded)
  1916.  
  1917. if paint.doGray then
  1918.  
  1919. for a = 1, #paintEncoded do
  1920.  
  1921. for b = 1, #paintEncoded[a] do
  1922.  
  1923. output[a][b].b = grayOut(paintEncoded[a][b].b)
  1924.  
  1925. output[a][b].t = grayOut(paintEncoded[a][b].t)
  1926.  
  1927. if not output[a][b].m then output[a][b].m = 1 end
  1928.  
  1929. end
  1930.  
  1931. if a % 2 == 0 then yield() end
  1932.  
  1933. end
  1934.  
  1935. end
  1936.  
  1937. saveFile(fileName,output)
  1938.  
  1939. lastPaintEncoded = deepCopy(paintEncoded)
  1940.  
  1941. term.setCursorPos(9,scr_y)
  1942.  
  1943. barmsg = "Saved as '"..fileName.."'"
  1944.  
  1945. doRender = true
  1946.  
  1947. end,
  1948.  
  1949. [2] = function() --Export
  1950.  
  1951. nfpoutput = ""
  1952.  
  1953. local exportName = bottomPrompt("Export to: /")
  1954.  
  1955. if fs.combine("",exportName) == "" then return end
  1956.  
  1957. if fs.isReadOnly(exportName) then
  1958.  
  1959. barmsg = "That's read-only."
  1960.  
  1961. doRender = true
  1962.  
  1963. return
  1964.  
  1965. end
  1966.  
  1967. if fs.exists(exportName) then
  1968.  
  1969. if bottomPrompt("Overwrite? (Y/N)",_,"yn",{keys.leftCtrl,keys.rightCtrl}) ~= "y" then return end
  1970.  
  1971. end
  1972.  
  1973. local output = exportToNFP(paintEncoded[frame])
  1974.  
  1975. if keysDown[207] then --secretly convert into what paintutils.loadImage() would return!
  1976.  
  1977. local bepis = explode("\n",output)
  1978.  
  1979. output = {}
  1980.  
  1981. for y = 1, #bepis do
  1982.  
  1983. output[y] = {}
  1984.  
  1985. for x = 1, #bepis[y] do
  1986.  
  1987. output[y][x] = BTC(bepis[y]:sub(x,x))
  1988.  
  1989. end
  1990.  
  1991. end
  1992.  
  1993. output = textutils.serialize(output):gsub("\n",""):gsub(" ",""):gsub(",}","}")
  1994.  
  1995. end
  1996.  
  1997. local file = fs.open(exportName,"w")
  1998.  
  1999. file.write(output)
  2000.  
  2001. file.close()
  2002.  
  2003. doRender = true
  2004.  
  2005. barmsg = "Exported as '"..exportName.."'"
  2006.  
  2007. return
  2008.  
  2009. end,
  2010.  
  2011. [3] = function() --Del.Frame
  2012.  
  2013. local outcum = bottomPrompt("Thou art sure? (Y/N)",_,"yn",{keys.leftCtrl,keys.rightCtrl})
  2014.  
  2015. if outcum == "y" then
  2016.  
  2017. if #paintEncoded == 1 then
  2018.  
  2019. barmsg = "Ha! You can't do that."
  2020.  
  2021. return
  2022.  
  2023. end
  2024.  
  2025. table.remove(paintEncoded,frame)
  2026.  
  2027. barmsg = "Deleted frame "..frame.."."
  2028.  
  2029. if paintEncoded[frame-1] then
  2030.  
  2031. frame = frame - 1
  2032.  
  2033. else
  2034.  
  2035. frame = frame + 1
  2036.  
  2037. end
  2038.  
  2039. if #paintEncoded < frame then
  2040.  
  2041. repeat
  2042.  
  2043. frame = frame - 1
  2044.  
  2045. until #paintEncoded >= frame
  2046.  
  2047. end
  2048.  
  2049. --renderPAIN(paintEncoded[frame],paint.scrollX,paint.scrollY,true)
  2050.  
  2051. end
  2052.  
  2053. doRender = true
  2054.  
  2055. end,
  2056.  
  2057. [4] = function() --Clear
  2058.  
  2059. local outcum = bottomPrompt("Clear the frame? (Y/N)",_,"yn",{keys.leftCtrl,keys.rightCtrl})
  2060.  
  2061. if outcum == "y" then
  2062.  
  2063. paintEncoded[frame] = {}
  2064.  
  2065. barmsg = "Cleared frame "..frame.."."
  2066.  
  2067. --renderPAIN(paintEncoded[frame],paint.scrollX,paint.scrollY,true)
  2068.  
  2069. end
  2070.  
  2071. doRender = true
  2072.  
  2073. end,
  2074.  
  2075. [5] = function() --Exit
  2076.  
  2077. if not deepcompare(lastPaintEncoded,paintEncoded) then
  2078.  
  2079. local outcum = bottomPrompt("Abandon unsaved work? (Y/N)",_,"yn",{keys.leftCtrl,keys.rightCtrl})
  2080.  
  2081. sleep(0)
  2082.  
  2083. if outcum == "y" then
  2084.  
  2085. return "exit"
  2086.  
  2087. else
  2088.  
  2089. doRender = true
  2090.  
  2091. return nil
  2092.  
  2093. end
  2094.  
  2095. else
  2096.  
  2097. return "exit"
  2098.  
  2099. end
  2100.  
  2101. end,
  2102.  
  2103. }
  2104.  
  2105. local cursor = 1
  2106.  
  2107. local redrawmenu = true
  2108.  
  2109. local initial = os.time()
  2110.  
  2111. local clickdelay = 0.003
  2112.  
  2113. while true do
  2114.  
  2115. if redrawmenu then
  2116.  
  2117. term.setCursorPos(2,cleary)
  2118.  
  2119. term.clearLine()
  2120.  
  2121. for a = 1, #menuOptions do
  2122.  
  2123. if a == cursor then
  2124.  
  2125. term.setTextColor(colors.black)
  2126.  
  2127. term.setBackgroundColor(colors.white)
  2128.  
  2129. else
  2130.  
  2131. term.setTextColor(colors.black)
  2132.  
  2133. term.setBackgroundColor(colors.lightGray)
  2134.  
  2135. end
  2136.  
  2137. menuPoses[a] = {term.getCursorPos()}
  2138.  
  2139. write(menuOptions[a])
  2140.  
  2141. term.setBackgroundColor(colors.lightGray)
  2142.  
  2143. if a ~= #menuOptions then
  2144.  
  2145. write(" ")
  2146.  
  2147. end
  2148.  
  2149. end
  2150.  
  2151. redrawmenu = false
  2152.  
  2153. end
  2154.  
  2155. local event,key,x,y = getEvents("key","char","mouse_click","mouse_up","mouse_drag")
  2156.  
  2157. if event == "key" then
  2158.  
  2159. if key == keys.left then
  2160.  
  2161. redrawmenu = true
  2162.  
  2163. cursor = cursor - 1
  2164.  
  2165. elseif key == keys.right then
  2166.  
  2167. redrawmenu = true
  2168.  
  2169. cursor = cursor + 1
  2170.  
  2171. elseif key == keys.enter then
  2172.  
  2173. local res = menuFunctions[cursor]()
  2174.  
  2175. if res == "exit" then
  2176.  
  2177. return "exit"
  2178.  
  2179. else
  2180.  
  2181. return
  2182.  
  2183. end
  2184.  
  2185. elseif key == keys.leftCtrl or key == keys.rightCtrl then
  2186.  
  2187. doRender = true
  2188.  
  2189. return
  2190.  
  2191. end
  2192.  
  2193. elseif event == "char" then
  2194.  
  2195. for a = 1, #menuOptions do
  2196.  
  2197. if key:lower() == menuOptions[a]:sub(1,1):lower() and a ~= cursor then
  2198.  
  2199. cursor = a
  2200.  
  2201. redrawmenu = true
  2202.  
  2203. break
  2204.  
  2205. end
  2206.  
  2207. end
  2208.  
  2209. elseif event == "mouse_click" or event == "mouse_up" then
  2210.  
  2211. if y < cleary then
  2212.  
  2213. return
  2214.  
  2215. elseif key == 1 and initial+clickdelay < os.time() then --key? more like button
  2216.  
  2217. for a = 1, #menuPoses do
  2218.  
  2219. if y == menuPoses[a][2] then
  2220.  
  2221. if x >= menuPoses[a][1] and x <= menuPoses[a][1]+#menuOptions[a] then
  2222.  
  2223. local res = menuFunctions[a]()
  2224.  
  2225. if res == "exit" then
  2226.  
  2227. return "exit"
  2228.  
  2229. else
  2230.  
  2231. return
  2232.  
  2233. end
  2234.  
  2235. end
  2236.  
  2237. end
  2238.  
  2239. end
  2240.  
  2241. end
  2242.  
  2243. --elseif event == "mouse_drag" then
  2244.  
  2245. end
  2246.  
  2247. if (initial+clickdelay < os.time()) and string.find(event,"mouse") then
  2248.  
  2249. if key == 1 then --key? key? what key? all I see is button!
  2250.  
  2251. for a = 1, #menuPoses do
  2252.  
  2253. if y == menuPoses[a][2] then
  2254.  
  2255. if x >= menuPoses[a][1] and x <= menuPoses[a][1]+#menuOptions[a] then
  2256.  
  2257. cursor = a
  2258.  
  2259. redrawmenu = true
  2260.  
  2261. break
  2262.  
  2263. end
  2264.  
  2265. end
  2266.  
  2267. end
  2268.  
  2269. end
  2270.  
  2271. end
  2272.  
  2273. if cursor < 1 then
  2274.  
  2275. cursor = #menuOptions
  2276.  
  2277. elseif cursor > #menuOptions then
  2278.  
  2279. cursor = 1
  2280.  
  2281. end
  2282.  
  2283. end
  2284.  
  2285. end
  2286.  
  2287.  
  2288.  
  2289. local lastMX,lastMY
  2290.  
  2291.  
  2292.  
  2293. local doNonEventDrivenMovement = function() --what a STUPID function name, man
  2294.  
  2295. local didMove
  2296.  
  2297. while true do
  2298.  
  2299. didMove = false
  2300.  
  2301. if (not keysDown[keys.leftShift]) and (not isDragging) and (not keysDown[keys.tab]) then
  2302.  
  2303. if keysDown[keys.right] then
  2304.  
  2305. paint.scrollX = paint.scrollX + 1
  2306.  
  2307. didMove = true
  2308.  
  2309. elseif keysDown[keys.left] then
  2310.  
  2311. paint.scrollX = paint.scrollX - 1
  2312.  
  2313. didMove = true
  2314.  
  2315. end
  2316.  
  2317. if keysDown[keys.down] then
  2318.  
  2319. paint.scrollY = paint.scrollY + 1
  2320.  
  2321. didMove = true
  2322.  
  2323. elseif keysDown[keys.up] then
  2324.  
  2325. paint.scrollY = paint.scrollY - 1
  2326.  
  2327. didMove = true
  2328.  
  2329. end
  2330.  
  2331. if didMove then
  2332.  
  2333. if lastMX and lastMY then
  2334.  
  2335. if miceDown[1] then
  2336.  
  2337. os.queueEvent("mouse_click",1,lastMX,lastMY)
  2338.  
  2339. end
  2340.  
  2341. if miceDown[2] then
  2342.  
  2343. os.queueEvent("mouse_click",2,lastMX,lastMY)
  2344.  
  2345. end
  2346.  
  2347. end
  2348.  
  2349. doRender = true
  2350.  
  2351. end
  2352.  
  2353. end
  2354.  
  2355. sleep(0)
  2356.  
  2357. end
  2358.  
  2359. end
  2360.  
  2361.  
  2362.  
  2363. local linePoses = {}
  2364.  
  2365. local dragPoses = {}
  2366.  
  2367.  
  2368.  
  2369. local getInput = function() --gotta catch them all
  2370.  
  2371. local button, x, y, oldmx, oldmy, origx, origy
  2372.  
  2373. local isDragging = false
  2374.  
  2375. local proceed = false
  2376.  
  2377. renderBar(barmsg)
  2378.  
  2379. while true do
  2380.  
  2381. doRender = false
  2382.  
  2383. local oldx,oldy = paint.scrollX,paint.scrollY
  2384.  
  2385. local evt = {getEvents("mouse_scroll","mouse_click", "mouse_drag","mouse_up","key","key_up",true)}
  2386.  
  2387. if (evt[1] == "mouse_scroll") and (not viewing) then
  2388.  
  2389. local dir = evt[2]
  2390.  
  2391. if dir == 1 then
  2392.  
  2393. if keysDown[keys.leftShift] or keysDown[keys.rightShift] then
  2394.  
  2395. paint.t = paint.t * 2
  2396.  
  2397. if paint.t > 32768 then
  2398.  
  2399. paint.t = 32768
  2400.  
  2401. end
  2402.  
  2403. else
  2404.  
  2405. paint.b = paint.b * 2
  2406.  
  2407. if paint.b > 32768 then
  2408.  
  2409. paint.b = 32768
  2410.  
  2411. end
  2412.  
  2413. end
  2414.  
  2415. else
  2416.  
  2417. if keysDown[keys.leftShift] or keysDown[keys.rightShift] then
  2418.  
  2419. paint.t = math.ceil(paint.t / 2)
  2420.  
  2421. if paint.t < 1 then
  2422.  
  2423. paint.t = 1
  2424.  
  2425. end
  2426.  
  2427. else
  2428.  
  2429. paint.b = math.ceil(paint.b / 2)
  2430.  
  2431. if paint.b < 1 then
  2432.  
  2433. paint.b = 1
  2434.  
  2435. end
  2436.  
  2437. end
  2438.  
  2439. end
  2440.  
  2441. renderBar(barmsg)
  2442.  
  2443. elseif ((evt[1] == "mouse_click") or (evt[1] == "mouse_drag")) and (not viewing) then
  2444.  
  2445. if evt[1] == "mouse_click" then
  2446.  
  2447. origx, origy = evt[3], evt[4]
  2448.  
  2449. end
  2450.  
  2451. oldmx,oldmy = x or evt[3], y or evt[4]
  2452.  
  2453. lastMX,lastMY = evt[3],evt[4]
  2454.  
  2455. button,x,y = evt[2],evt[3],evt[4]
  2456.  
  2457. if renderBlittle then
  2458.  
  2459. x = 2*x
  2460.  
  2461. y = 3*y
  2462.  
  2463. lastMX = 2*lastMX
  2464.  
  2465. lastMY = 3*lastMY
  2466.  
  2467. end
  2468.  
  2469. linePoses = {{x=oldmx,y=oldmy},{x=x,y=y}}
  2470.  
  2471. miceDown[button] = true
  2472.  
  2473. doRender = true
  2474.  
  2475. if y <= scr_y-(renderBlittle and 0 or doRenderBar) then
  2476.  
  2477. if (button == 3) then
  2478.  
  2479. putDownText(x,y)
  2480.  
  2481. miceDown = {}
  2482.  
  2483. keysDown = {}
  2484.  
  2485. elseif button == 1 then
  2486.  
  2487. if keysDown[keys.leftShift] and evt[1] == "mouse_click" then
  2488.  
  2489. isDragging = true
  2490.  
  2491. end
  2492.  
  2493. if isDragging then
  2494.  
  2495. if evt[1] == "mouse_click" then
  2496.  
  2497. dragPoses[1] = {x=x,y=y}
  2498.  
  2499. end
  2500.  
  2501. dragPoses[2] = {x=x,y=y}
  2502.  
  2503. else
  2504.  
  2505. if evt[1] == "mouse_drag" then
  2506.  
  2507. local points = getDotsInLine(linePoses[1].x,linePoses[1].y,linePoses[2].x,linePoses[2].y)
  2508.  
  2509. for a = 1, #points do
  2510.  
  2511. table.insert(paintEncoded[frame],{
  2512.  
  2513. x = points[a].x + paint.scrollX,
  2514.  
  2515. y = points[a].y + paint.scrollY,
  2516.  
  2517. c = paint.c,
  2518.  
  2519. b = paint.b,
  2520.  
  2521. t = paint.t,
  2522.  
  2523. m = paint.m,
  2524.  
  2525. })
  2526.  
  2527. end
  2528.  
  2529. else
  2530.  
  2531. table.insert(paintEncoded[frame],{
  2532.  
  2533. x = x + paint.scrollX,
  2534.  
  2535. y = y + paint.scrollY,
  2536.  
  2537. c = paint.c,
  2538.  
  2539. b = paint.b,
  2540.  
  2541. t = paint.t,
  2542.  
  2543. m = paint.m,
  2544.  
  2545. })
  2546.  
  2547. end
  2548.  
  2549. end
  2550.  
  2551. elseif button == 2 and y <= scr_y-(renderBlittle and 0 or doRenderBar) then
  2552.  
  2553. deleteDot(x+paint.scrollX,y+paint.scrollY)
  2554.  
  2555. end
  2556.  
  2557. elseif origy >= scr_y-(renderBlittle and 0 or doRenderBar) then
  2558.  
  2559. keysDown = {}
  2560.  
  2561. local res = displayMenu()
  2562.  
  2563. if res == "exit" then break end
  2564.  
  2565. doRender = true
  2566.  
  2567. end
  2568.  
  2569. elseif (evt[1] == "mouse_up") and (not viewing) then
  2570.  
  2571. origx,origy = 0,0
  2572.  
  2573. local button = evt[2]
  2574.  
  2575. miceDown[button] = false
  2576.  
  2577. oldmx,oldmy = nil,nil
  2578.  
  2579. lastMX, lastMY = nil,nil
  2580.  
  2581. if isDragging then
  2582.  
  2583. local points = getDotsInLine(dragPoses[1].x,dragPoses[1].y,dragPoses[2].x,dragPoses[2].y)
  2584.  
  2585. for a = 1, #points do
  2586.  
  2587. table.insert(paintEncoded[frame],{
  2588.  
  2589. x = points[a].x + paint.scrollX,
  2590.  
  2591. y = points[a].y + paint.scrollY,
  2592.  
  2593. c = paint.c,
  2594.  
  2595. b = paint.b,
  2596.  
  2597. t = paint.t,
  2598.  
  2599. m = paint.m,
  2600.  
  2601. })
  2602.  
  2603. end
  2604.  
  2605. doRender = true
  2606.  
  2607. end
  2608.  
  2609. isDragging = false
  2610.  
  2611. elseif evt[1] == "key" then
  2612.  
  2613. local key = evt[2]
  2614.  
  2615. if (not keysDown[keys.leftShift]) and (keysDown[keys.tab]) then
  2616.  
  2617. if key == keys.right and (not keysDown[keys.right]) then
  2618.  
  2619. paint.scrollX = paint.scrollX + 1
  2620.  
  2621. doRender = true
  2622.  
  2623. elseif key == keys.left and (not keysDown[keys.left]) then
  2624.  
  2625. paint.scrollX = paint.scrollX - 1
  2626.  
  2627. doRender = true
  2628.  
  2629. end
  2630.  
  2631. if key == keys.down and (not keysDown[keys.down]) then
  2632.  
  2633. paint.scrollY = paint.scrollY + 1
  2634.  
  2635. doRender = true
  2636.  
  2637. elseif key == keys.up and (not keysDown[keys.up]) then
  2638.  
  2639. paint.scrollY = paint.scrollY - 1
  2640.  
  2641. doRender = true
  2642.  
  2643. end
  2644.  
  2645. end
  2646.  
  2647. keysDown[key] = true
  2648.  
  2649. if key == keys.space then
  2650.  
  2651. if keysDown[keys.leftShift] then
  2652.  
  2653. evenDrawGrid = not evenDrawGrid
  2654.  
  2655. else
  2656.  
  2657. doRenderBar = math.abs(doRenderBar-1)
  2658.  
  2659. end
  2660.  
  2661. doRender = true
  2662.  
  2663. end
  2664.  
  2665. if key == keys.b then
  2666.  
  2667. local blTerm, oldTerm = getBlittle()
  2668.  
  2669. renderBlittle = not renderBlittle
  2670.  
  2671. term.setBackgroundColor(colors.black)
  2672.  
  2673. term.clear()
  2674.  
  2675. if renderBlittle then
  2676.  
  2677. term.redirect(blTerm)
  2678.  
  2679. blTerm.setVisible(true)
  2680.  
  2681. else
  2682.  
  2683. term.redirect(oldTerm)
  2684.  
  2685. blTerm.setVisible(false)
  2686.  
  2687. end
  2688.  
  2689. doRender = true
  2690.  
  2691. scr_x, scr_y = term.current().getSize()
  2692.  
  2693. end
  2694.  
  2695. if (key == keys.c) and (not renderBlittle) then
  2696.  
  2697. local newX = tonumber(bottomPrompt("Goto X:"))
  2698.  
  2699. local newY
  2700.  
  2701. if newX then
  2702.  
  2703. newY = tonumber(bottomPrompt("Goto Y:"))
  2704.  
  2705. paint.scrollX = newX or paint.scrollX
  2706.  
  2707. paint.scrollY = newY or paint.scrollY
  2708.  
  2709. end
  2710.  
  2711. doRender = true
  2712.  
  2713. end
  2714.  
  2715. if (keysDown[keys.leftShift]) and (not isDragging) then
  2716.  
  2717. if key == keys.left then
  2718.  
  2719. paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],-1,0)
  2720.  
  2721. doRender = true
  2722.  
  2723. elseif key == keys.right then
  2724.  
  2725. paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],1,0)
  2726.  
  2727. doRender = true
  2728.  
  2729. elseif key == keys.up then
  2730.  
  2731. paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],0,-1)
  2732.  
  2733. doRender = true
  2734.  
  2735. elseif key == keys.down then
  2736.  
  2737. paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],0,1)
  2738.  
  2739. doRender = true
  2740.  
  2741. end
  2742.  
  2743. end
  2744.  
  2745. if keysDown[keys.leftAlt] then
  2746.  
  2747. if #paintEncoded > 1 then
  2748.  
  2749. if key == keys.equals and paintEncoded[frame+1] then --basically plus
  2750.  
  2751. local first = deepCopy(paintEncoded[frame])
  2752.  
  2753. local next = deepCopy(paintEncoded[frame+1])
  2754.  
  2755. paintEncoded[frame] = next
  2756.  
  2757. paintEncoded[frame+1] = first
  2758.  
  2759. frame = frame + 1
  2760.  
  2761. barmsg = "Swapped prev frame."
  2762.  
  2763. end
  2764.  
  2765. if key == keys.minus and paintEncoded[frame-1] then
  2766.  
  2767. local first = deepCopy(paintEncoded[frame])
  2768.  
  2769. local next = deepCopy(paintEncoded[frame-1])
  2770.  
  2771. paintEncoded[frame] = next
  2772.  
  2773. paintEncoded[frame-1] = first
  2774.  
  2775. frame = frame - 1
  2776.  
  2777. barmsg = "Swapped next frame."
  2778.  
  2779. end
  2780.  
  2781. end
  2782.  
  2783. end
  2784.  
  2785. if not renderBlittle then
  2786.  
  2787. if key == keys.m then
  2788.  
  2789. local incum = bottomPrompt("Set meta: ",metaHistory)
  2790.  
  2791. paint.m = incum:gsub(" ","") ~= "" and incum or paint.m
  2792.  
  2793. if paint.m ~= metaHistory[#metaHistory] then
  2794.  
  2795. table.insert(metaHistory,paint.m)
  2796.  
  2797. end
  2798.  
  2799. doRender = true
  2800.  
  2801. end
  2802.  
  2803. if key == keys.f7 then
  2804.  
  2805. bepimode = not bepimode
  2806.  
  2807. doRender = true
  2808.  
  2809. end
  2810.  
  2811. if key == keys.t then
  2812.  
  2813. renderBottomBar("Click to place text.")
  2814.  
  2815. local mevt
  2816.  
  2817. repeat
  2818.  
  2819. mevt = {os.pullEvent("mouse_click")}
  2820.  
  2821. until mevt[2] == 1 and mevt[4] < scr_y-(renderBlittle and 0 or doRenderBar)
  2822.  
  2823. local x,y = mevt[3],mevt[4]
  2824.  
  2825. if renderBlittle then
  2826.  
  2827. x = 2*x
  2828.  
  2829. y = 3*y
  2830.  
  2831. end
  2832.  
  2833. putDownText(x,y)
  2834.  
  2835. miceDown = {}
  2836.  
  2837. keysDown = {}
  2838.  
  2839. end
  2840.  
  2841. if not keysDown[keys.leftAlt] then
  2842.  
  2843. if key == keys.equals then --basically 'plus'
  2844.  
  2845. if not paintEncoded[frame+1] then
  2846.  
  2847. paintEncoded[frame+1] = {}
  2848.  
  2849. local sheet = paintEncoded[frame]
  2850.  
  2851. if keysDown[keys.leftShift] then
  2852.  
  2853. paintEncoded[frame+1] = deepCopy(sheet)
  2854.  
  2855. end
  2856.  
  2857. end
  2858.  
  2859. frame = frame + 1
  2860.  
  2861. doRender = true
  2862.  
  2863. elseif key == keys.minus then
  2864.  
  2865. if frame > 1 then
  2866.  
  2867. frame = frame - 1
  2868.  
  2869. doRender = true
  2870.  
  2871. end
  2872.  
  2873. end
  2874.  
  2875. end
  2876.  
  2877. if (key == keys.leftCtrl or key == keys.rightCtrl) then
  2878.  
  2879. keysDown = {[207] = keysDown[207]}
  2880.  
  2881. local res = displayMenu()
  2882.  
  2883. if res == "exit" then break end
  2884.  
  2885. doRender = true
  2886.  
  2887. end
  2888.  
  2889. end
  2890.  
  2891. if (key == keys.f and keysDown[keys.leftShift]) then
  2892.  
  2893. local deredots = {}
  2894.  
  2895. for a = 1, #paintEncoded[frame] do
  2896.  
  2897. local dot = paintEncoded[frame][a]
  2898.  
  2899. if dot.x-paint.scrollX > 0 and dot.x-paint.scrollX <= scr_x then
  2900.  
  2901. if dot.y-paint.scrollY > 0 and dot.y-paint.scrollY <= scr_y then
  2902.  
  2903. table.insert(deredots,{dot.x-paint.scrollX, dot.y-paint.scrollY})
  2904.  
  2905. end
  2906.  
  2907. end
  2908.  
  2909. end
  2910.  
  2911. for y = 1, scr_y-(renderBlittle and 0 or doRenderBar) do
  2912.  
  2913. for x = 1, scr_x do
  2914.  
  2915. local good = true
  2916.  
  2917. for a = 1, #deredots do
  2918.  
  2919. if (deredots[a][1] == x) and (deredots[a][2] == y) then
  2920.  
  2921. good = bad
  2922.  
  2923. break
  2924.  
  2925. end
  2926.  
  2927. end
  2928.  
  2929. if good then
  2930.  
  2931. table.insert(paintEncoded[frame],{
  2932.  
  2933. x = x+paint.scrollX,
  2934.  
  2935. y = y+paint.scrollY,
  2936.  
  2937. c = " ",
  2938.  
  2939. t = paint.t,
  2940.  
  2941. b = paint.b,
  2942.  
  2943. m = paint.m,
  2944.  
  2945. })
  2946.  
  2947. end
  2948.  
  2949. end
  2950.  
  2951. end
  2952.  
  2953. doRender = true
  2954.  
  2955. end
  2956.  
  2957. if key == keys.g then
  2958.  
  2959. paint.doGray = not paint.doGray
  2960.  
  2961. doRender = true
  2962.  
  2963. end
  2964.  
  2965. if key == keys.a then
  2966.  
  2967. paint.scrollX = 0
  2968.  
  2969. paint.scrollY = 0
  2970.  
  2971. doRender = true
  2972.  
  2973. end
  2974.  
  2975. if key == keys.f1 then
  2976.  
  2977. guiHelp()
  2978.  
  2979. end
  2980.  
  2981. if key == keys.leftBracket then
  2982.  
  2983. os.queueEvent("mouse_scroll",2,1,1)
  2984.  
  2985. elseif key == keys.rightBracket then
  2986.  
  2987. os.queueEvent("mouse_scroll",1,1,1)
  2988.  
  2989. end
  2990.  
  2991. elseif evt[1] == "key_up" then
  2992.  
  2993. local key = evt[2]
  2994.  
  2995. keysDown[key] = false
  2996.  
  2997. end
  2998.  
  2999. if (oldx~=paint.scrollX) or (oldy~=paint.scrollY) then
  3000.  
  3001. doRender = true
  3002.  
  3003. end
  3004.  
  3005. if doRender then
  3006.  
  3007. renderPAIN(paintEncoded[frame],paint.scrollX,paint.scrollY,true)
  3008.  
  3009. doRender = false
  3010.  
  3011. end
  3012.  
  3013. end
  3014.  
  3015. end
  3016.  
  3017.  
  3018.  
  3019. if not shell then return end
  3020.  
  3021.  
  3022.  
  3023. fileName = shell.resolve(tostring(tArg[1]))
  3024.  
  3025.  
  3026.  
  3027. if not fs.exists(fileName) then
  3028.  
  3029. paintEncoded = {{}}
  3030.  
  3031. else
  3032.  
  3033. local file = fs.open(fileName,"r")
  3034.  
  3035. local contents = file.readAll()
  3036.  
  3037. file.close()
  3038.  
  3039. if type(tun(contents)) ~= "table" then
  3040.  
  3041. if pMode ~= 1 then print("Importing from NFP...") end
  3042.  
  3043. paintEncoded = {importFromNFP(contents)}
  3044.  
  3045. if fileName:sub(-4,-1) == ".nfp" then
  3046.  
  3047. fileName = fileName:sub(1,-5)
  3048.  
  3049. end
  3050.  
  3051. else
  3052.  
  3053. paintEncoded = tun(contents)
  3054.  
  3055. end
  3056.  
  3057. end
  3058.  
  3059.  
  3060.  
  3061. paintEncoded = tun(tse(paintEncoded):gsub("bg","b"):gsub("txt","t"):gsub("char","c"):gsub("meta","m")) -- gotta have backwards compatibility, sorta
  3062.  
  3063.  
  3064.  
  3065. if not paintEncoded[frame] then paintEncoded = {paintEncoded} end
  3066.  
  3067. if pMode == 1 then
  3068.  
  3069. doRenderBar = 0
  3070.  
  3071. renderPAIN(paintEncoded[tonumber(tArg[5]) or 1],tonumber(tArg[3]) or 0,tonumber(tArg[4]) or 0)
  3072.  
  3073. sleep(0)
  3074.  
  3075. return
  3076.  
  3077. else
  3078.  
  3079. renderPAIN(paintEncoded[frame],paint.scrollX,paint.scrollY,true)
  3080.  
  3081. end
  3082.  
  3083. lastPaintEncoded = deepCopy(paintEncoded)
  3084.  
  3085.  
  3086.  
  3087. parallel.waitForAny(getInput,doNonEventDrivenMovement)
  3088.  
  3089.  
  3090.  
  3091. term.setCursorPos(1,scr_y)
  3092.  
  3093. term.setBackgroundColor(colors.black)
  3094.  
  3095. term.clearLine()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement