diff --git a/src/net/torvald/terrarum/gameworld/BlockLayer.kt b/src/net/torvald/terrarum/gameworld/BlockLayer.kt index 8f2f480c9..e79b23cc9 100644 --- a/src/net/torvald/terrarum/gameworld/BlockLayer.kt +++ b/src/net/torvald/terrarum/gameworld/BlockLayer.kt @@ -2,7 +2,7 @@ package net.torvald.terrarum.gameworld import com.badlogic.gdx.utils.Disposable import net.torvald.terrarum.AppLoader.printdbg -import sun.misc.Unsafe +import java.nio.ByteBuffer /** * Original version Created by minjaesong on 2016-01-17. @@ -12,17 +12,23 @@ import sun.misc.Unsafe */ open class BlockLayer(val width: Int, val height: Int) : Disposable { - private val unsafe: Unsafe + private var unsafeArrayDestroyed = false + + /*private val unsafe: Unsafe init { val unsafeConstructor = Unsafe::class.java.getDeclaredConstructor() unsafeConstructor.isAccessible = true unsafe = unsafeConstructor.newInstance() } - private var unsafeArrayDestroyed = false - private var layerPtr = unsafe.allocateMemory(width * height * BYTES_PER_BLOCK.toLong()) + private val layerPtr = unsafe.allocateMemory(width * height * BYTES_PER_BLOCK.toLong())*/ + + private val directByteBuffer: ByteBuffer + init { - unsafe.setMemory(layerPtr, width * height * BYTES_PER_BLOCK.toLong(), 0) // does reliably fill the memory with zeroes + //unsafe.setMemory(layerPtr, width * height * BYTES_PER_BLOCK.toLong(), 0) // does reliably fill the memory with zeroes + + directByteBuffer = ByteBuffer.allocateDirect(width * height * BYTES_PER_BLOCK) } /** @@ -40,7 +46,8 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable { * TL;DR: LITTLE ENDIAN PLEASE */ constructor(width: Int, height: Int, data: ByteArray) : this(width, height) { - data.forEachIndexed { index, byte -> unsafe.putByte(layerPtr + index, byte) } + TODO() + //data.forEachIndexed { index, byte -> unsafe.putByte(layerPtr + index, byte) } } @@ -65,8 +72,10 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable { iteratorCount += 2 val offset = 2 * (y * width + x) - val lsb = unsafe.getByte(layerPtr + offset) - val msb = unsafe.getByte(layerPtr + offset + 1) + //val lsb = unsafe.getByte(layerPtr + offset) + val lsb = directByteBuffer[offset] + //val msb = unsafe.getByte(layerPtr + offset + 1) + val msb = directByteBuffer[offset + 1] //return data[y * width + x] return lsb.toUint() + msb.toUint().shl(8) @@ -91,15 +100,18 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable { override fun next(): Byte { iteratorCount += 1 - return unsafe.getByte(layerPtr + iteratorCount) + //return unsafe.getByte(layerPtr + iteratorCount) + return directByteBuffer[iteratorCount] } } } internal fun unsafeGetTile(x: Int, y: Int): Int { val offset = BYTES_PER_BLOCK * (y * width + x) - val lsb = unsafe.getByte(layerPtr + offset) - val msb = unsafe.getByte(layerPtr + offset + 1) + //val lsb = unsafe.getByte(layerPtr + offset) + //val msb = unsafe.getByte(layerPtr + offset + 1) + val lsb = directByteBuffer[offset] + val msb = directByteBuffer[offset + 1] return lsb.toUint() + msb.toUint().shl(8) } @@ -110,28 +122,32 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable { val lsb = tile.and(0xff).toByte() val msb = tile.ushr(8).and(0xff).toByte() - unsafe.putByte(layerPtr + offset, lsb) - unsafe.putByte(layerPtr + offset + 1, msb) + + directByteBuffer.put(offset, lsb) + directByteBuffer.put(offset + 1, msb) + //unsafe.putByte(layerPtr + offset, lsb) + //unsafe.putByte(layerPtr + offset + 1, msb) } /** * @param blockOffset Offset in blocks. BlockOffset of 0x100 is equal to ```layerPtr + 0x200``` */ - internal fun unsafeSetTile(blockOffset: Long, tile: Int) { - val offset = 2 * blockOffset + /*internal fun unsafeSetTile(blockOffset: Long, tile: Int) { + val offset = BYTES_PER_BLOCK * blockOffset val lsb = tile.and(0xff).toByte() val msb = tile.ushr(8).and(0xff).toByte() unsafe.putByte(layerPtr + offset, lsb) unsafe.putByte(layerPtr + offset + 1, msb) - } + }*/ fun isInBound(x: Int, y: Int) = (x >= 0 && y >= 0 && x < width && y < height) override fun dispose() { if (!unsafeArrayDestroyed) { - unsafe.freeMemory(layerPtr) + //unsafe.freeMemory(layerPtr) + directByteBuffer.clear() unsafeArrayDestroyed = true printdbg(this, "BlockLayer successfully freed") }