mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 19:14:05 +09:00
fix: water stripes on blocksdrawer
This commit is contained in:
@@ -21,6 +21,7 @@ import net.torvald.terrarum.realestate.LandUtil
|
|||||||
import net.torvald.terrarum.serialise.toBig64
|
import net.torvald.terrarum.serialise.toBig64
|
||||||
import net.torvald.terrarum.worlddrawer.CreateTileAtlas.Companion.WALL_OVERLAY_COLOUR
|
import net.torvald.terrarum.worlddrawer.CreateTileAtlas.Companion.WALL_OVERLAY_COLOUR
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
|
import net.torvald.unsafe.UnsafeInt2D
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
|
||||||
@@ -87,11 +88,12 @@ internal object BlocksDrawer {
|
|||||||
private const val GZIP_READBUF_SIZE = 8192
|
private const val GZIP_READBUF_SIZE = 8192
|
||||||
|
|
||||||
|
|
||||||
private lateinit var terrainTilesBuffer: Array<IntArray>
|
private lateinit var terrainTilesBuffer: UnsafeInt2D
|
||||||
private lateinit var wallTilesBuffer: Array<IntArray>
|
private lateinit var wallTilesBuffer: UnsafeInt2D
|
||||||
private lateinit var oreTilesBuffer: Array<IntArray>
|
private lateinit var oreTilesBuffer: UnsafeInt2D
|
||||||
private lateinit var fluidTilesBuffer: Array<IntArray>
|
private lateinit var fluidTilesBuffer: UnsafeInt2D
|
||||||
private lateinit var occlusionBuffer: Array<IntArray>
|
private lateinit var occlusionBuffer: UnsafeInt2D
|
||||||
|
private lateinit var tempRenderTypeBuffer: UnsafeInt2D // 0x tttt 00 ii; where t=rawTileNum, i=nearbyTilesInfo
|
||||||
private var tilesBuffer: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
|
private var tilesBuffer: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
|
||||||
|
|
||||||
private lateinit var tilesQuad: Mesh
|
private lateinit var tilesQuad: Mesh
|
||||||
@@ -312,6 +314,8 @@ internal object BlocksDrawer {
|
|||||||
return (XXHash64.hash(LandUtil.getBlockAddr(world, x, y).toBig64(), ((x*16777619) xor (y+1+layer)).toLong()) fmod mod.toLong()).toInt()
|
return (XXHash64.hash(LandUtil.getBlockAddr(world, x, y).toBig64(), ((x*16777619) xor (y+1+layer)).toLong()) fmod mod.toLong()).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Autotiling; writes to buffer. Actual draw code must be called after this operation.
|
* Autotiling; writes to buffer. Actual draw code must be called after this operation.
|
||||||
*
|
*
|
||||||
@@ -346,7 +350,7 @@ internal object BlocksDrawer {
|
|||||||
|
|
||||||
val (wx, wy) = world.coerceXY(x, y)
|
val (wx, wy) = world.coerceXY(x, y)
|
||||||
|
|
||||||
var thisTile: Int = when (mode) {
|
var rawTileNum: Int = when (mode) {
|
||||||
WALL -> world.layerWall.unsafeGetTile(wx, wy)
|
WALL -> world.layerWall.unsafeGetTile(wx, wy)
|
||||||
TERRAIN -> world.layerTerrain.unsafeGetTile(wx, wy)
|
TERRAIN -> world.layerTerrain.unsafeGetTile(wx, wy)
|
||||||
ORES -> world.layerOres.unsafeGetTile(wx, wy)//.also { println(it) }
|
ORES -> world.layerOres.unsafeGetTile(wx, wy)//.also { println(it) }
|
||||||
@@ -358,7 +362,7 @@ internal object BlocksDrawer {
|
|||||||
else -> throw IllegalArgumentException()
|
else -> throw IllegalArgumentException()
|
||||||
}
|
}
|
||||||
|
|
||||||
var hash = if ((mode == WALL || mode == TERRAIN) && !BlockCodex[world.tileNumberToNameMap[thisTile.toLong()]].hasTag("NORANDTILE"))
|
var hash = if ((mode == WALL || mode == TERRAIN) && !BlockCodex[world.tileNumberToNameMap[rawTileNum.toLong()]].hasTag("NORANDTILE"))
|
||||||
getHashCoord(x, y, 8, mode)
|
getHashCoord(x, y, 8, mode)
|
||||||
else 0
|
else 0
|
||||||
|
|
||||||
@@ -387,51 +391,59 @@ internal object BlocksDrawer {
|
|||||||
world.getTileFromTerrain(wx, wy)
|
world.getTileFromTerrain(wx, wy)
|
||||||
|
|
||||||
if (/*fluidCornerLut[solids] != 0 &&*/ BlockCodex[tile].isSolidForTileCnx && nearbyFluidType != null) {
|
if (/*fluidCornerLut[solids] != 0 &&*/ BlockCodex[tile].isSolidForTileCnx && nearbyFluidType != null) {
|
||||||
thisTile = world.tileNameToNumberMap[nearbyFluidType]!!
|
rawTileNum = world.tileNameToNumberMap[nearbyFluidType]!!
|
||||||
18 + tileToUse
|
18 + tileToUse
|
||||||
}
|
}
|
||||||
else if (thisTile == 0)
|
else if (rawTileNum == 0)
|
||||||
0
|
0
|
||||||
else if (fluids[3].amount >= 1.5f / 16f)
|
else if (fluids[3].amount >= 1.5f / 16f)
|
||||||
17
|
17
|
||||||
else if (fluids[3].amount >= 0.5f / 16f)
|
else if (fluids[3].amount >= 0.5f / 16f) {
|
||||||
16
|
//if tile above is fluid tile which use 16, use 17
|
||||||
|
if (bufferY > 0 && tempRenderTypeBuffer[bufferY - 1, bufferX].let {
|
||||||
|
(it.ushr(16) == rawTileNum && it.and(255) >= 16) ||
|
||||||
|
(it.ushr(16) == rawTileNum && it.and(255) == 1)
|
||||||
|
})
|
||||||
|
17
|
||||||
|
// else, use 16
|
||||||
|
else 16
|
||||||
|
}
|
||||||
else if (fillThis < 0.5f / 16f)
|
else if (fillThis < 0.5f / 16f)
|
||||||
0
|
0
|
||||||
else
|
else
|
||||||
(fillThis * 16f - 0.5f).roundToInt().coerceIn(0, 15)
|
(fillThis * 16f - 0.5f).roundToInt().coerceIn(0, 15)
|
||||||
}
|
}
|
||||||
else if (treeLeavesTiles.binarySearch(thisTile) >= 0) {
|
else if (treeLeavesTiles.binarySearch(rawTileNum) >= 0) {
|
||||||
getNearbyTilesInfoTrees(x, y, mode).swizzle8(thisTile, hash)
|
getNearbyTilesInfoTrees(x, y, mode).swizzle8(rawTileNum, hash)
|
||||||
}
|
}
|
||||||
else if (treeTrunkTiles.binarySearch(thisTile) >= 0) {
|
else if (treeTrunkTiles.binarySearch(rawTileNum) >= 0) {
|
||||||
hash = 0
|
hash = 0
|
||||||
getNearbyTilesInfoTrees(x, y, mode)
|
getNearbyTilesInfoTrees(x, y, mode)
|
||||||
}
|
}
|
||||||
else if (platformTiles.binarySearch(thisTile) >= 0) {
|
else if (platformTiles.binarySearch(rawTileNum) >= 0) {
|
||||||
hash %= 2
|
hash %= 2
|
||||||
getNearbyTilesInfoPlatform(x, y).swizzleH2(thisTile, hash)
|
getNearbyTilesInfoPlatform(x, y).swizzleH2(rawTileNum, hash)
|
||||||
}
|
}
|
||||||
else if (wallStickerTiles.binarySearch(thisTile) >= 0) {
|
else if (wallStickerTiles.binarySearch(rawTileNum) >= 0) {
|
||||||
hash = 0
|
hash = 0
|
||||||
getNearbyTilesInfoWallSticker(x, y)
|
getNearbyTilesInfoWallSticker(x, y)
|
||||||
}
|
}
|
||||||
else if (connectMutualTiles.binarySearch(thisTile) >= 0) {
|
else if (connectMutualTiles.binarySearch(rawTileNum) >= 0) {
|
||||||
getNearbyTilesInfoConMutual(x, y, mode).swizzle8(thisTile, hash)
|
getNearbyTilesInfoConMutual(x, y, mode).swizzle8(rawTileNum, hash)
|
||||||
}
|
}
|
||||||
else if (connectSelfTiles.binarySearch(thisTile) >= 0) {
|
else if (connectSelfTiles.binarySearch(rawTileNum) >= 0) {
|
||||||
getNearbyTilesInfoConSelf(x, y, mode, thisTile).swizzle8(thisTile, hash)
|
getNearbyTilesInfoConSelf(x, y, mode, rawTileNum).swizzle8(rawTileNum, hash)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
val renderTag = if (mode == OCCLUSION) occlusionRenderTag else App.tileMaker.getRenderTag(thisTile)
|
val renderTag = if (mode == OCCLUSION) occlusionRenderTag else App.tileMaker.getRenderTag(rawTileNum)
|
||||||
|
|
||||||
val tileNumberBase = renderTag.tileNumber
|
val tileNumberBase = renderTag.tileNumber
|
||||||
var tileNumber = if (thisTile == 0 && mode != OCCLUSION) 0
|
var tileNumber = if (rawTileNum == 0 && mode != OCCLUSION) 0
|
||||||
// special case: actorblocks and F3 key
|
// special case: actorblocks and F3 key
|
||||||
else if (renderOnF3Only.binarySearch(thisTile) >= 0 && !KeyToggler.isOn(Keys.F3))
|
else if (renderOnF3Only.binarySearch(rawTileNum) >= 0 && !KeyToggler.isOn(Keys.F3))
|
||||||
0
|
0
|
||||||
// special case: fluids
|
// special case: fluids
|
||||||
else if (mode == FLUID)
|
else if (mode == FLUID)
|
||||||
@@ -464,6 +476,7 @@ internal object BlocksDrawer {
|
|||||||
|
|
||||||
// draw a tile
|
// draw a tile
|
||||||
writeToBuffer(mode, bufferX, bufferY, thisTileX, thisTileY, breakingStage, hash)
|
writeToBuffer(mode, bufferX, bufferY, thisTileX, thisTileY, breakingStage, hash)
|
||||||
|
tempRenderTypeBuffer[bufferY, bufferX] = nearbyTilesInfo or rawTileNum.shl(16)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -763,7 +776,7 @@ internal object BlocksDrawer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sourceBuffer[bufferPosY][bufferPosX] = sheetXYToTilemapColour(mode, sheetX, sheetY, breakage, hash)
|
sourceBuffer[bufferPosY, bufferPosX] = sheetXYToTilemapColour(mode, sheetX, sheetY, breakage, hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var _tilesBufferAsTex: Texture = Texture(1, 1, Pixmap.Format.RGBA8888)
|
private var _tilesBufferAsTex: Texture = Texture(1, 1, Pixmap.Format.RGBA8888)
|
||||||
@@ -801,7 +814,7 @@ internal object BlocksDrawer {
|
|||||||
// As the texture size is very small, multithreading it would be less effective
|
// As the texture size is very small, multithreading it would be less effective
|
||||||
for (y in 0 until tilesBuffer.height) {
|
for (y in 0 until tilesBuffer.height) {
|
||||||
for (x in 0 until tilesBuffer.width) {
|
for (x in 0 until tilesBuffer.width) {
|
||||||
val color = sourceBuffer[y][x]
|
val color = sourceBuffer[y, x]
|
||||||
tilesBuffer.setColor(color)
|
tilesBuffer.setColor(color)
|
||||||
tilesBuffer.drawPixel(x, y)
|
tilesBuffer.drawPixel(x, y)
|
||||||
}
|
}
|
||||||
@@ -871,11 +884,19 @@ internal object BlocksDrawer {
|
|||||||
|
|
||||||
// only update if it's really necessary
|
// only update if it's really necessary
|
||||||
if (oldTH != tilesInHorizontal || oldTV != tilesInVertical) {
|
if (oldTH != tilesInHorizontal || oldTV != tilesInVertical) {
|
||||||
terrainTilesBuffer = Array(tilesInVertical) { IntArray(tilesInHorizontal) }
|
if (::terrainTilesBuffer.isInitialized) terrainTilesBuffer.destroy()
|
||||||
wallTilesBuffer = Array(tilesInVertical) { IntArray(tilesInHorizontal) }
|
if (::wallTilesBuffer.isInitialized) wallTilesBuffer.destroy()
|
||||||
oreTilesBuffer = Array(tilesInVertical) { IntArray(tilesInHorizontal) }
|
if (::oreTilesBuffer.isInitialized) oreTilesBuffer.destroy()
|
||||||
fluidTilesBuffer = Array(tilesInVertical) { IntArray(tilesInHorizontal) }
|
if (::fluidTilesBuffer.isInitialized) fluidTilesBuffer.destroy()
|
||||||
occlusionBuffer = Array(tilesInVertical) { IntArray(tilesInHorizontal) }
|
if (::occlusionBuffer.isInitialized) occlusionBuffer.destroy()
|
||||||
|
if (::tempRenderTypeBuffer.isInitialized) tempRenderTypeBuffer.destroy()
|
||||||
|
|
||||||
|
terrainTilesBuffer = UnsafeInt2D(tilesInHorizontal, tilesInVertical)
|
||||||
|
wallTilesBuffer = UnsafeInt2D(tilesInHorizontal, tilesInVertical)
|
||||||
|
oreTilesBuffer = UnsafeInt2D(tilesInHorizontal, tilesInVertical)
|
||||||
|
fluidTilesBuffer = UnsafeInt2D(tilesInHorizontal, tilesInVertical)
|
||||||
|
occlusionBuffer = UnsafeInt2D(tilesInHorizontal, tilesInVertical)
|
||||||
|
tempRenderTypeBuffer = UnsafeInt2D(tilesInHorizontal, tilesInVertical)
|
||||||
|
|
||||||
tilesBuffer.dispose()
|
tilesBuffer.dispose()
|
||||||
tilesBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
|
tilesBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
|
||||||
@@ -954,6 +975,14 @@ internal object BlocksDrawer {
|
|||||||
tilesQuad.tryDispose()
|
tilesQuad.tryDispose()
|
||||||
shader.dispose()
|
shader.dispose()
|
||||||
|
|
||||||
|
if (::terrainTilesBuffer.isInitialized) terrainTilesBuffer.destroy()
|
||||||
|
if (::wallTilesBuffer.isInitialized) wallTilesBuffer.destroy()
|
||||||
|
if (::oreTilesBuffer.isInitialized) oreTilesBuffer.destroy()
|
||||||
|
if (::fluidTilesBuffer.isInitialized) fluidTilesBuffer.destroy()
|
||||||
|
if (::occlusionBuffer.isInitialized) occlusionBuffer.destroy()
|
||||||
|
if (::tempRenderTypeBuffer.isInitialized) tempRenderTypeBuffer.destroy()
|
||||||
|
|
||||||
|
|
||||||
App.tileMaker.dispose()
|
App.tileMaker.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
src/net/torvald/unsafe/UnsafeInt2D.kt
Normal file
22
src/net/torvald/unsafe/UnsafeInt2D.kt
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package net.torvald.unsafe
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2024-07-22.
|
||||||
|
*/
|
||||||
|
class UnsafeInt2D(width: Int, height: Int) {
|
||||||
|
|
||||||
|
val width = width.toLong()
|
||||||
|
val height = height.toLong()
|
||||||
|
|
||||||
|
private val ptr = UnsafeHelper.allocate(4L * width * height)
|
||||||
|
|
||||||
|
private inline fun toIndex(y: Int, x: Int) = width * y + x
|
||||||
|
|
||||||
|
operator fun set(y: Int, x: Int, value: Int) = ptr.setInt(toIndex(y, x), value)
|
||||||
|
operator fun get(y: Int, x: Int) = ptr.getInt(toIndex(y, x))
|
||||||
|
|
||||||
|
fun destroy() = ptr.destroy()
|
||||||
|
val destroyed: Boolean
|
||||||
|
get() = ptr.destroyed
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user