@@ -124,12 +124,153 @@ local function FindAlbums(path)
124124 return albums
125125end
126126
127+ local unitExceptions = include (" Configs/snd_music_exception.lua" )
128+
129+ local warThreshold = 5000
130+ local peaceThreshold = 1000
131+ local PLAYLIST_FILE = ' sounds/music/playlist.lua'
132+ local LOOP_BUFFER = 0.015 -- if looping track is this close to the end, go ahead and loop
133+ local UPDATE_PERIOD = 1
134+ local MUSIC_VOLUME_DEFAULT = 0.25
135+
136+ local musicType = ' peace'
137+ local dethklok = {} -- keeps track of the number of doods killed in each time frame
138+ local timeframetimer = 0
139+ local timeframetimer_short = 0
140+ local loopTrack = ' '
141+ local previousTrack = ' '
142+ local previousTrackType = ' '
143+ local currentTrackName = ' '
144+ local haltMusic = false
145+ local looping = false
146+ local musicMuted = false
147+ local musicPaused = false
148+
149+ local initialized = false
150+ local gameStarted = Spring .GetGameFrame () > 0
151+ local widgetReloaded = gameStarted
152+
153+ local myTeam = Spring .GetMyTeamID ()
154+ local isSpec = Spring .GetSpectatingState () or Spring .IsReplay ()
155+ local defeat = false
156+
157+ local spToggleSoundStreamPaused = Spring .PauseSoundStream
158+ local spGetUnitRulesParam = Spring .GetUnitRulesParam
159+
127160local includedAlbums = FindAlbums (' sounds/music/' )
128161local trackListName = includedAlbums .superintendent and ' superintendent' or next (includedAlbums )
129162local trackList = includedAlbums [trackListName ].tracks
130163
164+ local musicTrackWindow
165+ local musicTrackPanel
166+ local musicTrackName
167+ local musicTrackProgress
131168
169+ panel_path = ' Settings/HUD Panels/Music Player'
132170options_path = ' Settings/Audio'
171+
172+ local function UpdateMusicText (track )
173+ currentTrackName = track or currentTrackName
174+ if not musicTrackName then
175+ return
176+ end
177+ musicTrackName :SetCaption (currentTrackName )
178+ end
179+
180+ local function FormatSeconds (seconds )
181+ local minutes = math.floor (seconds / 60 )
182+ return minutes .. " :" .. string.format (" %02d" , seconds - 60 * minutes )
183+ end
184+
185+ local function UpdateMusicProgress (seconds , trackLength )
186+ if not musicTrackProgress then
187+ return
188+ end
189+ musicTrackProgress :SetCaption (FormatSeconds (seconds ) .. " / " .. FormatSeconds (trackLength ))
190+ end
191+
192+ local function InitMusicPanel ()
193+ musicTrackWindow = WG .Chili .Window :New {
194+ parent = WG .Chili .Screen0 ,
195+ noFont = true ,
196+ dockable = true ,
197+ name = " MusicPlayerWindow" ,
198+ padding = {0 ,- 1 ,0 ,0 },
199+ x = 0 ,
200+ y = 120 ,
201+ clientWidth = 300 ,
202+ clientHeight = 40 ,
203+ minHeight = 40 ,
204+ backgroundColor = {0 , 0 , 0 , 0 },
205+ color = {0 , 0 , 0 , 0 },
206+ draggable = false ,
207+ resizable = false ,
208+ tweakDraggable = true ,
209+ tweakResizable = true ,
210+ minimizable = false ,
211+ OnMouseDown = { function (self ) -- OnClick don't work here, probably because its children can steal click
212+ local alt , ctrl , meta , shift = Spring .GetModKeyState ()
213+ if not meta then
214+ return false
215+ end
216+ WG .crude .OpenPath (panel_path )
217+ WG .crude .ShowMenu ()
218+ return true
219+ end },
220+ }
221+ musicTrackPanel = WG .Chili .Panel :New {
222+ parent = musicTrackWindow ,
223+ dockable = true ,
224+ name = name ,
225+ padding = {0 ,0 ,0 ,0 },
226+ color = {1 , 1 , 1 , options .background_opacity .value },
227+ y = 0 ,
228+ x = 0 ,
229+ right = 0 ,
230+ bottom = 0 ,
231+ classname = " main_window_small_very_flat" ,
232+ }
233+ musicTrackName = WG .Chili .Label :New {
234+ parent = musicTrackPanel ,
235+ x = 14 ,
236+ y = 6 ,
237+ right = 14 ,
238+ bottom = 8 ,
239+ caption = " " ,
240+ align = " left" ,
241+ valign = " top" ,
242+ autosize = false ,
243+ -- font = {
244+ -- size = 36,
245+ -- outline = true,
246+ -- outlineWidth = 2,
247+ -- outlineWeight = 2,
248+ -- },
249+ }
250+ if options .music_progress .value then
251+ musicTrackProgress = WG .Chili .Label :New {
252+ parent = musicTrackPanel ,
253+ x = 14 ,
254+ y = 6 ,
255+ right = 14 ,
256+ bottom = 8 ,
257+ caption = " " ,
258+ align = " right" ,
259+ valign = " bottom" ,
260+ autosize = false ,
261+ -- font = {
262+ -- size = 36,
263+ -- outline = true,
264+ -- outlineWidth = 2,
265+ -- outlineWeight = 2,
266+ -- },
267+ }
268+ else
269+ musicTrackProgress = false
270+ end
271+ UpdateMusicText ()
272+ end
273+
133274options = {
134275 pausemusic = {
135276 name = ' Pause Music' ,
@@ -138,6 +279,53 @@ options = {
138279 desc = " Music pauses with game" ,
139280 noHotkey = true ,
140281 },
282+ background_opacity = {
283+ name = " Opacity" ,
284+ type = " number" ,
285+ value = 1 , min = 0 , max = 1 , step = 0.01 ,
286+ path = panel_path ,
287+ OnChange = function (self )
288+ if musicTrackWindow then
289+ musicTrackPanel .color [4 ] = self .value
290+ Spring .Echo (" self.value" , self .value )
291+ musicTrackPanel :Invalidate ()
292+ end
293+ end
294+ },
295+ show_music = {
296+ name = ' Show Track' ,
297+ type = ' bool' ,
298+ value = false ,
299+ desc = " Show currently playing music track" ,
300+ path = panel_path ,
301+ OnChange = function (self )
302+ local value = self .value
303+ if musicTrackWindow then
304+ musicTrackWindow :Dispose ()
305+ musicTrackWindow = false
306+ end
307+ if value and not musicTrackWindow then
308+ InitMusicPanel ()
309+ end
310+ end
311+ },
312+ music_progress = {
313+ name = ' Show Progress' ,
314+ type = ' bool' ,
315+ value = true ,
316+ desc = " Show progress through current track" ,
317+ path = panel_path ,
318+ OnChange = function (self )
319+ local value = options .show_music .value
320+ if musicTrackWindow then
321+ musicTrackWindow :Dispose ()
322+ musicTrackWindow = false
323+ end
324+ if value and not musicTrackWindow then
325+ InitMusicPanel ()
326+ end
327+ end
328+ },
141329 albumSelection = {
142330 name = ' Track list' ,
143331 type = ' radioButton' ,
@@ -187,40 +375,9 @@ options = {
187375 },
188376}
189377
190- local unitExceptions = include (" Configs/snd_music_exception.lua" )
191-
192- local warThreshold = 5000
193- local peaceThreshold = 1000
194- local PLAYLIST_FILE = ' sounds/music/playlist.lua'
195- local LOOP_BUFFER = 0.015 -- if looping track is this close to the end, go ahead and loop
196- local UPDATE_PERIOD = 1
197- local MUSIC_VOLUME_DEFAULT = 0.25
198-
199- local musicType = ' peace'
200- local dethklok = {} -- keeps track of the number of doods killed in each time frame
201- local timeframetimer = 0
202- local timeframetimer_short = 0
203- local loopTrack = ' '
204- local previousTrack = ' '
205- local previousTrackType = ' '
206- local haltMusic = false
207- local looping = false
208- local musicMuted = false
209- local musicPaused = false
210-
211- local initialized = false
212- local gameStarted = Spring .GetGameFrame () > 0
213- local widgetReloaded = gameStarted
214-
215- local myTeam = Spring .GetMyTeamID ()
216- local isSpec = Spring .GetSpectatingState () or Spring .IsReplay ()
217- local defeat = false
218-
219- local spToggleSoundStreamPaused = Spring .PauseSoundStream
220- local spGetUnitRulesParam = Spring .GetUnitRulesParam
221-
222378---- ----------------------------------------------------------------------------
223379---- ----------------------------------------------------------------------------
380+
224381local function GetMusicType ()
225382 return musicType
226383end
@@ -235,6 +392,7 @@ local function StartLoopingTrack(trackInit, trackLoop)
235392
236393 loopTrack = trackLoop
237394 Spring .PlaySoundStream (trackInit , WG .music_volume or MUSIC_VOLUME_DEFAULT )
395+ UpdateMusicText (trackInit )
238396 looping = 0.5
239397end
240398
@@ -284,6 +442,7 @@ local function StartTrack(track)
284442 end
285443 previousTrack = newTrack
286444 Spring .PlaySoundStream (newTrack ,WG .music_volume or MUSIC_VOLUME_DEFAULT )
445+ UpdateMusicText (newTrack )
287446
288447 WG .music_start_volume = WG .music_volume
289448end
@@ -334,13 +493,15 @@ function widget:Update(dt)
334493 timeframetimer_short = timeframetimer_short + dt
335494 if timeframetimer_short > 0.03 then
336495 local playedTime , totalTime = Spring .GetSoundStreamTime ()
496+ UpdateMusicProgress (playedTime , totalTime )
337497 playedTime = tonumber ( (" %.2f" ):format (playedTime ) )
338498 if looping then
339499 if looping == 0.5 then
340500 looping = 1
341501 elseif playedTime >= totalTime - LOOP_BUFFER then
342502 Spring .StopSoundStream ()
343503 Spring .PlaySoundStream (loopTrack ,WG .music_volume or MUSIC_VOLUME_DEFAULT )
504+ UpdateMusicText (loopTrack )
344505 end
345506 end
346507 timeframetimer_short = 0
@@ -378,6 +539,7 @@ function widget:Update(dt)
378539 end
379540
380541 local playedTime , totalTime = Spring .GetSoundStreamTime ()
542+ UpdateMusicProgress (playedTime , totalTime )
381543 playedTime = math.floor (playedTime )
382544 totalTime = math.floor (totalTime )
383545 local _ , _ , paused = Spring .GetGameSpeed ()
@@ -503,6 +665,7 @@ local function PlayGameOverMusic(gameWon)
503665 looping = false
504666 Spring .StopSoundStream ()
505667 Spring .PlaySoundStream (track ,WG .music_volume or MUSIC_VOLUME_DEFAULT )
668+ UpdateMusicText (track )
506669 WG .music_start_volume = WG .music_volume
507670end
508671
0 commit comments