diff --git a/src/net/torvald/terrarum/blockstats/MinimapComposer.kt b/src/net/torvald/terrarum/blockstats/MinimapComposer.kt index 036d2c174..f1a54c006 100644 --- a/src/net/torvald/terrarum/blockstats/MinimapComposer.kt +++ b/src/net/torvald/terrarum/blockstats/MinimapComposer.kt @@ -9,20 +9,26 @@ import com.badlogic.gdx.utils.GdxRuntimeException import com.badlogic.gdx.utils.Queue import net.torvald.terrarum.App import net.torvald.terrarum.App.printdbg +import net.torvald.terrarum.abs import net.torvald.terrarum.concurrent.ThreadExecutor import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.modulebasegame.ui.UIInventoryMinimap.Companion.MINIMAP_HEIGHT import net.torvald.terrarum.modulebasegame.ui.UIInventoryMinimap.Companion.MINIMAP_WIDTH +import net.torvald.terrarum.sqr import net.torvald.terrarum.toInt +import java.util.concurrent.Callable import java.util.concurrent.atomic.AtomicInteger +import kotlin.math.absoluteValue +import kotlin.math.roundToInt object MinimapComposer : Disposable { private val threadExecutor = ThreadExecutor(maxOf(1, App.THREAD_COUNT.times(2).div(3))) - val MINIMAP_TILE_WIDTH = MINIMAP_WIDTH.toInt() + 16 - val MINIMAP_TILE_HEIGHT = MINIMAP_HEIGHT.toInt() + 16 + const val SQUARE_SIZE = 13 // preferably in odd number + val MINIMAP_TILE_WIDTH = (MINIMAP_WIDTH.toInt() * 3) / SQUARE_SIZE + 4 + val MINIMAP_TILE_HEIGHT = (MINIMAP_HEIGHT.toInt() * 3) / SQUARE_SIZE + 4 private var world: GameWorld = GameWorld.makeNullWorld() @@ -42,11 +48,49 @@ object MinimapComposer : Disposable { } } - val pixmaps = Array(9) { Pixmap(MINIMAP_TILE_WIDTH, MINIMAP_TILE_HEIGHT, Pixmap.Format.RGBA8888) } + val pixmaps = Array(SQUARE_SIZE*SQUARE_SIZE) { Pixmap(MINIMAP_TILE_WIDTH, MINIMAP_TILE_HEIGHT, Pixmap.Format.RGBA8888) } - private val updaterQueue = Array(pixmaps.size) { null } - private var currentThreads = Array(9) { Thread() } + private val updaterQueue = Array?>(pixmaps.size) { null } + private val spiralIndices = ArrayList() + + init { + val X = SQUARE_SIZE + val Y = SQUARE_SIZE + var x = 0 + var y = 0 + var dx = 0 + var dy = -1 + + (0 until SQUARE_SIZE*SQUARE_SIZE).forEach { +// if ((-(X/2) <= x && x <= X/2) && (-(Y/2) <= y && y <= Y/2)) // just in case it's not a square + spiralIndices.add((y + Y/2) * X + (x + X/2)) + if (x == y || (x < 0 && x == -y) || (x > 0 && x == 1-y)) { + val d1 = -dy + val d2 = dx + dx = d1 + dy = d2 + } + x += dx + y += dy + } + } + + private infix fun Int.pow(exp: Int): Int { + var exp = exp + var base = this + var result = 1 + while (true) { + if (exp and 1 != 0) + result *= base + exp = exp shr 1 + if (exp.inv() != 0) + break + base *= base + } + + return result + } init { @@ -70,12 +114,14 @@ object MinimapComposer : Disposable { // make the queueing work // enqueue first - pixmaps.forEachIndexed { i, pixmap -> - val tx = tlx + (MINIMAP_TILE_WIDTH * ((i % 3) - 1)) - val ty = tly + (MINIMAP_TILE_HEIGHT * ((i / 3) - 1)) + spiralIndices.forEachIndexed { index, i -> + val pixmap = pixmaps[i] - updaterQueue[i] = createUpdater(tx, ty, pixmap, i) - printdbg(this, "Queueing tilemap update ($tx,$ty) from queue[$i]") + val tx = tlx + (MINIMAP_TILE_WIDTH * ((i % SQUARE_SIZE) - (SQUARE_SIZE / 2))) + val ty = tly + (MINIMAP_TILE_HEIGHT * ((i / SQUARE_SIZE) - (SQUARE_SIZE / 2))) + + updaterQueue[index] = Callable { createUpdater(tx, ty, pixmap, i).run() } +// printdbg(this, "Queueing tilemap update ($tx,$ty) from queue[$i]") } // consume the queue @@ -89,28 +135,31 @@ object MinimapComposer : Disposable { } }*/ - updaterQueue.forEachIndexed { k, runnable -> + + /*updaterQueue.forEachIndexed { k, runnable -> if (runnable != null) { currentThreads[k] = Thread(runnable, "MinimapLivetilePainter") printdbg(this, "Consuming from queue[$k]") currentThreads[k].start() } - } + }*/ + + + threadExecutor.renew() + // TODO submit in spiral index + threadExecutor.submitAll(updaterQueue.filterNotNull()) + Thread { threadExecutor.join() }.start() + } else { - printdbg(this, "$udc Threads still running, request disregarded") +// printdbg(this, "$udc Threads still running, request disregarded") } - printdbg(this, "** $udc Threads still running **") +// printdbg(this, "** $udc Threads still running **") } - private val HQRNG = net.torvald.random.HQRNG() - - private val testcols = arrayOf( - Color.CORAL, Color.LIME, Color.CYAN, - Color.YELLOW, Color.SKY, Color.GOLD, - Color.BROWN, Color.DARK_GRAY, Color.RED - ).map { Color(it.lerp(Color.WHITE, 0.5f)) } + private val oobColTop = Color(0) + private val oobColBtm = Color(0x202020FF) /** * @param tx top-left of the world @@ -118,23 +167,31 @@ object MinimapComposer : Disposable { * @param pixmap pixmap to draw pixels on */ private fun createUpdater(tx: Int, ty: Int, pixmap: Pixmap, index: Int) = Runnable { - for (y in ty until ty + MINIMAP_TILE_HEIGHT) { - for (x in tx until tx + MINIMAP_TILE_WIDTH) { - val tileTerr = world.getTileFromTerrain(x, y) - val wallTerr = world.getTileFromWall(x, y) - val colTerr = App.tileMaker.terrainTileColourMap.get(tileTerr)!!.toGdxColor() - val colWall = App.tileMaker.terrainTileColourMap.get(wallTerr)!!.toGdxColor().mul(App.tileMaker.wallOverlayColour) + try { + for (y in ty until ty + MINIMAP_TILE_HEIGHT) { + for (x in tx until tx + MINIMAP_TILE_WIDTH) { + val tileTerr = world.getTileFromTerrain(x, y) + val wallTerr = world.getTileFromWall(x, y) + val colTerr = App.tileMaker.terrainTileColourMap.get(tileTerr)!!.toGdxColor() + val colWall = App.tileMaker.terrainTileColourMap.get(wallTerr)!!.toGdxColor().mul(App.tileMaker.wallOverlayColour) - val outCol = if (colTerr.a > 0.1f) colTerr else colWall + val outCol = if (y < 0) + oobColTop + else if (y >= world.height) + oobColBtm + else if (colTerr.a > 0.1f) colTerr else colWall - pixmap.blending = Pixmap.Blending.None -// pixmap.setColor(outCol) - pixmap.setColor(outCol.mul(testcols[index])) - pixmap.drawPixel(x - tx, y - ty) + pixmap.blending = Pixmap.Blending.None + pixmap.setColor(outCol) + pixmap.drawPixel(x - tx, y - ty) + } } - } - updaterQueue[index] = null + updaterQueue[index] = null + } + catch(e: Throwable) { + e.printStackTrace() + } } override fun dispose() { diff --git a/src/net/torvald/terrarum/gameworld/GameWorld.kt b/src/net/torvald/terrarum/gameworld/GameWorld.kt index 4db5f23d6..d1970af4a 100644 --- a/src/net/torvald/terrarum/gameworld/GameWorld.kt +++ b/src/net/torvald/terrarum/gameworld/GameWorld.kt @@ -171,6 +171,8 @@ open class GameWorld() : Disposable { } } + fun coordInWorld(x: Int, y: Int) = y in 0 until height // ROUNDWORLD implementation + fun coordInWorldStrict(x: Int, y: Int) = x in 0 until width && y in 0 until height // ROUNDWORLD implementation fun renumberTilesAfterLoad() { // before the renaming, update the name maps diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryMinimap.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryMinimap.kt index 016017108..6fe7f13b9 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryMinimap.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryMinimap.kt @@ -45,7 +45,7 @@ class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() { private val minimapCamera = OrthographicCamera(MINIMAP_WIDTH, MINIMAP_HEIGHT) private var minimapRerenderTimer = 0f - private val minimapRerenderInterval = 0.5f // seconds + private var minimapRerenderInterval = 5f // seconds private var dragStatus = 0 @@ -66,8 +66,15 @@ class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() { // if left click is down and cursor is in the map area if (Terrarum.mouseDown && Terrarum.mouseScreenY in cellOffY..cellOffY + INVENTORY_CELLS_UI_HEIGHT) { - val mdx = Terrarum.mouseDeltaX * 2f / minimapZoom - val mdy = Terrarum.mouseDeltaY * 2f / minimapZoom + val mdx = Terrarum.mouseDeltaX * 3f / minimapZoom + var mdy = Terrarum.mouseDeltaY * 3f / minimapZoom + + val ymin = 0//-MINIMAP_HEIGHT / 2 + val ymax = INGAME.world.height// - MINIMAP_HEIGHT + val my = minimapPanY + mdy + + if (my < ymin) mdy += my - ymin + else if (my > ymax) mdy += my - ymax minimapPanX -= mdx minimapPanY -= mdy @@ -89,6 +96,7 @@ class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() { minimapZoom = 1f minimapPanX = INGAME.actorNowPlaying?.intTilewiseHitbox?.centeredX?.toFloat() ?: (INGAME.world.width / 2f) minimapPanY = INGAME.actorNowPlaying?.intTilewiseHitbox?.centeredY?.toFloat() ?: (INGAME.world.height / 2f) + dragStatus = 1 } @@ -136,10 +144,10 @@ class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() { renderTextures[MinimapComposer.pixmaps.lastIndex - index].dispose() renderTextures[MinimapComposer.pixmaps.lastIndex - index] = Texture(pixmap) - val ix = index % 3; val iy = index / 3 + val ix = index % MinimapComposer.SQUARE_SIZE; val iy = index / MinimapComposer.SQUARE_SIZE - val ox = (ix - 0.5f) * MINIMAP_TILE_WIDTH - val oy = (iy - 0.5f) * MINIMAP_TILE_HEIGHT + val ox = (ix - (MinimapComposer.SQUARE_SIZE / 2) + 0.5f) * MINIMAP_TILE_WIDTH + val oy = (iy - (MinimapComposer.SQUARE_SIZE / 2) + 0.5f) * MINIMAP_TILE_HEIGHT val tx = (minimapTranslateX - ox) * minimapZoom + 0.5f * MINIMAP_WIDTH val ty = (minimapTranslateY - oy) * minimapZoom + 0.5f * MINIMAP_HEIGHT @@ -177,7 +185,12 @@ class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() { override fun doClosing(delta: Float) {} - override fun endOpening(delta: Float) {} + override fun endOpening(delta: Float) { + minimapPanX = INGAME.actorNowPlaying?.intTilewiseHitbox?.centeredX?.toFloat() ?: (INGAME.world.width / 2f) + minimapPanY = INGAME.actorNowPlaying?.intTilewiseHitbox?.centeredY?.toFloat() ?: (INGAME.world.height / 2f) + + minimapRerenderInterval = 0.25f + } override fun endClosing(delta: Float) {}