mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
working tapestry decoder and fixture object
Former-commit-id: dd61b61e6061cfb3dc2ad9d9f65fd1b272475718 Former-commit-id: 7acc72a0e59203c0ea56c355eadaeed1474e3ac1
This commit is contained in:
BIN
assets/theworld
Normal file
BIN
assets/theworld
Normal file
Binary file not shown.
@@ -50,7 +50,8 @@ object CommandDict {
|
||||
Pair("testgetlight", TestGetLight),
|
||||
Pair("spawnball", SpawnPhysTestBall),
|
||||
Pair("spawntorch", SpawnTikiTorch),
|
||||
Pair("musictest", MusicTest)
|
||||
Pair("musictest", MusicTest),
|
||||
Pair("spawntapestry", SpawnTapestry)
|
||||
)
|
||||
|
||||
operator fun get(commandName: String): ConsoleCommand {
|
||||
|
||||
25
src/net/torvald/terrarum/console/SpawnTapestry.kt
Normal file
25
src/net/torvald/terrarum/console/SpawnTapestry.kt
Normal file
@@ -0,0 +1,25 @@
|
||||
package net.torvald.terrarum.console
|
||||
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.gameactors.DecodeTapestry
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
|
||||
/**
|
||||
* Created by SKYHi14 on 2017-01-14.
|
||||
*/
|
||||
object SpawnTapestry : ConsoleCommand {
|
||||
override fun execute(args: Array<String>) {
|
||||
if (args.size < 2) {
|
||||
printUsage()
|
||||
return
|
||||
}
|
||||
|
||||
val tapestry = DecodeTapestry(File(args[1]))
|
||||
Terrarum.ingame.addActor(tapestry)
|
||||
}
|
||||
|
||||
override fun printUsage() {
|
||||
println("Usage: spawntapestry <tapestry_file>")
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,20 @@
|
||||
package net.torvald.terrarum.gameactors
|
||||
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.terrarum.gameworld.toUint
|
||||
import org.newdawn.slick.Color
|
||||
import org.newdawn.slick.Image
|
||||
import org.newdawn.slick.ImageBuffer
|
||||
import org.newdawn.slick.opengl.ImageData
|
||||
import org.newdawn.slick.opengl.TextureImpl
|
||||
import java.io.File
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.charset.Charset
|
||||
import java.util.*
|
||||
|
||||
object DecodeTapestry {
|
||||
|
||||
val colourIndices = arrayListOf(
|
||||
val colourIndices64 = arrayOf(
|
||||
0x333.fourBitCol(),
|
||||
0x600.fourBitCol(),
|
||||
0xA36.fourBitCol(),
|
||||
@@ -72,13 +81,116 @@ object DecodeTapestry {
|
||||
0xEBA.fourBitCol()
|
||||
)
|
||||
|
||||
val colourIndices16 = arrayOf(
|
||||
0x000.fourBitCol(),
|
||||
0xfff.fourBitCol(),
|
||||
0x666.fourBitCol(),
|
||||
0xccc.fourBitCol(),
|
||||
0xfe0.fourBitCol(),
|
||||
0xe60.fourBitCol(),
|
||||
0xe00.fourBitCol(),
|
||||
0xe2a.fourBitCol(),
|
||||
0x427.fourBitCol(),
|
||||
0x32f.fourBitCol(),
|
||||
0x4af.fourBitCol(),
|
||||
0x5f0.fourBitCol(),
|
||||
0x390.fourBitCol(),
|
||||
0x353.fourBitCol(),
|
||||
0x533.fourBitCol(),
|
||||
0xa63.fourBitCol()
|
||||
)
|
||||
|
||||
private fun Int.fourBitCol() = Color(
|
||||
this.and(0xF00).shl(12) + this.and(0xF00).shl(8) +
|
||||
this.and(0x0F0).shl(8) + this.and(0x0F0).shl(4) +
|
||||
this.and(0x00F).shl(4) + this.and(0x00F)
|
||||
)
|
||||
|
||||
operator fun invoke(file: File) {
|
||||
val MAGIC = "TEAF".toByteArray(charset = Charset.forName("US-ASCII"))
|
||||
val FORMAT_16 = 1
|
||||
val FORMAT_64 = 2
|
||||
|
||||
operator fun invoke(fileObj: File): TapestryObject {
|
||||
fun magicMismatch(magic: ByteArray): Boolean {
|
||||
MAGIC.forEachIndexed { i, byte ->
|
||||
if (byte != magic[i])
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
val file = fileObj.readBytes()
|
||||
|
||||
val magic = file.copyOfRange(0, 4)
|
||||
|
||||
if (magicMismatch(magic))
|
||||
throw RuntimeException("Invalid file -- type mismatch: expected header " +
|
||||
"${MAGIC[0]} ${MAGIC[1]} ${MAGIC[2]} ${MAGIC[3]}; got " +
|
||||
"${magic[0]} ${magic[1]} ${magic[2]} ${magic[3]}")
|
||||
|
||||
val colourModel = file[4].toUint()
|
||||
|
||||
if (colourModel != FORMAT_16 && colourModel != FORMAT_64)
|
||||
throw RuntimeException("Invalid colour model: $colourModel")
|
||||
|
||||
val width = file[6].toUint().shl(8) + file[7].toUint()
|
||||
|
||||
val artNameBytes = ArrayList<Byte>()
|
||||
val authorNameBytes = ArrayList<Byte>()
|
||||
|
||||
var readCounter = 8
|
||||
|
||||
while (file[readCounter] != 0x00.toByte()) {
|
||||
artNameBytes.add(file[readCounter])
|
||||
readCounter++
|
||||
}
|
||||
|
||||
readCounter++ // jump over null terminator
|
||||
|
||||
while (file[readCounter] != 0x00.toByte()) {
|
||||
authorNameBytes.add(file[readCounter])
|
||||
readCounter++
|
||||
}
|
||||
|
||||
readCounter++ // jump over null terminator
|
||||
|
||||
|
||||
|
||||
val artName = kotlin.text.String(artNameBytes.toByteArray(), charset = Charset.forName("UTF-8"))
|
||||
val authorName = kotlin.text.String(authorNameBytes.toByteArray(), charset = Charset.forName("UTF-8"))
|
||||
|
||||
val imageDataSize = file.size - readCounter
|
||||
val height = imageDataSize / width
|
||||
val outImageData = ImageBuffer(width, height)
|
||||
val counterOffset = readCounter
|
||||
while (readCounter < file.size) {
|
||||
val ofs = readCounter - counterOffset
|
||||
val palIndex = file[readCounter].toUint()
|
||||
|
||||
if (colourModel == FORMAT_16) {
|
||||
outImageData.setRGBA(
|
||||
ofs % width,
|
||||
ofs / width,
|
||||
colourIndices16[palIndex].redByte,
|
||||
colourIndices16[palIndex].greenByte,
|
||||
colourIndices16[palIndex].blueByte,
|
||||
255
|
||||
)
|
||||
}
|
||||
else {
|
||||
outImageData.setRGBA(
|
||||
ofs % width,
|
||||
ofs / width,
|
||||
colourIndices64[palIndex].redByte,
|
||||
colourIndices64[palIndex].greenByte,
|
||||
colourIndices64[palIndex].blueByte,
|
||||
255
|
||||
)
|
||||
}
|
||||
|
||||
readCounter++
|
||||
}
|
||||
|
||||
return TapestryObject(outImageData.image.getScaledCopy(2f), artName, authorName)
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,23 @@
|
||||
package net.torvald.terrarum.gameactors
|
||||
|
||||
import org.newdawn.slick.Color
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.gamecontroller.mouseX
|
||||
import net.torvald.terrarum.gamecontroller.mouseY
|
||||
import org.newdawn.slick.GameContainer
|
||||
import org.newdawn.slick.Graphics
|
||||
import java.io.File
|
||||
import org.newdawn.slick.Image
|
||||
|
||||
/**
|
||||
* Created by SKYHi14 on 2017-01-07.
|
||||
*/
|
||||
class TapestryObject(imageDataPath: String) : FixtureBase() {
|
||||
class TapestryObject(val image: Image, val artName: String, val artAuthor: String) : FixtureBase() {
|
||||
|
||||
init {
|
||||
|
||||
makeNewSprite(image.width, image.height)
|
||||
setHitboxDimension(image.width, image.height, 0, 0)
|
||||
sprite!!.setSpriteImage(image)
|
||||
isNoSubjectToGrav = true
|
||||
setPosition(Terrarum.appgc.mouseX, Terrarum.appgc.mouseY)
|
||||
}
|
||||
|
||||
override fun update(gc: GameContainer, delta: Int) {
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user