diff --git a/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt b/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt index 12479b7f5..498f82d4d 100644 --- a/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt +++ b/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt @@ -27,7 +27,7 @@ internal class UnsafeCvecArray(val width: Int, val height: Int) { fun getG(x: Int, y: Int) = array.getFloat(toAddr(x, y) + 4) fun getB(x: Int, y: Int) = array.getFloat(toAddr(x, y) + 8) fun getA(x: Int, y: Int) = array.getFloat(toAddr(x, y) + 12) - fun getVec(x: Int, y: Int) = Cvec( + inline fun getVec(x: Int, y: Int) = Cvec( array.getFloat(toAddr(x, y)), array.getFloat(toAddr(x, y) + 4), array.getFloat(toAddr(x, y) + 8), @@ -36,7 +36,7 @@ internal class UnsafeCvecArray(val width: Int, val height: Int) { /** * @param channel 0 for R, 1 for G, 2 for B, 3 for A */ - inline fun channelGet(x: Int, y: Int, channel: Int) = array.getFloat(toAddr(x, y) + 4L * channel) + fun channelGet(x: Int, y: Int, channel: Int) = array.getFloat(toAddr(x, y) + 4L * channel) // setters fun zerofill() = array.fillWith(0) @@ -44,13 +44,13 @@ internal class UnsafeCvecArray(val width: Int, val height: Int) { fun setG(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y) + 4, value) } fun setB(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y) + 8, value) } fun setA(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y) + 12, value) } - fun setVec(x: Int, y: Int, value: Cvec) { + inline fun setVec(x: Int, y: Int, value: Cvec) { array.setFloat(toAddr(x, y), value.r) array.setFloat(toAddr(x, y) + 4, value.g) array.setFloat(toAddr(x, y) + 8, value.b) array.setFloat(toAddr(x, y) + 12, value.a) } - fun setScalar(x: Int, y: Int, value: Float) { + inline fun setScalar(x: Int, y: Int, value: Float) { array.setFloat(toAddr(x, y), value) array.setFloat(toAddr(x, y) + 4, value) array.setFloat(toAddr(x, y) + 8, value) @@ -59,18 +59,99 @@ internal class UnsafeCvecArray(val width: Int, val height: Int) { /** * @param channel 0 for R, 1 for G, 2 for B, 3 for A */ - inline fun channelSet(x: Int, y: Int, channel: Int, value: Float) { + fun channelSet(x: Int, y: Int, channel: Int, value: Float) { array.setFloat(toAddr(x, y) + 4L * channel, value) } // operators - fun max(x: Int, y: Int, other: Cvec) { + inline fun max(x: Int, y: Int, other: Cvec) { setR(x, y, maxOf(getR(x, y), other.r)) setG(x, y, maxOf(getG(x, y), other.g)) setB(x, y, maxOf(getB(x, y), other.b)) setA(x, y, maxOf(getA(x, y), other.a)) } + inline fun mul(x: Int, y: Int, scalar: Float) { + setR(x, y, getR(x, y) * scalar) + setG(x, y, getG(x, y) * scalar) + setB(x, y, getB(x, y) * scalar) + setA(x, y, getA(x, y) * scalar) + } fun destroy() = this.array.destroy() +} + + +/** + * Safe (and slower) version of UnsafeCvecArray utilised to tackle down the SEGFAULT + */ +internal class TestCvecArr(val width: Int, val height: Int) { + + val TOTAL_SIZE_IN_BYTES = 4 * width * height + + val array = FloatArray(TOTAL_SIZE_IN_BYTES) + + private inline fun toAddr(x: Int, y: Int) = 4 * (y * width + x) + + init { + zerofill() + } + + // getters + fun getR(x: Int, y: Int) = array.get(toAddr(x, y)) + fun getG(x: Int, y: Int) = array.get(toAddr(x, y) + 1) + fun getB(x: Int, y: Int) = array.get(toAddr(x, y) + 2) + fun getA(x: Int, y: Int) = array.get(toAddr(x, y) + 3) + inline fun getVec(x: Int, y: Int) = Cvec( + array.get(toAddr(x, y)), + array.get(toAddr(x, y) + 1), + array.get(toAddr(x, y) + 2), + array.get(toAddr(x, y) + 3) + ) + /** + * @param channel 0 for R, 1 for G, 2 for B, 3 for A + */ + fun channelGet(x: Int, y: Int, channel: Int) = array.get(toAddr(x, y) + 1 * channel) + + // setters + fun zerofill() = array.fill(0f) + fun setR(x: Int, y: Int, value: Float) { array.set(toAddr(x, y), value) } + fun setG(x: Int, y: Int, value: Float) { array.set(toAddr(x, y) + 1, value) } + fun setB(x: Int, y: Int, value: Float) { array.set(toAddr(x, y) + 2, value) } + fun setA(x: Int, y: Int, value: Float) { array.set(toAddr(x, y) + 3, value) } + inline fun setVec(x: Int, y: Int, value: Cvec) { + array.set(toAddr(x, y), value.r) + array.set(toAddr(x, y) + 1, value.g) + array.set(toAddr(x, y) + 2, value.b) + array.set(toAddr(x, y) + 3, value.a) + } + inline fun setScalar(x: Int, y: Int, value: Float) { + array.set(toAddr(x, y), value) + array.set(toAddr(x, y) + 1, value) + array.set(toAddr(x, y) + 2, value) + array.set(toAddr(x, y) + 3, value) + } + /** + * @param channel 0 for R, 1 for G, 2 for B, 3 for A + */ + fun channelSet(x: Int, y: Int, channel: Int, value: Float) { + array.set(toAddr(x, y) + 1 * channel, value) + } + + // operators + inline fun max(x: Int, y: Int, other: Cvec) { + setR(x, y, maxOf(getR(x, y), other.r)) + setG(x, y, maxOf(getG(x, y), other.g)) + setB(x, y, maxOf(getB(x, y), other.b)) + setA(x, y, maxOf(getA(x, y), other.a)) + } + inline fun mul(x: Int, y: Int, scalar: Float) { + setR(x, y, getR(x, y) * scalar) + setG(x, y, getG(x, y) * scalar) + setB(x, y, getB(x, y) * scalar) + setA(x, y, getA(x, y) * scalar) + } + + fun destroy() = {} + } \ No newline at end of file diff --git a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt index 3f6f52f11..971de3ac3 100644 --- a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt +++ b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt @@ -7,6 +7,7 @@ import com.badlogic.gdx.graphics.glutils.ShaderProgram import com.jme3.math.FastMath import net.torvald.gdx.graphics.Cvec import net.torvald.gdx.graphics.UnsafeCvecArray +import net.torvald.gdx.graphics.TestCvecArr import net.torvald.terrarum.* import net.torvald.terrarum.AppLoader.printdbg import net.torvald.terrarum.blockproperties.Block @@ -23,10 +24,6 @@ import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.modulebasegame.IngameRenderer import net.torvald.terrarum.modulebasegame.ui.abs import net.torvald.terrarum.realestate.LandUtil -import net.torvald.terrarum.worlddrawer.LightmapRenderer.convX -import net.torvald.terrarum.worlddrawer.LightmapRenderer.convY -import net.torvald.util.SortedArrayList -import kotlin.math.sign import kotlin.system.exitProcess /** @@ -761,7 +758,7 @@ object LightmapRenderer { fun precalculate(rawx: Int, rawy: Int) { val lx = rawx.convX(); val ly = rawy.convY() - val (x, y) = world.coerceXY(rawx, rawy) + val (worldX, worldY) = world.coerceXY(rawx, rawy) //printdbg(this, "precalculate ($rawx, $rawy) -> ($lx, $ly) | ($LIGHTMAP_WIDTH, $LIGHTMAP_HEIGHT)") @@ -771,23 +768,23 @@ object LightmapRenderer { } - _thisTerrain = world.getTileFromTerrainRaw(x, y) - _thisFluid = world.getFluid(x, y) - _thisWall = world.getTileFromWallRaw(x, y) + _thisTerrain = world.getTileFromTerrainRaw(worldX, worldY) + _thisFluid = world.getFluid(worldX, worldY) + _thisWall = world.getTileFromWallRaw(worldX, worldY) // regarding the issue #26 // uncomment this and/or run JVM with -ea if you're facing diabolically indescribable bugs try { - val fuck = BlockCodex[_thisTerrain].getLumCol(x, y) + val fuck = BlockCodex[_thisTerrain].getLumCol(worldX, worldY) } catch (e: NullPointerException) { - System.err.println("## NPE -- x: $x, y: $y, value: $_thisTerrain") + System.err.println("## NPE -- x: $worldX, y: $worldY, value: $_thisTerrain") e.printStackTrace() // create shitty minidump System.err.println("MINIMINIDUMP START") - for (xx in x - 16 until x + 16) { - val raw = world.getTileFromTerrain(xx, y) + for (xx in worldX - 16 until worldX + 16) { + val raw = world.getTileFromTerrain(xx, worldY) val lsb = raw.and(0xff).toString(16).padStart(2, '0') val msb = raw.ushr(8).and(0xff).toString(16).padStart(2, '0') System.err.print(lsb) @@ -803,14 +800,14 @@ object LightmapRenderer { if (_thisFluid.type != Fluid.NULL) { _fluidAmountToCol.set(_thisFluid.amount, _thisFluid.amount, _thisFluid.amount, _thisFluid.amount) - _thisTileLuminosity.set(BlockCodex[_thisTerrain].getLumCol(x, y)) - _thisTileLuminosity.maxAndAssign(BlockCodex[_thisFluid.type].getLumCol(x, y).mul(_fluidAmountToCol)) // already been div by four + _thisTileLuminosity.set(BlockCodex[_thisTerrain].getLumCol(worldX, worldY)) + _thisTileLuminosity.maxAndAssign(BlockCodex[_thisFluid.type].getLumCol(worldX, worldY).mul(_fluidAmountToCol)) // already been div by four _mapThisTileOpacity.setVec(lx, ly, BlockCodex[_thisTerrain].opacity) _mapThisTileOpacity.max(lx, ly, BlockCodex[_thisFluid.type].opacity.mul(_fluidAmountToCol))// already been div by four } else { - _thisTileLuminosity.set(BlockCodex[_thisTerrain].getLumCol(x, y)) - _mapThisTileOpacity.setVec(x, y, BlockCodex[_thisTerrain].opacity) + _thisTileLuminosity.set(BlockCodex[_thisTerrain].getLumCol(worldX, worldY)) + _mapThisTileOpacity.setVec(lx, ly, BlockCodex[_thisTerrain].opacity) } _mapThisTileOpacity2.setR(lx, ly, _mapThisTileOpacity.getR(lx, ly) * 1.41421356f) @@ -827,7 +824,7 @@ object LightmapRenderer { // blend lantern _mapLightLevelThis.max(lx, ly, _thisTileLuminosity.maxAndAssign( - lanternMap[LandUtil.getBlockAddr(world, x, y)] ?: colourNull + lanternMap[LandUtil.getBlockAddr(world, worldX, worldY)] ?: colourNull )) }