mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-14 20:44:05 +09:00
musicplayer: playlist scrolling and mouseup anims
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package net.torvald.terrarum.musicplayer.gui
|
package net.torvald.terrarum.musicplayer.gui
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.OrthographicCamera
|
import com.badlogic.gdx.graphics.OrthographicCamera
|
||||||
import com.badlogic.gdx.graphics.Pixmap
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
@@ -174,6 +175,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var mouseOnButton: Int? = null
|
private var mouseOnButton: Int? = null
|
||||||
|
private var mouseOnList: Int? = null
|
||||||
|
|
||||||
override fun updateUI(delta: Float) {
|
override fun updateUI(delta: Float) {
|
||||||
// process transition request
|
// process transition request
|
||||||
@@ -265,7 +267,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// mouse is over which button?
|
// mouse is over which button?
|
||||||
if (mode >= MODE_MOUSE_UP && relativeMouseY.toFloat() in posYforControls + 10f .. posYforControls + 10f + BUTTON_HEIGHT) {
|
if (mode >= MODE_MOUSE_UP && relativeMouseY.toFloat() in posYforControls + 12f .. posYforControls + 12f + BUTTON_HEIGHT) {
|
||||||
mouseOnButton = if (relativeMouseX.toFloat() in Toolkit.hdrawWidthf - 120f .. Toolkit.hdrawWidthf - 120f + 5 * BUTTON_WIDTH) {
|
mouseOnButton = if (relativeMouseX.toFloat() in Toolkit.hdrawWidthf - 120f .. Toolkit.hdrawWidthf - 120f + 5 * BUTTON_WIDTH) {
|
||||||
((relativeMouseX.toFloat() - (Toolkit.hdrawWidthf - 120f)) / BUTTON_WIDTH).toInt()
|
((relativeMouseX.toFloat() - (Toolkit.hdrawWidthf - 120f)) / BUTTON_WIDTH).toInt()
|
||||||
}
|
}
|
||||||
@@ -275,6 +277,15 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
mouseOnButton = null
|
mouseOnButton = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mouse is over which list
|
||||||
|
mouseOnList = if (mode >= MODE_SHOW_LIST &&
|
||||||
|
relativeMouseY.toFloat() in _posY + 9.._posY + 9 + PLAYLIST_LINES*PLAYLIST_LINE_HEIGHT &&
|
||||||
|
relativeMouseX.toFloat() in _posX.._posX + width) {
|
||||||
|
|
||||||
|
((relativeMouseY - (_posY + 9)) / PLAYLIST_LINE_HEIGHT).toInt()
|
||||||
|
}
|
||||||
|
else null
|
||||||
|
|
||||||
|
|
||||||
// make button work
|
// make button work
|
||||||
if (!playControlButtonLatched && mouseOnButton != null && Terrarum.mouseDown) {
|
if (!playControlButtonLatched && mouseOnButton != null && Terrarum.mouseDown) {
|
||||||
@@ -297,24 +308,42 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
1 -> { // prev
|
1 -> { // prev
|
||||||
getPrevSongFromPlaylist()?.let { ingame.musicGovernor.unshiftPlaylist(it) }
|
// prev song
|
||||||
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f)
|
if (mode < MODE_SHOW_LIST) {
|
||||||
|
getPrevSongFromPlaylist()?.let { ingame.musicGovernor.unshiftPlaylist(it) }
|
||||||
|
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f)
|
||||||
|
}
|
||||||
|
// prev page in the list
|
||||||
|
else {
|
||||||
|
val scrollMax = ((currentlySelectedAlbum?.length ?: 0).toFloat() / PLAYLIST_LINES).ceilToInt() * PLAYLIST_LINES
|
||||||
|
playlistScroll = (playlistScroll - PLAYLIST_LINES) fmod scrollMax
|
||||||
|
}
|
||||||
}
|
}
|
||||||
2 -> { // stop
|
2 -> { // stop
|
||||||
if (AudioMixer.musicTrack.isPlaying) {
|
if (mode < MODE_SHOW_LIST) { // disable stop button entirely on MODE_SHOW_LIST
|
||||||
val thisMusic = AudioMixer.musicTrack.currentTrack
|
if (AudioMixer.musicTrack.isPlaying) {
|
||||||
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f)
|
val thisMusic = AudioMixer.musicTrack.currentTrack
|
||||||
AudioMixer.musicTrack.nextTrack = null
|
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f)
|
||||||
ingame.musicGovernor.stopMusic()
|
AudioMixer.musicTrack.nextTrack = null
|
||||||
thisMusic?.let { ingame.musicGovernor.queueMusicToPlayNext(it) }
|
ingame.musicGovernor.stopMusic()
|
||||||
}
|
thisMusic?.let { ingame.musicGovernor.queueMusicToPlayNext(it) }
|
||||||
else {
|
}
|
||||||
ingame.musicGovernor.startMusic()
|
else {
|
||||||
|
ingame.musicGovernor.startMusic()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
3 -> { // next
|
3 -> { // next
|
||||||
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) {
|
// next song
|
||||||
|
if (mode < MODE_SHOW_LIST) {
|
||||||
|
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) {
|
||||||
// ingame.musicGovernor.startMusic() // it works without this?
|
// ingame.musicGovernor.startMusic() // it works without this?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// next page in the list
|
||||||
|
else {
|
||||||
|
val scrollMax = ((currentlySelectedAlbum?.length ?: 0).toFloat() / PLAYLIST_LINES).ceilToInt() * PLAYLIST_LINES
|
||||||
|
playlistScroll = (playlistScroll + PLAYLIST_LINES) fmod scrollMax
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
4 -> { // playlist
|
4 -> { // playlist
|
||||||
@@ -322,6 +351,14 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
if (!transitionOngoing) {
|
if (!transitionOngoing) {
|
||||||
transitionRequest = MODE_SHOW_LIST
|
transitionRequest = MODE_SHOW_LIST
|
||||||
currentListMode = 1
|
currentListMode = 1
|
||||||
|
// reset list scroll
|
||||||
|
val currentlyPlaying = playlist.indexOf(AudioMixer.musicTrack.currentTrack)
|
||||||
|
if (currentlyPlaying >= 0) {
|
||||||
|
playlistScroll = (currentlyPlaying / PLAYLIST_LINES) * PLAYLIST_LINES
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
playlistScroll = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (currentListMode != 1) {
|
else if (currentListMode != 1) {
|
||||||
@@ -474,7 +511,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
get() = relativeMouseX.toFloat() in _posX-capsuleMosaicSize .. _posX+width+capsuleMosaicSize &&
|
get() = relativeMouseX.toFloat() in _posX-capsuleMosaicSize .. _posX+width+capsuleMosaicSize &&
|
||||||
relativeMouseY.toFloat() in _posY .. _posY+height
|
relativeMouseY.toFloat() in _posY .. _posY+height
|
||||||
|
|
||||||
override fun renderUI(batch: SpriteBatch, camera: OrthographicCamera) {
|
override fun renderUI(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) {
|
||||||
widthForFreqMeter = if (transitionOngoing && modeNext >= MODE_MOUSE_UP || mode >= MODE_MOUSE_UP)
|
widthForFreqMeter = if (transitionOngoing && modeNext >= MODE_MOUSE_UP || mode >= MODE_MOUSE_UP)
|
||||||
uiWidthFromTextWidth(nameLength)
|
uiWidthFromTextWidth(nameLength)
|
||||||
else
|
else
|
||||||
@@ -513,13 +550,20 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
drawBaloon(batch, _posX, _posY, width.toFloat(), (height - capsuleHeight.toFloat()).coerceAtLeast(0f))
|
drawBaloon(batch, _posX, _posY, width.toFloat(), (height - capsuleHeight.toFloat()).coerceAtLeast(0f))
|
||||||
drawText(batch, posXforMusicLine, posYforMusicLine)
|
drawText(batch, posXforMusicLine, posYforMusicLine)
|
||||||
drawFreqMeter(batch, posXforMusicLine + widthForFreqMeter - 18f, _posY + height - (capsuleHeight / 2) + 1f)
|
drawFreqMeter(batch, posXforMusicLine + widthForFreqMeter - 18f, _posY + height - (capsuleHeight / 2) + 1f)
|
||||||
drawControls(App.UPDATE_RATE, batch, _posX, posYforControls)
|
drawControls(frameDelta, batch, _posX, posYforControls)
|
||||||
drawList(camera, App.UPDATE_RATE, batch, _posX, _posY)
|
drawList(camera, frameDelta, batch, _posX, _posY)
|
||||||
|
|
||||||
batch.color = Color.WHITE
|
batch.color = Color.WHITE
|
||||||
}
|
}
|
||||||
|
|
||||||
private val playListAnimAkku = FloatArray(8) // how many lines on the list view?
|
private val widthForList = 320
|
||||||
|
|
||||||
|
private val PLAYLIST_LEFT_GAP = METERS_WIDTH.toInt() + maskOffWidth
|
||||||
|
private val PLAYLIST_NAME_LEN = widthForList
|
||||||
|
private val PLAYLIST_LINE_HEIGHT = 28f
|
||||||
|
private val PLAYLIST_LINES = App.getConfigInt("musicplayer:playlistlines").let { if (it < 4) 4 else it }
|
||||||
|
|
||||||
|
private val playListAnimAkku = FloatArray(PLAYLIST_LINES) // how many control buttons?
|
||||||
private val playListAnimLength = 0.2f
|
private val playListAnimLength = 0.2f
|
||||||
|
|
||||||
private fun drawList(camera: OrthographicCamera, delta: Float, batch: SpriteBatch, x: Float, y: Float) {
|
private fun drawList(camera: OrthographicCamera, delta: Float, batch: SpriteBatch, x: Float, y: Float) {
|
||||||
@@ -557,7 +601,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
|
|
||||||
// update playListAnimAkku
|
// update playListAnimAkku
|
||||||
for (i in playListAnimAkku.indices) {
|
for (i in playListAnimAkku.indices) {
|
||||||
if (mouseOnButton == i && mode >= MODE_MOUSE_UP && modeNext >= MODE_MOUSE_UP)
|
if (mouseOnList == i && mode >= MODE_SHOW_LIST && modeNext >= MODE_SHOW_LIST)
|
||||||
playListAnimAkku[i] = (playListAnimAkku[i] + (delta / playListAnimLength)).coerceIn(0f, 1f)
|
playListAnimAkku[i] = (playListAnimAkku[i] + (delta / playListAnimLength)).coerceIn(0f, 1f)
|
||||||
else
|
else
|
||||||
playListAnimAkku[i] = (playListAnimAkku[i] - (delta / playListAnimLength)).coerceIn(0f, 1f)
|
playListAnimAkku[i] = (playListAnimAkku[i] - (delta / playListAnimLength)).coerceIn(0f, 1f)
|
||||||
@@ -565,12 +609,6 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val widthForList = 320
|
|
||||||
|
|
||||||
private val PLAYLIST_LEFT_GAP = METERS_WIDTH.toInt() + maskOffWidth
|
|
||||||
private val PLAYLIST_NAME_LEN = widthForList
|
|
||||||
private val PLAYLIST_LINE_HEIGHT = 28f
|
|
||||||
private val PLAYLIST_LINES = 7
|
|
||||||
|
|
||||||
private val widthForMouseUp = (nameStrMaxLen + METERS_WIDTH + maskOffWidth).toInt()
|
private val widthForMouseUp = (nameStrMaxLen + METERS_WIDTH + maskOffWidth).toInt()
|
||||||
private val heightThin = 28
|
private val heightThin = 28
|
||||||
@@ -607,6 +645,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
batch.end()
|
batch.end()
|
||||||
|
|
||||||
playlistFBOs.forEachIndexed { i, it ->
|
playlistFBOs.forEachIndexed { i, it ->
|
||||||
|
val pnum = i + playlistScroll
|
||||||
it.inAction(camera, batch) {
|
it.inAction(camera, batch) {
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
batch.color = Color.WHITE
|
batch.color = Color.WHITE
|
||||||
@@ -614,7 +653,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
blendNormalStraightAlpha(batch)
|
blendNormalStraightAlpha(batch)
|
||||||
|
|
||||||
// draw text
|
// draw text
|
||||||
App.fontGameFBO.draw(batch, if (i + playlistScroll in playlist.indices) playlist[i].name else "", maskOffWidth - playlistNameScrolls[i + playlistScroll], (PLAYLIST_LINE_HEIGHT - 24) / 2)
|
App.fontGameFBO.draw(batch, if (pnum in playlist.indices) playlist[pnum].name else "", maskOffWidth - playlistNameScrolls[pnum], (PLAYLIST_LINE_HEIGHT - 24) / 2)
|
||||||
|
|
||||||
// mask off the area
|
// mask off the area
|
||||||
batch.color = Color.WHITE
|
batch.color = Color.WHITE
|
||||||
@@ -633,7 +672,10 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
blendNormalStraightAlpha(batch)
|
blendNormalStraightAlpha(batch)
|
||||||
if (alpha > 0f) {
|
if (alpha > 0f) {
|
||||||
playlistFBOs.forEachIndexed { i, it ->
|
playlistFBOs.forEachIndexed { i, it ->
|
||||||
val m1 = playlist.getOrNull(i + playlistScroll)
|
val alpha2 = alpha + (playListAnimAkku[i] * 0.2f)
|
||||||
|
val pnum = i + playlistScroll
|
||||||
|
|
||||||
|
val m1 = playlist.getOrNull(pnum)
|
||||||
val m2 = AudioMixer.musicTrack.currentTrack
|
val m2 = AudioMixer.musicTrack.currentTrack
|
||||||
val currentlyPlaying = if (m1 == null || m2 == null) false else (m1 == m2)
|
val currentlyPlaying = if (m1 == null || m2 == null) false else (m1 == m2)
|
||||||
|
|
||||||
@@ -641,25 +683,25 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
|
|
||||||
// print bars instead of numbers if the song is currently being played
|
// print bars instead of numbers if the song is currently being played
|
||||||
if (currentlyPlaying) {
|
if (currentlyPlaying) {
|
||||||
val xoff = 5
|
val xoff = 6
|
||||||
val yoff = 5 + 7 + (PLAYLIST_LINE_HEIGHT - 24) / 2
|
val yoff = 5 + 7 + (PLAYLIST_LINE_HEIGHT - 24) / 2
|
||||||
// it will set the colour on its own
|
// it will set the colour on its own
|
||||||
drawFreqMeter(batch, x + xoff, y + yoff + PLAYLIST_LINE_HEIGHT * i * scale, alpha)
|
drawFreqMeter(batch, x + xoff, y + yoff + PLAYLIST_LINE_HEIGHT * i * scale, alpha)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val xoff = maskOffWidth + (if (i < 9) 3 else 0)
|
val xoff = maskOffWidth + (if (pnum < 9) 3 else 0)
|
||||||
val yoff = 7 + (PLAYLIST_LINE_HEIGHT - 24) / 2
|
val yoff = 7 + (PLAYLIST_LINE_HEIGHT - 24) / 2
|
||||||
batch.color = Color(1f, 1f, 1f, alpha * 0.75f)
|
batch.color = Color(1f, 1f, 1f, alpha * 0.75f)
|
||||||
App.fontSmallNumbers.draw(
|
App.fontSmallNumbers.draw(
|
||||||
batch,
|
batch,
|
||||||
if (i + playlistScroll in playlist.indices) "${i + playlistScroll + 1}" else "",
|
if (pnum in playlist.indices) "${pnum + 1}" else "",
|
||||||
x + xoff,
|
x + xoff,
|
||||||
y + yoff + PLAYLIST_LINE_HEIGHT * i * scale
|
y + yoff + PLAYLIST_LINE_HEIGHT * i * scale
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// print the name
|
// print the name
|
||||||
batch.color = Color(1f, 1f, 1f, alpha)
|
batch.color = Color(1f, 1f, 1f, alpha2)
|
||||||
batch.draw(it.colorBufferTexture, x + PLAYLIST_LEFT_GAP * scale, y + PLAYLIST_LINE_HEIGHT * i * scale, it.width * scale, it.height * scale)
|
batch.draw(it.colorBufferTexture, x + PLAYLIST_LEFT_GAP * scale, y + PLAYLIST_LINE_HEIGHT * i * scale, it.width * scale, it.height * scale)
|
||||||
|
|
||||||
// separator
|
// separator
|
||||||
@@ -717,7 +759,15 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
1f to false
|
1f to false
|
||||||
else
|
else
|
||||||
0f to false
|
0f to false
|
||||||
// TODO fade away the << o >>, replacing with the page buttons
|
|
||||||
|
val p = transitionAkku / TRANSITION_LENGTH
|
||||||
|
val buttonFadePerc =
|
||||||
|
if (modeNext == MODE_SHOW_LIST)
|
||||||
|
p
|
||||||
|
else if (mode == MODE_SHOW_LIST && modeNext == MODE_MOUSE_UP)
|
||||||
|
1f - p
|
||||||
|
else
|
||||||
|
0f
|
||||||
|
|
||||||
if (alpha > 0f) {
|
if (alpha > 0f) {
|
||||||
val alpha0 = alpha.coerceIn(0f, 1f).organicOvershoot().coerceAtMost(1f)
|
val alpha0 = alpha.coerceIn(0f, 1f).organicOvershoot().coerceAtMost(1f)
|
||||||
@@ -726,15 +776,48 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
val anchorX = Toolkit.hdrawWidthf
|
val anchorX = Toolkit.hdrawWidthf
|
||||||
val posY = posY + 12f
|
val posY = posY + 12f
|
||||||
for (i in 0..4) {
|
for (i in 0..4) {
|
||||||
batch.color = Color(1f, 1f, 1f,
|
val alphaBase = 0.75f * (if (reverse) 1f - alpha0 else alpha0).pow(3f) + (playControlAnimAkku[i] * 0.2f)
|
||||||
0.75f * (if (reverse) 1f - alpha0 else alpha0).pow(3f) + (playControlAnimAkku[i].pow(2f) * 1.2f)
|
val alphaBase2 = 0.75f * (if (reverse) 1f - alpha0 else alpha0).pow(3f)
|
||||||
)
|
|
||||||
|
|
||||||
val offset = i - 2
|
val offset = i - 2
|
||||||
val posX = anchorX + offset * separation
|
val posX = anchorX + offset * separation
|
||||||
|
|
||||||
val iconY = if (!AudioMixer.musicTrack.isPlaying && i == 2) 1 else 0
|
|
||||||
batch.draw(controlButtons.get(i, iconY), (posX - BUTTON_WIDTH / 2).roundToFloat(), posY.roundToFloat())
|
val btnX = (posX - BUTTON_WIDTH / 2).roundToFloat()
|
||||||
|
val btnY = posY.roundToFloat()
|
||||||
|
|
||||||
|
// actually draw icon
|
||||||
|
// prev/next button
|
||||||
|
if (i == 1 || i == 3) {
|
||||||
|
// prev/next song button
|
||||||
|
batch.color = Color(1f, 1f, 1f, alphaBase * (1f - buttonFadePerc))
|
||||||
|
batch.draw(controlButtons.get(i, 0), btnX, btnY)
|
||||||
|
// prev/next page button
|
||||||
|
batch.color = Color(1f, 1f, 1f, alphaBase * buttonFadePerc)
|
||||||
|
batch.draw(controlButtons.get(i, 1), btnX, btnY)
|
||||||
|
}
|
||||||
|
// stop button
|
||||||
|
else if (i == 2) {
|
||||||
|
// get correct stop/play button
|
||||||
|
val iconY = if (!AudioMixer.musicTrack.isPlaying) 1 else 0
|
||||||
|
// fade if avaliable
|
||||||
|
batch.color = Color(1f, 1f, 1f, alphaBase * (1f - buttonFadePerc))
|
||||||
|
batch.draw(controlButtons.get(i, iconY), btnX, btnY)
|
||||||
|
// page number
|
||||||
|
batch.color = Color(1f, 1f, 1f, alphaBase2 * buttonFadePerc) // don't use mouse-up effect
|
||||||
|
Toolkit.drawTextCentered(
|
||||||
|
batch, App.fontSmallNumbers,
|
||||||
|
"${(playlistScroll.div(PLAYLIST_LINES).plus(1).toString().padStart(4,' '))}/" +
|
||||||
|
"${((currentlySelectedAlbum?.length ?: 0).toFloat().div(PLAYLIST_LINES).ceilToInt().toString().padEnd(4,' '))}",
|
||||||
|
120, anchorX.toInt() - 60, btnY.toInt() + 14
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// else button
|
||||||
|
else {
|
||||||
|
batch.color = Color(1f, 1f, 1f, alphaBase)
|
||||||
|
batch.draw(controlButtons.get(i, 0), btnX, btnY)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// update playControlAnimAkku
|
// update playControlAnimAkku
|
||||||
if (mouseOnButton == i && mode >= MODE_MOUSE_UP && modeNext >= MODE_MOUSE_UP)
|
if (mouseOnButton == i && mode >= MODE_MOUSE_UP && modeNext >= MODE_MOUSE_UP)
|
||||||
@@ -884,8 +967,11 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val permittedExts = hashSetOf("WAV", "OGG", "MP3")
|
||||||
|
|
||||||
private fun getAlbumProp(albumDir: File): AlbumProp {
|
private fun getAlbumProp(albumDir: File): AlbumProp {
|
||||||
if (!albumDir.exists()) throw IllegalArgumentException("Album dir does not exist: $albumDir")
|
if (!albumDir.exists()) throw IllegalArgumentException("Album dir does not exist: $albumDir")
|
||||||
|
val fileCount = albumDir.listFiles { _, name -> permittedExts.contains(name.substringAfterLast('.').uppercase()) }?.size ?: 0
|
||||||
val playlistFile = File(albumDir, "playlist.json")
|
val playlistFile = File(albumDir, "playlist.json")
|
||||||
if (playlistFile.exists()) {
|
if (playlistFile.exists()) {
|
||||||
val playlistFile = JsonFetcher.invoke(playlistFile)
|
val playlistFile = JsonFetcher.invoke(playlistFile)
|
||||||
@@ -893,16 +979,17 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
val diskJockeyingMode = playlistFile.get("diskJockeyingMode").asString()
|
val diskJockeyingMode = playlistFile.get("diskJockeyingMode").asString()
|
||||||
val shuffled = playlistFile.get("shuffled").asBoolean()
|
val shuffled = playlistFile.get("shuffled").asBoolean()
|
||||||
val fileToName = playlistFile.get("titles")
|
val fileToName = playlistFile.get("titles")
|
||||||
return AlbumProp(albumDir, albumName, diskJockeyingMode, shuffled, fileToName)
|
return AlbumProp(albumDir, albumName, diskJockeyingMode, shuffled, fileToName, fileCount)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return AlbumProp(albumDir, albumDir.name, "intermittent", true, null)
|
return AlbumProp(albumDir, albumDir.name, "intermittent", true, null, fileCount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class AlbumProp(
|
private data class AlbumProp(
|
||||||
val ref: File, val name: String,
|
val ref: File, val name: String,
|
||||||
val diskJockeyingMode: String, val shuffled: Boolean, val fileToName: JsonValue?,
|
val diskJockeyingMode: String, val shuffled: Boolean, val fileToName: JsonValue?,
|
||||||
|
val length: Int,
|
||||||
val albumArt: TextureRegion? = null
|
val albumArt: TextureRegion? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,20 +1,22 @@
|
|||||||
## Sampling Rate
|
## Sampling Rate
|
||||||
|
|
||||||
The basegame is build assuming the sampling rate of 48000 Hz.
|
The audio engine of the basegame has the fixed sampling rate of 48000 Hz.
|
||||||
|
|
||||||
Any audio files with lower sampling rate will be resampled on-the-fly by the game's audio engine,
|
Any audio files with lower sampling rate will be resampled on-the-fly by the game's audio engine,
|
||||||
but doing so may introduce artefacts, most notably fast periodic clicks, which may be audible in certain
|
but doing so may introduce artefacts, most notably fast periodic clicks, which is only audible in certain
|
||||||
circumstances. For the best results, please resample your audio files to 48000 Hz beforehand.
|
artificial cases such as high-pitched monotonic sine wave. If you are concerned about the artefacts,
|
||||||
|
please resample your audio files to 48000 Hz beforehand. This is easily achievable using free software
|
||||||
|
such as [Audacity](https://www.audacityteam.org/) or [FFmpeg](https://ffmpeg.org/download.html).
|
||||||
|
|
||||||
|
|
||||||
## Mono Incompatibility
|
## Mono Incompatibility
|
||||||
|
|
||||||
The audio engine does not support monaural audio. Please convert your mono audio file to stereo beforehand.
|
The audio engine does not read monaural audio. Please convert your mono audio files to stereo beforehand.
|
||||||
|
|
||||||
|
|
||||||
## Gapless Playback
|
## Gapless Playback
|
||||||
|
|
||||||
The basegame (and by the extension this music player) does support the Gapless Playback.
|
The basegame (and by extension this music player) does support the Gapless Playback.
|
||||||
|
|
||||||
However, because of the inherent limitation of the MP3 format, the Gapless Playback is not achievable
|
However, because of the inherent limitation of the MP3 format, the Gapless Playback is not achievable
|
||||||
without extensive hacks. If you do care, please convert your MP3 files into WAV or OGG format.
|
without extensive hacks. If you do care, please convert your MP3 files into WAV or OGG format.
|
||||||
|
|||||||
Reference in New Issue
Block a user