64_Tesseract

quadfilt

May 15th, 2021 (edited)
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.20 KB | None | 0 0
  1. --[[
  2. Converts simple commands to FILT colours for my "Quad-Instruction FILT Computer" [2714304] in The Powder Toy
  3. To use, create a .txt file with a command per line, open the TPT console with ~ and type:
  4.     dofile("PATH-TO-THIS-SCRIPT")
  5. Replace PATH-TO-THIS-SCRIPT with the complete directory and any backslashes with 2 backslashes (if on Windows), for example:
  6.     dofile("C:\\Users\\User\\Downloads\\quadfilt.lua")
  7. Then type the directory to your script in the prompt, with only 1 slash for folders this time. You may like to add a suffix directory below this comment block, so you only have to type the file name in only a specific folder. Close the dialog box, and click on the top-right most white FILT that's sticking out of the memory rectangle.
  8.  
  9. Keep in mind that the computer starts reading from pixel 0, so if you're setting variables
  10.  
  11. Available commands (anything else will be ignored):
  12.     `sub [a] [b]`: Subtracts [b] from [a], and puts the result in [a]
  13.    `goto [a] [b]`: If [a] <= 0, set the instruction position to [b]
  14.       `print [a]`: Outputs the value of [a] to the display module
  15.        `read [a]`: Waits for the input module to send a number, and puts the value into [a]
  16.         `set [a]`: Sets the pixel in memory to a numeric value
  17.  
  18. Adding `(TEXT)` to the end of a line will mark it as a memory position that can be referred to later. All instances of `[TEXT]` will be replaced with the RAM/ROM index of the line with `(TEXT)` in it. For example, the following script will subtract 5 from 12 and replace 12 with the result, then loop until the number at 12 is less than or equal to 0:
  19.  
  20. 0| sub [count] [inc] (start)
  21. 1| goto [count] [start]
  22. 2|
  23. 3| set 5 (inc)
  24. 4| set 12 (count)
  25.  
  26. If you were to look at the code after it has been processed, you would see `[start]` has been replaced with 0, `[count]` with 4, etc.
  27. ]]
  28.  
  29. folder = "C:\\"  -- Set this to the folder with your scripts, for example: "C:\\Users\\User\\Documents\\"
  30. debugMode = false
  31.  
  32. numAdd = 0x20000000  -- All numbers need the last bit set, in case it's a zero and the default value is sent instead
  33.  
  34. -- Numbers corresponding to commands
  35. commandNums = {["sub"] = 0, ["goto"] = 1, ["print"] = 2, ["read"] = 3}
  36.  
  37. function command_to_num (args)
  38.     if not contains(commandNums, args[1]) then return nil end
  39.  
  40.     local mode = commandNums[args[1]]
  41.     local a = tonumber(args[2])
  42.     local b = 0
  43.     if mode <= 1 then b = tonumber(args[3]) end
  44.  
  45.     if a == nil or b == nil then return nil end
  46.  
  47.     return bit.bor(numAdd, a, bit.lshift(b, 13), bit.lshift(mode, 27))
  48. end
  49.  
  50. function contains (tbl, element)
  51.     for key, value in pairs(tbl) do
  52.         if key == element then
  53.             return true
  54.         end
  55.     end
  56.     return false
  57. end
  58.  
  59. function contains_tag (str)
  60.     return string.match(str, "%(%w+%)")
  61. end
  62.  
  63. function split (splitted, sep)
  64.     if sep == nil then
  65.         sep = "%s"
  66.     end
  67.     local t = {}
  68.     for str in string.gmatch(splitted, "([^" .. sep .. "]+)") do
  69.         table.insert(t, str)
  70.     end
  71.     return t
  72. end
  73.  
  74. function get_len (tbl)
  75.     count = 0
  76.     for _ in pairs(tbl) do count = count + 1 end
  77.     return count
  78. end
  79.  
  80. function file_exists (file)
  81.     local f = io.open(file, "rb")
  82.     if f then f:close() end
  83.     if f == nil then
  84.         tpt.log("\nFailed to load file")
  85.     end
  86.     return f ~= nil
  87. end
  88.  
  89. function lines_from (file)
  90.     if not file_exists(file) then return false end
  91.     lines = {}
  92.     tpt.log("\nReading")
  93.     for line in io.lines(file) do
  94.         table.insert(lines, line)
  95.     end
  96.     return lines
  97. end
  98.  
  99. function generate_script (file)
  100.     lines = lines_from(file)
  101.     strippedLines = {}
  102.     commands = {}
  103.     gotoTags = {}
  104.  
  105.     if not lines then
  106.         if debugMode then tpt.log("\nNo input!") end
  107.         return nil
  108.     end
  109.  
  110.     for index, command in pairs(lines) do  -- Ignore invalid commands
  111.         args = split(command)
  112.         if contains(commandNums, args[1]) or args[1] == "set" then
  113.             table.insert(strippedLines, command)
  114.         end
  115.     end
  116.  
  117.     if debugMode then tpt.log("\nGoto tags are as follows") end
  118.     for index, command in pairs(strippedLines) do  -- Store tag if present
  119.         tag = contains_tag(command)
  120.         args = split(command)
  121.         if tag ~= nil then
  122.             tag = string.gsub(tag, "[%(%)]", "")
  123.             gotoTags[tag] = index - 1
  124.             if debugMode then tpt.log("\n    " .. tag .. ": " .. gotoTags[tag]) end
  125.         end
  126.     end
  127.  
  128.     for index, command in pairs(strippedLines) do  -- Replace all tags with their value
  129.         for tag, value in pairs(gotoTags) do
  130.             command = string.gsub(command, "%[" .. tag .. "%]", value)
  131.         end
  132.         strippedLines[index] = command  -- Overwrite new command
  133.     end
  134.  
  135.  
  136.     if debugMode then tpt.log("\n" .. get_len(strippedLines) .. " lines are as follows:") end
  137.     for index, command in pairs(strippedLines) do
  138.         if debugMode then tpt.log("\n    " .. command) end
  139.         args = split(command)
  140.         local filtVal = nil
  141.  
  142.         if contains(commandNums, args[1]) then  -- Set values to commands if specified
  143.             filtVal = command_to_num(args)
  144.             if filtVal == nil then
  145.                 tpt.log("\nError at line " .. index .. ":\n    " .. command)
  146.                 return nil
  147.             end
  148.  
  149.         elseif args[1] == "set" then  -- Set value to raw number
  150.             local num = tonumber(args[2])
  151.             if num == nil then
  152.                 tpt.log("\nError at line " .. index .. ":\n    " .. command)
  153.                 return nil
  154.             end
  155.             filtVal = bit.bor(numAdd, num)
  156.         end
  157.  
  158.         table.insert(commands, filtVal)
  159.     end
  160.  
  161.     return commands
  162. end
  163.  
  164. function paste_script (commands)
  165.     tpt.log("\nCreating " .. get_len(commands) .. " commands")
  166.     for index, command in pairs(commands) do
  167.         if debugMode then tpt.log(command) end
  168.         x, y = sim.adjustCoords(tpt.mousex, tpt.mousey)
  169.         x = x - (index - 1) % 64 - 1
  170.         y = y + math.floor((index - 1) / 64) + 1
  171.         tpt.create(x, y, "filt")
  172.         tpt.set_property("tmp", 0, x, y)
  173.         tpt.set_property("ctype", command, x, y)
  174.     end
  175. end
  176.  
  177. function preview_code ()
  178.     x, y = sim.adjustCoords(tpt.mousex, tpt.mousey)
  179.     graphics.fillRect(x - 64, y + 1, 64, 128, 255, 0, 0, 96)
  180.     graphics.drawLine(x, y, x, y + 128, 255, 255, 255, 96)
  181. end
  182.  
  183. function click_paste (x, y, btn)
  184.     if btn == 1 then
  185.         paste_script(cmds)
  186.     end
  187.     stop_listen()
  188. end
  189.  
  190. function start_listen ()
  191.     event.register(event.tick, preview_code)
  192.     event.register(event.mousedown, click_paste)
  193.     tpt.set_console(0)
  194.     tpt.message_box("Notice", "Make sure the computer is reset, then align & left click")
  195.     tpt.log("\nReady to")
  196. end
  197.  
  198. function stop_listen ()
  199.     cmds = nil
  200.     event.register(event.tick, preview_code)
  201.     event.unregister(event.tick, preview_code)
  202.     event.unregister(event.mousedown, click_paste)
  203.     tpt.log("\nDone")
  204. end
  205.  
  206.  
  207. if debugMode then tpt.log("\nLoaded code") end
  208. file = tpt.input("Script file", "Convert script file\n" .. folder, "")
  209. if file == "" then
  210.     tpt.log("\nCancelled")
  211.     return
  212. end
  213. cmds = generate_script(folder .. file)
  214.  
  215. if cmds then
  216.     start_listen()
  217. else
  218.     stop_listen()
  219. end
Advertisement
Add Comment
Please, Sign In to add comment