fix: explosion cuts off randomly

This commit is contained in:
minjaesong
2024-02-17 00:30:04 +09:00
parent ffd470f2b4
commit 9caf9ab2fa
12 changed files with 110 additions and 41 deletions

Binary file not shown.

View File

@@ -340,10 +340,11 @@ Sound from <https://freesound.org/people/DrinkingWindGames>
℗ 2019 Richwise
Sound from <https://freesound.org/people/richwise>
- effects/explosion/bang_small.ogg
℗ 2009 Superex1110
Sound from <https://freesound.org/people/Superex1110/>
- effects/explosion/fuse.ogg
- effects/explosion/fuse_continue.ogg
℗ 2012, 2015 j1987 and ScouseMouseJB
Sound from <https://freesound.org/people/j1987> and <https://freesound.org/people/ScouseMouseJB>

View File

@@ -453,9 +453,9 @@ class AudioMixer : Disposable {
}
fun startAmb(song: MusicContainer) {
val ambientTrack = if (!ambientTrack1.streamPlaying)
val ambientTrack = if (!ambientTrack1.streamPlaying.get())
ambientTrack1
else if (!ambientTrack2.streamPlaying)
else if (!ambientTrack2.streamPlaying.get())
ambientTrack2
else if (ambientTrack1.playStartedTime < ambientTrack2.playStartedTime)
ambientTrack1

View File

@@ -181,8 +181,15 @@ class MixerTrackProcessor(bufferSize: Int, val rate: Int, val track: TerrarumAud
// fetch deviceBufferSize amount of sample from the disk
if (track.trackType != TrackType.MASTER && track.trackType != TrackType.BUS && track.streamPlaying) {
if (streamBuf == null && track.currentTrack != null) allocateStreamBuf(track)
if (track.playRequested.get()) {
track.play()
}
if (track.trackType != TrackType.MASTER && track.trackType != TrackType.BUS && track.streamPlaying.get()) {
if (streamBuf == null && track.currentTrack != null) {
allocateStreamBuf(track)
}
streamBuf!!.fetchBytes()
}
@@ -208,7 +215,7 @@ class MixerTrackProcessor(bufferSize: Int, val rate: Int, val track: TerrarumAud
}
// source channel: skip processing if there's no active input
// else if (track.getSidechains().any { it != null && !it.isBus && !it.isMaster && !it.streamPlaying } && !track.streamPlaying) {
else if (!track.streamPlaying || streamBuf == null || streamBuf!!.validSamplesInBuf < App.audioBufferSize) {
else if (!track.streamPlaying.get() || streamBuf == null || streamBuf!!.validSamplesInBuf < App.audioBufferSize) {
samplesL1 = emptyBuf
samplesR1 = emptyBuf

View File

@@ -41,13 +41,13 @@ data class MusicContainer(
is Wav.Music -> {
val rate = gdxMusic.extortField<Wav.WavInputStream>("input")!!.sampleRate
App.printdbg(this, "music $name is WAV; rate = $rate")
// App.printdbg(this, "music $name is WAV; rate = $rate")
rate
}
is Ogg.Music -> {
val rate = gdxMusic.extortField<OggInputStream>("input")!!.sampleRate
App.printdbg(this, "music $name is OGG; rate = $rate")
// App.printdbg(this, "music $name is OGG; rate = $rate")
rate
}
is Mp3.Music -> {
@@ -62,11 +62,11 @@ data class MusicContainer(
// val rate = header.sampleRate
// gdxMusic.reset()
App.printdbg(this, "music $name is MP3; rate = $rate")
// App.printdbg(this, "music $name is MP3; rate = $rate")
rate
}
else -> {
App.printdbg(this, "music $name is ${gdxMusic::class.qualifiedName}; rate = default")
// App.printdbg(this, "music $name is ${gdxMusic::class.qualifiedName}; rate = default")
TerrarumAudioMixerTrack.SAMPLING_RATE
}
}

View File

@@ -5,11 +5,14 @@ import com.badlogic.gdx.backends.lwjgl3.audio.OpenALLwjgl3Audio
import com.badlogic.gdx.utils.Disposable
import com.badlogic.gdx.utils.Queue
import net.torvald.terrarum.App
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.audio.dsp.NullFilter
import net.torvald.terrarum.audio.dsp.TerrarumAudioFilter
import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.getHashStr
import net.torvald.terrarum.hashStrMap
import net.torvald.terrarum.printStackTrace
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.math.log10
import kotlin.math.pow
@@ -60,7 +63,7 @@ class TerrarumAudioMixerTrack(
var trackingTarget: Actor? = null
internal var streamPlaying = false
internal val streamPlaying = AtomicBoolean(false)
var playStartedTime = 0L; internal set
@@ -70,7 +73,7 @@ class TerrarumAudioMixerTrack(
other.nextTrack = this.nextTrack
other.volume = this.volume
other.trackingTarget = this.trackingTarget
other.streamPlaying = this.streamPlaying
other.streamPlaying.set(this.streamPlaying.get())
other.playStartedTime = this.playStartedTime
filters.indices.forEach { i ->
other.filters[i].copyParamsFrom(this.filters[i])
@@ -133,15 +136,18 @@ class TerrarumAudioMixerTrack(
nextTrack = nextNext
}
val playRequested = AtomicBoolean(false)
fun play() {
playStartedTime = System.nanoTime()
streamPlaying = true
streamPlaying.set(true)
playRequested.set(false)
// currentTrack?.gdxMusic?.play()
}
val isPlaying: Boolean
get() = streamPlaying//currentTrack?.gdxMusic?.isPlaying
get() = streamPlaying.get()//currentTrack?.gdxMusic?.isPlaying
override fun dispose() {
/*if (isMaster) { // uncomment to multithread
@@ -158,7 +164,7 @@ class TerrarumAudioMixerTrack(
fun stop() {
currentTrack?.reset()
streamPlaying = false
streamPlaying.set(false)
// playStartedTime = 0L
if (trackingTarget != null && currentTrack != null) {

View File

@@ -2,6 +2,7 @@ package net.torvald.terrarum.gameactors
import net.torvald.random.HQRNG
import net.torvald.terrarum.App
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.INGAME
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.audio.MusicContainer
@@ -12,6 +13,9 @@ import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
import net.torvald.terrarum.savegame.toBigEndian
import net.torvald.terrarum.utils.PasswordBase32
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
typealias ActorID = Int
@@ -72,6 +76,8 @@ abstract class Actor : Comparable<Actor>, Runnable {
@Transient open val canBeDespawned = true
@Volatile internal var despawned = false
@Transient open val stopMusicOnDespawn = true
override fun equals(other: Any?): Boolean {
if (other == null) return false
@@ -105,8 +111,12 @@ abstract class Actor : Comparable<Actor>, Runnable {
musicTracks1.forEach { name ->
val it = App.audioMixer.dynamicTracks[name.substring(2).toInt() - 1]
println("stop track $name")
it.stop()
printdbg(this, "stop track $name")
if (stopMusicOnDespawn) {
it.stop()
}
it.filters[0] = NullFilter
it.filters[1] = NullFilter
it.processor.streamBuf?.pitch = 1f
@@ -149,6 +159,7 @@ abstract class Actor : Comparable<Actor>, Runnable {
if (track != null) {
musicTracks[music] = track
musicTracks1.add(track.name)
track.stop()
}
}
@@ -161,14 +172,20 @@ abstract class Actor : Comparable<Actor>, Runnable {
* To loop the audio, set `music.gdxMusic.isLooping` to `true`
*/
open fun startAudio(music: MusicContainer, volume: TrackVolume = 1.0, doSomethingWithTrack: (TerrarumAudioMixerTrack) -> Unit = {}) {
getTrackByAudio(music)?.let {
it.stop()
it.trackingTarget = this
it.currentTrack = music
it.maxVolumeFun = { volume }
it.volume = volume
doSomethingWithTrack(it)
it.play()
getTrackByAudio(music).let {
if (it == null) {
printdbg(this, "cannot startAudio $music")
}
else {
printdbg(this, "startAudio $music")
it.trackingTarget = this
it.currentTrack = music
it.maxVolumeFun = { volume }
it.volume = volume
doSomethingWithTrack(it)
// it.play()
it.playRequested.set(true)
}
}
}
@@ -177,9 +194,15 @@ abstract class Actor : Comparable<Actor>, Runnable {
}*/
open fun stopAudio(music: MusicContainer, doSomethingWithTrack: (TerrarumAudioMixerTrack) -> Unit = {}) {
musicTracks[music]?.let {
doSomethingWithTrack(it)
it.stop()
musicTracks[music].let {
if (it == null) {
// printdbg(this, "cannot stopAudio $music")
}
else {
// printdbg(this, "stopAudio $music")
doSomethingWithTrack(it)
it.stop()
}
}
}

View File

@@ -54,14 +54,14 @@ object ExplosionManager {
Thread {
while (true) {
try {
val job = runners.first { !it.executed }
val executor = Executors.newSingleThreadExecutor()
executor.submit(job.runner).get(500L, TimeUnit.MILLISECONDS)
executor.shutdownNow()
job.executed = true
runners.toList().firstOrNull { !it.executed }?.let { job ->
val executor = Executors.newSingleThreadExecutor()
executor.submit(job.runner).get(500L, TimeUnit.MILLISECONDS)
executor.shutdownNow()
job.executed = true
}
}
catch (_: TimeoutException) { }
catch (_: NoSuchElementException) { }
Thread.sleep(50L)
}

View File

@@ -38,10 +38,36 @@ open class ActorPrimedBomb(
) {
this.flagDespawn()
}
@Transient private val fuseSound = MusicContainer(
"fuse", ModMgr.getFile("basegame", "audio/effects/explosion/fuse.ogg")
) {
this.flagDespawn()
}
@Transient private val fuseSoundCont = MusicContainer(
"fuse_continue", ModMgr.getFile("basegame", "audio/effects/explosion/fuse_continue.ogg")
) {
this.flagDespawn()
}
private var fuseSoundStatus = 0 // this value must be stored into the savegame
@Transient private var fuseSoundFired = false
override val stopMusicOnDespawn: Boolean
get() = this.isVisible
override fun updateImpl(delta: Float) {
super.updateImpl(delta)
if (!fuseSoundFired && fuse > 0f) {
fuseSoundFired = true
if (fuseSoundStatus == 0) {
startAudio(fuseSound, 2.0)
fuseSoundStatus = 1
}
else
startAudio(fuseSoundCont, 2.0)
}
fuse -= delta
if (fuse <= 0f && !explosionCalled) {
@@ -57,6 +83,7 @@ open class ActorPrimedBomb(
) {
physProp.usePhysics = false
this.isVisible = false // or play explosion anim
stopAudio(fuseSound)
startAudio(boomSound, 10.0)
}
}
@@ -65,6 +92,8 @@ open class ActorPrimedBomb(
override fun dispose() {
super.dispose()
boomSound.dispose()
fuseSound.dispose()
fuseSoundCont.dispose()
}
}

View File

@@ -805,7 +805,7 @@ class BasicDebugInfoWindow : UICanvas() {
drawFaderHandle(batch, sliderX.toFloat(), faderY + 18f + meterHeight - faderKnobDbFs * meterHeight)
// currently streaming
if (track.streamPlaying) {
if (track.streamPlaying.get()) {
batch.color = ICON_GREEN
App.fontSmallNumbers.draw(batch, "\u00C0", x + 17f, faderY + 1f)
}