From 68d8bf13b7f0002ace5d33c6f18d74c69eba740a Mon Sep 17 00:00:00 2001 From: minjaesong Date: Mon, 28 Feb 2022 11:39:29 +0900 Subject: [PATCH] tapestry sprite to draw frame --- .../basegame/tapestries/common/canvas.tga | 3 + .../tapestries/common/frame_basegame-48.tga | 3 + .../torvald/terrarum/CommonResourcePool.kt | 5 + src/net/torvald/terrarum/Terrarum.kt | 15 +++ .../gameactors/DecodeTapestry.kt | 10 +- .../gameactors/TapestryObject.kt | 93 +++++++++++++++---- src/net/torvald/terrarum/serialise/Common.kt | 10 ++ .../tapestries/common/frame_basegame-NUM.kra | 3 + 8 files changed, 118 insertions(+), 24 deletions(-) create mode 100644 assets/mods/basegame/tapestries/common/canvas.tga create mode 100644 assets/mods/basegame/tapestries/common/frame_basegame-48.tga create mode 100644 work_files/graphics/tapestries/common/frame_basegame-NUM.kra diff --git a/assets/mods/basegame/tapestries/common/canvas.tga b/assets/mods/basegame/tapestries/common/canvas.tga new file mode 100644 index 000000000..1b26c5503 --- /dev/null +++ b/assets/mods/basegame/tapestries/common/canvas.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b12807d46445ac52eacc35a50b7b49e31a80ed925c455492ee28895898cc6225 +size 34 diff --git a/assets/mods/basegame/tapestries/common/frame_basegame-48.tga b/assets/mods/basegame/tapestries/common/frame_basegame-48.tga new file mode 100644 index 000000000..0960bacf8 --- /dev/null +++ b/assets/mods/basegame/tapestries/common/frame_basegame-48.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6442d4fa1e6ea07026e3a9e5bd2b1979cd7f32d67ed9f3062fc9bc790d7cd4ce +size 16402 diff --git a/src/net/torvald/terrarum/CommonResourcePool.kt b/src/net/torvald/terrarum/CommonResourcePool.kt index 53231267b..992534336 100644 --- a/src/net/torvald/terrarum/CommonResourcePool.kt +++ b/src/net/torvald/terrarum/CommonResourcePool.kt @@ -115,6 +115,11 @@ object CommonResourcePool { return pool[identifier]!! } + fun getOrNull(identifier: String) = pool[identifier] + fun getOrDefault(identifier: String, defaultValue: Any) = pool.getOrDefault(identifier, defaultValue) + fun getOrPut(identifier: String, defaultValue: () -> Any) = pool.getOrPut(identifier, defaultValue) + fun getOrElse(identifier: String, defaultValue: () -> Any) = pool.getOrElse(identifier, defaultValue) + inline fun getAs(identifier: String) = get(identifier) as T fun getAsTextureRegionPack(identifier: String) = getAs(identifier) fun getAsTextureRegion(identifier: String) = getAs(identifier) diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 53e4fcc99..39ecdda9e 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -37,6 +37,7 @@ import java.io.PrintStream import java.util.* import kotlin.math.absoluteValue import kotlin.math.round +import kotlin.math.roundToInt @@ -348,6 +349,20 @@ inline fun FrameBuffer.inActionF(camera: OrthographicCamera?, batch: SpriteBatch } +private val rgbMultLUT = Array(256) { y -> IntArray(256) { x -> + val i = (x % 256) / 255f + val j = (y / 256) / 255f + (i * j).times(255f).roundToInt() +} } + +infix fun Int.rgbamul(other: Int): Int { + val r = rgbMultLUT[this.ushr(24).and(255)][other.ushr(24).and(255)] + val g = rgbMultLUT[this.ushr(16).and(255)][other.ushr(16).and(255)] + val b = rgbMultLUT[this.ushr(8).and(255)][other.ushr(8).and(255)] + val a = rgbMultLUT[this.ushr(0).and(255)][other.ushr(0).and(255)] + return r.shl(24) or g.shl(16) or b.shl(8) or a +} + infix fun Color.mul(other: Color): Color = this.cpy().mul(other) infix fun Color.mulAndAssign(other: Color): Color { this.r *= other.r diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/DecodeTapestry.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/DecodeTapestry.kt index 085b81ba5..d172c3c8a 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/DecodeTapestry.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/DecodeTapestry.kt @@ -109,13 +109,11 @@ object DecodeTapestry { val FORMAT_16 = 1 val FORMAT_64 = 2 - operator fun invoke(fileObj: File): TapestryObject { + operator fun invoke(file: ByteArray): TapestryInfo { fun magicMismatch(magic: ByteArray, array: ByteArray): Boolean { return !Arrays.equals(array.sliceArray(0..magic.lastIndex), magic) } - val file = fileObj.readBytes() - val magic = file.copyOfRange(0, 4) if (magicMismatch(MAGIC, magic)) @@ -174,6 +172,8 @@ object DecodeTapestry { readCounter++ } - return TapestryObject(outImageData, artName, authorName) { "$ccW$authorName, $ccC$artName" } + return TapestryInfo(outImageData, artName, authorName) } -} \ No newline at end of file +} + +data class TapestryInfo(val pixmap: Pixmap, val artName: String, val authorName: String) \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/TapestryObject.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/TapestryObject.kt index 68da1c552..faa93f595 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/TapestryObject.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/TapestryObject.kt @@ -1,12 +1,15 @@ package net.torvald.terrarum.modulebasegame.gameactors +import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Pixmap import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.graphics.g2d.SpriteBatch -import net.torvald.terrarum.Terrarum +import net.torvald.terrarum.* +import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF -import net.torvald.terrarum.ceilInt +import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.gameactors.ActorID +import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack /** @@ -14,34 +17,86 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack */ class TapestryObject : FixtureBase { - // physics = false only speeds up for ~2 frames with 50 tapestries + @Transient private var initialised = false var artName = ""; private set var artAuthor = ""; private set + val tw = 1 + val th = 1 + + private var rawBytes = ByteArray(tw * th * 256) + private var frameBlock: ItemID = Block.PLANK_NORMAL + private constructor() : super() - constructor(pixmap: Pixmap, artName: String, artAuthor: String, nameFun: () -> String) : super() { + constructor(rawBytes: ByteArray, framingMaterial: ItemID) : super() { this.artName = artName this.artAuthor = artAuthor - this.nameFun = nameFun - - val texture = Texture(pixmap) - pixmap.dispose() - texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) - val texturePack = TextureRegionPack(texture, texture.width, texture.height) - - makeNewSprite(texturePack) - setHitboxDimension(texture.width, texture.height, 0, 0) - setPosition(Terrarum.mouseX, Terrarum.mouseY) - // you CAN'T destroy the image - - // redefine blockbox - this.blockBox = BlockBox(BlockBox.NO_COLLISION, texture.width.div(TILE_SIZEF).ceilInt(), texture.height.div(TILE_SIZEF).ceilInt()) - this.renderOrder = RenderOrder.BEHIND + this.nameFun = { "$ccW$artAuthor, $ccC$artName" } + this.rawBytes = rawBytes + this.frameBlock = framingMaterial } override fun update(delta: Float) { + if (!initialised) { + initialised = true + + + val (pixmap, name, author) = DecodeTapestry(rawBytes) + artName = name + artAuthor = author + + if (pixmap.width % TILE_SIZE != 0 || pixmap.height % TILE_SIZE != 0 || pixmap.width * pixmap.height == 0) { + throw UnsupportedOperationException("Tapestry size not multiple of tile size: (${pixmap.width}x${pixmap.height})") + } + + // draw canvas and frame texture over the pixmap + val tileFilename = "${frameBlock.replace(':','-')}" + val frame = CommonResourcePool.getOrPut("tapestries-common-frame_$tileFilename.tga") { + Pixmap(ModMgr.getGdxFilesFromEveryMod("tapestries/common/frame_$tileFilename.tga").last().second) + } as Pixmap + val canvas = CommonResourcePool.getOrPut("tapestries-common-canvas") { + Pixmap(ModMgr.getGdxFilesFromEveryMod("tapestries/common/canvas.tga").last().second) + } as Pixmap + + val tw = pixmap.width.div(TILE_SIZEF).ceilInt() + val th = pixmap.height.div(TILE_SIZEF).ceilInt() + + // blend canvas texture + for (y in 0 until pixmap.height) { for (x in 0 until pixmap.width) { + val srcCol = canvas.getPixel(x % pixmap.width, y % pixmap.height) + val dstCol = pixmap.getPixel(x, y) + pixmap.drawPixel(x, y, dstCol rgbamul srcCol) + } } + + // draw frame + for (ty in 0 until th) { for (tx in 0 until tw) { + val srcx = TILE_SIZE * (if (tw == 1) 0 else if (tx == 0) 1 else if (tx == tw - 1) 3 else 2) + val srcy = TILE_SIZE * (if (th == 1) 0 else if (ty == 0) 1 else if (tw == th - 1) 3 else 2) + val dstx = tx * TILE_SIZE + val dsty = ty * TILE_SIZE + pixmap.drawPixmap(frame, srcx, srcy, TILE_SIZE, TILE_SIZE, dstx, dsty, TILE_SIZE, TILE_SIZE) + } } + + + val texture = Texture(pixmap) + texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) + val texturePack = TextureRegionPack(texture, texture.width, texture.height) + + makeNewSprite(texturePack) + setHitboxDimension(texture.width, texture.height, 0, 0) + setPosition(Terrarum.mouseX, Terrarum.mouseY) + + // redefine blockbox + this.blockBox = BlockBox(BlockBox.NO_COLLISION, tw, th) + this.renderOrder = RenderOrder.BEHIND + + + pixmap.dispose() + INGAME.disposables.add(texture) + } + super.update(delta) } diff --git a/src/net/torvald/terrarum/serialise/Common.kt b/src/net/torvald/terrarum/serialise/Common.kt index 3c3053691..5987ee3c4 100644 --- a/src/net/torvald/terrarum/serialise/Common.kt +++ b/src/net/torvald/terrarum/serialise/Common.kt @@ -203,6 +203,16 @@ object Common { return rng } }) + // kotlin.ByteArray + jsoner.setSerializer(ByteArray::class.java, object : Json.Serializer { + override fun write(json: Json, obj: ByteArray, knownType: Class<*>?) { + json.writeValue(bytesToZipdStr(obj.iterator())) + } + + override fun read(json: Json, jsonData: JsonValue, type: Class<*>?): ByteArray { + return strToBytes(StringReader(jsonData.asString())).toByteArray() + } + }) } private data class LayerInfo(val h: String, val b: String, val x: Int, val y: Int) diff --git a/work_files/graphics/tapestries/common/frame_basegame-NUM.kra b/work_files/graphics/tapestries/common/frame_basegame-NUM.kra new file mode 100644 index 000000000..12b483533 --- /dev/null +++ b/work_files/graphics/tapestries/common/frame_basegame-NUM.kra @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8ceb708794dd7051403e7918e4d0ae745b37243089979480a132e8a74def6f5 +size 23625