randomised music disc sprite

This commit is contained in:
minjaesong
2024-01-14 22:16:19 +09:00
parent 7aa376dc69
commit a973d33e02
5 changed files with 113 additions and 3 deletions

Binary file not shown.

View File

@@ -35,7 +35,7 @@ class AudioProcessBuf(val inputSamplingRate: Int, val audioReadFun: (ByteArray)
get() = inputSamplingRate * playbackSpeed get() = inputSamplingRate * playbackSpeed
private val doResample private val doResample
get() = inputSamplingRate == SAMPLING_RATE && (playbackSpeed - 1f).absoluteValue < (1f / 1024f) get() = !(inputSamplingRate == SAMPLING_RATE && (playbackSpeed - 1f).absoluteValue < (1f / 1024f))
companion object { companion object {
private val epsilon: Double = Epsilon.E private val epsilon: Double = Epsilon.E

View File

@@ -16,6 +16,7 @@ import java.util.UUID
open class ItemFileRef(originalID: ItemID) : GameItem(originalID) { open class ItemFileRef(originalID: ItemID) : GameItem(originalID) {
var author = "" var author = ""
var collection = ""
open var uuid: UUID = UUID(0, 0) open var uuid: UUID = UUID(0, 0)

View File

@@ -1,14 +1,26 @@
package net.torvald.terrarum.modulebasegame.gameitems package net.torvald.terrarum.modulebasegame.gameitems
import com.badlogic.gdx.files.FileHandle import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.colourutil.HUSLColorConverter
import net.torvald.colourutil.OKLCh
import net.torvald.random.HQRNG
import net.torvald.random.XXHash32
import net.torvald.random.XXHash64
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.ModMgr import net.torvald.terrarum.ModMgr
import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.savegame.toHex
import net.torvald.terrarum.utils.JsonFetcher import net.torvald.terrarum.utils.JsonFetcher
import net.torvald.terrarum.worlddrawer.toRGBA
/** /**
* Created by minjaesong on 2024-01-13. * Created by minjaesong on 2024-01-13.
*/ */
data class MusicDiscMetadata(val title: String, val author: String) data class MusicDiscMetadata(val title: String, val author: String, val album: String)
object MusicDiscHelper { object MusicDiscHelper {
fun getMetadata(musicFile: FileHandle): MusicDiscMetadata { fun getMetadata(musicFile: FileHandle): MusicDiscMetadata {
@@ -18,8 +30,9 @@ object MusicDiscHelper {
val artist = propForThisFile.get("artist").asString() val artist = propForThisFile.get("artist").asString()
val title = propForThisFile.get("title").asString() val title = propForThisFile.get("title").asString()
val album = propForThisFile.get("album").asString()
return MusicDiscMetadata(title, artist) return MusicDiscMetadata(title, artist, album)
} }
} }
@@ -34,6 +47,80 @@ open class MusicDiscPrototype(originalID: ItemID, module: String, path: String)
val meta = MusicDiscHelper.getMetadata(getAsGdxFile()) val meta = MusicDiscHelper.getMetadata(getAsGdxFile())
name = meta.title name = meta.title
author = meta.author author = meta.author
collection = meta.album
}
@Transient override val itemImage: TextureRegion = generateSprite()
/**
* Reads a channel-wise black and white image and tints it using HSLuv colour space
*/
private fun generateSprite(): TextureRegion {
val authorHash = XXHash64.hash(author.encodeToByteArray(), 54)
val albumHash = XXHash64.hash(collection.encodeToByteArray(), 32)
val nameHash = XXHash64.hash(name.encodeToByteArray(), 10)
val authorRand = HQRNG(authorHash)
val albumRand = HQRNG(albumHash)
val nameRand = HQRNG(nameHash)
val discColour = floatArrayOf(
albumRand.nextFloat() * 360f,
albumRand.nextFloat() * 70f + 10f,
albumRand.nextFloat() * 40f + 5f,
) // HSLuv
val labelColour = floatArrayOf(
nameRand.nextFloat() * 360f,
nameRand.nextFloat() * 20f + 75f,
nameRand.nextFloat() * 30f + 50f
) // HSLuv
val pixmap = Pixmap(ModMgr.getGdxFile("basegame", "items/record_sprite_base.tga"))
// tint the pixmap
for (y in 0 until pixmap.height) {
for (x in 0 until pixmap.width) {
val pixel = pixmap.getPixel(x, y) // RGBA
if (pixel and 0xFF == 0xFF) {
// red part
if (pixel and 0xFF000000.toInt() != 0) {
val b = pixel.ushr(24).and(255).toFloat() / 255f
val B = discColour.copyOf().also {
it[2] *= b
}
val outCol = HUSLColorConverter.hsluvToRgb(B).let {
Color(it[0], it[1], it[2], 1f)
}
pixmap.drawPixel(x, y, outCol.toRGBA())
}
// green part
else if (pixel and 0x00FF0000.toInt() != 0) {
val b = pixel.ushr(16).and(255).toFloat() / 255f
val B = labelColour.copyOf().also {
it[2] *= b
}
val outCol = HUSLColorConverter.hsluvToRgb(B).let {
Color(it[0], it[1], it[2], 1f)
}
pixmap.drawPixel(x, y, outCol.toRGBA())
}
}
}
}
val ret = TextureRegion(Texture(pixmap))
pixmap.dispose()
return ret
} }
} }

View File

@@ -4,11 +4,13 @@ import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.* import net.torvald.terrarum.*
import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
import net.torvald.terrarum.modulebasegame.gameactors.FixtureJukebox import net.torvald.terrarum.modulebasegame.gameactors.FixtureJukebox
import net.torvald.terrarum.modulebasegame.gameitems.ItemFileRef import net.torvald.terrarum.modulebasegame.gameitems.ItemFileRef
import net.torvald.terrarum.ui.* import net.torvald.terrarum.ui.*
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import net.torvald.unicode.getKeycapPC
/** /**
* Created by minjaesong on 2024-01-13. * Created by minjaesong on 2024-01-13.
@@ -46,6 +48,14 @@ class UIJukebox : UICanvas(
} }
} }
private val controlHelp: String
get() = if (App.environment == RunningEnvironment.PC)
"${getKeycapPC(ControlPresets.getKey("control_key_inventory"))} ${Lang["GAME_ACTION_CLOSE"]}"
else
"${App.gamepadLabelStart} ${Lang["GAME_ACTION_CLOSE"]} "
private val transitionalSonglistPanel = UIJukeboxSonglistPanel(this) private val transitionalSonglistPanel = UIJukeboxSonglistPanel(this)
private val transitionalDiscInventory = UIJukeboxInventory(this) private val transitionalDiscInventory = UIJukeboxInventory(this)
private val transitionPanel = UIItemHorizontalFadeSlide( private val transitionPanel = UIItemHorizontalFadeSlide(
@@ -85,8 +95,17 @@ class UIJukebox : UICanvas(
override fun renderUI(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) { override fun renderUI(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) {
UIInventoryFull.drawBackground(batch, 1f) UIInventoryFull.drawBackground(batch, 1f)
uiItems.forEach { it.render(frameDelta, batch, camera) } uiItems.forEach { it.render(frameDelta, batch, camera) }
val controlHintXPos = thisOffsetX + 2f
App.fontGame.draw(batch, controlHelp, controlHintXPos, yEnd - 20)
} }
private val halfSlotOffset = (UIItemInventoryElemSimple.height + UIItemInventoryItemGrid.listGap) / 2
private val thisOffsetX = UIInventoryFull.INVENTORY_CELLS_OFFSET_X() + UIItemInventoryElemSimple.height + UIItemInventoryItemGrid.listGap - halfSlotOffset
private val yEnd = -UIInventoryFull.YPOS_CORRECTION + (App.scr.height + UIInventoryFull.internalHeight).div(2).toFloat()
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
if (!openingClickLatched) { if (!openingClickLatched) {
return super.touchDown(screenX, screenY, pointer, button) return super.touchDown(screenX, screenY, pointer, button)