mirror of
https://fem.mint.lgbt/m/Rhythmblock.git
synced 2024-08-14 20:27:11 +00:00
203 lines
6.9 KiB
Lua
203 lines
6.9 KiB
Lua
--[[
|
|
|
|
Rhythmblock - a graphical music player for CC: Tweaked
|
|
(c) 2021 mint <they@mint.lgbt>
|
|
|
|
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 <https://www.gnu.org/licenses/>.
|
|
|
|
--]]
|
|
|
|
-- 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
|