diff --git a/src/net/torvald/terrarum/gameworld/GameWorld.kt b/src/net/torvald/terrarum/gameworld/GameWorld.kt index d65bdd31f..2c2361320 100644 --- a/src/net/torvald/terrarum/gameworld/GameWorld.kt +++ b/src/net/torvald/terrarum/gameworld/GameWorld.kt @@ -155,9 +155,12 @@ open class GameWorld { val damageDataArray: ByteArray get() = layerTerrainLowBits.data + private fun coerceXY(x: Int, y: Int) = (x fmod width) to (y.coerceWorld()) + fun getTileFromWall(x: Int, y: Int): Int? { - val wall: Int? = layerWall.getTile(x fmod width, y.coerceWorld().coerceWorld()) - val wallDamage: Int? = getWallLowBits(x fmod width, y.coerceWorld()) + val (x, y) = coerceXY(x, y) + val wall: Int? = layerWall.getTile(x, y) + val wallDamage: Int? = getWallLowBits(x, y) return if (wall == null || wallDamage == null) null else @@ -165,8 +168,9 @@ open class GameWorld { } fun getTileFromTerrain(x: Int, y: Int): Int? { - val terrain: Int? = layerTerrain.getTile(x fmod width, y.coerceWorld()) - val terrainDamage: Int? = getTerrainLowBits(x fmod width, y.coerceWorld()) + val (x, y) = coerceXY(x, y) + val terrain: Int? = layerTerrain.getTile(x, y) + val terrainDamage: Int? = getTerrainLowBits(x, y) return if (terrain == null || terrainDamage == null) null else @@ -174,15 +178,18 @@ open class GameWorld { } fun getTileFromWire(x: Int, y: Int): Int? { - return layerWire.getTile(x fmod width, y.coerceWorld()) + val (x, y) = coerceXY(x, y) + return layerWire.getTile(x, y) } fun getWallLowBits(x: Int, y: Int): Int? { - return layerWallLowBits.getData(x fmod width, y.coerceWorld()) + val (x, y) = coerceXY(x, y) + return layerWallLowBits.getData(x, y) } fun getTerrainLowBits(x: Int, y: Int): Int? { - return layerTerrainLowBits.getData(x fmod width, y.coerceWorld()) + val (x, y) = coerceXY(x, y) + return layerTerrainLowBits.getData(x, y) } /** @@ -194,7 +201,8 @@ open class GameWorld { * @param combinedTilenum (tilenum * 16) + damage */ fun setTileWall(x: Int, y: Int, combinedTilenum: Int) { - setTileWall(x fmod width, y.coerceWorld(), (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE) + val (x, y) = coerceXY(x, y) + setTileWall(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE) } /** @@ -206,12 +214,14 @@ open class GameWorld { * @param combinedTilenum (tilenum * 16) + damage */ fun setTileTerrain(x: Int, y: Int, combinedTilenum: Int) { - setTileTerrain(x fmod width, y.coerceWorld(), (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE) + val (x, y) = coerceXY(x, y) + setTileTerrain(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE) } fun setTileWall(x: Int, y: Int, tile: Byte, damage: Int) { - layerWall.setTile(x fmod width, y.coerceWorld(), tile) - layerWallLowBits.setData(x fmod width, y.coerceWorld(), damage) + val (x, y) = coerceXY(x, y) + layerWall.setTile(x, y, tile) + layerWallLowBits.setData(x, y, damage) wallDamages.remove(LandUtil.getBlockAddr(this, x, y)) } @@ -219,8 +229,9 @@ open class GameWorld { * Warning: this function alters fluid lists: be wary of call order! */ fun setTileTerrain(x: Int, y: Int, tile: Byte, damage: Int) { - layerTerrain.setTile(x fmod width, y.coerceWorld(), tile) - layerTerrainLowBits.setData(x fmod width, y.coerceWorld(), damage) + val (x, y) = coerceXY(x, y) + layerTerrain.setTile(x, y, tile) + layerTerrainLowBits.setData(x, y, damage) val blockAddr = LandUtil.getBlockAddr(this, x, y) terrainDamages.remove(blockAddr) @@ -232,7 +243,8 @@ open class GameWorld { } fun setTileWire(x: Int, y: Int, tile: Byte) { - layerWire.setTile(x fmod width, y.coerceWorld(), tile) + val (x, y) = coerceXY(x, y) + layerWire.setTile(x, y, tile) } fun getTileFrom(mode: Int, x: Int, y: Int): Int? { diff --git a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt index 5bffec770..b087afd3f 100644 --- a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt +++ b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt @@ -228,6 +228,8 @@ object LightmapRenderer { // wipe out lightmap AppLoader.debugTimers["Renderer.Light0"] = measureNanoTime { for (k in 0 until lightmap.size) lightmap[k] = colourNull + // when disabled, light will "decay out" instead of "instantly out", which can have a cool effect + // but the performance boost is measly 0.1 ms on 6700K } // O((5*9)n) == O(n) where n is a size of the map. @@ -428,11 +430,13 @@ object LightmapRenderer { * @param pass one-based */ private fun calculate(x: Int, y: Int): Color { + // O(9n) == O(n) where n is a size of the map // TODO devise multithreading on this ambientAccumulator.set(0f,0f,0f,0f) + // this six fetch tasks take 2 ms ?! lightLevelThis.set(0f,0f,0f,0f) thisTerrain = world.getTileFromTerrain(x, y) ?: Block.STONE thisWall = world.getTileFromWall(x, y) ?: Block.STONE @@ -446,13 +450,14 @@ object LightmapRenderer { if (thisTerrain == AIR && thisWall == AIR) { lightLevelThis.set(sunLight) } - // luminous tile on top of air - else if (thisWall == AIR && thisTileLuminosity.nonZero()) { - lightLevelThis.set(sunLight maxBlend thisTileLuminosity) // maximise to not exceed 1.0 with normal (<= 1.0) light - } - // opaque wall and luminous tile - else if (thisWall != AIR && thisTileLuminosity.nonZero()) { - lightLevelThis.set(thisTileLuminosity) + // luminous tile + else if (thisTileLuminosity.nonZero()) { + // luminous tile on top of air + if (thisWall == AIR) + lightLevelThis.set(sunLight maxBlend thisTileLuminosity) // maximise to not exceed 1.0 with normal (<= 1.0) light + // opaque wall and luminous tile + else + lightLevelThis.set(thisTileLuminosity) } // END MIX TILE @@ -468,16 +473,16 @@ object LightmapRenderer { */ // will "overwrite" what's there in the lightmap if it's the first pass - // TODO colour math against integers - /* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y - 1) ?: Color.CLEAR, scaleSqrt2(thisTileOpacity))) - /* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y - 1) ?: Color.CLEAR, scaleSqrt2(thisTileOpacity))) - /* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y + 1) ?: Color.CLEAR, scaleSqrt2(thisTileOpacity))) - /* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y + 1) ?: Color.CLEAR, scaleSqrt2(thisTileOpacity))) + // takes about 2 ms + /* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y - 1) ?: colourNull, scaleSqrt2(thisTileOpacity))) + /* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y - 1) ?: colourNull, scaleSqrt2(thisTileOpacity))) + /* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y + 1) ?: colourNull, scaleSqrt2(thisTileOpacity))) + /* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y + 1) ?: colourNull, scaleSqrt2(thisTileOpacity))) - /* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x, y - 1) ?: Color.CLEAR, thisTileOpacity)) - /* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x, y + 1) ?: Color.CLEAR, thisTileOpacity)) - /* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y) ?: Color.CLEAR, thisTileOpacity)) - /* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y) ?: Color.CLEAR, thisTileOpacity)) + /* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x, y - 1) ?: colourNull, thisTileOpacity)) + /* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x, y + 1) ?: colourNull, thisTileOpacity)) + /* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y) ?: colourNull, thisTileOpacity)) + /* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y) ?: colourNull, thisTileOpacity)) val ret = lightLevelThis maxBlend ambientAccumulator