Advertisement
Rolcam

RVRX's Computronics Cassette Utility

Jul 12th, 2024 (edited)
11
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.56 KB | None | 0 0
  1. --[[
  2. From: RVRX
  3. https://raw.githubusercontent.com/RVRX/computronics-tape-util/master/tape-util.lua
  4.  
  5.  
  6. A Utility Program for Computronics Cassette Tapes.
  7. Provides:
  8.     - automatic tape writing from web location
  9.     - automatic tape looping
  10.     - More in future updates
  11. ]]
  12.  
  13. local args = { ... }
  14.  
  15. --tape check
  16. local tape = peripheral.find("tape_drive")
  17. if not tape then
  18.   print("This program requires a tape drive to run.")
  19.   return
  20. end
  21.  
  22. local function helpText()
  23.     print("Usage:")
  24.     print(" - 'tape-util' to display this help text")
  25.     print(" - 'tape-util loop' to loop a cassette tape")
  26.     print(" - 'tape-util dl [num files] [web dir]' to write web directory to tape")
  27.     print(" - 'tape-util dl' to display full download utility help text")
  28.     return
  29. end
  30.  
  31. local function helpTextDl()
  32.     print("Usage:")
  33.     print(" - 'tape-util dl' to display this help text")
  34.     print(" - 'tape-util dl [num files] [web dir]' to write web directory to tape")
  35.     print("directory url must contain ending forward-slash.\nFiles must be named their order number .dfpwm, ex:\n'1.dfpwm', '2.dfpwm', etc")
  36. end
  37.  
  38. --add helpText for loop util, when more features are added.
  39.  
  40.  
  41.  
  42.  
  43.  
  44. --TAPE LOOP CONTENT------------
  45. --Program for looping tracks
  46.  
  47. local tape = peripheral.find("tape_drive")
  48. if not tape then
  49. --  print("This program requires a tape drive to run.")
  50. --  return
  51. end
  52.  
  53. --Returns true if position 1 away is zero
  54. local function seekNCheck()
  55.     --seek 1 and check
  56.     tape.seek(1)
  57.     print("Seeking 1...")
  58.     if tape.read() == 0 then
  59.         return true
  60.     else return false
  61.     end
  62. end
  63.  
  64. --Checks multiple bits into distance to make sure it is actual end of track, and not just a quiet(?) part
  65. local function seekNCheckMultiple()
  66.     for i=1,10 do
  67.         if seekNCheck() == false then
  68.             return false
  69.         end
  70.     end
  71.     return true
  72. end
  73.    
  74. -- this could be made into a more efficient algo?
  75. local function findTapeEnd( ... )
  76.  
  77.     local accuracy = 100
  78.     print("Using accuracy of " .. accuracy)
  79.  
  80.     local tapeSize = tape.getSize()
  81.     print("Tape has size of: " .. tapeSize)
  82.     tape.seek(-tapeSize) -- rewind tape
  83.     local runningEnd = 0
  84.  
  85.     for i=0,tapeSize do --for every piece of the tape
  86.    
  87.         os.queueEvent("randomEvent") -- timeout
  88.         os.pullEvent()               -- prevention
  89.  
  90.  
  91.         tape.seek(accuracy) --seek forward one unit (One takes too long, bigger values not as accurate)
  92.         if tape.read() ~= 0 then --if current location is not a zero
  93.             runningEnd = i*accuracy --Update Running runningEnd var. i * accuracy gets current location in tape
  94.             print("End Candidate: " .. runningEnd)
  95.         elseif seekNCheckMultiple() then --check a few spots away to see if zero as well
  96.             return runningEnd
  97.         --else return runningEnd --otherwise, (if 0) return runningEnd
  98.         end --end if
  99.     end
  100.  
  101. end
  102.  
  103. --Main Function
  104. local function looper( ... )
  105.     print("Initializing...")
  106.     --find tape end
  107.     print("Locating end of song...")
  108.     local endLoc = findTapeEnd()
  109.     print("End of song at position " .. endLoc .. ", or " .. endLoc/6000 .. " seconds in\n")
  110.  
  111.     print("Starting Loop! Hold Ctrl+T to Terminate")
  112.     while true do
  113.         tape.seek(-tape.getSize())
  114.         tape.play()
  115.         print("... Playing")
  116.         sleep(endLoc/6000)
  117.         print("Song Ended, Restarting...")
  118.     end
  119.  
  120.     --play tape until
  121. end
  122.  
  123. --END TAPE LOOP CONTENT---------------------------------
  124.  
  125.  
  126.  
  127.  
  128.  
  129. --START TAPE DL CONTENT--------------------------------
  130. --Credit to the writers of Computronics for the bulk of wrtieTapeModified() function, see README for more info.
  131. local function writeTapeModified(relPath)
  132.     --check for tape drive
  133.     local tape = peripheral.find("tape_drive")
  134.     if not tape then
  135.         print("This program requires a tape drive to run.")
  136.         return
  137.     end
  138.   local file, msg, _, y, success
  139.   local block = 8192 --How much to read at a time
  140.  
  141.   -- if not confirm("Are you sure you want to write to this tape?") then return end
  142.   tape.stop()
  143.   --tape.seek(-tape.getSize()) --MODIFIED this part has been removed to stop seeking back to start between writes
  144.   tape.stop() --Just making sure
  145.  
  146.   local path = shell.resolve(relPath)
  147.   local bytery = 0 --For the progress indicator
  148.   local filesize = fs.getSize(path)
  149.   print("Path: " .. path)
  150.   file, msg = fs.open(path, "rb")
  151.   if not fs.exists(path) then msg = "file not found" end
  152.   if not file then
  153.     printError("Failed to open file " .. relPath .. (msg and ": " .. tostring(msg)) or "")
  154.     return
  155.   end
  156.  
  157.   print("Writing...")
  158.  
  159.   _, y = term.getCursorPos()
  160.  
  161.   if filesize > tape.getSize() then
  162.     term.setCursorPos(1, y)
  163.     printError("Error: File is too large for tape, shortening file")
  164.     _, y = term.getCursorPos()
  165.     filesize = tape.getSize()
  166.   end
  167.  
  168.   repeat
  169.     local bytes = {}
  170.     for i = 1, block do
  171.       local byte = file.read()
  172.       if not byte then break end
  173.       bytes[#bytes + 1] = byte
  174.     end
  175.     if #bytes > 0 then
  176.       if not tape.isReady() then
  177.         io.stderr:write("\nError: Tape was removed during writing.\n")
  178.         file.close()
  179.         return
  180.       end
  181.       term.setCursorPos(1, y)
  182.       bytery = bytery + #bytes
  183.       term.write("Read " .. tostring(math.min(bytery, filesize)) .. " of " .. tostring(filesize) .. " bytes...")
  184.       for i = 1, #bytes do
  185.         tape.write(bytes[i])
  186.       end
  187.       sleep(0)
  188.     end
  189.   until not bytes or #bytes <= 0 or bytery > filesize
  190.   file.close()
  191.   tape.stop()
  192.   --tape.seek(-tape.getSize()) --MODIFIED same reaosn as above...
  193.   tape.stop() --Just making sure
  194.   print("\nDone.")
  195. end
  196.  
  197. local function tapeDl(numParts,url)
  198.     --check for tape drive.
  199.     local tape = peripheral.find("tape_drive")
  200.     if not tape then
  201.         print("This program requires a tape drive to run.")
  202.         return
  203.     end
  204.  
  205.     local i = 1 --iterator
  206.  
  207.     --Main Loop
  208.     while i <= tonumber(numParts) do
  209.         shell.run("wget", "" .. url .. i .. ".dfpwm", "/tmp/temp_dl.dfpwm") --wget file
  210.         writeTapeModified("/tmp/temp_dl.dfpwm") --write to tape
  211.         shell.run("rm", "/tmp/temp_dl.dfpwm") -- rm temp file
  212.         i = i + 1 -- i++
  213.     end
  214.     tape.seek(-tape.getSize()) --rewind tape
  215. end
  216. --END TAPE DL CONTENT----------------------------------
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223. if args[1] == "loop" then
  224.     looper()
  225. elseif args[1] == "dl" then
  226.     if args[2] ~= nil then
  227.         print("running tapeDl")
  228.         tapeDl(args[2],args[3])
  229.     else helpTextDl()
  230.     end
  231. else
  232.     helpText()
  233. end
  234.  
  235.  
  236. --[[ known issues:
  237. tape-util dl, does not rewind at start.
  238. tape-util dl, should say when it rewinds at end, that the program is finished.
  239. findTapeEnd, timeout protection might not be necessary anymore, adding bloat.
  240. looper(), could do with some cleaner prints. can screen be cleared?
  241. looper(), needs accuracy argument! will be very slow on larger cassettes to find length
  242.  
  243. ]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement