mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-14 20:44:05 +09:00
limitedly successful attempt to create a title screen
This commit is contained in:
@@ -1,42 +0,0 @@
|
||||
package net.torvald.terrarum.serialise
|
||||
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-08-24.
|
||||
*/
|
||||
// internal for everything: prevent malicious module from messing up the savedata
|
||||
internal object ReadGameMapData {
|
||||
|
||||
internal fun InputStream.readRelative(b: ByteArray, off: Int, len: Int): Int {
|
||||
if (b == null) {
|
||||
throw NullPointerException()
|
||||
} else if (off < 0 || len < 0 || len > b.size) {
|
||||
throw IndexOutOfBoundsException()
|
||||
} else if (len == 0) {
|
||||
return 0
|
||||
}
|
||||
|
||||
var c = read()
|
||||
if (c == -1) {
|
||||
return -1
|
||||
}
|
||||
b[0] = c.toByte()
|
||||
|
||||
var i = 1
|
||||
try {
|
||||
while (i < len) {
|
||||
c = read()
|
||||
if (c == -1) {
|
||||
break
|
||||
}
|
||||
b[i] = c.toByte()
|
||||
i++
|
||||
}
|
||||
} catch (ee: IOException) {
|
||||
}
|
||||
|
||||
return i
|
||||
}
|
||||
}
|
||||
114
src/net/torvald/terrarum/serialise/ReadLayerData.kt
Normal file
114
src/net/torvald/terrarum/serialise/ReadLayerData.kt
Normal file
@@ -0,0 +1,114 @@
|
||||
package net.torvald.terrarum.serialise
|
||||
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.lang.IllegalArgumentException
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-08-24.
|
||||
*/
|
||||
// internal for everything: prevent malicious module from messing up the savedata
|
||||
internal object ReadLayerData {
|
||||
|
||||
|
||||
internal operator fun invoke(inputStream: InputStream, inWorld: GameWorld? = null): GameWorld {
|
||||
val magicBytes = ByteArray(4)
|
||||
val layerSizeBytes = ByteArray(1)
|
||||
val layerCountBytes = ByteArray(1)
|
||||
val worldWidthBytes = ByteArray(4)
|
||||
val worldHeightBytes = ByteArray(4)
|
||||
val spawnCoordXBytes = ByteArray(4)
|
||||
val spawnCoordYBytes = ByteArray(4)
|
||||
|
||||
// read header first
|
||||
inputStream.read(magicBytes)
|
||||
if (!Arrays.equals(magicBytes, WriteLayerData.MAGIC)) {
|
||||
throw IllegalArgumentException("File not a Layer Data")
|
||||
}
|
||||
|
||||
inputStream.read(layerSizeBytes)
|
||||
inputStream.read(layerCountBytes)
|
||||
inputStream.skip(2) // reserved bytes
|
||||
inputStream.read(worldWidthBytes)
|
||||
inputStream.read(worldHeightBytes)
|
||||
inputStream.read(spawnCoordXBytes)
|
||||
inputStream.read(spawnCoordYBytes)
|
||||
|
||||
val worldWidth = worldWidthBytes.toLittleInt()
|
||||
val worldHeight = worldHeightBytes.toLittleInt()
|
||||
val bytesPerTile = layerSizeBytes[0].toUint()
|
||||
val layerCount = layerCountBytes[0].toUint()
|
||||
val layerSize = worldWidth * worldHeight * bytesPerTile
|
||||
|
||||
val terrainLayerMSB = ByteArray(layerSize)
|
||||
val wallLayerMSB = ByteArray(layerSize)
|
||||
val terrainLayerLSB = ByteArray(layerSize / 2)
|
||||
val wallLayerLSB = ByteArray(layerSize / 2)
|
||||
var wireLayer: ByteArray? = null
|
||||
|
||||
inputStream.read(terrainLayerMSB)
|
||||
inputStream.read(wallLayerMSB)
|
||||
inputStream.read(terrainLayerLSB)
|
||||
inputStream.read(wallLayerLSB)
|
||||
|
||||
if (layerCount == 4) {
|
||||
wireLayer = ByteArray(layerSize)
|
||||
inputStream.read(wireLayer)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// create world out of tiles data
|
||||
|
||||
val retWorld = inWorld ?: GameWorld(worldWidth, worldHeight)
|
||||
|
||||
retWorld.layerTerrain.data = terrainLayerMSB
|
||||
retWorld.layerWall.data = wallLayerMSB
|
||||
retWorld.layerTerrainLowBits.data = terrainLayerLSB
|
||||
retWorld.layerWallLowBits.data = wallLayerLSB
|
||||
|
||||
if (wireLayer != null) {
|
||||
retWorld.layerWire.data = wireLayer
|
||||
}
|
||||
|
||||
retWorld.spawnX = spawnCoordXBytes.toLittleInt()
|
||||
retWorld.spawnY = spawnCoordYBytes.toLittleInt()
|
||||
|
||||
|
||||
return retWorld
|
||||
}
|
||||
|
||||
|
||||
internal fun InputStream.readRelative(b: ByteArray, off: Int, len: Int): Int {
|
||||
if (b == null) {
|
||||
throw NullPointerException()
|
||||
} else if (off < 0 || len < 0 || len > b.size) {
|
||||
throw IndexOutOfBoundsException()
|
||||
} else if (len == 0) {
|
||||
return 0
|
||||
}
|
||||
|
||||
var c = read()
|
||||
if (c == -1) {
|
||||
return -1
|
||||
}
|
||||
b[0] = c.toByte()
|
||||
|
||||
var i = 1
|
||||
try {
|
||||
while (i < len) {
|
||||
c = read()
|
||||
if (c == -1) {
|
||||
break
|
||||
}
|
||||
b[i] = c.toByte()
|
||||
i++
|
||||
}
|
||||
} catch (ee: IOException) {
|
||||
}
|
||||
|
||||
return i
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ internal object WriteCSV {
|
||||
Files.copy(tempPathMat, pathMat, StandardCopyOption.REPLACE_EXISTING)
|
||||
Files.deleteIfExists(tempPathMat)
|
||||
|
||||
println("Saved map data '${WriteGameMapData.META_FILENAME}' to $saveDirectoryName.")
|
||||
println("Saved map data '${WriteLayerData.META_FILENAME}' to $saveDirectoryName.")
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
package net.torvald.terrarum.serialise
|
||||
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import java.io.IOException
|
||||
import java.nio.charset.Charset
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
import java.nio.file.StandardCopyOption
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-03-18.
|
||||
*/
|
||||
// internal for everything: prevent malicious module from messing up the savedata
|
||||
internal object WriteGameMapData {
|
||||
|
||||
val META_FILENAME = "worldinfo1"
|
||||
|
||||
val MAGIC = "TEMD".toByteArray(charset = Charset.forName("US-ASCII"))
|
||||
|
||||
val BYTE_NULL: Byte = 0
|
||||
|
||||
|
||||
internal fun write(saveDirectoryName: String): Boolean {
|
||||
val path = Paths.get("${Terrarum.defaultSaveDir}" +
|
||||
"/$saveDirectoryName/${WriteMeta.META_FILENAME}")
|
||||
val tempPath = Files.createTempFile(path.toString(), "_temp")
|
||||
val map = Terrarum.ingame!!.world
|
||||
|
||||
// TODO gzip
|
||||
|
||||
// write binary
|
||||
Files.write(tempPath, MAGIC)
|
||||
Files.write(tempPath, byteArrayOf(GameWorld.SIZEOF))
|
||||
Files.write(tempPath, byteArrayOf(GameWorld.LAYERS))
|
||||
Files.write(tempPath, byteArrayOf(BYTE_NULL))
|
||||
Files.write(tempPath, byteArrayOf(BYTE_NULL))
|
||||
Files.write(tempPath, toByteArray(map.width))
|
||||
Files.write(tempPath, toByteArray(map.height))
|
||||
Files.write(tempPath, toByteArray(map.spawnX))
|
||||
Files.write(tempPath, toByteArray(map.spawnY))
|
||||
map.layerTerrain.forEach(
|
||||
{ b -> Files.write(tempPath, byteArrayOf(b)) })
|
||||
map.layerWall.forEach(
|
||||
{ b -> Files.write(tempPath, byteArrayOf(b)) })
|
||||
map.layerTerrainLowBits.forEach(
|
||||
{ b -> Files.write(tempPath, byteArrayOf(b)) })
|
||||
map.layerWallLowBits.forEach(
|
||||
{ b -> Files.write(tempPath, byteArrayOf(b)) })
|
||||
map.layerWire.forEach(
|
||||
{ b -> Files.write(tempPath, byteArrayOf(b)) })
|
||||
|
||||
// replace savemeta with tempfile
|
||||
try {
|
||||
Files.copy(tempPath, path, StandardCopyOption.REPLACE_EXISTING)
|
||||
Files.deleteIfExists(tempPath)
|
||||
println("Saved map data '$META_FILENAME' to $saveDirectoryName.")
|
||||
|
||||
return true
|
||||
}
|
||||
catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun toByteArray(int: Int): ByteArray {
|
||||
return byteArrayOf(
|
||||
((int ushr 0x18) and 0xFF).toByte(),
|
||||
((int ushr 0x10) and 0xFF).toByte(),
|
||||
((int ushr 0x08) and 0xFF).toByte(),
|
||||
((int ) and 0xFF).toByte()
|
||||
)
|
||||
}
|
||||
}
|
||||
126
src/net/torvald/terrarum/serialise/WriteLayerData.kt
Normal file
126
src/net/torvald/terrarum/serialise/WriteLayerData.kt
Normal file
@@ -0,0 +1,126 @@
|
||||
package net.torvald.terrarum.serialise
|
||||
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.console.EchoError
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.nio.charset.Charset
|
||||
import java.util.zip.GZIPOutputStream
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-03-18.
|
||||
*/
|
||||
// internal for everything: prevent malicious module from messing up the savedata
|
||||
internal object WriteLayerData {
|
||||
|
||||
val META_FILENAME = "worldinfo1"
|
||||
|
||||
val MAGIC = "TEMD".toByteArray(charset = Charset.forName("US-ASCII"))
|
||||
|
||||
val BYTE_NULL: Byte = 0
|
||||
|
||||
|
||||
internal operator fun invoke(saveDirectoryName: String): Boolean {
|
||||
val path = "${Terrarum.defaultSaveDir}/$saveDirectoryName/${META_FILENAME}"
|
||||
val tempPath = "${path}_bak"
|
||||
val map = Terrarum.ingame!!.world
|
||||
|
||||
val parentDir = File("${Terrarum.defaultSaveDir}/$saveDirectoryName")
|
||||
if (!parentDir.exists()) {
|
||||
parentDir.mkdir()
|
||||
}
|
||||
else if (!parentDir.isDirectory) {
|
||||
EchoError("Savegame directory is not actually a directory, aborting...")
|
||||
return false
|
||||
}
|
||||
|
||||
val tempFile = File(tempPath)
|
||||
val outFile = File(path)
|
||||
tempFile.createNewFile()
|
||||
|
||||
val outputStream = GZIPOutputStream(FileOutputStream(tempFile))
|
||||
|
||||
|
||||
// write binary
|
||||
outputStream.write(MAGIC)
|
||||
outputStream.write(byteArrayOf(GameWorld.SIZEOF))
|
||||
outputStream.write(byteArrayOf(GameWorld.LAYERS))
|
||||
outputStream.write(byteArrayOf(BYTE_NULL))
|
||||
outputStream.write(byteArrayOf(BYTE_NULL))
|
||||
outputStream.write(map.width.toLittle())
|
||||
outputStream.write(map.height.toLittle())
|
||||
outputStream.write(map.spawnX.toLittle())
|
||||
outputStream.write(map.spawnY.toLittle())
|
||||
// write one row (byteArray) at a time
|
||||
outputStream.write(map.layerTerrain.data)
|
||||
outputStream.write(map.layerWall.data)
|
||||
outputStream.write(map.layerTerrainLowBits.data)
|
||||
outputStream.write(map.layerWallLowBits.data)
|
||||
outputStream.write(map.layerWire.data)
|
||||
|
||||
// replace savemeta with tempfile
|
||||
try {
|
||||
outputStream.flush()
|
||||
outputStream.close()
|
||||
|
||||
outFile.delete()
|
||||
tempFile.copyTo(outFile, overwrite = true)
|
||||
tempFile.delete()
|
||||
println("Saved map data '$META_FILENAME' to $saveDirectoryName.")
|
||||
|
||||
return true
|
||||
}
|
||||
catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
finally {
|
||||
outputStream.close()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
fun Int.toLittle() = byteArrayOf(
|
||||
this.and(0xFF).toByte(),
|
||||
this.ushr(8).and(0xFF).toByte(),
|
||||
this.ushr(16).and(0xFF).toByte(),
|
||||
this.ushr(24).and(0xFF).toByte()
|
||||
)
|
||||
fun Long.toLittle() = byteArrayOf(
|
||||
this.and(0xFF).toByte(),
|
||||
this.ushr(8).and(0xFF).toByte(),
|
||||
this.ushr(16).and(0xFF).toByte(),
|
||||
this.ushr(24).and(0xFF).toByte(),
|
||||
this.ushr(32).and(0xFF).toByte(),
|
||||
this.ushr(40).and(0xFF).toByte(),
|
||||
this.ushr(48).and(0xFF).toByte(),
|
||||
this.ushr(56).and(0xFF).toByte()
|
||||
)
|
||||
fun Double.toLittle() = java.lang.Double.doubleToRawLongBits(this).toLittle()
|
||||
fun Boolean.toLittle() = byteArrayOf(if (this) 0xFF.toByte() else 0.toByte())
|
||||
|
||||
fun ByteArray.toLittleInt() =
|
||||
if (this.size != 4) throw Error("Array not in size of 4")
|
||||
else this[0].toUint() or
|
||||
this[1].toUint().shl(8) or
|
||||
this[2].toUint().shl(16) or
|
||||
this[3].toUint().shl(24)
|
||||
fun ByteArray.toLittleLong() =
|
||||
if (this.size != 8) throw Error("Array not in size of 8")
|
||||
else this[0].toUlong() or
|
||||
this[1].toUlong().shl(8) or
|
||||
this[2].toUlong().shl(16) or
|
||||
this[3].toUlong().shl(24) or
|
||||
this[4].toUlong().shl(32) or
|
||||
this[5].toUlong().shl(40) or
|
||||
this[6].toUlong().shl(48) or
|
||||
this[7].toUlong().shl(56)
|
||||
fun ByteArray.toLittleDouble() = java.lang.Double.longBitsToDouble(this.toLittleLong())
|
||||
|
||||
fun Byte.toUlong() = java.lang.Byte.toUnsignedLong(this)
|
||||
fun Byte.toUint() = java.lang.Byte.toUnsignedInt(this)
|
||||
Reference in New Issue
Block a user