-- Rhythmblock - music player for CC: Tweaked -- (c) 2021 mint -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -- Change these lines to change the GUI colors. accentColor = colors.gray buttonColor = colors.lightGray textColor = colors.lightGray backgroundColor = colors.black -- Code starts from here function round(n) -- We need a function to round the center of the terminal return n % 1 >= 0.5 and math.ceil(n) or math.floor(n) end width, height = term.getSize() -- Gets the terminal size to determine the center centerWidth = round(width / 2) -- Defines the horizontal center centerHeight = round(height / 2) -- Defines the vertical center if arg[1] == nil then peripherals = peripheral.getNames() -- Gets peripherals to check if any disk drives are available if #peripherals == 0 then term.setTextColor(colors.red) print("No drive") return false -- Exits if there's no disk drive else driveCount = 0 for n = 1, #peripherals do local driveCheck = peripherals[n] if peripheral.getType(driveCheck) == "drive" then drive = driveCheck driveCount = driveCount + 1 end end if driveCount > 1 then term.setTextColor(colors.red) print("Too many disk drives. Specify where the desired disk drive is located by running 'rhythmblock [drive position]'") -- For safety reasons return false elseif driveCount == 0 then term.setTextColor(colors.red) print("No drive") return false -- Exits if there's no disk drive end end else drive = arg[1] end --[[ Instead of calling every status by string, we call the variables storing the strings. This may ease translation if we plan to do so in the future. ]] defaultStatus = "Rhythmblock" invalidFormatStatus = "Not a music disc" noDiscStatus = "No disc" noAudioStatus = "No audio is playing" ejectText = "Eject" function playDisc() term.clear() if disk.isPresent(drive) and disk.hasAudio(drive) then -- Determines if there's a disc or not and if it's a music disc disk.playAudio(drive) buttonRender(true) playing = true status = disk.getAudioTitle(drive) buttonRender(true) elseif disk.isPresent(drive) then status = invalidFormatStatus buttonRender(false) else -- If none of these checks are passed then it just means there's no disc in the drive. status = noDiscStatus buttonRender(false) end end function ejectDisc() -- Ejects the disc! How cool is that? term.clear() buttonRender(false) if playing then stopDisc() disk.eject(drive) elseif disk.isPresent(drive) then -- If there's a disc, it'll be ejected. disk.eject(drive) else -- If not it'll report there's no disc. status = noDiscStatus end end function stopDisc() -- Stops the music playing = false status = defaultStatus disk.stopAudio(drive) term.clear() buttonRender(false) end function renderPlayButton() -- Renders the Play button paintutils.drawFilledBox(centerWidth - 4, centerHeight - 4, centerWidth + 4, centerHeight + 2, accentColor) paintutils.drawFilledBox(centerWidth - 2, centerHeight - 3, centerWidth - 1, centerHeight + 1, buttonColor) paintutils.drawFilledBox(centerWidth, centerHeight - 2, centerWidth + 1, centerHeight, buttonColor) paintutils.drawPixel(centerWidth + 2, centerHeight - 1, buttonColor) end function renderStopButton() -- Renders the Stop button paintutils.drawFilledBox(centerWidth - 4, centerHeight - 4, centerWidth + 4, centerHeight + 2, accentColor) paintutils.drawFilledBox(centerWidth - 2, centerHeight - 3, centerWidth + 2, centerHeight + 1, buttonColor) end function renderEjectButton() -- Renders the Eject button paintutils.drawLine(centerWidth - 3, centerHeight + 4, centerWidth + 3, centerHeight + 4, accentColor) term.setTextColor(buttonColor) term.setCursorPos(centerWidth - 2, centerHeight + 4) term.write(ejectText) end function renderCloseButton() -- Renders the Close button term.setCursorPos(width - 1, 1) term.setTextColor(textColor) term.setBackgroundColor(backgroundColor) term.write(" x") end function buttonRender(play) -- Render some buttons depending if the computer is advanced or not if play then renderStopButton() else renderPlayButton() end if term.isColour() then renderEjectButton() renderCloseButton() end end function statusRender(s) -- Renders the status bar term.setCursorPos(1, 1) term.setTextColor(textColor) term.setBackgroundColor(backgroundColor) term.write(s) end term.clear() term.setBackgroundColor(backgroundColor) -- Setting the background color buttonRender(false) status = defaultStatus -- Setting the value to the default while true do statusRender(status) -- Renders the status if term.isColour() then -- Renders the close button (if the song title is too long, the close button kind of disappears) renderCloseButton() end local eventData = {os.pullEvent()} local event = eventData[1] if event == "mouse_up" then -- If the event triggered is the mouse clicking it'll do what's next if eventData[2] == 1 and eventData[3] >= centerWidth - 4 and eventData[4] >= centerHeight - 4 and eventData[3] <= centerWidth + 4 and eventData[4] <= centerHeight + 2 then -- If the user clicks on the play/stop button it'll begin playing the disc if playing then stopDisc() else playDisc() end elseif eventData[2] == 1 and eventData[3] >= centerWidth - 2 and eventData[4] >= centerHeight + 4 and eventData[3] <= centerWidth + 2 and eventData[4] <= centerHeight + 4 then -- If the user clicks on the eject button it'll eject the disc ejectDisc() elseif eventData[2] == 1 and eventData[3] == width and eventData[4] == 1 then -- If the user presses the X it'll quit stopDisc() term.clear() term.setCursorPos(1, 1) return true end elseif event == "key_up" then -- Same order but now with keys local name = keys.getName(eventData[2]) or "unknown key" if name == "space" then if playing then stopDisc() else playDisc() end elseif name == "e" then ejectDisc() elseif name == "q" then stopDisc() term.clear() term.setCursorPos(1, 1) return true end end end