marquee and cleanup

This commit is contained in:
visionmercer 2026-06-09 10:36:00 +02:00
commit b6c1a1c1c0

177
cimp.bas
View file

@ -1,9 +1,8 @@
declare library "terminkey" declare library "terminkey"
function terminkey% () function terminkey%()
sub echooff () sub echooff()
sub echoon () sub echoon()
function termwidth () function termwidth()
end declare end declare
$console:only $console:only
@ -26,54 +25,18 @@ end if
echooff echooff
cursoroff cursoroff
chdir _startdir$ chdir _startdir$
dim volume as single dim volume as single
dim repeat as integer dim repeat as integer
dim shuffle as integer dim shuffle as integer
dim nooutput as integer dim nooutput as integer
dim timevis as integer dim timevis as integer
dim nyan as integer dim nyan as integer
dim marqueeOffset as integer
volume = 1 dim i as integer
repeat = 0
shuffle = 0
nooutput = 0
timevis = 1
nyan = 0
for i = 1 to _commandcount
select case command$(i)
case "-v", "--volume"
i = i + 1
volume = val(command$(i)) / 100
case "-s", "--shuffle"
shuffle = -1
case "-r", "--repeat"
if command$(i + 1) = "1" then
repeat = 1
else
repeat = -1
end if
case "-n", "--nooutput"
nooutput = -1
case "-N", "--nyan"
nyan = -1
case else
if _fileexists(command$(i)) then
if lcase$(right$(command$(i), 4)) = ".m3u" then
ParseM3U command$(i), file()
else
file(ubound(file)) = command$(i)
redim _preserve file(ubound(file) + 1)
end if
end if
end select
next
redim _preserve file(ubound(file) - 1)
dim musichandle as long dim musichandle as long
dim oldhandle as long dim oldhandle as long
dim keyin as integer dim keyin as integer
dim playnext as integer dim playnext as integer
@ -82,8 +45,60 @@ dim songname as string
dim progress as string dim progress as string
dim progressbar as string dim progressbar as string
if shuffle = -1 then shufflearray file() dim tw as integer
i = 0 dim fixedWidth as integer
dim maxTitleWidth as integer
dim visibleTitle as string
dim currentSongWidth as integer
dim paddedTitle as string
dim paddedLength as integer
dim idx as integer
dim addedWidth as integer
dim charIdx as integer
dim nextChar as string
dim marqueeFrame as integer
volume=1
repeat=0
shuffle=0
nooutput=0
timevis=1
nyan=0
marqueeOffset=0
for i=1 to _commandcount
select case command$(i)
case "-v", "--volume"
i=i+1
volume=val(command$(i)) / 100
case "-s","--shuffle"
shuffle=-1
case "-r","--repeat"
if command$(i+1)="1" then
repeat=1
else
repeat=-1
end if
case "-n","--nooutput"
nooutput=-1
case "-N","--nyan"
nyan=-1
case else
if _fileexists(command$(i)) then
if lcase$(right$(command$(i), 4))=".m3u" then
ParseM3U command$(i),file()
else
file(ubound(file))=command$(i)
redim _preserve file(ubound(file)+1)
end if
end if
end select
next
redim _preserve file(ubound(file)-1)
if shuffle=-1 then shufflearray file()
i=0
musichandle = _sndopen(file(i)) musichandle = _sndopen(file(i))
if musichandle = 0 then if musichandle = 0 then
print "Error: could not open file "; file(i) print "Error: could not open file "; file(i)
@ -148,7 +163,6 @@ while keyin <> 27
timevis = -timevis timevis = -timevis
case asc("s") case asc("s")
shufflearray file() shufflearray file()
case else
end select end select
if _sndgetpos(musichandle) = _sndlen(musichandle) then playnext = 1 if _sndgetpos(musichandle) = _sndlen(musichandle) then playnext = 1
@ -175,15 +189,57 @@ while keyin <> 27
else else
progress = " " + timeelapsed(musichandle) progress = " " + timeelapsed(musichandle)
end if end if
if nooutput=0 then if nooutput = 0 then
if nyan = -1 then tw = termwidth
print termcolor(7); state; AnimatedRainbowText(songname); termcolor(7); progress; clearrest fixedWidth = UWidth(state) + UWidth(progress)
else maxTitleWidth = tw - fixedWidth - 2
print termcolor(7); state; termcolor(3); songname; termcolor(7); progress; clearrest currentSongWidth = UWidth(songname)
if currentSongWidth > maxTitleWidth and maxTitleWidth > 4 then
paddedTitle = songname + " "
paddedLength = ulen(paddedTitle)
visibleTitle = ""
addedWidth = 0
idx = 0
while addedWidth < maxTitleWidth
charIdx = ((marqueeOffset + idx) mod paddedLength) + 1
nextChar = umid(paddedTitle, charIdx, 1)
if addedWidth + UWidth(nextChar) > maxTitleWidth then exit while
visibleTitle = visibleTitle + nextChar
addedWidth = addedWidth + UWidth(nextChar)
idx = idx + 1
wend
if addedWidth < maxTitleWidth then
visibleTitle = visibleTitle + space$(maxTitleWidth - addedWidth)
end if end if
progressbar = bar(UWidth(state) + UWidth(songname) + UWidth(progress), (_sndgetpos(musichandle) / _sndlen(musichandle)) * 100, 11, 7)
marqueeFrame = marqueeFrame + 1
if marqueeFrame mod 4 = 0 then
marqueeOffset = marqueeOffset + 1
if marqueeOffset >= paddedLength then marqueeOffset = 0
end if
else
' Terminal is wide enough, no scrolling needed
visibleTitle = songname
marqueeOffset = 0
end if
' Reset marquee offset if song changes
if playnext <> 0 then marqueeOffset = 0
' Print the text line
if nyan = -1 then
print termcolor(7); state; AnimatedRainbowText(visibleTitle); termcolor(7); progress; clearrest
else
print termcolor(7); state; termcolor(3); visibleTitle; termcolor(7); progress; clearrest
end if
' Generate and print progress bar matching the layout width
progressbar = bar(UWidth(state) + UWidth(visibleTitle) + UWidth(progress), (_sndgetpos(musichandle) / _sndlen(musichandle)) * 100, 11, 7)
print progressbar; clearrest; cursorback; print progressbar; clearrest; cursorback;
end if end if
_limit 30 _limit 30
if _exit then goto quit if _exit then goto quit
wend wend
@ -199,6 +255,7 @@ system
sub shufflearray (stringarray() as string) sub shufflearray (stringarray() as string)
randomize timer randomize timer
dim n as long, j as long
for n = ubound(stringarray) to 1 step -1 for n = ubound(stringarray) to 1 step -1
j = int(rnd * n) j = int(rnd * n)
swap stringarray(n), stringarray(j) swap stringarray(n), stringarray(j)
@ -206,6 +263,8 @@ sub shufflearray (stringarray() as string)
end sub end sub
sub ParseM3U (filename$, array$()) sub ParseM3U (filename$, array$())
dim i as long, f as long, count as long
dim basePath$, l$, resolvedPath$
for i = len(filename$) to 1 step -1 for i = len(filename$) to 1 step -1
if mid$(filename$, i, 1) = "/" or mid$(filename$, i, 1) = "\" then if mid$(filename$, i, 1) = "/" or mid$(filename$, i, 1) = "\" then
basePath$ = left$(filename$, i) basePath$ = left$(filename$, i)
@ -259,7 +318,6 @@ function termcolor$ (colorvalue as _unsigned long)
end select end select
end function end function
function cursorback$ () function cursorback$ ()
cursorback = chr$(27) + "[F" cursorback = chr$(27) + "[F"
end function end function
@ -283,6 +341,7 @@ end sub
function bar$ (length as integer, percent as integer, color1 as long, color2 as long) function bar$ (length as integer, percent as integer, color1 as long, color2 as long)
dim done as string dim done as string
dim notdone as string dim notdone as string
dim i as integer
for i = 1 to int((percent / 100) * length) for i = 1 to int((percent / 100) * length)
done = done + "━" done = done + "━"
next i next i
@ -300,8 +359,6 @@ function beforelast$ (delim as string, strng as string)
beforelast = left$(strng, _instrrev(strng, delim) - 1) beforelast = left$(strng, _instrrev(strng, delim) - 1)
end function end function
function AnimatedRainbowText$ (text$) function AnimatedRainbowText$ (text$)
static offset as double static offset as double
dim result as string dim result as string
@ -309,6 +366,7 @@ function AnimatedRainbowText$ (text$)
dim r as integer, g as integer, b as integer dim r as integer, g as integer, b as integer
dim hue as double, f as double dim hue as double, f as double
dim sector as integer, v as integer, p as integer, q as integer, t as integer dim sector as integer, v as integer, p as integer, q as integer, t as integer
dim rgbPart$
L = ulen(text$) L = ulen(text$)
if L = 0 then exit function if L = 0 then exit function
@ -353,11 +411,10 @@ end function
function umid$ (txt$, startChar%, numChars%) function umid$ (txt$, startChar%, numChars%)
if startChar% < 1 or numChars% <= 0 or txt$ = "" then exit function if startChar% < 1 or numChars% <= 0 or txt$ = "" then exit function
dim byteIdx%, charCount%, startByte%, endByte% dim byteIdx%, charCount%, startByte%, endByte%, b%
byteIdx% = 1 byteIdx% = 1
charCount% = 0 charCount% = 0
' 1. Find the starting byte of the character at startChar%
while byteIdx% <= len(txt$) while byteIdx% <= len(txt$)
b% = asc(txt$, byteIdx%) b% = asc(txt$, byteIdx%)
if (b% and &H80) = 0 or (b% and &HC0) = &HC0 then if (b% and &H80) = 0 or (b% and &HC0) = &HC0 then
@ -370,23 +427,19 @@ function umid$ (txt$, startChar%, numChars%)
if startByte% = 0 then exit function if startByte% = 0 then exit function
' 2. Find the byte where the sequence ends
byteIdx% = startByte% byteIdx% = startByte%
dim charsFound% dim charsFound%
charsFound% = 0 charsFound% = 0
' We look for the start of the "lastChar + 1" to find the boundary
while byteIdx% <= len(txt$) while byteIdx% <= len(txt$)
b% = asc(txt$, byteIdx%) b% = asc(txt$, byteIdx%)
if (b% and &H80) = 0 or (b% and &HC0) = &HC0 then if (b% and &H80) = 0 or (b% and &HC0) = &HC0 then
charsFound% = charsFound% + 1 charsFound% = charsFound% + 1
end if end if
' If we found the start of the character AFTER our range, stop
if charsFound% > numChars% then exit while if charsFound% > numChars% then exit while
byteIdx% = byteIdx% + 1 byteIdx% = byteIdx% + 1
wend wend
' byteIdx now points to the start of the next char, or LEN+1
umid$ = mid$(txt$, startByte%, byteIdx% - startByte%) umid$ = mid$(txt$, startByte%, byteIdx% - startByte%)
end function end function