forked from hkc/cc-stuff
1
0
Fork 0
cc-stuff/tape-playlist.lua

100 lines
2.9 KiB
Lua
Raw Normal View History

2023-10-17 15:28:43 +03:00
local drive = peripheral.find("tape_drive")
2023-10-17 15:32:35 +03:00
if not drive then
2023-10-17 15:28:43 +03:00
printError("no tape drive found")
printError("it's kinda required to play tapes, you know?")
return
end
local running = true
local table_of_contents = {}
local function read32()
local v = 0
for i = 1, 4 do
local b = drive.read()
2023-10-17 15:33:15 +03:00
v = bit32.bor(bit32.lshift(v, 8), b)
2023-10-17 15:28:43 +03:00
end
return v
end
local function bytes2time(b)
local s = math.floor(b / 6000)
if s < 60 then return string.format("%ds", s) end
return string.format("%dm, %ds", math.floor(s / 60), s % 60)
end
2023-10-17 16:16:02 +03:00
local screen_w, screen_h = term.getSize()
2023-10-17 15:28:43 +03:00
parallel.waitForAll(
function()
while running do
2023-10-17 16:28:20 +03:00
for i = 1, math.min(screen_h - 1, 48) do
2023-10-17 16:16:02 +03:00
term.setCursorPos(1, i)
2023-10-17 16:26:53 +03:00
term.clearLine()
2023-10-17 16:16:02 +03:00
local song = table_of_contents[i]
if song then
term.write(string.format("#%2d %9s %s", i, bytes2time(song.length), song.title))
end
end
2023-10-17 16:28:20 +03:00
term.setCursorPos(1, screen_h)
term.write(string.format("%s - %d", drive.getState(), drive.getPosition()))
2023-10-17 15:28:43 +03:00
os.sleep(0.1)
end
end,
function()
while running do
local evd = { os.pullEvent() }
local ev, evd = table.remove(evd, 1), evd
if ev == "mouse_click" then
local x, y = table.unpack(evd, 1)
2023-10-17 16:26:53 +03:00
if drive.isReady() and y <= #table_of_contents then
drive.seek(-drive.getSize())
2023-10-17 16:29:23 +03:00
drive.seek(table_of_contents[y].offset)
2023-10-17 16:26:53 +03:00
drive.play()
end
2023-10-17 16:16:02 +03:00
elseif ev == "term_resize" then
screen_w, screen_h = term.getSize()
2023-10-17 15:28:43 +03:00
elseif ev == "tape_present" then
table_of_contents = {}
if evd[1] then
drive.stop()
2023-10-17 15:28:43 +03:00
drive.seek(-drive.getSize())
for i = 1, 48 do
local offset = read32()
local length = read32()
2023-10-17 16:20:16 +03:00
local title = drive.read(117):gsub("\x00", "")
if length > 0 then
table.insert(table_of_contents, {
title = title,
offset = offset,
length = length,
ending = offset + length
})
end
2023-10-17 15:28:43 +03:00
end
end
end
end
end,
function()
local tape_was_present = nil
local drive_old_state = nil
while running do
local tape_present = drive.isReady()
if tape_present ~= tape_was_present then
os.queueEvent("tape_present", tape_present)
tape_was_present = tape_present
2023-10-17 15:28:43 +03:00
end
local drive_state = drive.getState()
if drive_old_state ~= drive_state then
os.queueEvent("drive_state", drive_state)
drive_old_state = drive_state
2023-10-17 15:28:43 +03:00
end
os.sleep(0.25)
end
end)