disksInfo = { ["C418 - 11"] = {duration=75, title="C418 - 11"}, ["C418 - 13"] = {duration=178, title="C418 - 13"}, ["C418 - blocks"] = {duration=355, title="C418 - Blocks"}, ["C418 - cat"] = {duration=188, title="C418 - Cat"}, ["C418 - chirp"] = {duration=186, title="C418 - Chirp"}, ["C418 - far"] = {duration=172, title="C418 - Far"}, ["C418 - mall"] = {duration=200, title="C418 - Mall"}, ["C418 - mellohi"] = {duration=99, title="C418 - Mellohi"}, ["C418 - stal"] = {duration=156, title="C418 - Stal"}, ["C418 - strad"] = {duration=193, title="C418 - Strad"}, ["C418 - wait"] = {duration=235, title="C418 - Wait"}, ["C418 - ward"] = {duration=251, title="C418 - Ward"}, ["pg.radioloop"] = {duration=25, title="Valve - Radio Loop"}, ["pg.stillalive"] = {duration=175, title="Valve - Still Alive"}, ["pg.wantyougone"] = {duration=135, title="Valve - Want You Gone"}, } math.randomseed(os.time()) finishTimer = nil startTime = 0 diskInfo = nil state = "startup" drive = nil -- Face turtle towards Disk Drive for i = 1, 4 do if peripheral.getType("front") == "drive" then drive = peripheral.wrap("front") break end turtle.turnLeft() end if drive == nil then error("Disk Drive not found") end monitor = peripheral.find("monitor") function changeDisk(direction) turtle.suck() local disks = {} for i = 1, 16 do if turtle.getItemCount(i) ~= 0 then table.insert(disks, i) end end if #disks == 0 then error("No disks found") end local slot = 1 if direction == nil then slot = disks[math.random(#disks)] else current_slot = turtle.getSelectedSlot() for k, v in pairs(disks) do if v >= current_slot then slot = disks[((k + direction - 1) % #disks) + 1] break end end end if turtle.getItemCount(slot) ~= 1 then error("No disk Found") end turtle.select(slot) turtle.drop() if not drive.hasAudio() then error("Item is not a disk") end end function renderButton(text, active, color) local old_color = monitor.getTextColor() if (active == nil) or (active == state) then monitor.setTextColor(color) else monitor.setTextColor(colors.gray) end monitor.write(text) monitor.setTextColor(old_color) end function renderFooter() if (monitor ~= nil) and monitor.isColor() then monitor.setCursorPos(1,5) monitor.clearLine() renderButton("[]", "stopped", colors.red) renderButton("<<", nil, colors.blue) renderButton("[?]", nil, colors.yellow) renderButton(">>", nil, colors.blue) renderButton("[>", "playing", colors.green) end end function startPlayback() if finishTimer ~= nil then print("Already playing") return end if not drive.hasAudio() then changeDisk(1) end local title = drive.getAudioTitle() if title == nil then print("No disk found") changeDisk(1) end diskInfo = disksInfo[title] if diskInfo == nil then print("No disk info found for " .. title) changeDisk(1) end term.clear() term.setCursorPos(1,2) print("Playing " .. diskInfo["title"] .. " for " .. diskInfo["duration"] .. " seconds") state = "playing" if monitor ~= nil then monitor.clear() monitor.setCursorPos(1,1) monitor.setTextColor(colors.gray) monitor.write("Now Playing:") monitor.setCursorPos(2,2) monitor.setTextColor(colors.white) monitor.write(diskInfo["title"]) renderFooter() end drive.playAudio() finishTimer = os.startTimer(diskInfo["duration"]) startTime = os.clock() renderDuration() print("[P]lay, [F]orward, [B]ack, [S]top") end function stopPlayback() drive.stopAudio() finishTimer = nil startTime = 0 state = "stopped" if monitor ~= nil then monitor.clear() monitor.setCursorPos(1,1) monitor.setTextColor(colors.gray) monitor.write("Stopped...") renderFooter() end print("Stopped") end function playDisk(direction) stopPlayback() changeDisk(direction) startPlayback() end function renderDuration() if monitor ~= nil then monitor.setCursorPos(2,3) monitor.clearLine() local timeLeft = math.floor(os.clock() - startTime) if timeLeft > diskInfo["duration"] then timeLeft = diskInfo["duration"] end monitor.setTextColor(colors.white) monitor.write(time_string(timeLeft) .. "/" .. time_string(diskInfo["duration"])) end end function time_string(sec) local min = math.floor((sec/60)) local secs = sec - (min * 60) if secs < 10 then secs = "0" .. secs end return min .. ":" .. secs end startPlayback() while true do local ev, p1, p2, p3 = os.pullEvent() if state == "playing" then -- Placed outside of timer loop to fix issues with timer in multiplayer os.startTimer(1) renderDuration() end if ev == "timer" then if finishTimer == p1 and drive.hasAudio() then playDisk(1) end elseif ev == "char" then if p1 == 'p' then startPlayback() elseif p1 == 'f' then playDisk(1) elseif p1 == 'b' then playDisk(-1) elseif p1 == 's' then stopPlayback() elseif p1 == 'r' then playDisk(nil) end elseif ev == "monitor_touch" then local x = p2 local y = p3 if y == 5 then if x == 1 or x == 2 then stopPlayback() elseif x == 3 or x == 4 then playDisk(-1) elseif x == 5 or x == 6 or x == 7 then playDisk(nil) elseif x == 8 or x == 9 then playDisk(1) elseif x == 10 or x == 11 then startPlayback() end renderFooter() end end end