Advertisement
LDDestroier

Project </BETA> Sign (PROGDOR)

Feb 12th, 2017
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. false
  2. {
  3.   [ "/c" ] = {
  4.     "",
  5.     "",
  6.     "",
  7.     "",
  8.     "",
  9.     "",
  10.     "",
  11.     "",
  12.     "",
  13.     "",
  14.     "",
  15.     "",
  16.     "",
  17.     "",
  18.     "",
  19.     "",
  20.     "",
  21.     "       ddddd55555     ",
  22.     "    5555ddddd555555   ",
  23.     "  55555555dddd555555  ",
  24.     " 55555555555dddd55555 ",
  25.     "5555555       ddd55555",
  26.     "55555           dd5555",
  27.     "d555              555 ",
  28.     "5ddd                  ",
  29.     "d555                  ",
  30.     "dddd                  ",
  31.     "ddddd                 ",
  32.     " ddddd           5555 ",
  33.     " ddddddd        ddd555",
  34.     "  dddddddddddd55555ddd",
  35.     "   dddddddddddddddd55 ",
  36.     "     dddddddddddddd   ",
  37.     "         dddddd       ",
  38.     "",
  39.   },
  40.   [ "/test" ] = {
  41.     "local mon = peripheral.find(\"monitor\")",
  42.     "term.redirect(mon)",
  43.     "os.loadAPI(\"pain\")",
  44.     "shell.run(\"render\")",
  45.     "term.setBackgroundColor(colors.black)",
  46.     "term.clear()",
  47.     "local space = 2",
  48.     "local dif = 1",
  49.     "function ion(txt)",
  50.     "  term.native().setCursorPos(1,2)",
  51.     "  term.native().write(txt..\"  \")",
  52.     "end",
  53.     "pain.renderPAINFS(\"BETA\",2,35)",
  54.     "while true do",
  55.     "  render(1,space)",
  56.     "  if (space >= 5) or (space <= 1) then",
  57.     "    dif = dif*-1",
  58.     "  end",
  59.     "  space = space + dif",
  60.     "  ion(space..\"/\"..dif)",
  61.     "  sleep(0.2)",
  62.     "end",
  63.     "",
  64.   },
  65.   [ "/r" ] = {
  66.     "",
  67.     "",
  68.     "",
  69.     "",
  70.     "",
  71.     "",
  72.     "",
  73.     "",
  74.     "",
  75.     "",
  76.     "",
  77.     "",
  78.     "",
  79.     "",
  80.     "",
  81.     "",
  82.     "",
  83.     " 55555555d  5555555     ",
  84.     " 55555555  d555555555   ",
  85.     "  555555555ddd55555555  ",
  86.     "  5555555555dddd5555555 ",
  87.     "  555555555555dddd555555",
  88.     "  5555555555555dddd55555",
  89.     "  5555555555      d55555",
  90.     "  ddd5555          55555",
  91.     "  555d555           5555",
  92.     "  ddd5dd5               ",
  93.     "  dddd55d               ",
  94.     " ddddddd5               ",
  95.     " dddddddd               ",
  96.     " dddddddd               ",
  97.     " ddddddd                ",
  98.     "dddddddd                ",
  99.     "ddddddd                 ",
  100.     "",
  101.   },
  102.   [ "/P" ] = {
  103.     "      5555d55555555555         ",
  104.     "   5555555dd5555555555555      ",
  105.     "   55555555d555555555555555    ",
  106.     "   55555555dd5555555555555555  ",
  107.     "    55555555dd5555555555555555 ",
  108.     "    555555555dd     55555555555",
  109.     "    5555555555d        55555555",
  110.     "    55555555555           55555",
  111.     "    55555555555           55555",
  112.     "     5555555555            5555",
  113.     "     555555555             5555",
  114.     "    5555555555            55555",
  115.     "    d55555555555555     5555555",
  116.     "    d55555555555555555ddd555555",
  117.     "    5d55555555555555555ddd555  ",
  118.     "    d5d55555555555555555ddd5   ",
  119.     "   ddd5d555555555555555        ",
  120.     "   dddd5d55555                 ",
  121.     "   dddd5d55555                 ",
  122.     "   ddddd5d5555                 ",
  123.     "  dddddd5d5555                 ",
  124.     "  ddddddd5d55                  ",
  125.     "  dddddddd5dd                  ",
  126.     "  ddddddddd55                  ",
  127.     "  ddddddddddd                  ",
  128.     " dddddddddddd                  ",
  129.     " ddddddddddd                   ",
  130.     " ddddddddddd                   ",
  131.     " ddddddddddd                   ",
  132.     "ddddddddddd                    ",
  133.     "dddddddddd                     ",
  134.     "ddddddddd                      ",
  135.     "dddddddd                       ",
  136.     " ddddd                         ",
  137.     "",
  138.   },
  139.   [ "/j" ] = {
  140.     "",
  141.     "",
  142.     "",
  143.     "",
  144.     "",
  145.     "",
  146.     "",
  147.     "",
  148.     "",
  149.     "",
  150.     "              5555 ",
  151.     "             555555",
  152.     "             d5555 ",
  153.     "             dd55  ",
  154.     "            dddd   ",
  155.     "",
  156.     "",
  157.     "            55dd   ",
  158.     "           5555dd  ",
  159.     "           55555dd ",
  160.     "           555555d ",
  161.     "            555555d",
  162.     "            5555555",
  163.     "  55        5555555",
  164.     " ddd         555555",
  165.     "5555d        555555",
  166.     "dddd55       ddd555",
  167.     "dddddd       555ddd",
  168.     "dddddd      dddd555",
  169.     "ddddddd   dddddddd ",
  170.     "dddddddddddddddddd ",
  171.     " dddddddddddddddd  ",
  172.     "   ddddddddddddd   ",
  173.     "     dddddddddd    ",
  174.     "",
  175.   },
  176.   [ "/e" ] = {
  177.     "",
  178.     "",
  179.     "",
  180.     "",
  181.     "",
  182.     "",
  183.     "",
  184.     "",
  185.     "",
  186.     "",
  187.     "",
  188.     "",
  189.     "",
  190.     "",
  191.     "",
  192.     "",
  193.     "",
  194.     "   ddddd5555555       ",
  195.     "  55dddddd5555555     ",
  196.     " 55555dddddd5555555   ",
  197.     " 555555         55555 ",
  198.     "555555           dd55 ",
  199.     "555555            dddd",
  200.     "dd5555            555d",
  201.     "55ddddd          55555",
  202.     "dd5555555ddddddd555555",
  203.     "ddddddddd5555555ddddd ",
  204.     "ddddddd               ",
  205.     " dddddd               ",
  206.     " dddddddd             ",
  207.     "  ddddddddd     dddddd",
  208.     "   ddddddddddddddddddd",
  209.     "    ddddddddddddddddd ",
  210.     "       ddddddddddddd  ",
  211.     "",
  212.   },
  213.   [ "/o" ] = {
  214.     "",
  215.     "",
  216.     "",
  217.     "",
  218.     "",
  219.     "",
  220.     "",
  221.     "",
  222.     "",
  223.     "",
  224.     "",
  225.     "",
  226.     "",
  227.     "",
  228.     "",
  229.     "",
  230.     "",
  231.     "      d5555       ",
  232.     "   55ddd55555     ",
  233.     "  55555ddd55555   ",
  234.     "  555555dddd5555  ",
  235.     " 55555555dddddddd ",
  236.     "555555      dddddd",
  237.     "dd555        ddddd",
  238.     "55dd           555",
  239.     "dd55           555",
  240.     "dddd           555",
  241.     "ddddd         5ddd",
  242.     "dddddd       dd55 ",
  243.     " dddddddddddddddd ",
  244.     " ddddddddddddddd  ",
  245.     "  ddddddddddddd   ",
  246.     "    dddddddddd    ",
  247.     "      dddddd      ",
  248.     "",
  249.   },
  250.   [ "/pain" ] = {
  251.     "--[[\r",
  252.     "   PAIN picture editor for ComputerCraft\r",
  253.     "   Get it with\r",
  254.     "    pastebin get wJQ7jav0 pain\r",
  255.     "    std pb wJQ7jav0 pain\r",
  256.     "     std ld pain pain\r",
  257.     "   \r",
  258.     "   This is a stable release. You fool!\r",
  259.     "--]]\r",
  260.     "\r",
  261.     "local displayHelp = function()\r",
  262.     "   local progname = fs.getName(shell.getRunningProgram())\r",
  263.     "   print(progname..\" <filename>\")\r",
  264.     "   print(\"Press F1 in program for more.\")\r",
  265.     "end\r",
  266.     "\r",
  267.     "local pMode = 0\r",
  268.     "\r",
  269.     "local tArg = {...}\r",
  270.     "if (not tArg[1]) and shell then\r",
  271.     "   return displayHelp()\r",
  272.     "end\r",
  273.     "\r",
  274.     "if tArg[2] == \"view\" then\r",
  275.     "   pMode = 1\r",
  276.     "elseif tArg[2] == \"moo\" then\r",
  277.     "   return print(\"This PAIN does not have Super Cow Powers.\")\r",
  278.     "end\r",
  279.     "\r",
  280.     "local fileName\r",
  281.     "if not term.isColor() then\r",
  282.     "   error(\"Only for Advanced computers\")\r",
  283.     "end\r",
  284.     "local barmsg = \"Press F1 for help.\"\r",
  285.     "local tse = textutils.serialise\r",
  286.     "local tun = textutils.unserialise\r",
  287.     "local paintEncoded\r",
  288.     "local lastPaintEncoded\r",
  289.     "local frame = 1\r",
  290.     "local doRender = false\r",
  291.     "local metaHistory = {}\r",
  292.     "local bepimode = false      --this is a family-friendly program! now stand still while I murder you\r",
  293.     "local evenDrawGrid = true   --will you evenDraw(the)Grid ?\r",
  294.     "local renderBlittle = false --whether or not to render all in blittle\r",
  295.     "local firstTerm, blittleTerm = term.current()\r",
  296.     "local firstBG = term.getBackgroundColor()\r",
  297.     "local firstTX = term.getTextColor()\r",
  298.     "\r",
  299.     "local grid\r",
  300.     "\r",
  301.     "local yield = function()\r",
  302.     "   os.queueEvent(\"yield\")\r",
  303.     "   os.pullEvent(\"yield\")\r",
  304.     "end\r",
  305.     "\r",
  306.     "local paint = {\r",
  307.     "   scrollX = 0,\r",
  308.     "   scrollY = 0,\r",
  309.     "   t = colors.gray,\r",
  310.     "   b = colors.white,\r",
  311.     "   m = 1,  --in case you want to use PAIN as a level editor or something\r",
  312.     "   c = \" \",\r",
  313.     "   doGray = false,\r",
  314.     "}\r",
  315.     "\r",
  316.     "local scr_x, scr_y = term.getSize()\r",
  317.     "local scrollX, scrollY = 0, 0\r",
  318.     "\r",
  319.     "local keysDown = {}\r",
  320.     "local miceDown = {}\r",
  321.     "\r",
  322.     "local doRenderBar = 1 -- 1 and 0. Not true or false\r",
  323.     "\r",
  324.     "local fixstr = function(str)\r",
  325.     "   return str:gsub(\"\\\\(%d%d%d)\",string.char)\r",
  326.     "end\r",
  327.     "\r",
  328.     "local choice = function(input,breakkeys)\r",
  329.     "   repeat\r",
  330.     "       event, key = os.pullEvent(\"key\")\r",
  331.     "       if type(key) == \"number\" then key = keys.getName(key) end\r",
  332.     "       if key == nil then key = \" \" end\r",
  333.     "       if type(breakkeys) == \"table\" then\r",
  334.     "           for a = 1, #breakkeys do\r",
  335.     "               if key == breakkeys[a] then\r",
  336.     "                   return \"\"\r",
  337.     "               end\r",
  338.     "           end\r",
  339.     "       end\r",
  340.     "   until string.find(input, key)\r",
  341.     "   return key\r",
  342.     "end\r",
  343.     "local explode = function(div,str)\r",
  344.     "    if (div=='') then return false end\r",
  345.     "    local pos,arr = 0,{}\r",
  346.     "    for st,sp in function() return string.find(str,div,pos,true) end do\r",
  347.     "        table.insert(arr,str:sub(pos,st-1))\r",
  348.     "        pos = sp + 1\r",
  349.     "    end\r",
  350.     "    table.insert(arr,str:sub(pos))\r",
  351.     "    return arr\r",
  352.     "end\r",
  353.     "\r",
  354.     "local function cutString(max_line_length, str) --from stack overflow\r",
  355.     "   local lines = {}\r",
  356.     "   local line\r",
  357.     "   str:gsub('(%s*)(%S+)', \r",
  358.     "      function(spc, word) \r",
  359.     "         if not line or #line + #spc + #word > max_line_length then\r",
  360.     "            table.insert(lines, line)\r",
  361.     "            line = word\r",
  362.     "         else\r",
  363.     "            line = line..spc..word\r",
  364.     "         end\r",
  365.     "      end\r",
  366.     "   )\r",
  367.     "   table.insert(lines, line)\r",
  368.     "   return lines\r",
  369.     "end\r",
  370.     "\r",
  371.     "local cutUp = function(len,tbl)\r",
  372.     "   local output = {}\r",
  373.     "   local e = 0\r",
  374.     "   local s\r",
  375.     "   for a = 1, #tbl do\r",
  376.     "       if #(tbl[a]:gsub(\" \",\"\")) == 0 then\r",
  377.     "           s = {\"\"}\r",
  378.     "       else\r",
  379.     "           s = cutString(len,tbl[a])\r",
  380.     "       end\r",
  381.     "       for b = 1, #s do\r",
  382.     "           table.insert(output,s[b])\r",
  383.     "       end\r",
  384.     "   end\r",
  385.     "   return output\r",
  386.     "end\r",
  387.     "\r",
  388.     "local getEvents = function(...)\r",
  389.     "   local output\r",
  390.     "   while true do\r",
  391.     "       output = {os.pullEvent()}\r",
  392.     "       for a = 1, #arg do\r",
  393.     "           if type(arg[a]) == \"boolean\" then\r",
  394.     "               if doRender == arg[a] then\r",
  395.     "                   return {}\r",
  396.     "               end\r",
  397.     "           elseif output[1] == arg[a] then\r",
  398.     "               return unpack(output)\r",
  399.     "           end\r",
  400.     "       end\r",
  401.     "   end\r",
  402.     "end\r",
  403.     "\r",
  404.     "local sanitize = function(sani,tize)\r",
  405.     "   local _,x = string.find(sani,tize)\r",
  406.     "   if x then\r",
  407.     "       return sani:sub(x+1)\r",
  408.     "   else\r",
  409.     "       return sani\r",
  410.     "   end\r",
  411.     "end\r",
  412.     "local ro = function(input, max)\r",
  413.     "   return math.floor(input % max)\r",
  414.     "end\r",
  415.     "\r",
  416.     "local guiHelp = function()\r",
  417.     "   term.redirect(firstTerm)\r",
  418.     "   scr_x, scr_y = term.current().getSize()\r",
  419.     "   local _helpText = [[\r",
  420.     "\r",
  421.     " 'PAIN' Help Page\r",
  422.     "Programmed by LDDestroier/EldidiStroyrr\r",
  423.     "\r",
  424.     "(use UP/DOWN or scrollwheel, exit with Q)\r",
  425.     "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!\r",
  426.     "\r",
  427.     "Syntax:\r",
  428.     ">pain <filename> [view]\r",
  429.     "\r",
  430.     "[view]: disable all writing capability to view a file\r",
  431.     "\r",
  432.     "You can see what colors are selected based on the word \"PAIN\" on the hotbar.\r",
  433.     "\r",
  434.     "Hotkeys:\r",
  435.     " left/right ctrl: toggle the menu\r",
  436.     "\r",
  437.     " left click:\r",
  438.     "  +shift = drag and let go to make a line\r",
  439.     "  -alone = place pixel\r",
  440.     "\r",
  441.     " right click: delete pixel\r",
  442.     "\r",
  443.     " middle click OR \"t\": place text down with current colors\r",
  444.     "\r",
  445.     " \"[\" or mouse scroll down:\r",
  446.     "  +shift = change to previous text color\r",
  447.     "  -alone = change to previous background color\r",
  448.     "\r",
  449.     " \"]\" or mouse scroll up:\r",
  450.     "  +shift = change to next text color\r",
  451.     "  -alone = change to next background color\r",
  452.     "\r",
  453.     " spacebar:\r",
  454.     "  +shift = toggle grid\r",
  455.     "  -alone = toggle bar visibility\r",
  456.     "\r",
  457.     " arrowkeys:\r",
  458.     "  +shift = move entire picture\r",
  459.     "  +tab = move one pixel at a time\r",
  460.     "  -alone = looks around the canvas smoothly\r",
  461.     "\r",
  462.     " \"+\" (or equals):\r",
  463.     "  +left alt = swap the current frame with the next frame\r",
  464.     "  -alone = change to next frame\r",
  465.     "\r",
  466.     " \"-\":\r",
  467.     "  +left alt = swap the current frame with the previous frame\r",
  468.     "  -alone = change to previous frame\r",
  469.     "\r",
  470.     " \"a\": set the coordinates to 0,0\r",
  471.     "\r",
  472.     " \"b\": toggle redirect to blittle, to preview in teletext characters\r",
  473.     "\r",
  474.     " \"c\": input coordinates to move the canvas to\r",
  475.     "\r",
  476.     " \"g\": toggle grayscale mode. everything is in shades of gray. if you Save, it saves in grayscale.\r",
  477.     "\r",
  478.     " \"f\":\r",
  479.     "  +shift = fill all empty pixels with background color\r",
  480.     "  -alone = absolutely nothing\r",
  481.     "\r",
  482.     " \"m\": set metadata for pixels (for game makers, otherwise safe to ignore)\r",
  483.     "\r",
  484.     "\r",
  485.     " Le Menu (access with CTRL):\r",
  486.     "\r",
  487.     " -left click on a menu item to select it.\r",
  488.     " -if you click on the menubar, let go on an option to select it.\r",
  489.     "\r",
  490.     " \"Save\"\r",
  491.     " 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.\r",
  492.     "\r",
  493.     " \"Export\"\r",
  494.     " Exports current frame to the basic paint format, which doesn't save text, but is WAY more space-efficient. Specify a path, too.\r",
  495.     "\r",
  496.     " \"Del. Frame\"\r",
  497.     " Deletes the current frame. Tells you off if you try to delete the only frame.\r",
  498.     "\r",
  499.     " \"Clear\"\r",
  500.     " Deletes all pixels on the current frame.\r",
  501.     "\r",
  502.     " \"Exit\"\r",
  503.     " Durr I dunno, I think it exits.\r",
  504.     "\r",
  505.     "\r",
  506.     "I hope my PAIN causes you joy.\r",
  507.     "]]\r",
  508.     "   _helpText = explode(\"\\n\",_helpText)\r",
  509.     "   helpText = cutUp(scr_x,_helpText)\r",
  510.     "   local helpscroll = 0\r",
  511.     "   term.setBackgroundColor(colors.gray)\r",
  512.     "   term.setTextColor(colors.white)\r",
  513.     "   term.clear()\r",
  514.     "   local evt, key\r",
  515.     "   while true do\r",
  516.     "       term.clear()\r",
  517.     "       for a = 1, scr_y do\r",
  518.     "           term.setCursorPos(1,a)\r",
  519.     "           term.clearLine()\r",
  520.     "           term.write(helpText[a-helpscroll] or \"\")\r",
  521.     "       end\r",
  522.     "       repeat\r",
  523.     "           evt,key = os.pullEvent()\r",
  524.     "       until evt == \"key\" or evt == \"mouse_scroll\"\r",
  525.     "       if evt == \"key\" then\r",
  526.     "           if key == keys.up then\r",
  527.     "               helpscroll = helpscroll + 1\r",
  528.     "           elseif key == keys.down then\r",
  529.     "               helpscroll = helpscroll - 1\r",
  530.     "           elseif key == keys.pageUp then\r",
  531.     "               helpscroll = helpscroll + scr_y\r",
  532.     "           elseif key == keys.pageDown then\r",
  533.     "               helpscroll = helpscroll - scr_y\r",
  534.     "           elseif (key == keys.q) or (key == keys.space) then\r",
  535.     "               doRender = true\r",
  536.     "               if renderBlittle then term.redirect(blittleTerm) end\r",
  537.     "               scr_x, scr_y = term.current().getSize()\r",
  538.     "               return\r",
  539.     "           end\r",
  540.     "       elseif evt == \"mouse_scroll\" then\r",
  541.     "           helpscroll = helpscroll - key\r",
  542.     "       end\r",
  543.     "       if helpscroll > 0 then\r",
  544.     "           helpscroll = 0\r",
  545.     "       elseif helpscroll < -(#helpText-(scr_y-3)) then\r",
  546.     "           helpscroll = -(#helpText-(scr_y-3))\r",
  547.     "       end\r",
  548.     "   end\r",
  549.     "end\r",
  550.     "\r",
  551.     "local tableRemfind = function(tbl, str)\r",
  552.     "   local out = tbl\r",
  553.     "   for a = 1, #tbl do\r",
  554.     "       if tbl[a] == str then\r",
  555.     "           table.remove(out,a)\r",
  556.     "           return out,a\r",
  557.     "       end\r",
  558.     "   end\r",
  559.     "   return {}\r",
  560.     "end\r",
  561.     "\r",
  562.     "local stringShift = function(str,amt)\r",
  563.     "   return str:sub(ro(amt-1,#str)+1)..str:sub(1,ro(amt-1,#str))\r",
  564.     "end\r",
  565.     "\r",
  566.     "local deepCopy\r",
  567.     "deepCopy = function(obj)\r",
  568.     "   if type(obj) ~= 'table' then return obj end\r",
  569.     "   local res = {}\r",
  570.     "   for k, v in pairs(obj) do res[deepCopy(k)] = deepCopy(v) end\r",
  571.     "   return res\r",
  572.     "end\r",
  573.     "\r",
  574.     "local renderBottomBar = function(txt)\r",
  575.     "   term.setCursorPos(1,scr_y)\r",
  576.     "   term.setBackgroundColor(colors.lightGray)\r",
  577.     "   term.setTextColor(colors.black)\r",
  578.     "   term.clearLine()\r",
  579.     "   term.write(txt)\r",
  580.     "end\r",
  581.     "\r",
  582.     "local bottomPrompt = function(txt,history,cho,breakkeys)\r",
  583.     "   renderBottomBar(txt)\r",
  584.     "   local out\r",
  585.     "   sleep(0)\r",
  586.     "   if cho then\r",
  587.     "       out = choice(cho,breakkeys)\r",
  588.     "   else\r",
  589.     "       out = read(_,history)\r",
  590.     "   end\r",
  591.     "   return out\r",
  592.     "end\r",
  593.     "\r",
  594.     "local getDotsInLine = function( startX, startY, endX, endY ) --stolen from the paintutils API...hehehe\r",
  595.     "    local out = {}\r",
  596.     "    \r",
  597.     "    startX = math.floor(startX)\r",
  598.     "    startY = math.floor(startY)\r",
  599.     "    endX = math.floor(endX)\r",
  600.     "    endY = math.floor(endY)\r",
  601.     "\r",
  602.     "    if startX == endX and startY == endY then\r",
  603.     "        out = {{x=startX,y=startY}}\r",
  604.     "        return out\r",
  605.     "    end\r",
  606.     "    \r",
  607.     "    local minX = math.min( startX, endX )\r",
  608.     "    if minX == startX then\r",
  609.     "        minY = startY\r",
  610.     "        maxX = endX\r",
  611.     "        maxY = endY\r",
  612.     "    else\r",
  613.     "        minY = endY\r",
  614.     "        maxX = startX\r",
  615.     "        maxY = startY\r",
  616.     "    end\r",
  617.     "        \r",
  618.     "    local xDiff = maxX - minX\r",
  619.     "    local yDiff = maxY - minY\r",
  620.     "            \r",
  621.     "    if xDiff > math.abs(yDiff) then\r",
  622.     "        local y = minY\r",
  623.     "        local dy = yDiff / xDiff\r",
  624.     "        for x=minX,maxX do\r",
  625.     "            table.insert(out,{x=x,y=math.floor(y+0.5)})\r",
  626.     "            y = y + dy\r",
  627.     "        end\r",
  628.     "    else\r",
  629.     "        local x = minX\r",
  630.     "        local dx = xDiff / yDiff\r",
  631.     "        if maxY >= minY then\r",
  632.     "            for y=minY,maxY do\r",
  633.     "                table.insert(out,{x=math.floor(x+0.5),y=y})\r",
  634.     "                x = x + dx\r",
  635.     "            end\r",
  636.     "        else\r",
  637.     "            for y=minY,maxY,-1 do\r",
  638.     "                table.insert(out,{x=math.floor(x+0.5),y=y})\r",
  639.     "                x = x - dx\r",
  640.     "            end\r",
  641.     "        end\r",
  642.     "    end\r",
  643.     "    return out\r",
  644.     "end\r",
  645.     "\r",
  646.     "local movePaintEncoded = function(pe,xdiff,ydiff)\r",
  647.     "   local outpootis = deepCopy(pe)\r",
  648.     "   for a = 1, #outpootis do\r",
  649.     "       outpootis[a].x = outpootis[a].x+xdiff\r",
  650.     "       outpootis[a].y = outpootis[a].y+ydiff\r",
  651.     "   end\r",
  652.     "   return outpootis\r",
  653.     "end\r",
  654.     "\r",
  655.     "local clearRedundant = function(dots)\r",
  656.     "   local input = {}\r",
  657.     "   local pheight = 0\r",
  658.     "   local pwidth = 0\r",
  659.     "   for a = 1, #dots do\r",
  660.     "       if dots[a].y > pheight then\r",
  661.     "           pheight = dots[a].y\r",
  662.     "       end\r",
  663.     "       if dots[a].x > pwidth then\r",
  664.     "           pwidth = dots[a].x\r",
  665.     "       end\r",
  666.     "   end\r",
  667.     "   for a = 1, #dots do\r",
  668.     "       if not input[dots[a].y] then input[dots[a].y] = {} end\r",
  669.     "       input[dots[a].y][dots[a].x] = dots[a]\r",
  670.     "   end\r",
  671.     "   local output = {}\r",
  672.     "   local frame = 0\r",
  673.     "   for y = 1, pheight do\r",
  674.     "       for x = 1, pwidth do\r",
  675.     "           if input[y] then\r",
  676.     "               if input[y][x] then\r",
  677.     "                   table.insert(output,input[y][x])\r",
  678.     "               end\r",
  679.     "           end\r",
  680.     "           if frame >= 50 then\r",
  681.     "               --yield()\r",
  682.     "               frame = 0\r",
  683.     "           end\r",
  684.     "       end\r",
  685.     "   end\r",
  686.     "   return output\r",
  687.     "end\r",
  688.     "\r",
  689.     "local grayOut = function(color)\r",
  690.     "   local c = deepCopy(_G.colors)\r",
  691.     "   local grays = {\r",
  692.     "       [c.white] = c.white,\r",
  693.     "       [c.orange] = c.lightGray,\r",
  694.     "       [c.magenta] = c.lightGray,\r",
  695.     "       [c.lightBlue] = c.lightGray,\r",
  696.     "       [c.yellow] = c.white,\r",
  697.     "       [c.lime] = c.lightGray,\r",
  698.     "       [c.pink] = c.lightGray,\r",
  699.     "       [c.gray] = c.gray,\r",
  700.     "       [c.lightGray] = c.lightGray,\r",
  701.     "       [c.cyan] = c.lightGray,\r",
  702.     "       [c.purple] = c.gray,\r",
  703.     "       [c.blue] = c.gray,\r",
  704.     "       [c.brown] = c.gray,\r",
  705.     "       [c.green] = c.lightGray,\r",
  706.     "       [c.red] = c.gray,\r",
  707.     "       [c.black] = c.black,\r",
  708.     "   }\r",
  709.     "   local newColor = grays[color] or 1\r",
  710.     "   return newColor\r",
  711.     "end\r",
  712.     "\r",
  713.     "local getOnscreenCoords = function(tbl,_x,_y)\r",
  714.     "   local screenTbl = {}\r",
  715.     "   for a = 1, #tbl do\r",
  716.     "       if tbl[a].x+paint.scrollX > 0 and tbl[a].x+paint.scrollX <= scr_x then\r",
  717.     "           if tbl[a].y+paint.scrollY > 0 and tbl[a].y+paint.scrollY <= scr_y then\r",
  718.     "               table.insert(screenTbl,{tbl[a].x+paint.scrollX,tbl[a].y+paint.scrollY})\r",
  719.     "           end\r",
  720.     "       end\r",
  721.     "   end\r",
  722.     "   if not _x and _y then\r",
  723.     "       return screenTbl\r",
  724.     "   else\r",
  725.     "       for a = 1, #screenTbl do\r",
  726.     "           if screenTbl[a][1] == _x and screenTbl[a][2] == _y then\r",
  727.     "               return true\r",
  728.     "           end\r",
  729.     "       end\r",
  730.     "       return false\r",
  731.     "   end\r",
  732.     "end\r",
  733.     "\r",
  734.     "local fillTool = function(info,cx,cy,color,layer) --takes a frame, not the whole paintEncoded\r",
  735.     "   local x,y\r",
  736.     "   local output = {}\r",
  737.     "   for a = 1, #info do\r",
  738.     "       if (info[a].x == cx) and (info[a].y == cy) then\r",
  739.     "           x = cx\r",
  740.     "           y = cy\r",
  741.     "           replaceColor = info[a].b\r",
  742.     "           break\r",
  743.     "       end\r",
  744.     "   end\r",
  745.     "   if not x and y then\r",
  746.     "       return\r",
  747.     "   end\r",
  748.     "   if color == replaceColor then\r",
  749.     "       return\r",
  750.     "   end\r",
  751.     "   table.insert(output,{\r",
  752.     "       [\"x\"] = x,\r",
  753.     "       [\"y\"] = y,\r",
  754.     "       [\"b\"] = color,\r",
  755.     "       [\"t\"] = color,\r",
  756.     "       [\"c\"] = \" \",\r",
  757.     "       [\"m\"] = paint.m\r",
  758.     "   })\r",
  759.     "   local loops = 0\r",
  760.     "   local tAffectedPoints = {\r",
  761.     "       [1] = {\r",
  762.     "           x = x+tTerm.scroll.x,\r",
  763.     "           z = z+tTerm.scroll.z\r",
  764.     "       }\r",
  765.     "   }\r",
  766.     "   while #tAffectedPoints > 0 do\r",
  767.     "       if loops%200 == 0 then\r",
  768.     "           sleep(0.05)\r",
  769.     "       end\r",
  770.     "       for i=-1,1,2 do\r",
  771.     "           local x = tAffectedPoints[1][\"x\"]+i\r",
  772.     "           local z = tAffectedPoints[1][\"z\"]\r",
  773.     "           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\r",
  774.     "               drawPoint(x,z,color,layer,true,true)\r",
  775.     "               table.insert(tAffectedPoints,{[\"x\"] = x,[\"z\"] = z})\r",
  776.     "           end\r",
  777.     "           x = tAffectedPoints[1][\"x\"]\r",
  778.     "           z = tAffectedPoints[1][\"z\"]+i\r",
  779.     "           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\r",
  780.     "               drawPoint(x,z,color,layer,true,true)\r",
  781.     "               table.insert(tAffectedPoints,{[\"x\"] = x,[\"z\"] = z})\r",
  782.     "           end\r",
  783.     "       end\r",
  784.     "       table.remove(tAffectedPoints,1)\r",
  785.     "       loops = loops+1\r",
  786.     "   end\r",
  787.     "end\r",
  788.     "\r",
  789.     "local saveFile = function(path,info)\r",
  790.     "   local output = {}\r",
  791.     "   for a = 1, #info do\r",
  792.     "       output[a] = clearRedundant(info[a])\r",
  793.     "       if a % 8 == 0 then yield() end\r",
  794.     "   end\r",
  795.     "   local fileout = textutils.serialize(output):gsub(\"  \",\"\"):gsub(\"\\n\",\"\"):gsub(\" = \",\"=\"):gsub(\",}\",\"}\")\r",
  796.     "   if #fileout >= fs.getFreeSpace(fs.getDir(path)) then\r",
  797.     "       barmsg = \"Not enough space.\"\r",
  798.     "       return\r",
  799.     "   end\r",
  800.     "   local file = fs.open(path,\"w\")\r",
  801.     "   file.write(fileout)\r",
  802.     "   file.close()\r",
  803.     "end\r",
  804.     "local renderBar = function(msg,dontSetVisible)\r",
  805.     "   local tsv = term.current().setVisible\r",
  806.     "   if (doRenderBar == 0) or renderBlittle then return end\r",
  807.     "   if tsv and (not dontSetVisible) then tsv(false) end\r",
  808.     "   term.setCursorPos(1,scr_y)\r",
  809.     "   term.setBackgroundColor(colors.lightGray)\r",
  810.     "   term.setTextColor(colors.black)\r",
  811.     "   term.clearLine()\r",
  812.     "   term.setBackgroundColor(paint.b)\r",
  813.     "   term.setTextColor(paint.t)\r",
  814.     "   term.setCursorPos(2,scr_y)\r",
  815.     "   term.write(\"PAIN\")\r",
  816.     "   term.setBackgroundColor(colors.lightGray)\r",
  817.     "   term.setTextColor(colors.black)\r",
  818.     "   term.setCursorPos(7,scr_y)\r",
  819.     "   term.write(msg..\" Frame: \"..frame..\"/\"..#paintEncoded)\r",
  820.     "   term.write(\" (X:\"..paint.scrollX..\" Y:\"..paint.scrollY..\")\")\r",
  821.     "   if tsv and (not dontSetVisible) then tsv(true) end\r",
  822.     "end\r",
  823.     "\r",
  824.     "local rendback = {\r",
  825.     "   b = colors.black,\r",
  826.     "   t = colors.gray,\r",
  827.     "}\r",
  828.     "\r",
  829.     "local getTablePaint = function(pe)\r",
  830.     "   local output = {}\r",
  831.     "   for a = 1, #pe do\r",
  832.     "       if not output[pe[a].y] then output[pe[a].y] = {} end\r",
  833.     "       output[pe[a].y][pe[a].x] = pe[a]\r",
  834.     "   end\r",
  835.     "   return output\r",
  836.     "end\r",
  837.     "\r",
  838.     "local renderPainyThings = function(xscroll,yscroll,doGrid)\r",
  839.     "   if bepimode then\r",
  840.     "       grid = {\r",
  841.     "           \"Bepis\",\r",
  842.     "           \"episB\",\r",
  843.     "           \"pisBe\",\r",
  844.     "           \"isBep\",\r",
  845.     "           \"sBepi\",\r",
  846.     "       }\r",
  847.     "   else\r",
  848.     "       grid = {\r",
  849.     "           \"%%..\",\r",
  850.     "           \"%%..\",\r",
  851.     "           \"%%..\",\r",
  852.     "           \"..%%\",\r",
  853.     "           \"..%%\",\r",
  854.     "           \"..%%\",\r",
  855.     "       }\r",
  856.     "   end\r",
  857.     "   term.setBackgroundColor(rendback.b)\r",
  858.     "   term.setTextColor(rendback.t)\r",
  859.     "   local badchar = \"/\"\r",
  860.     "   local blittlelabel = \"blittle max\"\r",
  861.     "   local screenlabel = \"screen max\"\r",
  862.     "   if doGrid then\r",
  863.     "       for y = 1, scr_y-(renderBlittle and 0 or doRenderBar) do\r",
  864.     "           term.setCursorPos(1,y)\r",
  865.     "           --the single most convoluted line I've ever written that works, and I love it\r",
  866.     "           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))\r",
  867.     "           term.setCursorPos(1,y)\r",
  868.     "           if ((scr_y+1)-yscroll) == y then --regular limit\r",
  869.     "               term.write( (string.rep(\"@\", ( (scr_x)     ) - (#screenlabel+2)  ) ..screenlabel:gsub(\" \",\"@\"):upper()..\"@@\"):sub(xscroll>0 and xscroll or 0) )\r",
  870.     "           elseif (((scr_y*3)+1)-yscroll) == y then --blittle limit\r",
  871.     "               term.write( (string.rep(\"@\", ( ((scr_x*2))   ) - (#blittlelabel+2) )..blittlelabel:gsub(\" \",\"@\"):upper()..\"@@\"):sub(xscroll>0 and xscroll or 0) )\r",
  872.     "           end\r",
  873.     "           --Stupid easter eggs, ho!--\r",
  874.     "           if 1000-yscroll == y then\r",
  875.     "               term.setCursorPos(1000-xscroll,y)\r",
  876.     "               term.write(\" What ARE you doing? Stop messing around! \")\r",
  877.     "           end\r",
  878.     "           if 2016-yscroll == y then\r",
  879.     "               term.setCursorPos(200-xscroll,y)\r",
  880.     "               term.write(\" MOTHER 3 is the best RPG ever. \")\r",
  881.     "           end\r",
  882.     "           if 2017-yscroll == y then\r",
  883.     "               term.setCursorPos(200-xscroll,y)\r",
  884.     "               term.write(\" Wouldn't you agree? \")\r",
  885.     "           end\r",
  886.     "           if 800-yscroll == y then\r",
  887.     "               term.setCursorPos(1700-xscroll,y)\r",
  888.     "               term.write(\" Which would you say is better? \")\r",
  889.     "           end\r",
  890.     "           if 801-yscroll == y then\r",
  891.     "               term.setCursorPos(1700-xscroll,y)\r",
  892.     "               term.write(\" Cave Story or Braid? \")\r",
  893.     "           end\r",
  894.     "           if 802-yscroll == y then\r",
  895.     "               term.setCursorPos(1700-xscroll,y)\r",
  896.     "               term.write(\" It depends what you're looking for. \")\r",
  897.     "           end\r",
  898.     "           --Is this the end?--\r",
  899.     "           if (xscroll > scr_x) and (xscroll < (scr_x*2)+1) then --blittle limit\r",
  900.     "               for y = 1, scr_y do\r",
  901.     "                   if y+yscroll <= (scr_y*3) then\r",
  902.     "                       if not (y == scr_y and doRenderBar == 1) then\r",
  903.     "                           term.setCursorPos((scr_x+1)-(xscroll-scr_x),y)\r",
  904.     "                           term.write(\"@\")\r",
  905.     "                       end\r",
  906.     "                   end\r",
  907.     "               end\r",
  908.     "           elseif (xscroll > 0) then --regular limit\r",
  909.     "               for y = 1, scr_y do\r",
  910.     "                   if y+yscroll <= scr_y then\r",
  911.     "                       if not (y == scr_y and doRenderBar == 1) then\r",
  912.     "                           term.setCursorPos((scr_x+1)-xscroll,y)\r",
  913.     "                           term.write(\"@\")\r",
  914.     "                       end\r",
  915.     "                   end\r",
  916.     "               end\r",
  917.     "           end\r",
  918.     "       end\r",
  919.     "       --render areas that won't save\r",
  920.     "       if xscroll < 0 then\r",
  921.     "           for y = 1, scr_y do\r",
  922.     "               if not (y == scr_y and doRenderBar == 1) then\r",
  923.     "                   term.setCursorPos(1,y)\r",
  924.     "                   term.write(badchar:rep(-xscroll))\r",
  925.     "               end\r",
  926.     "           end\r",
  927.     "       end\r",
  928.     "       if yscroll < 0 then\r",
  929.     "           for y = 1, -yscroll do\r",
  930.     "               if not (y == scr_y and doRenderBar == 1) then\r",
  931.     "                   term.setCursorPos(1,y)\r",
  932.     "                   term.write(badchar:rep(scr_x))\r",
  933.     "               end\r",
  934.     "           end\r",
  935.     "       end\r",
  936.     "   else\r",
  937.     "       term.clear()\r",
  938.     "   end\r",
  939.     "end\r",
  940.     "\r",
  941.     "renderPAIN = function(dots,xscroll,yscroll,doPain)\r",
  942.     "   local tsv = term.current().setVisible\r",
  943.     "   if tsv then tsv(false) end\r",
  944.     "   local beforeTX,beforeBG = term.getTextColor(), term.getBackgroundColor()\r",
  945.     "   local cx,cy = term.getCursorPos()\r",
  946.     "   local FUCK, SHIT = pcall(function()\r",
  947.     "       if doPain then\r",
  948.     "           renderPainyThings(xscroll,yscroll,evenDrawGrid)\r",
  949.     "           renderBar(barmsg,true)\r",
  950.     "       end\r",
  951.     "       for a = 1, #dots do\r",
  952.     "           local d = dots[a]\r",
  953.     "           if doPain then\r",
  954.     "               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\r",
  955.     "                   d = nil\r",
  956.     "               end\r",
  957.     "           end\r",
  958.     "           if d then\r",
  959.     "               term.setCursorPos(d.x-(xscroll or 0),d.y-(yscroll or 0))\r",
  960.     "               term.setTextColor((paint.doGray and grayOut(d.t)) or d.t)\r",
  961.     "               term.setBackgroundColor((paint.doGray and grayOut(d.b)) or d.b)\r",
  962.     "               term.write(d.c)\r",
  963.     "           end\r",
  964.     "       end\r",
  965.     "   end)\r",
  966.     "   term.setBackgroundColor(beforeBG)\r",
  967.     "   term.setTextColor(beforeTX)\r",
  968.     "   term.setCursorPos(cx,cy)\r",
  969.     "   if tsv then tsv(true) end\r",
  970.     "   if not FUCK then error(SHIT) end --GODDAMN IT\r",
  971.     "end\r",
  972.     "\r",
  973.     "renderPAINFS = function(filename,xscroll,yscroll,frameNo,doPain)\r",
  974.     "   local tun, tse = textutils.unserialize, textutils.serialize\r",
  975.     "   local file = fs.open(filename,\"r\")\r",
  976.     "   local contents = file.readAll()\r",
  977.     "   local amntFrames\r",
  978.     "   file.close()\r",
  979.     "   local tcontents = tun(contents)\r",
  980.     "   if type(tcontents) ~= \"table\" then\r",
  981.     "       tcontents = importFromNFP(contents)\r",
  982.     "   else\r",
  983.     "       amntFrames = #tcontents\r",
  984.     "       tcontents = tcontents[frameNo or 1]\r",
  985.     "   end\r",
  986.     "   renderPAIN(tcontents,xscroll,yscroll,doPain)\r",
  987.     "   return amntFrames\r",
  988.     "end\r",
  989.     "\r",
  990.     "local getBlittle = function()\r",
  991.     "   if not blittle then\r",
  992.     "       local geet = http.get(\"http://pastebin.com/raw/ujchRSnU\")\r",
  993.     "       if not geet then\r",
  994.     "           return false\r",
  995.     "       else\r",
  996.     "           geet = geet.readAll()\r",
  997.     "           local file = fs.open(\"/.templittle/blittle\",\"w\")\r",
  998.     "           file.write(geet)\r",
  999.     "           file.close()\r",
  1000.     "           os.loadAPI(\"/.templittle/blittle\")\r",
  1001.     "           fs.delete(\"/.templittle/\")\r",
  1002.     "           if not blittleTerm then\r",
  1003.     "               blittleTerm = blittle.createWindow()\r",
  1004.     "           end\r",
  1005.     "           return blittleTerm, firstTerm\r",
  1006.     "       end\r",
  1007.     "   else\r",
  1008.     "       if not blittleTerm then\r",
  1009.     "           blittleTerm = blittle.createWindow()\r",
  1010.     "       end\r",
  1011.     "       return blittleTerm, firstTerm\r",
  1012.     "   end\r",
  1013.     "end\r",
  1014.     "\r",
  1015.     "local putDownText = function(x,y)\r",
  1016.     "   term.setCursorPos(x,y)\r",
  1017.     "   term.setTextColor((paint.doGray and grayOut(paint.t)) or paint.t)\r",
  1018.     "   term.setBackgroundColor((paint.doGray and grayOut(paint.b)) or paint.b)\r",
  1019.     "   local msg = read()\r",
  1020.     "   if #msg > 0 then\r",
  1021.     "       for a = 1, #msg do\r",
  1022.     "           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})\r",
  1023.     "       end\r",
  1024.     "   end\r",
  1025.     "end\r",
  1026.     "\r",
  1027.     "local deleteDot = function(x,y)\r",
  1028.     "   local good = false\r",
  1029.     "   for a = #paintEncoded[frame],1,-1 do\r",
  1030.     "       local b = paintEncoded[frame][a]\r",
  1031.     "       if (x == b.x) and (y == b.y) then\r",
  1032.     "           table.remove(paintEncoded[frame],a)\r",
  1033.     "           good = true\r",
  1034.     "       end\r",
  1035.     "   end\r",
  1036.     "   return good\r",
  1037.     "end\r",
  1038.     "\r",
  1039.     "CTB = function(_color) --Color To Blit\r",
  1040.     "   local blitcolors = {\r",
  1041.     "       [colors.white] = \"0\",\r",
  1042.     "       [colors.orange] = \"1\",\r",
  1043.     "       [colors.magenta] = \"2\",\r",
  1044.     "       [colors.lightBlue] = \"3\",\r",
  1045.     "       [colors.yellow] = \"4\",\r",
  1046.     "       [colors.lime] = \"5\",\r",
  1047.     "       [colors.pink] = \"6\",\r",
  1048.     "       [colors.gray] = \"7\",\r",
  1049.     "       [colors.lightGray] = \"8\",\r",
  1050.     "       [colors.cyan] = \"9\",\r",
  1051.     "       [colors.purple] = \"a\",\r",
  1052.     "       [colors.blue] = \"b\",\r",
  1053.     "       [colors.brown] = \"c\",\r",
  1054.     "       [colors.green] = \"d\",\r",
  1055.     "       [colors.red] = \"e\",\r",
  1056.     "       [colors.black] = \"f\",\r",
  1057.     "   }\r",
  1058.     "   return blitcolors[_color] or \"f\"\r",
  1059.     "end\r",
  1060.     "\r",
  1061.     "BTC = function(_color) --Blit To Color\r",
  1062.     "   local blitcolors = {\r",
  1063.     "       [\"0\"] = colors.white,\r",
  1064.     "       [\"1\"] = colors.orange,\r",
  1065.     "       [\"2\"] = colors.magenta,\r",
  1066.     "       [\"3\"] = colors.lightBlue,\r",
  1067.     "       [\"4\"] = colors.yellow,\r",
  1068.     "       [\"5\"] = colors.lime,\r",
  1069.     "       [\"6\"] = colors.pink,\r",
  1070.     "       [\"7\"] = colors.gray,\r",
  1071.     "       [\"8\"] = colors.lightGray,\r",
  1072.     "       [\"9\"] = colors.cyan,\r",
  1073.     "       [\"a\"] = colors.purple,\r",
  1074.     "       [\"b\"] = colors.blue,\r",
  1075.     "       [\"c\"] = colors.brown,\r",
  1076.     "       [\"d\"] = colors.green,\r",
  1077.     "       [\"e\"] = colors.red,\r",
  1078.     "       [\"f\"] = colors.black,\r",
  1079.     "   }\r",
  1080.     "   return blitcolors[_color]\r",
  1081.     "end\r",
  1082.     "\r",
  1083.     "exportToNFP = function(input)\r",
  1084.     "   local doop = {}\r",
  1085.     "   local p = input\r",
  1086.     "   local pheight = 0\r",
  1087.     "   local pwidth = 0\r",
  1088.     "   for a = 1, #p do\r",
  1089.     "       if p[a].y > pheight then\r",
  1090.     "           pheight = p[a].y\r",
  1091.     "       end\r",
  1092.     "       if p[a].x > pwidth then\r",
  1093.     "           pwidth = p[a].x\r",
  1094.     "       end\r",
  1095.     "   end\r",
  1096.     "   for k,v in pairs(p) do\r",
  1097.     "       if not doop[v.y] then doop[v.y] = {} end\r",
  1098.     "       doop[v.y][v.x] = CTB(v.b)\r",
  1099.     "   end\r",
  1100.     "   for y = 1, pheight do\r",
  1101.     "       if doop[y] then\r",
  1102.     "           for x = 1, pwidth do\r",
  1103.     "               if doop[y][x] then\r",
  1104.     "                   nfpoutput = nfpoutput..doop[y][x]\r",
  1105.     "               else\r",
  1106.     "                   nfpoutput = nfpoutput..\" \"\r",
  1107.     "               end\r",
  1108.     "           end\r",
  1109.     "       end\r",
  1110.     "       nfpoutput = nfpoutput..\"\\n\"\r",
  1111.     "   end\r",
  1112.     "   return nfpoutput\r",
  1113.     "end\r",
  1114.     "\r",
  1115.     "importFromNFP = function(theInput)\r",
  1116.     "   local output = {}\r",
  1117.     "   local input = explode(\"\\n\",theInput)\r",
  1118.     "   for a = 1, #input do\r",
  1119.     "       line = input[a]\r",
  1120.     "       for b = 1, #line do\r",
  1121.     "           if (line:sub(b,b) ~= \" \") and BTC(line:sub(b,b)) then\r",
  1122.     "               table.insert(output,{\r",
  1123.     "                   x = b,\r",
  1124.     "                   y = a,\r",
  1125.     "                   t = colors.white,\r",
  1126.     "                   b = BTC(line:sub(b,b)) or colors.black,\r",
  1127.     "                   c = \" \",\r",
  1128.     "               })\r",
  1129.     "           end\r",
  1130.     "       end\r",
  1131.     "   end\r",
  1132.     "   return output\r",
  1133.     "end\r",
  1134.     "\r",
  1135.     "local getTheDoots = function(pe)\r",
  1136.     "   local hasBadDots = false\r",
  1137.     "   local baddestX,baddestY = 1,1\r",
  1138.     "   barmsg = \"Checking...\"\r",
  1139.     "   for b = 1, #pe do\r",
  1140.     "       local doot = pe[b]\r",
  1141.     "       if doot.x <= 0 or doot.y <= 0 then\r",
  1142.     "           hasBadDots = true\r",
  1143.     "           if doot.x < baddestX then\r",
  1144.     "               baddestX = doot.x\r",
  1145.     "           end\r",
  1146.     "           if doot.y < baddestY then\r",
  1147.     "               baddestY = doot.y\r",
  1148.     "           end\r",
  1149.     "       end\r",
  1150.     "       if b % 64 == 0 then yield() end\r",
  1151.     "   end\r",
  1152.     "   return baddestX, baddestY\r",
  1153.     "end\r",
  1154.     "\r",
  1155.     "local function deepcompare(t1,t2,ignore_mt)\r",
  1156.     "   local ty1 = type(t1)\r",
  1157.     "   local ty2 = type(t2)\r",
  1158.     "   if ty1 ~= ty2 then return false end\r",
  1159.     "   -- non-table types can be directly compared\r",
  1160.     "   if ty1 ~= 'table' and ty2 ~= 'table' then return t1 == t2 end\r",
  1161.     "   -- as well as tables which have the metamethod __eq\r",
  1162.     "   local mt = getmetatable(t1)\r",
  1163.     "   if not ignore_mt and mt and mt.__eq then return t1 == t2 end\r",
  1164.     "   for k1,v1 in pairs(t1) do\r",
  1165.     "       local v2 = t2[k1]\r",
  1166.     "       if v2 == nil or not deepcompare(v1,v2) then return false end\r",
  1167.     "   end\r",
  1168.     "   for k2,v2 in pairs(t2) do\r",
  1169.     "       local v1 = t1[k2]\r",
  1170.     "       if v1 == nil or not deepcompare(v1,v2) then return false end\r",
  1171.     "   end\r",
  1172.     "   return true\r",
  1173.     "end\r",
  1174.     "\r",
  1175.     "local displayMenu = function()\r",
  1176.     "   menuOptions = {\"Save\",\"Export\",\"Del.frame\",\"Clear\",\"Exit\"}\r",
  1177.     "   local diss = \" \"..table.concat(menuOptions,\" \")\r",
  1178.     "   local cleary = scr_y-math.floor(#diss/scr_x)\r",
  1179.     "   for a = cleary,scr_y do\r",
  1180.     "       term.setCursorPos(1,a)\r",
  1181.     "       term.setBackgroundColor(colors.lightGray)\r",
  1182.     "       term.clearLine()\r",
  1183.     "   end\r",
  1184.     "   local menuPoses = {}\r",
  1185.     "   local menuFunctions = {\r",
  1186.     "       [1] = function() --Save\r",
  1187.     "           local hasBadDots = false\r",
  1188.     "           for a = 1, #paintEncoded do\r",
  1189.     "               local radx,rady = getTheDoots(paintEncoded[a])\r",
  1190.     "               if radx ~= 1 or rady ~= 1 then\r",
  1191.     "                   hasBadDots = true\r",
  1192.     "               end\r",
  1193.     "           end\r",
  1194.     "           if hasBadDots then\r",
  1195.     "               local ting = bottomPrompt(\"Dot(s) are OoB! Save or fix? (Y/N/F)\",_,\"ynf\",{keys.leftCtrl,keys.rightCtrl})\r",
  1196.     "               if ting == \"f\" then\r",
  1197.     "                   for a = 1, #paintEncoded do\r",
  1198.     "                       local baddestX, baddestY = getTheDoots(paintEncoded[a])\r",
  1199.     "                       paintEncoded[a] = movePaintEncoded(paintEncoded[a],-(baddestX-1),-(baddestY-1))\r",
  1200.     "                   end\r",
  1201.     "               elseif ting ~= \"y\" then\r",
  1202.     "                   barmsg = \"\"\r",
  1203.     "                   return false\r",
  1204.     "               end\r",
  1205.     "           end\r",
  1206.     "           local output = deepCopy(paintEncoded)\r",
  1207.     "           if paint.doGray then\r",
  1208.     "               for a = 1, #paintEncoded do\r",
  1209.     "                   for b = 1, #paintEncoded[a] do\r",
  1210.     "                       output[a][b].b = grayOut(paintEncoded[a][b].b)\r",
  1211.     "                       output[a][b].t = grayOut(paintEncoded[a][b].t)\r",
  1212.     "                       if not output[a][b].m then output[a][b].m = 1 end\r",
  1213.     "                   end\r",
  1214.     "                   if a % 2 == 0 then yield() end\r",
  1215.     "               end\r",
  1216.     "           end\r",
  1217.     "           saveFile(fileName,output)\r",
  1218.     "           lastPaintEncoded = deepCopy(paintEncoded)\r",
  1219.     "           term.setCursorPos(9,scr_y)\r",
  1220.     "           barmsg = \"Saved as '\"..fileName..\"'\"\r",
  1221.     "           doRender = true\r",
  1222.     "       end,\r",
  1223.     "       [2] = function() --Export\r",
  1224.     "           nfpoutput = \"\"\r",
  1225.     "           local exportName = bottomPrompt(\"Export to: /\")\r",
  1226.     "           if fs.combine(\"\",exportName) == \"\" then return end\r",
  1227.     "           if fs.isReadOnly(exportName) then\r",
  1228.     "               barmsg = \"That's read-only.\"\r",
  1229.     "               doRender = true\r",
  1230.     "               return\r",
  1231.     "           end\r",
  1232.     "           if fs.exists(exportName) then\r",
  1233.     "               if bottomPrompt(\"Overwrite? (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl}) ~= \"y\" then return end\r",
  1234.     "           end\r",
  1235.     "           local output = exportToNFP(paintEncoded[frame])\r",
  1236.     "           local file = fs.open(exportName,\"w\")\r",
  1237.     "           file.write(output)\r",
  1238.     "           file.close()\r",
  1239.     "           doRender = true\r",
  1240.     "           barmsg = \"Exported as '\"..exportName..\"'\"\r",
  1241.     "           return\r",
  1242.     "       end,\r",
  1243.     "       [3] = function() --Del.Frame\r",
  1244.     "           local outcum = bottomPrompt(\"Thou art sure? (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl})\r",
  1245.     "           if outcum == \"y\" then\r",
  1246.     "               if #paintEncoded == 1 then\r",
  1247.     "                   barmsg = \"Ha! You can't do that.\"\r",
  1248.     "                   return\r",
  1249.     "               end\r",
  1250.     "               table.remove(paintEncoded,frame)\r",
  1251.     "               barmsg = \"Deleted frame \"..frame..\".\"\r",
  1252.     "               if paintEncoded[frame-1] then\r",
  1253.     "                   frame = frame - 1\r",
  1254.     "               else\r",
  1255.     "                   frame = frame + 1\r",
  1256.     "               end\r",
  1257.     "               if #paintEncoded < frame then\r",
  1258.     "                   repeat\r",
  1259.     "                       frame = frame - 1\r",
  1260.     "                   until #paintEncoded >= frame\r",
  1261.     "               end\r",
  1262.     "               --renderPAIN(paintEncoded[frame],paint.scrollX,paint.scrollY,true)\r",
  1263.     "           end\r",
  1264.     "           doRender = true\r",
  1265.     "       end,\r",
  1266.     "       [4] = function() --Clear\r",
  1267.     "           local outcum = bottomPrompt(\"Clear the frame? (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl})\r",
  1268.     "           if outcum == \"y\" then\r",
  1269.     "               paintEncoded[frame] = {}\r",
  1270.     "               barmsg = \"Cleared frame \"..frame..\".\"\r",
  1271.     "               --renderPAIN(paintEncoded[frame],paint.scrollX,paint.scrollY,true)\r",
  1272.     "           end\r",
  1273.     "           doRender = true\r",
  1274.     "       end,\r",
  1275.     "       [5] = function() --Exit\r",
  1276.     "           if not deepcompare(lastPaintEncoded,paintEncoded) then\r",
  1277.     "               local outcum = bottomPrompt(\"Abandon unsaved work? (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl})\r",
  1278.     "               sleep(0)\r",
  1279.     "               if outcum == \"y\" then\r",
  1280.     "                   return \"exit\"\r",
  1281.     "               else\r",
  1282.     "                   doRender = true\r",
  1283.     "                   return nil\r",
  1284.     "               end\r",
  1285.     "           else\r",
  1286.     "               return \"exit\"\r",
  1287.     "           end\r",
  1288.     "       end,\r",
  1289.     "   }\r",
  1290.     "   local cursor = 1\r",
  1291.     "   local redrawmenu = true\r",
  1292.     "   local initial = os.time()\r",
  1293.     "   local clickdelay = 0.003\r",
  1294.     "   while true do\r",
  1295.     "       if redrawmenu then\r",
  1296.     "           term.setCursorPos(2,cleary)\r",
  1297.     "           term.clearLine()\r",
  1298.     "           for a = 1, #menuOptions do\r",
  1299.     "               if a == cursor then\r",
  1300.     "                   term.setTextColor(colors.black)\r",
  1301.     "                   term.setBackgroundColor(colors.white)\r",
  1302.     "               else\r",
  1303.     "                   term.setTextColor(colors.black)\r",
  1304.     "                   term.setBackgroundColor(colors.lightGray)\r",
  1305.     "               end\r",
  1306.     "               menuPoses[a] = {term.getCursorPos()}\r",
  1307.     "               write(menuOptions[a])\r",
  1308.     "               term.setBackgroundColor(colors.lightGray)\r",
  1309.     "               if a ~= #menuOptions then\r",
  1310.     "                   write(\" \")\r",
  1311.     "               end\r",
  1312.     "           end\r",
  1313.     "           redrawmenu = false\r",
  1314.     "       end\r",
  1315.     "       local event,key,x,y = getEvents(\"key\",\"char\",\"mouse_click\",\"mouse_up\",\"mouse_drag\")\r",
  1316.     "       if event == \"key\" then\r",
  1317.     "           if key == keys.left then\r",
  1318.     "               redrawmenu = true\r",
  1319.     "               cursor = cursor - 1\r",
  1320.     "           elseif key == keys.right then\r",
  1321.     "               redrawmenu = true\r",
  1322.     "               cursor = cursor + 1\r",
  1323.     "           elseif key == keys.enter then\r",
  1324.     "               local res = menuFunctions[cursor]()\r",
  1325.     "               if res == \"exit\" then\r",
  1326.     "                   return \"exit\"\r",
  1327.     "               else\r",
  1328.     "                   return\r",
  1329.     "               end\r",
  1330.     "           elseif key == keys.leftCtrl or key == keys.rightCtrl then\r",
  1331.     "               doRender = true\r",
  1332.     "               return\r",
  1333.     "           end\r",
  1334.     "       elseif event == \"char\" then\r",
  1335.     "           for a = 1, #menuOptions do\r",
  1336.     "               if key:lower() == menuOptions[a]:sub(1,1):lower() and a ~= cursor then\r",
  1337.     "                   cursor = a\r",
  1338.     "                   redrawmenu = true\r",
  1339.     "                   break\r",
  1340.     "               end\r",
  1341.     "           end\r",
  1342.     "       elseif event == \"mouse_click\" or event == \"mouse_up\" then\r",
  1343.     "           if y < cleary then\r",
  1344.     "               return\r",
  1345.     "           elseif key == 1 and initial+clickdelay < os.time() then --key? more like button\r",
  1346.     "               for a = 1, #menuPoses do\r",
  1347.     "                   if y == menuPoses[a][2] then\r",
  1348.     "                       if x >= menuPoses[a][1] and x <= menuPoses[a][1]+#menuOptions[a] then\r",
  1349.     "                           local res = menuFunctions[a]()\r",
  1350.     "                           if res == \"exit\" then\r",
  1351.     "                               return \"exit\"\r",
  1352.     "                           else\r",
  1353.     "                               return\r",
  1354.     "                           end\r",
  1355.     "                       end\r",
  1356.     "                   end\r",
  1357.     "               end\r",
  1358.     "           end\r",
  1359.     "       --elseif event == \"mouse_drag\" then\r",
  1360.     "       end\r",
  1361.     "       if (initial+clickdelay < os.time()) and string.find(event,\"mouse\") then\r",
  1362.     "           if key == 1 then --key? key? what key? all I see is button!\r",
  1363.     "               for a = 1, #menuPoses do\r",
  1364.     "                   if y == menuPoses[a][2] then\r",
  1365.     "                       if x >= menuPoses[a][1] and x <= menuPoses[a][1]+#menuOptions[a] then\r",
  1366.     "                           cursor = a\r",
  1367.     "                           redrawmenu = true\r",
  1368.     "                           break\r",
  1369.     "                       end\r",
  1370.     "                   end\r",
  1371.     "               end\r",
  1372.     "           end\r",
  1373.     "       end\r",
  1374.     "       if cursor < 1 then\r",
  1375.     "           cursor = #menuOptions\r",
  1376.     "       elseif cursor > #menuOptions then\r",
  1377.     "           cursor = 1\r",
  1378.     "       end\r",
  1379.     "   end\r",
  1380.     "end\r",
  1381.     "\r",
  1382.     "local lastMX,lastMY\r",
  1383.     "\r",
  1384.     "local doNonEventDrivenMovement = function() --what a STUPID function name, man\r",
  1385.     "   local didMove\r",
  1386.     "   while true do\r",
  1387.     "       didMove = false\r",
  1388.     "       if (not keysDown[keys.leftShift]) and (not isDragging) and (not keysDown[keys.tab]) then\r",
  1389.     "           if keysDown[keys.right] then\r",
  1390.     "               paint.scrollX = paint.scrollX + 1\r",
  1391.     "               didMove = true\r",
  1392.     "           elseif keysDown[keys.left] then\r",
  1393.     "               paint.scrollX = paint.scrollX - 1\r",
  1394.     "               didMove = true\r",
  1395.     "           end\r",
  1396.     "           if keysDown[keys.down] then\r",
  1397.     "               paint.scrollY = paint.scrollY + 1\r",
  1398.     "               didMove = true\r",
  1399.     "           elseif keysDown[keys.up] then\r",
  1400.     "               paint.scrollY = paint.scrollY - 1\r",
  1401.     "               didMove = true\r",
  1402.     "           end\r",
  1403.     "           if didMove then\r",
  1404.     "               if lastMX and lastMY then\r",
  1405.     "                   if miceDown[1] then\r",
  1406.     "                       os.queueEvent(\"mouse_click\",1,lastMX,lastMY)\r",
  1407.     "                   end\r",
  1408.     "                   if miceDown[2] then\r",
  1409.     "                       os.queueEvent(\"mouse_click\",2,lastMX,lastMY)\r",
  1410.     "                   end\r",
  1411.     "               end\r",
  1412.     "               doRender = true\r",
  1413.     "           end\r",
  1414.     "       end\r",
  1415.     "       sleep(0)\r",
  1416.     "   end\r",
  1417.     "end\r",
  1418.     "\r",
  1419.     "local linePoses = {}\r",
  1420.     "local dragPoses = {}\r",
  1421.     "\r",
  1422.     "local getInput = function() --gotta catch them all\r",
  1423.     "   local button, x, y, oldmx, oldmy, origx, origy\r",
  1424.     "   local isDragging = false\r",
  1425.     "   local proceed = false\r",
  1426.     "   renderBar(barmsg)\r",
  1427.     "   while true do\r",
  1428.     "       doRender = false\r",
  1429.     "       local oldx,oldy = paint.scrollX,paint.scrollY\r",
  1430.     "       local evt = {getEvents(\"mouse_scroll\",\"mouse_click\", \"mouse_drag\",\"mouse_up\",\"key\",\"key_up\",true)}\r",
  1431.     "       if (evt[1] == \"mouse_scroll\") and (not viewing) then\r",
  1432.     "           local dir = evt[2]\r",
  1433.     "           if dir == 1 then\r",
  1434.     "               if keysDown[keys.leftShift] or keysDown[keys.rightShift] then\r",
  1435.     "                   paint.t = paint.t * 2\r",
  1436.     "                   if paint.t > 32768 then\r",
  1437.     "                       paint.t = 32768\r",
  1438.     "                   end\r",
  1439.     "               else\r",
  1440.     "                   paint.b = paint.b * 2\r",
  1441.     "                   if paint.b > 32768 then\r",
  1442.     "                       paint.b = 32768\r",
  1443.     "                   end\r",
  1444.     "               end\r",
  1445.     "           else\r",
  1446.     "               if keysDown[keys.leftShift] or keysDown[keys.rightShift] then\r",
  1447.     "                   paint.t = math.ceil(paint.t / 2)\r",
  1448.     "                   if paint.t < 1 then\r",
  1449.     "                       paint.t = 1\r",
  1450.     "                   end\r",
  1451.     "               else\r",
  1452.     "                   paint.b = math.ceil(paint.b / 2)\r",
  1453.     "                   if paint.b < 1 then\r",
  1454.     "                       paint.b = 1\r",
  1455.     "                   end\r",
  1456.     "               end\r",
  1457.     "           end\r",
  1458.     "           renderBar(barmsg)\r",
  1459.     "       elseif ((evt[1] == \"mouse_click\") or (evt[1] == \"mouse_drag\")) and (not viewing) then\r",
  1460.     "           if evt[1] == \"mouse_click\" then\r",
  1461.     "               origx, origy = evt[3], evt[4]\r",
  1462.     "           end\r",
  1463.     "           oldmx,oldmy = x or evt[3], y or evt[4]\r",
  1464.     "           lastMX,lastMY = evt[3],evt[4]\r",
  1465.     "           button,x,y = evt[2],evt[3],evt[4]\r",
  1466.     "           if renderBlittle then\r",
  1467.     "               x = 2*x\r",
  1468.     "               y = 3*y\r",
  1469.     "               lastMX = 2*lastMX\r",
  1470.     "               lastMY = 3*lastMY\r",
  1471.     "           end\r",
  1472.     "           linePoses = {{x=oldmx,y=oldmy},{x=x,y=y}}\r",
  1473.     "           miceDown[button] = true\r",
  1474.     "           doRender = true\r",
  1475.     "           if y <= scr_y-(renderBlittle and 0 or doRenderBar) then\r",
  1476.     "               if (button == 3) then\r",
  1477.     "                   putDownText(x,y)\r",
  1478.     "                   miceDown = {}\r",
  1479.     "                   keysDown = {}\r",
  1480.     "               elseif button == 1 then\r",
  1481.     "                   if keysDown[keys.leftShift] and evt[1] == \"mouse_click\" then\r",
  1482.     "                       isDragging = true\r",
  1483.     "                   end\r",
  1484.     "                   if isDragging then\r",
  1485.     "                       if evt[1] == \"mouse_click\" then\r",
  1486.     "                           dragPoses[1] = {x=x,y=y}\r",
  1487.     "                       end\r",
  1488.     "                       dragPoses[2] = {x=x,y=y}\r",
  1489.     "                   else\r",
  1490.     "                       if evt[1] == \"mouse_drag\" then\r",
  1491.     "                           local points = getDotsInLine(linePoses[1].x,linePoses[1].y,linePoses[2].x,linePoses[2].y)\r",
  1492.     "                           for a = 1, #points do\r",
  1493.     "                               table.insert(paintEncoded[frame],{\r",
  1494.     "                                   x = points[a].x + paint.scrollX,\r",
  1495.     "                                   y = points[a].y + paint.scrollY,\r",
  1496.     "                                   c = paint.c,\r",
  1497.     "                                   b = paint.b,\r",
  1498.     "                                   t = paint.t,\r",
  1499.     "                                   m = paint.m,\r",
  1500.     "                               })\r",
  1501.     "                           end\r",
  1502.     "                       else\r",
  1503.     "                           table.insert(paintEncoded[frame],{\r",
  1504.     "                               x = x + paint.scrollX,\r",
  1505.     "                               y = y + paint.scrollY,\r",
  1506.     "                               c = paint.c,\r",
  1507.     "                               b = paint.b,\r",
  1508.     "                               t = paint.t,\r",
  1509.     "                               m = paint.m,\r",
  1510.     "                           })\r",
  1511.     "                       end\r",
  1512.     "                   end\r",
  1513.     "               elseif button == 2 and y <= scr_y-(renderBlittle and 0 or doRenderBar) then\r",
  1514.     "                   deleteDot(x+paint.scrollX,y+paint.scrollY)\r",
  1515.     "               end\r",
  1516.     "           elseif origy >= scr_y-(renderBlittle and 0 or doRenderBar) then\r",
  1517.     "               keysDown = {}\r",
  1518.     "               local res = displayMenu()\r",
  1519.     "               if res == \"exit\" then break end\r",
  1520.     "               doRender = true\r",
  1521.     "           end\r",
  1522.     "       elseif (evt[1] == \"mouse_up\") and (not viewing) then\r",
  1523.     "           origx,origy = 0,0\r",
  1524.     "           local button = evt[2]\r",
  1525.     "           miceDown[button] = false\r",
  1526.     "           oldmx,oldmy = nil,nil\r",
  1527.     "           lastMX, lastMY = nil,nil\r",
  1528.     "           if isDragging then\r",
  1529.     "               local points = getDotsInLine(dragPoses[1].x,dragPoses[1].y,dragPoses[2].x,dragPoses[2].y)\r",
  1530.     "               for a = 1, #points do\r",
  1531.     "                   table.insert(paintEncoded[frame],{\r",
  1532.     "                       x = points[a].x + paint.scrollX,\r",
  1533.     "                       y = points[a].y + paint.scrollY,\r",
  1534.     "                       c = paint.c,\r",
  1535.     "                       b = paint.b,\r",
  1536.     "                       t = paint.t,\r",
  1537.     "                       m = paint.m,\r",
  1538.     "                   })\r",
  1539.     "               end\r",
  1540.     "               doRender = true\r",
  1541.     "           end\r",
  1542.     "           isDragging = false\r",
  1543.     "       elseif evt[1] == \"key\" then\r",
  1544.     "           local key = evt[2]\r",
  1545.     "           if (not keysDown[keys.leftShift]) and (keysDown[keys.tab]) then\r",
  1546.     "               if key == keys.right and (not keysDown[keys.right]) then\r",
  1547.     "                   paint.scrollX = paint.scrollX + 1\r",
  1548.     "                   doRender = true\r",
  1549.     "               elseif key == keys.left and (not keysDown[keys.left]) then\r",
  1550.     "                   paint.scrollX = paint.scrollX - 1\r",
  1551.     "                   doRender = true\r",
  1552.     "               end\r",
  1553.     "               if key == keys.down and (not keysDown[keys.down]) then\r",
  1554.     "                   paint.scrollY = paint.scrollY + 1\r",
  1555.     "                   doRender = true\r",
  1556.     "               elseif key == keys.up and (not keysDown[keys.up]) then\r",
  1557.     "                   paint.scrollY = paint.scrollY - 1\r",
  1558.     "                   doRender = true\r",
  1559.     "               end\r",
  1560.     "           end\r",
  1561.     "           keysDown[key] = true\r",
  1562.     "           if key == keys.space then\r",
  1563.     "               if keysDown[keys.leftShift] then\r",
  1564.     "                   evenDrawGrid = not evenDrawGrid\r",
  1565.     "               else\r",
  1566.     "                   doRenderBar = math.abs(doRenderBar-1)\r",
  1567.     "               end\r",
  1568.     "               doRender = true\r",
  1569.     "           end\r",
  1570.     "           if key == keys.b then\r",
  1571.     "               local blTerm, oldTerm = getBlittle()\r",
  1572.     "               renderBlittle = not renderBlittle\r",
  1573.     "               term.setBackgroundColor(colors.black)\r",
  1574.     "               term.clear()\r",
  1575.     "               if renderBlittle then\r",
  1576.     "                   term.redirect(blTerm)\r",
  1577.     "                   blTerm.setVisible(true)\r",
  1578.     "               else\r",
  1579.     "                   term.redirect(oldTerm)\r",
  1580.     "                   blTerm.setVisible(false)\r",
  1581.     "               end\r",
  1582.     "               doRender = true\r",
  1583.     "               scr_x, scr_y = term.current().getSize()\r",
  1584.     "           end\r",
  1585.     "           if (key == keys.c) and (not renderBlittle) then\r",
  1586.     "               local newX = tonumber(bottomPrompt(\"Goto X:\"))\r",
  1587.     "               local newY\r",
  1588.     "               if newX then\r",
  1589.     "                   newY = tonumber(bottomPrompt(\"Goto Y:\"))\r",
  1590.     "                   paint.scrollX = newX or paint.scrollX\r",
  1591.     "                   paint.scrollY = newY or paint.scrollY\r",
  1592.     "               end\r",
  1593.     "               doRender = true\r",
  1594.     "           end\r",
  1595.     "           if (keysDown[keys.leftShift]) and (not isDragging) then\r",
  1596.     "               if key == keys.left then\r",
  1597.     "                   paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],-1,0)\r",
  1598.     "                   doRender = true\r",
  1599.     "               elseif key == keys.right then\r",
  1600.     "                   paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],1,0)\r",
  1601.     "                   doRender = true\r",
  1602.     "               elseif key == keys.up then\r",
  1603.     "                   paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],0,-1)\r",
  1604.     "                   doRender = true\r",
  1605.     "               elseif key == keys.down then\r",
  1606.     "                   paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],0,1)\r",
  1607.     "                   doRender = true\r",
  1608.     "               end\r",
  1609.     "           end\r",
  1610.     "           if keysDown[keys.leftAlt] then\r",
  1611.     "               if #paintEncoded > 1 then\r",
  1612.     "                   if key == keys.equals and paintEncoded[frame+1] then --basically plus\r",
  1613.     "                       local first = deepCopy(paintEncoded[frame])\r",
  1614.     "                       local next = deepCopy(paintEncoded[frame+1])\r",
  1615.     "                       paintEncoded[frame] = next\r",
  1616.     "                       paintEncoded[frame+1] = first\r",
  1617.     "                       frame = frame + 1\r",
  1618.     "                       barmsg = \"Swapped prev frame.\"\r",
  1619.     "                   end\r",
  1620.     "                   if key == keys.minus and paintEncoded[frame-1] then\r",
  1621.     "                       local first = deepCopy(paintEncoded[frame])\r",
  1622.     "                       local next = deepCopy(paintEncoded[frame-1])\r",
  1623.     "                       paintEncoded[frame] = next\r",
  1624.     "                       paintEncoded[frame-1] = first\r",
  1625.     "                       frame = frame - 1\r",
  1626.     "                       barmsg = \"Swapped next frame.\"\r",
  1627.     "                   end\r",
  1628.     "               end\r",
  1629.     "           end\r",
  1630.     "           if not renderBlittle then\r",
  1631.     "               if key == keys.m then\r",
  1632.     "                   local incum = bottomPrompt(\"Set meta: \",metaHistory)\r",
  1633.     "                   paint.m = incum:gsub(\" \",\"\") ~= \"\" and incum or paint.m\r",
  1634.     "                   if paint.m ~= metaHistory[#metaHistory] then\r",
  1635.     "                       table.insert(metaHistory,paint.m)\r",
  1636.     "                   end\r",
  1637.     "                   doRender = true\r",
  1638.     "               end\r",
  1639.     "               if key == keys.f7 then\r",
  1640.     "                   bepimode = not bepimode\r",
  1641.     "                   doRender = true\r",
  1642.     "               end\r",
  1643.     "               if key == keys.t then\r",
  1644.     "                   renderBottomBar(\"Click to place text.\")\r",
  1645.     "                   local mevt\r",
  1646.     "                   repeat\r",
  1647.     "                       mevt = {os.pullEvent(\"mouse_click\")}\r",
  1648.     "                   until mevt[2] == 1 and mevt[4] < scr_y-(renderBlittle and 0 or doRenderBar)\r",
  1649.     "                   local x,y = mevt[3],mevt[4]\r",
  1650.     "                   if renderBlittle then\r",
  1651.     "                       x = 2*x\r",
  1652.     "                       y = 3*y\r",
  1653.     "                   end\r",
  1654.     "                   putDownText(x,y)\r",
  1655.     "                   miceDown = {}\r",
  1656.     "                   keysDown = {}\r",
  1657.     "               end\r",
  1658.     "               if not keysDown[keys.leftAlt] then\r",
  1659.     "                   if key == keys.equals then --basically 'plus'\r",
  1660.     "                       if not paintEncoded[frame+1] then\r",
  1661.     "                           paintEncoded[frame+1] = {}\r",
  1662.     "                           local sheet = paintEncoded[frame]\r",
  1663.     "                           if keysDown[keys.leftShift] then\r",
  1664.     "                               paintEncoded[frame+1] = deepCopy(sheet)\r",
  1665.     "                           end\r",
  1666.     "                       end\r",
  1667.     "                       frame = frame + 1\r",
  1668.     "                       doRender = true\r",
  1669.     "                   elseif key == keys.minus then\r",
  1670.     "                       if frame > 1 then\r",
  1671.     "                           frame = frame - 1\r",
  1672.     "                           doRender = true\r",
  1673.     "                       end\r",
  1674.     "                   end\r",
  1675.     "               end\r",
  1676.     "               if (key == keys.leftCtrl or key == keys.rightCtrl) then\r",
  1677.     "                   keysDown = {}\r",
  1678.     "                   local res = displayMenu()\r",
  1679.     "                   if res == \"exit\" then break end\r",
  1680.     "                   doRender = true\r",
  1681.     "               end\r",
  1682.     "           end\r",
  1683.     "           if (key == keys.f and keysDown[keys.leftShift]) then\r",
  1684.     "               local deredots = {}\r",
  1685.     "               for a = 1, #paintEncoded[frame] do\r",
  1686.     "                   local dot = paintEncoded[frame][a]\r",
  1687.     "                   if dot.x-paint.scrollX > 0 and dot.x-paint.scrollX <= scr_x then\r",
  1688.     "                       if dot.y-paint.scrollY > 0 and dot.y-paint.scrollY <= scr_y then\r",
  1689.     "                           table.insert(deredots,{dot.x-paint.scrollX, dot.y-paint.scrollY})\r",
  1690.     "                       end\r",
  1691.     "                   end\r",
  1692.     "               end\r",
  1693.     "               for y = 1, scr_y-(renderBlittle and 0 or doRenderBar) do\r",
  1694.     "                   for x = 1, scr_x do\r",
  1695.     "                       local good = true\r",
  1696.     "                       for a = 1, #deredots do\r",
  1697.     "                           if (deredots[a][1] == x) and (deredots[a][2] == y) then\r",
  1698.     "                               good = bad\r",
  1699.     "                               break\r",
  1700.     "                           end\r",
  1701.     "                       end\r",
  1702.     "                       if good then\r",
  1703.     "                           table.insert(paintEncoded[frame],{\r",
  1704.     "                               x = x+paint.scrollX,\r",
  1705.     "                               y = y+paint.scrollY,\r",
  1706.     "                               c = \" \",\r",
  1707.     "                               t = paint.t,\r",
  1708.     "                               b = paint.b,\r",
  1709.     "                               m = paint.m,\r",
  1710.     "                           })\r",
  1711.     "                       end\r",
  1712.     "                   end\r",
  1713.     "               end\r",
  1714.     "               doRender = true\r",
  1715.     "           end\r",
  1716.     "           if key == keys.g then\r",
  1717.     "               paint.doGray = not paint.doGray\r",
  1718.     "               doRender = true\r",
  1719.     "           end\r",
  1720.     "           if key == keys.a then\r",
  1721.     "               paint.scrollX = 0\r",
  1722.     "               paint.scrollY = 0\r",
  1723.     "               doRender = true\r",
  1724.     "           end\r",
  1725.     "           if key == keys.f1 then\r",
  1726.     "               guiHelp()\r",
  1727.     "           end\r",
  1728.     "           if key == keys.leftBracket then\r",
  1729.     "               os.queueEvent(\"mouse_scroll\",2,1,1)\r",
  1730.     "           elseif key == keys.rightBracket then\r",
  1731.     "               os.queueEvent(\"mouse_scroll\",1,1,1)\r",
  1732.     "           end\r",
  1733.     "       elseif evt[1] == \"key_up\" then\r",
  1734.     "           local key = evt[2]\r",
  1735.     "           keysDown[key] = false\r",
  1736.     "       end\r",
  1737.     "       if (oldx~=paint.scrollX) or (oldy~=paint.scrollY) then\r",
  1738.     "           doRender = true\r",
  1739.     "       end\r",
  1740.     "       if doRender then\r",
  1741.     "           renderPAIN(paintEncoded[frame],paint.scrollX,paint.scrollY,true)\r",
  1742.     "           doRender = false\r",
  1743.     "       end\r",
  1744.     "   end\r",
  1745.     "end\r",
  1746.     "\r",
  1747.     "if not shell then return end\r",
  1748.     "\r",
  1749.     "fileName = shell.resolve(tostring(tArg[1]))\r",
  1750.     "\r",
  1751.     "if not fs.exists(fileName) then\r",
  1752.     "   paintEncoded = {{}}\r",
  1753.     "else\r",
  1754.     "   local file = fs.open(fileName,\"r\")\r",
  1755.     "   local contents = file.readAll()\r",
  1756.     "   file.close()\r",
  1757.     "   if type(tun(contents)) ~= \"table\" then\r",
  1758.     "       if pMode ~= 1 then print(\"Importing from NFP...\") end\r",
  1759.     "       paintEncoded = {importFromNFP(contents)}\r",
  1760.     "       if fileName:sub(-4,-1) == \".nfp\" then\r",
  1761.     "           fileName = fileName:sub(1,-5)\r",
  1762.     "       end\r",
  1763.     "   else\r",
  1764.     "       paintEncoded = tun(contents)\r",
  1765.     "   end\r",
  1766.     "end\r",
  1767.     "\r",
  1768.     "paintEncoded = tun(tse(paintEncoded):gsub(\"bg\",\"b\"):gsub(\"txt\",\"t\"):gsub(\"char\",\"c\"):gsub(\"meta\",\"m\")) -- gotta have backwards compatibility, sorta\r",
  1769.     "\r",
  1770.     "if not paintEncoded[frame] then paintEncoded = {paintEncoded} end\r",
  1771.     "if pMode == 1 then\r",
  1772.     "   doRenderBar = 0\r",
  1773.     "   renderPAIN(paintEncoded[tonumber(tArg[5]) or 1],tonumber(tArg[3]) or 0,tonumber(tArg[4]) or 0)\r",
  1774.     "   sleep(0)\r",
  1775.     "   return\r",
  1776.     "else\r",
  1777.     "   renderPAIN(paintEncoded[frame],paint.scrollX,paint.scrollY,true)\r",
  1778.     "end\r",
  1779.     "lastPaintEncoded = deepCopy(paintEncoded)\r",
  1780.     "\r",
  1781.     "parallel.waitForAny(getInput,doNonEventDrivenMovement)\r",
  1782.     "\r",
  1783.     "term.setCursorPos(1,scr_y)\r",
  1784.     "term.setBackgroundColor(colors.black)\r",
  1785.     "term.clearLine()",
  1786.   },
  1787.   [ "/t" ] = {
  1788.     "",
  1789.     "         55555555          ",
  1790.     "         55555555          ",
  1791.     "         55555555          ",
  1792.     "        55555555           ",
  1793.     "        55555555           ",
  1794.     "        d555555            ",
  1795.     "       ddd5555             ",
  1796.     "       dddd555             ",
  1797.     "       dddd55     55555555 ",
  1798.     "   555dddddd5555555555555  ",
  1799.     "55555555ddddd5555555555    ",
  1800.     "5555555555dddd5555         ",
  1801.     "  555555555d               ",
  1802.     "      55555                ",
  1803.     "      55555                ",
  1804.     "      55555                ",
  1805.     "      55555                ",
  1806.     "      dd555                ",
  1807.     "      55dd5          dd5555",
  1808.     "      dd55dd        5dddd55",
  1809.     "      dddd55        5555ddd",
  1810.     "      ddddddd       555555d",
  1811.     "       dddddd       d555555",
  1812.     "       ddddddd     55d55555",
  1813.     "       dddddddd   ddd5dd55 ",
  1814.     "       ddddddddddddddd55dd ",
  1815.     "        dddddddddddddddd5  ",
  1816.     "        ddddddddddddddddd  ",
  1817.     "        dddddddddddddddd   ",
  1818.     "         ddddddddddddddd   ",
  1819.     "          ddddddddddddd    ",
  1820.     "           ddddddddddd     ",
  1821.     "              ddddddd      ",
  1822.     "",
  1823.   },
  1824.   [ "/render" ] = {
  1825.     "local mon = peripheral.find(\"monitor\") if mon then mon.setTextScale(0.5) end",
  1826.     "local sx,sy = term.getSize()",
  1827.     "letters = {}",
  1828.     "letters[1] = {",
  1829.     "  path = \"/P\", --path to paint file",
  1830.     "  x = 1,       --start x",
  1831.     "  xsize = 31,  --horizontal size of paint file",
  1832.     "}",
  1833.     "letters[2] = {",
  1834.     "  path = \"/r\",",
  1835.     "  x = letters[1].x+letters[1].xsize-2,",
  1836.     "  xsize = 25,",
  1837.     "}",
  1838.     "letters[3] = {",
  1839.     "  path = \"o\",",
  1840.     "  x = letters[2].x+letters[2].xsize+1,",
  1841.     "  xsize = 18,",
  1842.     "}",
  1843.     "letters[4] = {",
  1844.     "  path = \"j\",",
  1845.     "  x = letters[3].x+letters[3].xsize+2,",
  1846.     "  xsize = 19,",
  1847.     "}",
  1848.     "letters[5] = {",
  1849.     "  path = \"e\",",
  1850.     "  x = letters[4].x+letters[4].xsize+2,",
  1851.     "  xsize = 22,",
  1852.     "}",
  1853.     "letters[6] = {",
  1854.     "  path = \"c\",",
  1855.     "  x = letters[5].x+letters[5].xsize+2,",
  1856.     "  xsize = 22,",
  1857.     "}",
  1858.     "letters[7] = {",
  1859.     "  path = \"t\",",
  1860.     "  x = letters[6].x+letters[5].xsize-4,",
  1861.     "  xsize = 28,",
  1862.     "}",
  1863.     "letters[8] = {",
  1864.     "  path = \"BETA\",",
  1865.     "  xsize = 170,",
  1866.     "  y = 37,",
  1867.     "}",
  1868.     "letters[8].x = (sx/2)-(letters[8].xsize/2)",
  1869.     "local totalWidth = 0",
  1870.     "for a = 1, #letters do",
  1871.     "  totalWidth = totalWidth + letters[a].xsize",
  1872.     "  if a > 1 then",
  1873.     "    totalWidth = totalWidth + letters[a].x-letters[a-1].x",
  1874.     "  end",
  1875.     "end",
  1876.     "",
  1877.     "clearLines = function(start,stop)",
  1878.     "  local cx,cy = term.getCursorPos()",
  1879.     "  for y = start,stop do",
  1880.     "    term.setCursorPos(1,y)",
  1881.     "    term.clearLine()",
  1882.     "  end",
  1883.     "  term.setCursorPos(cx,cy)",
  1884.     "end",
  1885.     "p = {}",
  1886.     "l = {}",
  1887.     "for a = 1, #letters do",
  1888.     "  p[a] = paintutils.loadImage(letters[a].path)",
  1889.     "  l[a] = letters[a]",
  1890.     "end",
  1891.     "",
  1892.     "render = function(x,spacing)",
  1893.     "  term.setBackgroundColor(colors.black)",
  1894.     "  clearLines(1,35)",
  1895.     "  for a = 1, #p do",
  1896.     "    local drawX = (x+l[a].x)-(spacing*(a-(#letters/2)))",
  1897.     "    if a == 8 then --draw \"</BETA>\"",
  1898.     "      drawX = 1",
  1899.     "    end",
  1900.     "    paintutils.drawImage(p[a],drawX,l[a].y or 2)",
  1901.     "  end",
  1902.     "end",
  1903.     "--render(1,1)",
  1904.     "",
  1905.   },
  1906.   [ "/BETA" ] = {
  1907.     "            11111111             111111 11111111111111111111       11111111111111111111111 11111111111111111111111        11111111              11111111            ",
  1908.     "           11111111              111111 111111111111111111111      11111111111111111111111 11111111111111111111111       1111111111              11111111           ",
  1909.     "          11111111              111111  1111111111111111111111     11111111111111111111111 11111111111111111111111       1111111111               11111111          ",
  1910.     "         11111111               111111  1111111111111111111111     11111111111111111111111 11111111111111111111111      111111111111               11111111         ",
  1911.     "        11111111               111111   111111           111111    11111                 1 1        1111         1      111111111111                11111111        ",
  1912.     "       11111111                111111   111111            11111    11111                            1111               111111  111111                11111111       ",
  1913.     "      11111111                111111    111111             1111    11111                            1111               111111  111111                 11111111      ",
  1914.     "     11111111                 111111    111111            11111    11111                            1111              111111    111111                 11111111     ",
  1915.     "    11111111                 111111     111111           11111     11111                            1111              111111    111111                  11111111    ",
  1916.     "   11111111                  111111     111111111111111111111      111111111111111111               1111             111111      111111                  11111111   ",
  1917.     "  11111111                  111111      11111111111111111111111    111111111111111111               1111             111111111111111111                   11111111  ",
  1918.     " 11111111                   111111      111111           1111111   111111111111111111               1111            11111111111111111111                   11111111 ",
  1919.     "11111111                   111111       111111             111111  11111                            1111            11111111111111111111                    11111111",
  1920.     " 11111111                  111111       111111              11111  11111                            1111           111111          111111                  11111111 ",
  1921.     "  11111111                111111        111111               1111  11111                            1111           111111          111111                 11111111  ",
  1922.     "   11111111               111111        111111               1111  11111                            1111          111111            111111               11111111   ",
  1923.     "    11111111             111111         111111               1111  11111                            1111          111111            111111              11111111    ",
  1924.     "     11111111            111111         111111               1111  11111                            1111         111111              111111            11111111     ",
  1925.     "      11111111          111111          111111              11111  11111                            1111         111111              111111           11111111      ",
  1926.     "       11111111         111111          111111             111111  11111                            1111        111111                111111         11111111       ",
  1927.     "        11111111       111111           111111           11111111  11111                 1          1111        111111                111111        11111111        ",
  1928.     "         11111111      111111           111111111111111111111111   11111111111111111111111          1111       111111                  111111      11111111         ",
  1929.     "          11111111    111111            11111111111111111111111    11111111111111111111111          1111       111111                  111111     11111111          ",
  1930.     "           11111111   111111            1111111111111111111111     11111111111111111111111          1111      111111                    111111   11111111           ",
  1931.     "            11111111 111111             11111111111111111111       11111111111111111111111         111111    11111111                  11111111 11111111            ",
  1932.     "",
  1933.   },
  1934. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement