From b084f9e5a9174097d3613033d24a4074fd8e1962 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Tue, 14 Sep 2021 11:05:01 +0900 Subject: [PATCH] CHUNK ORDERING CHANGED/chunk loading screen --- .../modulebasegame/ChunkLoadingLoadScreen.kt | 101 ++++++++++++++++++ .../modulebasegame/WorldgenLoadScreen.kt | 10 +- .../terrarum/serialise/WriteSavegame.kt | 51 ++++----- 3 files changed, 127 insertions(+), 35 deletions(-) create mode 100644 src/net/torvald/terrarum/modulebasegame/ChunkLoadingLoadScreen.kt diff --git a/src/net/torvald/terrarum/modulebasegame/ChunkLoadingLoadScreen.kt b/src/net/torvald/terrarum/modulebasegame/ChunkLoadingLoadScreen.kt new file mode 100644 index 000000000..80fa78490 --- /dev/null +++ b/src/net/torvald/terrarum/modulebasegame/ChunkLoadingLoadScreen.kt @@ -0,0 +1,101 @@ +package net.torvald.terrarum.modulebasegame + +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.graphics.Pixmap +import com.badlogic.gdx.graphics.Texture +import net.torvald.terrarum.* +import net.torvald.terrarum.gameworld.GameWorld +import net.torvald.terrarum.ui.Toolkit +import kotlin.math.roundToInt + +/** + * Created by minjaesong on 2021-09-14. + */ +class ChunkLoadingLoadScreen(screenToBeLoaded: IngameInstance, private val worldwidth: Int, private val worldheight: Int, override var preLoadJob: (LoadScreenBase) -> Unit) : LoadScreenBase() { + + override var screenToLoad: IngameInstance? = screenToBeLoaded + private val world: GameWorld // must use Getter, as the field WILL BE redefined by the TerrarumIngame.enterCreateNewWorld() ! + get() = screenToLoad!!.world + + private var previewWidth = (App.scr.width * WorldgenLoadScreen.WIDTH_RATIO).roundToInt() + private var previewHeight = (App.scr.width * WorldgenLoadScreen.WIDTH_RATIO * worldheight / worldwidth).roundToInt() + + private lateinit var previewPixmap: Pixmap + private lateinit var previewTexture: Texture + + private var previewRenderCounter = 0f + + + // NOTE: actual world init and terragen is called by TerrarumIngame.enterLoadFromSave() + override fun show() { + super.show() + + previewPixmap = Pixmap(previewWidth, previewHeight, Pixmap.Format.RGBA8888) + previewTexture = Texture(1, 1, Pixmap.Format.RGBA8888) + + previewPixmap.setColor(Color.BLACK) + previewPixmap.fill() + } + + override fun render(delta: Float) { + gdxClearAndSetBlend(.094f, .094f, .094f, 0f) + + + if (worldwidth != -1 && worldheight != -1) { + + previewRenderCounter += delta + if (previewRenderCounter >= WorldgenLoadScreen.PREVIEW_UPDATE_RATE) { + previewRenderCounter -= WorldgenLoadScreen.PREVIEW_UPDATE_RATE + renderToPreview() + previewTexture.dispose() + previewTexture = Texture(previewPixmap) + } + + + App.batch.inUse { + it.color = Color.WHITE + val previewX = (App.scr.width - previewWidth).div(2f).round() + val previewY = (App.scr.height - previewHeight.times(1.5f)).div(2f).round() + Toolkit.drawBoxBorder(it, previewX.toInt() - 1, previewY.toInt() - 1, previewWidth + 2, previewHeight + 2) + it.draw(previewTexture, + previewX, + previewY + ) + val text = messages.getHeadElem() ?: "" + App.fontGame.draw(it, + text, + (App.scr.width - App.fontGame.getWidth(text)).div(2f).round(), + previewY + previewHeight + 98 - App.fontGame.lineHeight + ) + } + + } + + super.render(delta) + } + + private fun renderToPreview() { + for (y in 0 until previewHeight) { + for (x in 0 until previewWidth) { + val wx = (world.width.toFloat() / previewWidth * x).roundToInt() + val wy = (world.height.toFloat() / previewHeight * y).roundToInt() + + val outCol = if (BlockCodex[world.getTileFromTerrain(wx, wy)].isSolid) WorldgenLoadScreen.COL_TERR + else if (BlockCodex[world.getTileFromWall(wx, wy)].isSolid) WorldgenLoadScreen.COL_WALLED + else WorldgenLoadScreen.COL_AIR + + previewPixmap.setColor(outCol) + previewPixmap.drawPixel(x, previewHeight - 1 - y) // this flips Y + } + } + + } + + + override fun dispose() { + if (!previewPixmap.isDisposed) + previewPixmap.dispose() + + previewTexture.dispose() + } +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/WorldgenLoadScreen.kt b/src/net/torvald/terrarum/modulebasegame/WorldgenLoadScreen.kt index 7e7af2055..a0e4ccec5 100644 --- a/src/net/torvald/terrarum/modulebasegame/WorldgenLoadScreen.kt +++ b/src/net/torvald/terrarum/modulebasegame/WorldgenLoadScreen.kt @@ -26,12 +26,12 @@ class WorldgenLoadScreen(screenToBeLoaded: IngameInstance, private val worldwidt get() = screenToLoad!!.world companion object { - private const val WIDTH_RATIO = 0.7 - private const val PREVIEW_UPDATE_RATE = App.UPDATE_RATE + const val WIDTH_RATIO = 0.7 + const val PREVIEW_UPDATE_RATE = App.UPDATE_RATE - private val COL_TERR = Color.WHITE - private val COL_WALLED = Color(.5f, .5f, .5f, 1f) - private val COL_AIR = Color.BLACK + val COL_TERR = Color.WHITE + val COL_WALLED = Color(.5f, .5f, .5f, 1f) + val COL_AIR = Color.BLACK } private val previewWidth = (App.scr.width * WIDTH_RATIO).roundToInt() diff --git a/src/net/torvald/terrarum/serialise/WriteSavegame.kt b/src/net/torvald/terrarum/serialise/WriteSavegame.kt index bfa9a2674..35bab2bd2 100644 --- a/src/net/torvald/terrarum/serialise/WriteSavegame.kt +++ b/src/net/torvald/terrarum/serialise/WriteSavegame.kt @@ -7,6 +7,7 @@ import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.console.Echo import net.torvald.terrarum.gameworld.BlockLayer import net.torvald.terrarum.langpack.Lang +import net.torvald.terrarum.modulebasegame.ChunkLoadingLoadScreen import net.torvald.terrarum.modulebasegame.IngameRenderer import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer @@ -106,9 +107,9 @@ object WriteSavegame { val cw = ingame.world.width / LandUtil.CHUNK_W val ch = ingame.world.height / LandUtil.CHUNK_H for (layer in layers.indices) { - for (cy in 0 until ch) { - for (cx in 0 until cw) { - val chunkNumber = (cy * cw + cx).toLong() + for (cx in 0 until cw) { + for (cy in 0 until ch) { + val chunkNumber = (cx * ch + cy).toLong() val chunkBytes = WriteWorld.encodeChunk(layers[layer], cx, cy) val entryID = worldNum.toLong().shl(32) or layer.toLong().shl(24) or chunkNumber @@ -160,24 +161,18 @@ object LoadSavegame { operator fun invoke(disk: VirtualDisk) { val newIngame = TerrarumIngame(App.batch) + val meta = ReadMeta(disk) + + // NOTE: do NOT set ingame.actorNowPlaying as one read directly from the disk; + // you'll inevitably read the player actor twice, and they're separate instances of the player! + val currentWorld = (ReadActor.readActorBare(getFileReader(disk, Terrarum.PLAYER_REF_ID.toLong())) as IngamePlayer).worldCurrentlyPlaying + val world = ReadWorld(getFileReader(disk, currentWorld.toLong())) - val loadJob = { loadscreen: LoadScreenBase -> - val meta = ReadMeta(disk) - - loadscreen.addMessage("${Lang["MENU_LABEL_WELCOME"]} !") - - - // NOTE: do NOT set ingame.actorNowPlaying as one read directly from the disk; - // you'll inevitably read the player actor twice, and they're separate instances of the player! - val currentWorld = (ReadActor.readActorBare(getFileReader(disk, Terrarum.PLAYER_REF_ID.toLong())) as IngamePlayer).worldCurrentlyPlaying - val world = ReadWorld(getFileReader(disk, currentWorld.toLong())) - - loadscreen.addMessage("${Lang["MENU_LABEL_WORLD"]} : $currentWorld") - loadscreen.addMessage("${Lang["MENU_OPTIONS_SIZE"]} : ${world.width}x${world.height}") - + val loadJob = { it: LoadScreenBase -> + val loadscreen = it as ChunkLoadingLoadScreen val actors = world.actors.distinct()//.map { ReadActor(getFileReader(disk, it.toLong())) } // val block = Common.jsoner.fromJson(BlockCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -16))) val item = Common.jsoner.fromJson(ItemCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -17))) @@ -204,19 +199,16 @@ object LoadSavegame { val worldnum = world.worldIndex.toLong() val cw = LandUtil.CHUNK_W; val ch = LandUtil.CHUNK_H - val chunksX = world.width / cw + val chunksY = world.height / ch val chunkCount = world.width * world.height / (cw * ch) - for (layer in 0L..1L) { - val worldLayer = world.getLayer(layer.toInt()) - for (chunk in 0L until (world.width * world.height) / (cw * ch)) { - - loadscreen.addMessage("${Lang["MENU_IO_LOADING"]} ${layer * chunkCount + chunk + 1}/${2 * chunkCount}") - + val worldLayer = arrayOf(world.getLayer(0), world.getLayer(1)) + for (chunk in 0L until (world.width * world.height) / (cw * ch)) { + for (layer in 0L..1L) { val chunkFile = VDUtil.getAsNormalFile(disk, worldnum.shl(32) or layer.shl(24) or chunk) - val cx = chunk % chunksX - val cy = chunk / chunksX + val cy = chunk % chunksY + val cx = chunk / chunksY - ReadWorld.decodeChunkToLayer(chunkFile.getContent(), worldLayer, cx.toInt(), cy.toInt()) + ReadWorld.decodeChunkToLayer(chunkFile.getContent(), worldLayer[layer.toInt()], cx.toInt(), cy.toInt()) } } @@ -228,10 +220,9 @@ object LoadSavegame { printdbg(this, "Savegame loaded from ${disk.getDiskNameString(Common.CHARSET)}") } - SanicLoadScreen.preLoadJob = loadJob - SanicLoadScreen.screenToLoad = newIngame + val loadScreen = ChunkLoadingLoadScreen(newIngame, world.width, world.height, loadJob) Terrarum.setCurrentIngameInstance(newIngame) - App.setLoadScreen(SanicLoadScreen) + App.setLoadScreen(loadScreen) }