still working on light, no improvements perf-wise

This commit is contained in:
minjaesong
2019-01-17 18:28:43 +09:00
parent 0397c47aad
commit b594c3b053
2 changed files with 47 additions and 30 deletions

View File

@@ -155,9 +155,12 @@ open class GameWorld {
val damageDataArray: ByteArray val damageDataArray: ByteArray
get() = layerTerrainLowBits.data get() = layerTerrainLowBits.data
private fun coerceXY(x: Int, y: Int) = (x fmod width) to (y.coerceWorld())
fun getTileFromWall(x: Int, y: Int): Int? { fun getTileFromWall(x: Int, y: Int): Int? {
val wall: Int? = layerWall.getTile(x fmod width, y.coerceWorld().coerceWorld()) val (x, y) = coerceXY(x, y)
val wallDamage: Int? = getWallLowBits(x fmod width, y.coerceWorld()) val wall: Int? = layerWall.getTile(x, y)
val wallDamage: Int? = getWallLowBits(x, y)
return if (wall == null || wallDamage == null) return if (wall == null || wallDamage == null)
null null
else else
@@ -165,8 +168,9 @@ open class GameWorld {
} }
fun getTileFromTerrain(x: Int, y: Int): Int? { fun getTileFromTerrain(x: Int, y: Int): Int? {
val terrain: Int? = layerTerrain.getTile(x fmod width, y.coerceWorld()) val (x, y) = coerceXY(x, y)
val terrainDamage: Int? = getTerrainLowBits(x fmod width, y.coerceWorld()) val terrain: Int? = layerTerrain.getTile(x, y)
val terrainDamage: Int? = getTerrainLowBits(x, y)
return if (terrain == null || terrainDamage == null) return if (terrain == null || terrainDamage == null)
null null
else else
@@ -174,15 +178,18 @@ open class GameWorld {
} }
fun getTileFromWire(x: Int, y: Int): Int? { 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? { 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? { 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 * @param combinedTilenum (tilenum * 16) + damage
*/ */
fun setTileWall(x: Int, y: Int, combinedTilenum: Int) { 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 * @param combinedTilenum (tilenum * 16) + damage
*/ */
fun setTileTerrain(x: Int, y: Int, combinedTilenum: Int) { 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) { fun setTileWall(x: Int, y: Int, tile: Byte, damage: Int) {
layerWall.setTile(x fmod width, y.coerceWorld(), tile) val (x, y) = coerceXY(x, y)
layerWallLowBits.setData(x fmod width, y.coerceWorld(), damage) layerWall.setTile(x, y, tile)
layerWallLowBits.setData(x, y, damage)
wallDamages.remove(LandUtil.getBlockAddr(this, x, y)) 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! * Warning: this function alters fluid lists: be wary of call order!
*/ */
fun setTileTerrain(x: Int, y: Int, tile: Byte, damage: Int) { fun setTileTerrain(x: Int, y: Int, tile: Byte, damage: Int) {
layerTerrain.setTile(x fmod width, y.coerceWorld(), tile) val (x, y) = coerceXY(x, y)
layerTerrainLowBits.setData(x fmod width, y.coerceWorld(), damage) layerTerrain.setTile(x, y, tile)
layerTerrainLowBits.setData(x, y, damage)
val blockAddr = LandUtil.getBlockAddr(this, x, y) val blockAddr = LandUtil.getBlockAddr(this, x, y)
terrainDamages.remove(blockAddr) terrainDamages.remove(blockAddr)
@@ -232,7 +243,8 @@ open class GameWorld {
} }
fun setTileWire(x: Int, y: Int, tile: Byte) { 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? { fun getTileFrom(mode: Int, x: Int, y: Int): Int? {

View File

@@ -228,6 +228,8 @@ object LightmapRenderer {
// wipe out lightmap // wipe out lightmap
AppLoader.debugTimers["Renderer.Light0"] = measureNanoTime { AppLoader.debugTimers["Renderer.Light0"] = measureNanoTime {
for (k in 0 until lightmap.size) lightmap[k] = colourNull 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. // O((5*9)n) == O(n) where n is a size of the map.
@@ -428,11 +430,13 @@ object LightmapRenderer {
* @param pass one-based * @param pass one-based
*/ */
private fun calculate(x: Int, y: Int): Color { private fun calculate(x: Int, y: Int): Color {
// O(9n) == O(n) where n is a size of the map // O(9n) == O(n) where n is a size of the map
// TODO devise multithreading on this // TODO devise multithreading on this
ambientAccumulator.set(0f,0f,0f,0f) ambientAccumulator.set(0f,0f,0f,0f)
// this six fetch tasks take 2 ms ?!
lightLevelThis.set(0f,0f,0f,0f) lightLevelThis.set(0f,0f,0f,0f)
thisTerrain = world.getTileFromTerrain(x, y) ?: Block.STONE thisTerrain = world.getTileFromTerrain(x, y) ?: Block.STONE
thisWall = world.getTileFromWall(x, y) ?: Block.STONE thisWall = world.getTileFromWall(x, y) ?: Block.STONE
@@ -446,13 +450,14 @@ object LightmapRenderer {
if (thisTerrain == AIR && thisWall == AIR) { if (thisTerrain == AIR && thisWall == AIR) {
lightLevelThis.set(sunLight) lightLevelThis.set(sunLight)
} }
// luminous tile on top of air // luminous tile
else if (thisWall == AIR && thisTileLuminosity.nonZero()) { else if (thisTileLuminosity.nonZero()) {
lightLevelThis.set(sunLight maxBlend thisTileLuminosity) // maximise to not exceed 1.0 with normal (<= 1.0) light // luminous tile on top of air
} if (thisWall == AIR)
// opaque wall and luminous tile lightLevelThis.set(sunLight maxBlend thisTileLuminosity) // maximise to not exceed 1.0 with normal (<= 1.0) light
else if (thisWall != AIR && thisTileLuminosity.nonZero()) { // opaque wall and luminous tile
lightLevelThis.set(thisTileLuminosity) else
lightLevelThis.set(thisTileLuminosity)
} }
// END MIX TILE // END MIX TILE
@@ -468,16 +473,16 @@ object LightmapRenderer {
*/ */
// will "overwrite" what's there in the lightmap if it's the first pass // will "overwrite" what's there in the lightmap if it's the first pass
// TODO colour math against integers // takes about 2 ms
/* + */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y - 1) ?: Color.CLEAR, 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) ?: Color.CLEAR, 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) ?: Color.CLEAR, 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) ?: Color.CLEAR, 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) ?: colourNull, thisTileOpacity))
/* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x, y + 1) ?: Color.CLEAR, thisTileOpacity)) /* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x, y + 1) ?: colourNull, thisTileOpacity))
/* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y) ?: Color.CLEAR, thisTileOpacity)) /* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y) ?: colourNull, thisTileOpacity))
/* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y) ?: Color.CLEAR, thisTileOpacity)) /* * */ambientAccumulator.set(ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y) ?: colourNull, thisTileOpacity))
val ret = lightLevelThis maxBlend ambientAccumulator val ret = lightLevelThis maxBlend ambientAccumulator