mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
musicplayer: working prev and stop button
This commit is contained in:
@@ -9,7 +9,10 @@ import com.badlogic.gdx.utils.JsonValue
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.reflection.extortField
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.audio.*
|
||||
import net.torvald.terrarum.gameworld.fmod
|
||||
import net.torvald.terrarum.modulebasegame.MusicContainer
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.ui.BasicDebugInfoWindow
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
@@ -74,33 +77,38 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
||||
private val colourControlButton = Color(0xeeeeee_cc.toInt())
|
||||
|
||||
init {
|
||||
setAsAlwaysVisible()
|
||||
if (App.getConfigBoolean("musicplayer:usemusicplayer")) {
|
||||
setAsAlwaysVisible()
|
||||
|
||||
// test code
|
||||
// test code
|
||||
// val albumDir = App.customMusicDir + "/Gapless Test 2"
|
||||
val albumDir = App.customMusicDir + "/FurryJoA 2023 Live"
|
||||
val albumDir = App.customMusicDir + "/FurryJoA 2023 Live"
|
||||
// val albumDir = App.customMusicDir + "/Audio Test"
|
||||
val playlistFile = JsonFetcher.invoke("$albumDir/playlist.json")
|
||||
val playlistFile = JsonFetcher.invoke("$albumDir/playlist.json")
|
||||
|
||||
val diskJockeyingMode = playlistFile.get("diskJockeyingMode").asString()
|
||||
val shuffled = playlistFile.get("shuffled").asBoolean()
|
||||
val fileToName = playlistFile.get("titles")
|
||||
val diskJockeyingMode = playlistFile.get("diskJockeyingMode").asString()
|
||||
val shuffled = playlistFile.get("shuffled").asBoolean()
|
||||
val fileToName = playlistFile.get("titles")
|
||||
|
||||
|
||||
AudioMixer.musicTrack.let { track ->
|
||||
track.doGaplessPlayback = (diskJockeyingMode == "continuous")
|
||||
if (track.doGaplessPlayback) {
|
||||
track.pullNextTrack = {
|
||||
track.currentTrack = ingame.musicGovernor.pullNextMusicTrack(true)
|
||||
setMusicName(track.currentTrack?.name ?: "")
|
||||
AudioMixer.musicTrack.let { track ->
|
||||
track.doGaplessPlayback = (diskJockeyingMode == "continuous")
|
||||
if (track.doGaplessPlayback) {
|
||||
track.pullNextTrack = {
|
||||
track.currentTrack = ingame.musicGovernor.pullNextMusicTrack(true)
|
||||
setMusicName(track.currentTrack?.name ?: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
registerPlaylist(albumDir, fileToName, shuffled, diskJockeyingMode)
|
||||
}
|
||||
|
||||
|
||||
registerPlaylist(albumDir, fileToName, shuffled, diskJockeyingMode)
|
||||
}
|
||||
|
||||
private val playlist: List<MusicContainer>
|
||||
get() = ingame.musicGovernor.extortField<List<MusicContainer>>("songs")!!
|
||||
|
||||
fun registerPlaylist(path: String, fileToName: JsonValue, shuffled: Boolean, diskJockeyingMode: String) {
|
||||
ingame.musicGovernor.queueDirectory(path, shuffled, diskJockeyingMode) { filename ->
|
||||
fileToName.get(filename).let {
|
||||
@@ -239,13 +247,16 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
||||
|
||||
}
|
||||
1 -> { // prev
|
||||
// ingame.musicGovernor.playPrevMusic()
|
||||
getPrevSongFromPlaylist()?.let { ingame.musicGovernor.unshiftPlaylist(it) }
|
||||
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f)
|
||||
}
|
||||
2 -> { // stop
|
||||
if (AudioMixer.musicTrack.isPlaying) {
|
||||
val thisMusic = AudioMixer.musicTrack.currentTrack
|
||||
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f)
|
||||
AudioMixer.musicTrack.nextTrack = null
|
||||
ingame.musicGovernor.stopMusic()
|
||||
thisMusic?.let { ingame.musicGovernor.queueMusicToPlayNext(it) }
|
||||
}
|
||||
else {
|
||||
ingame.musicGovernor.startMusic()
|
||||
@@ -271,6 +282,18 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
||||
|
||||
private var playControlButtonLatched = false
|
||||
|
||||
private fun getPrevSongFromPlaylist(): MusicContainer? {
|
||||
val list = playlist.slice(playlist.indices) // make copy of the list
|
||||
val nowPlaying = AudioMixer.musicTrack.currentTrack ?: return null
|
||||
|
||||
// find current index
|
||||
val currentIndex = list.indexOfFirst { it == nowPlaying }
|
||||
if (currentIndex < 0) return null
|
||||
|
||||
val prevIndex = (currentIndex - 1).fmod(list.size)
|
||||
return list[prevIndex]
|
||||
}
|
||||
|
||||
// private fun smoothstep(x: Float) = (x*x*(3f-2f*x)).coerceIn(0f, 1f)
|
||||
// private fun smootherstep(x: Float) = (x*x*x*(x*(6f*x-15f)+10f)).coerceIn(0f, 1f)
|
||||
|
||||
|
||||
1
assets/mods/musicplayer/configplan.csv
Normal file
1
assets/mods/musicplayer/configplan.csv
Normal file
@@ -0,0 +1 @@
|
||||
usemusicplayer->Lang:MENU_OPTIONS_USE_MUSIC_PLAYER->toggle
|
||||
|
3
assets/mods/musicplayer/default.json
Normal file
3
assets/mods/musicplayer/default.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"usemusicplayer": true
|
||||
}
|
||||
3
assets/mods/musicplayer/locales/en/musicplayer.json
Normal file
3
assets/mods/musicplayer/locales/en/musicplayer.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"MENU_OPTIONS_USE_MUSIC_PLAYER": "Use Music Player"
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.audio.AudioMixer
|
||||
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATE
|
||||
import net.torvald.terrarum.gameworld.fmod
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import javax.sound.sampled.AudioSystem
|
||||
@@ -135,6 +136,8 @@ data class MusicContainer(
|
||||
samplesRead = 0L
|
||||
gdxMusic.forceInvoke<Int>("reset", arrayOf())
|
||||
}
|
||||
|
||||
override fun equals(other: Any?) = this.file.path == (other as MusicContainer).file.path
|
||||
}
|
||||
|
||||
class TerrarumMusicGovernor : MusicGovernor() {
|
||||
@@ -149,7 +152,7 @@ class TerrarumMusicGovernor : MusicGovernor() {
|
||||
}
|
||||
|
||||
private var songs: List<MusicContainer> = emptyList()
|
||||
private var musicBin: ArrayList<Int> = ArrayList()
|
||||
private var musicBin: ArrayList<MusicContainer> = ArrayList()
|
||||
private var shuffled = true
|
||||
private var diskJockeyingMode = "intermittent" // intermittent, continuous
|
||||
|
||||
@@ -184,8 +187,8 @@ class TerrarumMusicGovernor : MusicGovernor() {
|
||||
} ?: emptyList() // TODO test code
|
||||
}
|
||||
|
||||
private fun restockMUsicBin() {
|
||||
musicBin = if (shuffled) ArrayList(songs.indices.toList().shuffled()) else ArrayList(songs.indices.toList())
|
||||
private fun restockMusicBin() {
|
||||
musicBin = ArrayList(if (shuffled) songs.shuffled() else songs.slice(songs.indices))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,7 +208,30 @@ class TerrarumMusicGovernor : MusicGovernor() {
|
||||
this.shuffled = shuffled
|
||||
this.diskJockeyingMode = diskJockeyingMode
|
||||
|
||||
restockMUsicBin()
|
||||
restockMusicBin()
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a song to the head of the internal playlist (`musicBin`)
|
||||
*/
|
||||
fun queueMusicToPlayNext(music: MusicContainer) {
|
||||
musicBin.add(0, music)
|
||||
}
|
||||
|
||||
/**
|
||||
* Unshifts an internal playlist (`musicBin`). The `music` argument must be the song that exists on the `songs`.
|
||||
*/
|
||||
fun unshiftPlaylist(music: MusicContainer) {
|
||||
val indexAtMusicBin = songs.indexOf(music)
|
||||
if (indexAtMusicBin < 0) throw IllegalArgumentException("The music does not exist on the interal songs list ($music)")
|
||||
|
||||
// rewrite musicBin
|
||||
val newMusicBin = Array(songs.size - indexAtMusicBin) { offset ->
|
||||
val k = offset + indexAtMusicBin
|
||||
songs[k]
|
||||
}
|
||||
|
||||
musicBin = ArrayList(newMusicBin.toList())
|
||||
}
|
||||
|
||||
private val ambients: List<MusicContainer> =
|
||||
@@ -300,9 +326,9 @@ class TerrarumMusicGovernor : MusicGovernor() {
|
||||
|
||||
// prevent same song to play twice in row (for the most time)
|
||||
if (musicBin.isEmpty()) {
|
||||
restockMUsicBin()
|
||||
restockMusicBin()
|
||||
}
|
||||
return songs[musicBin.removeAt(0)].also { mus ->
|
||||
return musicBin.removeAt(0).also { mus ->
|
||||
if (callNextMusicHook && musicStartHooks.isNotEmpty()) musicStartHooks.forEach { it(mus) }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user