Brick icon

ComputerCraft Auto-Jukebox

Brick | PRO | 08/30/15 12:11:44 PM UTC | 0 ⭐ | 406 👁️ | Never ⏰ | []
Lua |

6.35 KB

|

None

|

0 👍

/

0 👎

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

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎