From 3bd7e740d424d8f4d15da6b7c668fc59cd42f9a5 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Thu, 28 Oct 2021 17:32:09 +0900 Subject: [PATCH] working create-new-world --- src/net/torvald/random/XXHash64.java | 123 ++++++++++++++++++ src/net/torvald/terrarum/IngameInstance.kt | 5 +- src/net/torvald/terrarum/Terrarum.kt | 2 + .../terrarum/modulebasegame/TerrarumIngame.kt | 14 +- .../terrarum/modulebasegame/ui/UINewWorld.kt | 30 +++++ src/net/torvald/terrarum/ui/ConsoleWindow.kt | 41 ++++-- 6 files changed, 191 insertions(+), 24 deletions(-) create mode 100644 src/net/torvald/random/XXHash64.java diff --git a/src/net/torvald/random/XXHash64.java b/src/net/torvald/random/XXHash64.java new file mode 100644 index 000000000..124ca0c81 --- /dev/null +++ b/src/net/torvald/random/XXHash64.java @@ -0,0 +1,123 @@ +package net.torvald.random; + +import net.torvald.UnsafeHelper; + +/** + * Code from https://richardstartin.github.io/posts/xxhash + * https://github.com/richardstartin/xxhash-benchmark + * Created by minjaesong on 2021-10-28. + */ +public class XXHash64 { + + static final long PRIME64_1 = 0x9E3779B185EBCA87L; + static final long PRIME64_2 = 0xC2B2AE3D27D4EB4FL; + static final long PRIME64_3 = 0x165667B19E3779F9L; + static final long PRIME64_4 = 0x85EBCA77C2B2AE63L; + static final long PRIME64_5 = 0x27D4EB2F165667C5L; + + public static long hash(byte[] input, long seed) { + long hash; + long remaining = input.length; + int offset = 0; + + if (remaining >= 32) { + long v1 = seed + PRIME64_1 + PRIME64_2; + long v2 = seed + PRIME64_2; + long v3 = seed; + long v4 = seed - PRIME64_1; + + do { + v1 += getLong(input, offset) * PRIME64_2; + v1 = Long.rotateLeft(v1, 31); + v1 *= PRIME64_1; + + v2 += getLong(input, offset + 8) * PRIME64_2; + v2 = Long.rotateLeft(v2, 31); + v2 *= PRIME64_1; + + v3 += getLong(input, offset + 16) * PRIME64_2; + v3 = Long.rotateLeft(v3, 31); + v3 *= PRIME64_1; + + v4 += getLong(input, offset + 24) * PRIME64_2; + v4 = Long.rotateLeft(v4, 31); + v4 *= PRIME64_1; + + offset += 32; + remaining -= 32; + } while (remaining >= 32); + + hash = Long.rotateLeft(v1, 1) + + Long.rotateLeft(v2, 7) + + Long.rotateLeft(v3, 12) + + Long.rotateLeft(v4, 18); + + v1 *= PRIME64_2; + v1 = Long.rotateLeft(v1, 31); + v1 *= PRIME64_1; + hash ^= v1; + hash = hash * PRIME64_1 + PRIME64_4; + + v2 *= PRIME64_2; + v2 = Long.rotateLeft(v2, 31); + v2 *= PRIME64_1; + hash ^= v2; + hash = hash * PRIME64_1 + PRIME64_4; + + v3 *= PRIME64_2; + v3 = Long.rotateLeft(v3, 31); + v3 *= PRIME64_1; + hash ^= v3; + hash = hash * PRIME64_1 + PRIME64_4; + + v4 *= PRIME64_2; + v4 = Long.rotateLeft(v4, 31); + v4 *= PRIME64_1; + hash ^= v4; + hash = hash * PRIME64_1 + PRIME64_4; + } else { + hash = seed + PRIME64_5; + } + + hash += input.length; + + while (remaining >= 8) { + long k1 = getLong(input, offset); + k1 *= PRIME64_2; + k1 = Long.rotateLeft(k1, 31); + k1 *= PRIME64_1; + hash ^= k1; + hash = Long.rotateLeft(hash, 27) * PRIME64_1 + PRIME64_4; + offset += 8; + remaining -= 8; + } + + if (remaining >= 4) { + hash ^= getInt(input, offset) * PRIME64_1; + hash = Long.rotateLeft(hash, 23) * PRIME64_2 + PRIME64_3; + offset += 4; + remaining -= 4; + } + + while (remaining != 0) { + hash ^= input[offset] * PRIME64_5; + hash = Long.rotateLeft(hash, 11) * PRIME64_1; + --remaining; + ++offset; + } + + hash ^= hash >>> 33; + hash *= PRIME64_2; + hash ^= hash >>> 29; + hash *= PRIME64_3; + hash ^= hash >>> 32; + return hash; + } + + protected static long getLong(byte[] data, int offset) { + return UnsafeHelper.INSTANCE.getUnsafe().getLong(data, offset + UnsafeHelper.INSTANCE.getArrayOffset(data)); + } + protected static int getInt(byte[] data, int offset) { + return UnsafeHelper.INSTANCE.getUnsafe().getInt(data, offset + UnsafeHelper.INSTANCE.getArrayOffset(data)); + } +} diff --git a/src/net/torvald/terrarum/IngameInstance.kt b/src/net/torvald/terrarum/IngameInstance.kt index c57863beb..b8a5fe887 100644 --- a/src/net/torvald/terrarum/IngameInstance.kt +++ b/src/net/torvald/terrarum/IngameInstance.kt @@ -61,7 +61,7 @@ open class IngameInstance(val batch: SpriteBatch, val isMultiplayer: Boolean = f open var consoleHandler: ConsoleWindow = ConsoleWindow() - var paused: Boolean = false + var paused: Boolean = false; protected set val consoleOpened: Boolean get() = consoleHandler.isOpened || consoleHandler.isOpening @@ -71,7 +71,6 @@ open class IngameInstance(val batch: SpriteBatch, val isMultiplayer: Boolean = f open var uiTooltip: UITooltip = UITooltip() open var notifier: Notification = Notification() - init { consoleHandler.setPosition(0, 0) notifier.setPosition( @@ -151,9 +150,11 @@ open class IngameInstance(val batch: SpriteBatch, val isMultiplayer: Boolean = f } override fun pause() { + paused = true } override fun resume() { + paused = false } override fun resize(width: Int, height: Int) { diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index d8d5c2897..75c6f6ad7 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -637,6 +637,8 @@ class UIContainer { fun contains(element: Any) = data.contains(element) fun map(transformation: (UICanvas?) -> T) = iterator().asSequence().map(transformation) + + fun filter(predicate: (Any) -> Boolean) = data.filter(predicate) } interface Id_UICanvasNullable { diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index 5a6170572..87d957a85 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -137,6 +137,12 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { (this.hitbox.endX + world.width >= WorldCamera.x && this.hitbox.startX + world.width <= WorldCamera.xEnd) || // x: neither (this.hitbox.endX >= WorldCamera.x && this.hitbox.startX <= WorldCamera.xEnd)) + + val SIZE_SMALL = Point2i(6030, 1800) + val SIZE_NORMAL = Point2i(9000, 2250) + val SIZE_LARGE = Point2i(13500, 2970) + val SIZE_HUGE = Point2i(22500, 4500) + val WORLDSIZE = arrayOf(SIZE_SMALL, SIZE_NORMAL, SIZE_LARGE, SIZE_HUGE) } @@ -1224,14 +1230,6 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { } } - override fun pause() { - paused = true - } - - override fun resume() { - paused = false - } - override fun hide() { uiContainer.forEach { it?.handler?.dispose() } } diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UINewWorld.kt b/src/net/torvald/terrarum/modulebasegame/ui/UINewWorld.kt index fa7999aaf..64b478019 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UINewWorld.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UINewWorld.kt @@ -6,12 +6,20 @@ import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.TextureRegion import net.torvald.random.HQRNG +import net.torvald.random.XXHash64 import net.torvald.terrarum.App import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.ModMgr import net.torvald.terrarum.Second +import net.torvald.terrarum.Terrarum import net.torvald.terrarum.langpack.Lang +import net.torvald.terrarum.modulebasegame.TerrarumIngame +import net.torvald.terrarum.modulebasegame.WorldgenLoadScreen +import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer +import net.torvald.terrarum.savegame.ByteArray64Reader import net.torvald.terrarum.savegame.VirtualDisk +import net.torvald.terrarum.serialise.Common +import net.torvald.terrarum.serialise.ReadActor import net.torvald.terrarum.ui.* import net.torvald.terrarum.utils.RandomWordsName @@ -71,6 +79,28 @@ class UINewWorld(val remoCon: UIRemoCon) : UICanvas() { goButton.touchDownListener = { _, _, _, _ -> printdbg(this, "generate! Size=${sizeSelector.selection}, Name=${nameInput.getTextOrPlaceholder()}, Seed=${seedInput.getTextOrPlaceholder()}") + + val ingame = TerrarumIngame(App.batch) + val player = ReadActor.invoke(UILoadGovernor.playerDisk!!, ByteArray64Reader(UILoadGovernor.playerDisk!!.getFile(-1L)!!.bytes, Common.CHARSET)) as IngamePlayer + val seed = try { + seedInput.getTextOrPlaceholder().toLong() + } + catch (e: NumberFormatException) { + XXHash64.hash(seedInput.getTextOrPlaceholder().toByteArray(Charsets.UTF_8), 10000) + } + val (wx, wy) = TerrarumIngame.WORLDSIZE[sizeSelector.selection] + val worldParam = TerrarumIngame.NewGameParams( + player, TerrarumIngame.NewWorldParameters( + wx, wy, seed, nameInput.getTextOrPlaceholder() + ) + ) + ingame.gameLoadInfoPayload = worldParam + ingame.gameLoadMode = TerrarumIngame.GameLoadMode.CREATE_NEW + + Terrarum.setCurrentIngameInstance(ingame) + val loadScreen = WorldgenLoadScreen(ingame, wx, wy) + App.setLoadScreen(loadScreen) + } backButton.touchDownListener = { _, _, _, _ -> remoCon.openUI(UILoadDemoSavefiles(remoCon, 1)) diff --git a/src/net/torvald/terrarum/ui/ConsoleWindow.kt b/src/net/torvald/terrarum/ui/ConsoleWindow.kt index df141d4c7..0da71cb1b 100644 --- a/src/net/torvald/terrarum/ui/ConsoleWindow.kt +++ b/src/net/torvald/terrarum/ui/ConsoleWindow.kt @@ -26,9 +26,9 @@ class ConsoleWindow : UICanvas() { internal var UIColour = Color(0x404080_80.toInt()) private var inputCursorPos: Int = 0 - private val MESSAGES_MAX = 5000 + private val MESSAGES_MAX = 1000 private val COMMAND_HISTORY_MAX = 100 - private var messages = Array(MESSAGES_MAX) { "" } + private var messages = CircularArray(MESSAGES_MAX, true) private var messageDisplayPos: Int = 0 private var messagesCount: Int = 0 @@ -49,6 +49,8 @@ class ConsoleWindow : UICanvas() { private var historyIndex = -1 + private var iMadeTheGameToPause = false + init { reset() } @@ -94,9 +96,9 @@ class ConsoleWindow : UICanvas() { // messages - for (i in 0..MESSAGES_DISPLAY_COUNT - 1) { - val message = messages[messageDisplayPos + i] - App.fontGame.draw(batch, message, 1f + drawOffX, (LINE_HEIGHT * (i + 1)).toFloat() + drawOffY) + for (i in 0 until MESSAGES_DISPLAY_COUNT) { + val message = messages[messageDisplayPos + i] ?: "" + App.fontGame.draw(batch, message, 1f + drawOffX, (LINE_HEIGHT * (MESSAGES_DISPLAY_COUNT - i)).toFloat() + drawOffY) } } @@ -167,11 +169,9 @@ class ConsoleWindow : UICanvas() { } fun sendMessage(msg: String) { - messages[messagesCount] = msg + messages.appendHead(msg) messagesCount += 1 - if (messagesCount > MESSAGES_DISPLAY_COUNT) { - messageDisplayPos = messagesCount - MESSAGES_DISPLAY_COUNT - } + } private fun setDisplayPos(change: Int) { @@ -195,7 +195,7 @@ class ConsoleWindow : UICanvas() { } fun reset() { - messages = Array(MESSAGES_MAX) { "" } + messages = CircularArray(MESSAGES_MAX, true) messageDisplayPos = 0 messagesCount = 0 inputCursorPos = 0 @@ -210,7 +210,17 @@ class ConsoleWindow : UICanvas() { } override fun doOpening(delta: Float) { - Terrarum.ingame?.pause() + Terrarum.ingame?.let { + println("Game was paused beforehand: ${it.paused}") + if (!it.paused) { + iMadeTheGameToPause = true + it.pause() + } + else { + iMadeTheGameToPause = false + } + println("I made the game to pause: $iMadeTheGameToPause") + } /*openingTimeCounter += delta drawOffY = MovementInterpolator.fastPullOut(openingTimeCounter.toFloat() / openCloseTime.toFloat(), -height.toFloat(), 0f @@ -218,7 +228,6 @@ class ConsoleWindow : UICanvas() { } override fun doClosing(delta: Float) { - Terrarum.ingame?.resume() /*openingTimeCounter += delta drawOffY = MovementInterpolator.fastPullOut(openingTimeCounter.toFloat() / openCloseTime.toFloat(), 0f, -height.toFloat() @@ -226,16 +235,20 @@ class ConsoleWindow : UICanvas() { } override fun endOpening(delta: Float) { - Terrarum.ingame?.pause() drawOffY = 0f openingTimeCounter = 0f } override fun endClosing(delta: Float) { Terrarum.ingame?.setTooltipMessage(null) - Terrarum.ingame?.resume() + println("Close -- I made the game to pause: $iMadeTheGameToPause") + if (iMadeTheGameToPause) { + Terrarum.ingame?.resume() + println("Close -- resume game") + } drawOffY = -height.toFloat() openingTimeCounter = 0f + iMadeTheGameToPause = false } override fun dispose() {