diff --git a/assets/theworld b/assets/theworld new file mode 100644 index 000000000..b899ed5f7 Binary files /dev/null and b/assets/theworld differ diff --git a/src/net/torvald/terrarum/console/CommandDict.kt b/src/net/torvald/terrarum/console/CommandDict.kt index 4fb115278..972743440 100644 --- a/src/net/torvald/terrarum/console/CommandDict.kt +++ b/src/net/torvald/terrarum/console/CommandDict.kt @@ -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 { diff --git a/src/net/torvald/terrarum/console/SpawnTapestry.kt b/src/net/torvald/terrarum/console/SpawnTapestry.kt new file mode 100644 index 000000000..7b9a0c7e0 --- /dev/null +++ b/src/net/torvald/terrarum/console/SpawnTapestry.kt @@ -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) { + if (args.size < 2) { + printUsage() + return + } + + val tapestry = DecodeTapestry(File(args[1])) + Terrarum.ingame.addActor(tapestry) + } + + override fun printUsage() { + println("Usage: spawntapestry ") + } +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/DecodeTapestry.kt b/src/net/torvald/terrarum/gameactors/DecodeTapestry.kt index e0a2b6970..04dd0dc85 100644 --- a/src/net/torvald/terrarum/gameactors/DecodeTapestry.kt +++ b/src/net/torvald/terrarum/gameactors/DecodeTapestry.kt @@ -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() + val authorNameBytes = ArrayList() + + 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) } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/TapestryObject.kt b/src/net/torvald/terrarum/gameactors/TapestryObject.kt index 8317efe14..feb8bb3af 100644 --- a/src/net/torvald/terrarum/gameactors/TapestryObject.kt +++ b/src/net/torvald/terrarum/gameactors/TapestryObject.kt @@ -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) { diff --git a/work_files/graphics/colourmap/64_from_master_final.act b/work_files/graphics/colourmap/64_from_master_final.act index 14451f449..96b59c18e 100644 Binary files a/work_files/graphics/colourmap/64_from_master_final.act and b/work_files/graphics/colourmap/64_from_master_final.act differ