turntable to play disc

This commit is contained in:
minjaesong
2024-02-08 00:07:19 +09:00
parent ff15a3a8cf
commit 238dbfc3c4
15 changed files with 259 additions and 33 deletions

View File

@@ -62,5 +62,12 @@
"ingredients": [ "ingredients": [
[1, 20, "$WOOD"] /* 1 chest = 20 wood */ [1, 20, "$WOOD"] /* 1 chest = 20 wood */
] ]
},
"item@basegame:30": { /* turntable */
"workbench": "basiccrafting",
"ingredients": [
[1, 4, "item@basegame:144", 14, "$WOOD", 10, "item@basegame:113"] /* 1 turntable = 4 quartz, 14 wood, 10 iron */
]
} }
} }

View File

@@ -28,6 +28,7 @@ id;classname;tags
27;net.torvald.terrarum.modulebasegame.gameitems.ItemFurnaceAndAnvil;FIXTURE,CRAFTING 27;net.torvald.terrarum.modulebasegame.gameitems.ItemFurnaceAndAnvil;FIXTURE,CRAFTING
28;net.torvald.terrarum.modulebasegame.gameitems.ItemJukebox;FIXTURE,MUSIC 28;net.torvald.terrarum.modulebasegame.gameitems.ItemJukebox;FIXTURE,MUSIC
29;net.torvald.terrarum.modulebasegame.gameitems.ItemCharcoal;COMBUSTIBLE 29;net.torvald.terrarum.modulebasegame.gameitems.ItemCharcoal;COMBUSTIBLE
30;net.torvald.terrarum.modulebasegame.gameitems.ItemMusicalTurntable;FIXTURE,MUSIC
# ingots # ingots
26;net.torvald.terrarum.modulebasegame.gameitems.IngotSteel;INGOT 26;net.torvald.terrarum.modulebasegame.gameitems.IngotSteel;INGOT
@@ -78,15 +79,15 @@ id;classname;tags
# data storage (discs; 256) # data storage (discs; 256)
# 32768 is a reserved number for a blank disc # 32768 is a reserved number for a blank disc
32769;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc01;MUSIC 32769;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc01;MUSIC,PHONO
32770;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc02;MUSIC 32770;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc02;MUSIC,PHONO
32771;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc03;MUSIC 32771;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc03;MUSIC,PHONO
32772;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc04;MUSIC 32772;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc04;MUSIC,PHONO
32773;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc05;MUSIC 32773;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc05;MUSIC,PHONO
32774;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc06;MUSIC 32774;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc06;MUSIC,PHONO
32775;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc07;MUSIC 32775;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc07;MUSIC,PHONO
32776;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc08;MUSIC 32776;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc08;MUSIC,PHONO
32777;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc09;MUSIC 32777;net.torvald.terrarum.modulebasegame.gameitems.MusicDisc09;MUSIC,PHONO
# data storage (tapestries; 256) # data storage (tapestries; 256)
#33023;net.torvald.terrarum.modulebasegame.gameitems.ItemTapestry;FIXTURE #33023;net.torvald.terrarum.modulebasegame.gameitems.ItemTapestry;FIXTURE
1 id classname tags
28 28 net.torvald.terrarum.modulebasegame.gameitems.ItemJukebox FIXTURE,MUSIC
29 29 net.torvald.terrarum.modulebasegame.gameitems.ItemCharcoal COMBUSTIBLE
30 # ingots 30 net.torvald.terrarum.modulebasegame.gameitems.ItemMusicalTurntable FIXTURE,MUSIC
31 # ingots
32 26 net.torvald.terrarum.modulebasegame.gameitems.IngotSteel INGOT
33 112 net.torvald.terrarum.modulebasegame.gameitems.IngotCopper INGOT
34 113 net.torvald.terrarum.modulebasegame.gameitems.IngotIron INGOT
79 32777 net.torvald.terrarum.modulebasegame.gameitems.MusicDisc09 MUSIC MUSIC,PHONO
80 # data storage (tapestries 256)
81 #33023 net.torvald.terrarum.modulebasegame.gameitems.ItemTapestry FIXTURE
82 # fluids on storage
83 # preferably autogenerated
84 # 10000h..100FFh : Fluid type 0 (water) x container type 0..255
85 # 10100h..101FFh : Fluid type 1 (lava) x container type 0..255
86 # 10200h..102FFh : Fluid type 2 (crude oil) x container type 0..255
87 # 10300h..103FFh : Fluid type 3 (petroleum) x container type 0..255
88 # 10400h..104FFh : Fluid type 4 (compressed air) x container type 0..255
89 # 10500h..105FFh : Fluid type 5 (steam) x container type 0..255
90 # ...
91 # 1FF00h..1FFFFh : Fluid type 255 (???) x container type 0..255
92
93

Binary file not shown.

View File

@@ -62,6 +62,7 @@
"ITEM_SMELTER_SMALL": "Small Smelter", "ITEM_SMELTER_SMALL": "Small Smelter",
"ITEM_STORAGE_CHEST": "Storage Chest", "ITEM_STORAGE_CHEST": "Storage Chest",
"ITEM_TIKI_TORCH": "Tiki Torch", "ITEM_TIKI_TORCH": "Tiki Torch",
"ITEM_TURNTABLE": "Turntable",
"ITEM_TYPEWRITER": "Typewriter", "ITEM_TYPEWRITER": "Typewriter",
"ITEM_WIRE": "Wire", "ITEM_WIRE": "Wire",
"ITEM_WIRE_CUTTER": "Wire Cutter", "ITEM_WIRE_CUTTER": "Wire Cutter",

View File

@@ -62,6 +62,7 @@
"ITEM_SMELTER_SMALL": "소형 고로", "ITEM_SMELTER_SMALL": "소형 고로",
"ITEM_STORAGE_CHEST": "보관상자", "ITEM_STORAGE_CHEST": "보관상자",
"ITEM_TIKI_TORCH": "티키 토치", "ITEM_TIKI_TORCH": "티키 토치",
"ITEM_TURNTABLE": "전축",
"ITEM_TYPEWRITER": "타자기", "ITEM_TYPEWRITER": "타자기",
"ITEM_WIRE": "전선", "ITEM_WIRE": "전선",
"ITEM_WIRE_CUTTER": "전선 절단기", "ITEM_WIRE_CUTTER": "전선 절단기",

Binary file not shown.

View File

@@ -24,7 +24,7 @@ import kotlin.math.tanh
open class LoFi( open class LoFi(
staticModule: String, staticPath: String, staticModule: String, staticPath: String,
irModule: String, irPath: String, irModule: String, irPath: String,
val crossfeed: Float, gain: Float = 1f / 256f val crossfeed: Float, gain: Float = 1f / 256f, saturationLim: Float = 1f
): TerrarumAudioFilter(), DspCompressor { ): TerrarumAudioFilter(), DspCompressor {
override val downForce = arrayOf(1.0f, 1.0f) override val downForce = arrayOf(1.0f, 1.0f)
@@ -72,8 +72,9 @@ open class LoFi(
* Default function is `tanh(x)` * Default function is `tanh(x)`
*/ */
open fun saturate(v: Float): Float { open fun saturate(v: Float): Float {
return tanh(v) return K * tanh(v / K)
} }
private val K = saturationLim.coerceIn(0f, 1f)
override fun drawDebugView(batch: SpriteBatch, x: Int, y: Int) { override fun drawDebugView(batch: SpriteBatch, x: Int, y: Int) {
convolver.drawDebugView(batch, x, y) convolver.drawDebugView(batch, x, y)

View File

@@ -7,9 +7,9 @@ import net.torvald.terrarum.ModMgr
* *
* Created by minjaesong on 2024-01-24. * Created by minjaesong on 2024-01-24.
*/ */
class Phono(irModule: String, irPath: String, crossfeed: Float, gain: Float) : LoFi( class Phono(irModule: String, irPath: String, crossfeed: Float, gain: Float, saturationLim: Float) : LoFi(
"basegame", "audio/effects/static/phono_pops.ogg", "basegame", "audio/effects/static/phono_pops.ogg",
irModule, irPath, crossfeed, gain irModule, irPath, crossfeed, gain, saturationLim
) )
/** /**
@@ -17,9 +17,9 @@ class Phono(irModule: String, irPath: String, crossfeed: Float, gain: Float) : L
* *
* Created by minjaesong on 2024-01-24. * Created by minjaesong on 2024-01-24.
*/ */
class Tape(irModule: String, irPath: String, crossfeed: Float, gain: Float) : LoFi( class Tape(irModule: String, irPath: String, crossfeed: Float, gain: Float, saturationLim: Float) : LoFi(
"basegame", "audio/effects/static/tape_hiss.ogg", "basegame", "audio/effects/static/tape_hiss.ogg",
irModule, irPath, crossfeed, gain irModule, irPath, crossfeed, gain, saturationLim
) )
/** /**
@@ -29,7 +29,7 @@ class Tape(irModule: String, irPath: String, crossfeed: Float, gain: Float) : Lo
* *
* Created by minjaesong on 2024-01-24. * Created by minjaesong on 2024-01-24.
*/ */
class Holo(irModule: String, irPath: String, crossfeed: Float, gain: Float) : LoFi( class Holo(irModule: String, irPath: String, crossfeed: Float, gain: Float, saturationLim: Float) : LoFi(
"basegame", "audio/effects/static/film_pops_lowpass.ogg", "basegame", "audio/effects/static/film_pops_lowpass.ogg",
irModule, irPath, crossfeed, gain irModule, irPath, crossfeed, gain, saturationLim
) )

View File

@@ -379,6 +379,7 @@ abstract class GameItem(val originalID: ItemID) : Comparable<GameItem>, Cloneabl
fun hasTag(s: String) = tags.contains(s) fun hasTag(s: String) = tags.contains(s)
fun hasAllTags(s: List<String>) = tags.containsAll(s) fun hasAllTags(s: List<String>) = tags.containsAll(s)
fun hasAllTagOf(vararg s: String) = s.all { hasTag(it) }
companion object { companion object {

View File

@@ -18,6 +18,7 @@ import net.torvald.terrarum.audio.dsp.LoFi
import net.torvald.terrarum.audio.dsp.NullFilter import net.torvald.terrarum.audio.dsp.NullFilter
import net.torvald.terrarum.audio.dsp.Phono import net.torvald.terrarum.audio.dsp.Phono
import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameactors.Hitbox import net.torvald.terrarum.gameactors.Hitbox
import net.torvald.terrarum.gameactors.Lightbox import net.torvald.terrarum.gameactors.Lightbox
import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameitems.ItemID
@@ -217,19 +218,11 @@ class FixtureJukebox : Electric, PlaysMusic {
} }
private fun loadConvolver(it: TerrarumAudioMixerTrack?) { private fun loadConvolver(it: TerrarumAudioMixerTrack?) {
it?.filters?.set(filterIndex, Phono( Companion.loadConvolver(filterIndex, it, "basegame", "audio/convolution/Soundwoofer - large_speaker_Marshall JVM 205C SM57 A 0 0 1.bin")
"basegame",
"audio/convolution/Soundwoofer - large_speaker_Marshall JVM 205C SM57 A 0 0 1.bin",
0f, 5f / 16f
))
} }
private fun unloadConvolver(music: MusicContainer?) { private fun unloadConvolver(music: MusicContainer?) {
if (music != null) { Companion.unloadConvolver(this, filterIndex, music)
musicTracks[music]?.let {
it.filters[filterIndex] = NullFilter
}
}
} }
override fun reload() { override fun reload() {
@@ -242,8 +235,25 @@ class FixtureJukebox : Electric, PlaysMusic {
override fun dispose() { override fun dispose() {
App.audioMixerReloadHooks.remove(this) App.audioMixerReloadHooks.remove(this)
super.dispose() super.dispose()
// testMusic.gdxMusic.dispose()
// no need to dispose of backlamp and playmech: they share the same texture with the main sprite // no need to dispose of backlamp and playmech: they share the same texture with the main sprite
} }
companion object {
fun loadConvolver(filterIndex: Int, it: TerrarumAudioMixerTrack?, module: String, path: String, gain: Float = 5f / 16f, satLim: Float = 1f) {
it?.filters?.set(filterIndex, Phono(
module,
path,
0f, gain, satLim
))
}
fun unloadConvolver(actor: Actor, filterIndex: Int, music: MusicContainer?) {
if (music != null) {
actor.musicTracks[music]?.let {
it.filters[filterIndex] = NullFilter
}
}
}
}
} }

View File

@@ -0,0 +1,181 @@
package net.torvald.terrarum.modulebasegame.gameactors
import com.badlogic.gdx.Gdx
import net.torvald.spriteanimation.SheetSpriteAnimation
import net.torvald.terrarum.*
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.audio.AudioMixer
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack
import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.gameitems.GameItem
import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.MusicContainer
import net.torvald.terrarum.modulebasegame.TerrarumMusicGovernor
import net.torvald.terrarum.modulebasegame.gameitems.FixtureItemBase
import net.torvald.terrarum.modulebasegame.gameitems.ItemFileRef
import net.torvald.terrarum.modulebasegame.gameitems.MusicDiscHelper
import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore
import net.torvald.terrarum.ui.MouseLatch
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import org.dyn4j.geometry.Vector2
/**
* Created by minjaesong on 2024-02-07.
*/
class FixtureMusicalTurntable : Electric, PlaysMusic {
constructor() : super(
BlockBox(BlockBox.NO_COLLISION, 1, 1),
nameFun = { Lang["ITEM_TURNTABLE"] }
)
@Transient var musicNowPlaying: MusicContainer? = null; private set
@Transient private val filterIndex = 0
val musicIsPlaying: Boolean
get() = musicNowPlaying != null
init {
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/turntable.tga")
density = 1400.0
setHitboxDimension(TILE_SIZE * 1, TILE_SIZE * 1, 0, 0)
makeNewSprite(TextureRegionPack(itemImage.texture, TILE_SIZE * 1, TILE_SIZE * 1)).let {
it.setRowsAndFrames(2,2)
it.currentRow = 1
}
actorValue[AVKey.BASEMASS] = 20.0
setWireSinkAt(0, 0, "appliance_power")
setWireConsumptionAt(0, 2, Vector2(80.0, 0.0))
App.audioMixerReloadHooks[this] = {
loadConvolver(musicTracks[musicNowPlaying])
}
despawnHook = {
stopGracefully()
}
}
internal var disc: ItemID? = null
@Transient private val clickLatch = MouseLatch(listOf(App.getConfigInt("config_mousesecondary")))
override val canBeDespawned: Boolean
get() = disc == null
override fun update(delta: Float) {
super.update(delta)
// right click
if (mouseUp) {
clickLatch.latch {
if (disc == null) {
if (INGAME.actorNowPlaying != null) {
val itemOnGrip =
INGAME.actorNowPlaying!!.inventory.itemEquipped.get(GameItem.EquipPosition.HAND_GRIP)
val itemProp = ItemCodex[itemOnGrip]
if (itemProp?.hasAllTagOf("MUSIC", "PHONO") == true) {
disc = itemOnGrip
INGAME.actorNowPlaying!!.removeItem(itemOnGrip!!)
playDisc()
}
}
}
else {
stopGracefully()
PickaxeCore.dropItem(
disc!!,
intTilewiseHitbox.canonicalX.toInt(),
intTilewiseHitbox.canonicalY.toInt()
)
disc = null
}
}
}
// supress the normal background music playback
if (musicIsPlaying && !flagDespawn) {
(INGAME.musicGovernor as TerrarumMusicGovernor).stopMusic(this, true)
}
}
fun playDisc() {
if (disc == null) return
App.printdbg(this, "Play disc!")
val musicFile = (ItemCodex[disc] as? ItemFileRef)?.getAsGdxFile()
if (musicFile != null) {
val (title, artist) = MusicDiscHelper.getMetadata(musicFile)
App.printdbg(this, "Title: $title, artist: $artist")
musicNowPlaying = MusicContainer(title, musicFile.file(), Gdx.audio.newMusic(musicFile)) {
unloadConvolver(musicNowPlaying)
musicNowPlaying?.gdxMusic?.tryDispose()
musicNowPlaying = null
App.printdbg(this, "Stop music $title - $artist")
// can't call stopDiscPlayback() because of the recursion
(INGAME.musicGovernor as TerrarumMusicGovernor).stopMusic(this, pauseLen = (INGAME.musicGovernor as TerrarumMusicGovernor).getRandomMusicInterval())
}
App.audioMixer.requestFadeOut(App.audioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 2f) {
startAudio(musicNowPlaying!!) { loadConvolver(it) }
}
(sprite as SheetSpriteAnimation).currentRow = 0
}
}
/**
* Try to stop the disc being played, and reset the background music cue
*/
fun stopGracefully() {
stopDiscPlayback()
(INGAME.musicGovernor as TerrarumMusicGovernor).stopMusic(this, pauseLen = (INGAME.musicGovernor as TerrarumMusicGovernor).getRandomMusicInterval())
}
private fun stopDiscPlayback() {
musicNowPlaying?.let {
stopAudio(it)
unloadConvolver(it)
}
(sprite as SheetSpriteAnimation).currentRow = 1
}
private fun loadConvolver(it: TerrarumAudioMixerTrack?) {
FixtureJukebox.loadConvolver(filterIndex, it, "basegame", "audio/convolution/Soundwoofer - small_speaker_Gallien Krueger GK 250ML B5 Left A 230 200 320.bin", 3.5f / 16f, 0.8f)
}
private fun unloadConvolver(music: MusicContainer?) {
FixtureJukebox.unloadConvolver(this, filterIndex, music)
}
override fun reload() {
super.reload()
// cannot resume playback, just stop the music
musicNowPlaying = null
}
override fun dispose() {
App.audioMixerReloadHooks.remove(this)
super.dispose()
// no need to dispose of backlamp and playmech: they share the same texture with the main sprite
}
}

View File

@@ -20,3 +20,20 @@ class ItemJukebox(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald
override var originalName = "ITEM_JUKEBOX" override var originalName = "ITEM_JUKEBOX"
} }
/**
* Created by minjaesong on 2024-02-07.
*/
class ItemMusicalTurntable(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureMusicalTurntable") {
override var baseMass = 20.0
override val isDynamic = false
override val materialId = ""
override val itemImage: TextureRegion
get() = CommonResourcePool.getAsItemSheet("basegame.items").get(7,3)
override var baseToolSize: Double? = baseMass
override var originalName = "ITEM_TURNTABLE"
}

View File

@@ -127,8 +127,8 @@ internal class UnsafePtr(pointer: Long, allocSize: Long) {
// appear (e.g. getting garbage values when it fucking shouldn't) // appear (e.g. getting garbage values when it fucking shouldn't)
// using ifs instead of assertions: inactive assert statements still slows down the app // using ifs instead of assertions: inactive assert statements still slows down the app
if (destroyed) { throw DanglingPointerException("The pointer is already destroyed ($this)") } // if (destroyed) { throw DanglingPointerException("The pointer is already destroyed ($this)") }
if (index !in 0 until size) { throw AddressOverflowException("Index: $index; alloc size: $size") } // if (index !in 0 until size) { throw AddressOverflowException("Index: $index; alloc size: $size") }
} }
operator fun get(index: Long): Byte { operator fun get(index: Long): Byte {

Binary file not shown.