From ea507d4d8e218fc85e33096c7f0d3a4f3ffb2b96 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Fri, 1 Oct 2021 22:54:18 +0900 Subject: [PATCH] reading savefiles won't freeze the ui (too much) --- src/net/torvald/terrarum/App.java | 43 ++-- src/net/torvald/terrarum/TitleScreen.kt | 16 +- .../modulebasegame/ui/UILoadDemoSavefiles.kt | 184 +++++++++++------- .../terrarum/modulebasegame/ui/UIRemoCon.kt | 126 ++++++------ .../torvald/terrarum/ui/UIAutosaveNotifier.kt | 58 ++++++ src/net/torvald/terrarum/ui/UIHandler.kt | 2 +- 6 files changed, 256 insertions(+), 173 deletions(-) create mode 100644 src/net/torvald/terrarum/ui/UIAutosaveNotifier.kt diff --git a/src/net/torvald/terrarum/App.java b/src/net/torvald/terrarum/App.java index c0c8b1f53..03abfca2b 100644 --- a/src/net/torvald/terrarum/App.java +++ b/src/net/torvald/terrarum/App.java @@ -16,7 +16,6 @@ import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.JsonValue; import com.github.strikerx3.jxinput.XInputDevice; -import kotlin.Pair; import net.torvald.gdx.graphics.PixmapIO2; import net.torvald.getcpuname.GetCpuName; import net.torvald.terrarum.concurrent.ThreadExecutor; @@ -32,9 +31,7 @@ import net.torvald.terrarum.modulebasegame.IngameRenderer; import net.torvald.terrarum.modulebasegame.TerrarumIngame; import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory; import net.torvald.terrarum.serialise.WriteConfig; -import net.torvald.terrarum.serialise.WriteMeta; import net.torvald.terrarum.tvda.DiskSkimmer; -import net.torvald.terrarum.tvda.VirtualDisk; import net.torvald.terrarum.utils.JsonFetcher; import net.torvald.terrarum.worlddrawer.CreateTileAtlas; import net.torvald.terrarumsansbitmap.gdx.GameFontBase; @@ -235,7 +232,7 @@ public class App implements ApplicationListener { private static com.badlogic.gdx.graphics.Color gradWhiteTop = new com.badlogic.gdx.graphics.Color(0xf8f8f8ff); private static com.badlogic.gdx.graphics.Color gradWhiteBottom = new com.badlogic.gdx.graphics.Color(0xd8d8d8ff); - private static Screen currenScreen; + private static Screen currentScreen; private static LoadScreenBase currentSetLoadScreen; public static Texture textureWhiteSquare; @@ -288,6 +285,10 @@ public class App implements ApplicationListener { "xinput", "xbox", "game", "joy", "pad" }; + public static Screen getCurrentScreen() { + return currentScreen; + } + public static void main(String[] args) { // print copyright message System.out.println(csiB+GAME_NAME+" "+csiG+getVERSION_STRING()+" "+csiK+"\u2014"+" "+csi0+TerrarumAppConfiguration.COPYRIGHT_DATE_NAME); @@ -521,7 +522,7 @@ public class App implements ApplicationListener { // draw splash screen when predefined screen is null // because in normal operation, the only time screen == null is when the app is cold-launched // you can't have a text drawn here :v - if (currenScreen == null) { + if (currentScreen == null) { drawSplash(); loadTimer += Gdx.graphics.getDeltaTime(); @@ -539,10 +540,10 @@ public class App implements ApplicationListener { } // draw the screen else { - currenScreen.render(UPDATE_RATE); + currentScreen.render(UPDATE_RATE); } - KeyToggler.INSTANCE.update(currenScreen instanceof TerrarumIngame); + KeyToggler.INSTANCE.update(currentScreen instanceof TerrarumIngame); // nested FBOs are just not a thing in GL! net.torvald.terrarum.FrameBufferManager.end(); @@ -663,7 +664,7 @@ public class App implements ApplicationListener { scr.setDimension(width, height); - if (currenScreen != null) currenScreen.resize(scr.getWidth(), scr.getHeight()); + if (currentScreen != null) currentScreen.resize(scr.getWidth(), scr.getHeight()); updateFullscreenQuad(scr.getWidth(), scr.getHeight()); @@ -692,9 +693,9 @@ public class App implements ApplicationListener { System.out.println("Goodbye !"); - if (currenScreen != null) { - currenScreen.hide(); - currenScreen.dispose(); + if (currentScreen != null) { + currentScreen.hide(); + currentScreen.dispose(); } //IngameRenderer.INSTANCE.dispose(); @@ -741,12 +742,12 @@ public class App implements ApplicationListener { @Override public void pause() { - if (currenScreen != null) currenScreen.pause(); + if (currentScreen != null) currentScreen.pause(); } @Override public void resume() { - if (currenScreen != null) currenScreen.resume(); + if (currentScreen != null) currentScreen.resume(); } public static LoadScreenBase getLoadScreen() { @@ -773,26 +774,26 @@ public class App implements ApplicationListener { // this whole thing is directtly copied from com.badlogic.gdx.Game - if (currenScreen != null) { - printdbg("AppLoader-Static", "Screen before change: " + currenScreen.getClass().getCanonicalName()); + if (currentScreen != null) { + printdbg("AppLoader-Static", "Screen before change: " + currentScreen.getClass().getCanonicalName()); - currenScreen.hide(); - currenScreen.dispose(); + currentScreen.hide(); + currentScreen.dispose(); } else { printdbg("AppLoader-Static", "Screen before change: null"); } - currenScreen = screen; + currentScreen = screen; - currenScreen.show(); - currenScreen.resize(scr.getWidth(), scr.getHeight()); + currentScreen.show(); + currentScreen.resize(scr.getWidth(), scr.getHeight()); System.gc(); - printdbg("AppLoader-Static", "Screen transition complete: " + currenScreen.getClass().getCanonicalName()); + printdbg("AppLoader-Static", "Screen transition complete: " + currentScreen.getClass().getCanonicalName()); } /** diff --git a/src/net/torvald/terrarum/TitleScreen.kt b/src/net/torvald/terrarum/TitleScreen.kt index c56616333..90579a074 100644 --- a/src/net/torvald/terrarum/TitleScreen.kt +++ b/src/net/torvald/terrarum/TitleScreen.kt @@ -113,7 +113,7 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) { val uiContainer = UIContainer() - private lateinit var uiMenu: UICanvas + internal lateinit var uiRemoCon: UICanvas internal lateinit var uiFakeBlurOverlay: UICanvas private lateinit var worldFBO: FrameBuffer @@ -189,12 +189,12 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) { uiContainer.add(uiFakeBlurOverlay) - uiMenu = UIRemoCon(this, UITitleRemoConYaml(App.savegames.isNotEmpty())) - uiMenu.setPosition(0, 0) - uiMenu.setAsOpen() + uiRemoCon = UIRemoCon(this, UITitleRemoConYaml(App.savegames.isNotEmpty())) + uiRemoCon.setPosition(0, 0) + uiRemoCon.setAsOpen() - uiContainer.add(uiMenu) + uiContainer.add(uiRemoCon) CommandDict // invoke // TODO add console here @@ -340,10 +340,10 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) { // resize UI by re-creating it (!!) - uiMenu.resize(App.scr.width, App.scr.height) + uiRemoCon.resize(App.scr.width, App.scr.height) // TODO I forgot what the fuck kind of hack I was talking about //uiMenu.setPosition(0, UITitleRemoConRoot.menubarOffY) - uiMenu.setPosition(0, 0) // shitty hack. Could be: + uiRemoCon.setPosition(0, 0) // shitty hack. Could be: // 1: Init code and resize code are different // 2: The UI is coded shit @@ -354,7 +354,7 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) { } override fun dispose() { - uiMenu.dispose() + uiRemoCon.dispose() demoWorld.dispose() } diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt b/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt index 7a84d5a00..2f829a2ec 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt @@ -15,10 +15,8 @@ import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.serialise.Common import net.torvald.terrarum.serialise.LoadSavegame import net.torvald.terrarum.serialise.ReadMeta -import net.torvald.terrarum.tvda.ByteArray64InputStream -import net.torvald.terrarum.tvda.DiskSkimmer -import net.torvald.terrarum.tvda.EntryFile -import net.torvald.terrarum.tvda.VDUtil +import net.torvald.terrarum.serialise.WriteMeta +import net.torvald.terrarum.tvda.* import net.torvald.terrarum.ui.* import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack import java.time.Instant @@ -29,6 +27,8 @@ import java.util.zip.GZIPInputStream import kotlin.math.roundToInt /** + * Only works if current screen set by the App is [TitleScreen] + * * Created by minjaesong on 2021-09-09. */ class UILoadDemoSavefiles : UICanvas() { @@ -37,6 +37,9 @@ class UILoadDemoSavefiles : UICanvas() { CommonResourcePool.addToLoadingList("terrarum-defaultsavegamethumb") { TextureRegion(Texture(Gdx.files.internal("assets/graphics/gui/savegame_thumb_placeholder.png"))) } + CommonResourcePool.addToLoadingList("savegame_status_icon") { + TextureRegionPack("assets/graphics/gui/savegame_status_icon.tga", 24, 24) + } CommonResourcePool.loadAll() } @@ -52,21 +55,21 @@ class UILoadDemoSavefiles : UICanvas() { private val shapeRenderer = ShapeRenderer() - private val uiWidth = UIItemDemoSaveCells.WIDTH // 480 - private val uiX = (width - uiWidth) / 2 + internal val uiWidth = UIItemDemoSaveCells.WIDTH // 480 + internal val uiX = (width - uiWidth) / 2 - private val textH = App.fontGame.lineHeight.toInt() + internal val textH = App.fontGame.lineHeight.toInt() - private val cellGap = 20 - private val cellInterval = cellGap + UIItemDemoSaveCells.HEIGHT - private val gradAreaHeight = 32 + internal val cellGap = 20 + internal val cellInterval = cellGap + UIItemDemoSaveCells.HEIGHT + internal val gradAreaHeight = 32 - private val titleTextPosY: Int = App.scr.tvSafeGraphicsHeight + 10 - private val titleTopGradStart: Int = titleTextPosY + textH - private val titleTopGradEnd: Int = titleTopGradStart + gradAreaHeight - private val titleBottomGradStart: Int = height - App.scr.tvSafeGraphicsHeight - gradAreaHeight - private val titleBottomGradEnd: Int = titleBottomGradStart + gradAreaHeight - private val controlHelperY: Int = titleBottomGradStart + gradAreaHeight - textH + internal val titleTextPosY: Int = App.scr.tvSafeGraphicsHeight + 10 + internal val titleTopGradStart: Int = titleTextPosY + textH + internal val titleTopGradEnd: Int = titleTopGradStart + gradAreaHeight + internal val titleBottomGradStart: Int = height - App.scr.tvSafeGraphicsHeight - gradAreaHeight + internal val titleBottomGradEnd: Int = titleBottomGradStart + gradAreaHeight + internal val controlHelperY: Int = titleBottomGradStart + gradAreaHeight - textH private val controlHelp: String @@ -89,24 +92,42 @@ class UILoadDemoSavefiles : UICanvas() { private var sliderFBO = FrameBuffer(Pixmap.Format.RGBA8888, uiWidth + 10, height, true) + private var showSpinner = false + override fun show() { printdbg(this, "savefiles show()") - // read savegames - var savegamesCount = 0 - App.savegames.forEach { skimmer -> - val x = uiX - val y = titleTopGradEnd + cellInterval * savegamesCount - try { - addUIitem(UIItemDemoSaveCells(this, x, y, skimmer)) - savegamesCount += 1 - } - catch (e: Throwable) { - System.err.println("[UILoadDemoSavefiles] Savefile '${skimmer.diskFile.absolutePath}' cannot be loaded") - e.printStackTrace() - } + try { + val remoCon = (App.getCurrentScreen() as TitleScreen).uiRemoCon + + remoCon.handler.lockToggle() + showSpinner = true + + Thread { + // read savegames + var savegamesCount = 0 + App.savegames.forEach { skimmer -> + val x = uiX + val y = titleTopGradEnd + cellInterval * savegamesCount + try { + addUIitem(UIItemDemoSaveCells(this, x, y, skimmer)) + savegamesCount += 1 + } + catch (e: Throwable) { + System.err.println("[UILoadDemoSavefiles] Savefile '${skimmer.diskFile.absolutePath}' cannot be loaded") + e.printStackTrace() + } + + + } + + + remoCon.handler.unlockToggle() + showSpinner = false + }.start() } + catch (e: UninitializedPropertyAccessException) {} } override fun hide() { @@ -132,8 +153,8 @@ class UILoadDemoSavefiles : UICanvas() { } } - - uiItems.forEachIndexed { index, it -> + for (index in 0 until uiItems.size) { + val it = uiItems[index] if (index in listScroll - 2 until listScroll + savesVisible + 2) { // re-position it.posY = (it.initialY - uiScroll).roundToInt() @@ -155,7 +176,8 @@ class UILoadDemoSavefiles : UICanvas() { setCameraPosition(batch, camera, 0f, 0f) batch.color = Color.WHITE batch.inUse { - uiItems.forEachIndexed { index, it -> + for (index in 0 until uiItems.size) { + val it = uiItems[index] if (index in listScroll - 2 until listScroll + savesVisible + 2) { it.render(batch, camera) } @@ -303,27 +325,37 @@ class UIItemDemoSaveCells( const val HEIGHT = 120 } - init { - CommonResourcePool.addToLoadingList("savegame_status_icon") { - TextureRegionPack("assets/graphics/gui/savegame_status_icon.tga", 24, 24) - } - CommonResourcePool.loadAll() + private val metaFile: DiskEntry? + private val saveName: String + private val saveMode: Int + private val isQuick: Boolean + private val isAuto: Boolean + private val meta: WriteMeta.WorldMeta? + private val saveDamaged: Boolean + private val lastPlayedTimestamp: String + + init { printdbg(this, "Rebuilding skimmer for savefile ${skimmer.diskFile.absolutePath}") skimmer.rebuild() + + metaFile = skimmer.requestFile(-1) + saveName = skimmer.getDiskName(Common.CHARSET) + saveMode = skimmer.getSaveMode() + isQuick = (saveMode % 2 == 1) + isAuto = (saveMode.ushr(1) != 0) + meta = if (metaFile != null) ReadMeta.fromDiskEntry(metaFile) else null + + saveDamaged = checkForSavegameDamage(skimmer) + + lastPlayedTimestamp = if (meta != null) + Instant.ofEpochSecond(meta.lastplay_t) + .atZone(TimeZone.getDefault().toZoneId()) + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + + "/${parseDuration(meta.playtime_t)}" + else "--:--:--/--h--m--s" } - private var saveDamaged = checkForSavegameDamage(skimmer) - - override val width: Int = WIDTH - override val height: Int = HEIGHT - - private var thumbPixmap: Pixmap? = null - private var thumb: TextureRegion? = null - private val grad = CommonResourcePool.getAsTexture("title_halfgrad") - - private val icons = CommonResourcePool.getAsTextureRegionPack("savegame_status_icon") - private fun parseDuration(seconds: Long): String { val s = seconds % 60 val m = (seconds / 60) % 60 @@ -335,36 +367,20 @@ class UIItemDemoSaveCells( "${d}d${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s" } - private val metaFile = skimmer.requestFile(-1) + override val width: Int = WIDTH + override val height: Int = HEIGHT - private val saveName = skimmer.getDiskName(Common.CHARSET) - private val saveMode = skimmer.getSaveMode() - private val isQuick = (saveMode % 2 == 1) - private val isAuto = (saveMode.ushr(1) != 0) - private val meta = if (metaFile != null) ReadMeta.fromDiskEntry(metaFile) else null + private var thumbPixmap: Pixmap? = null + private var thumb: TextureRegion? = null + private val grad = CommonResourcePool.getAsTexture("title_halfgrad") - private val colourBad = Color(0xFF8888FF.toInt()) + private val icons = CommonResourcePool.getAsTextureRegionPack("savegame_status_icon") + + + private val colourBad = Color(0xFF0011FF.toInt()) - private val lastPlayedTimestamp = if (meta != null) - Instant.ofEpochSecond(meta.lastplay_t) - .atZone(TimeZone.getDefault().toZoneId()) - .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + - "/${parseDuration(meta.playtime_t)}" - else "--:--:--/--h--m--s" init { - // load thumbnail or use stock if the file is not there - skimmer.requestFile(-2)?.let { - val zippedTga = (it.contents as EntryFile).bytes - val gzin = GZIPInputStream(ByteArray64InputStream(zippedTga)) - val tgaFileContents = gzin.readAllBytes(); gzin.close() - - thumbPixmap = Pixmap(tgaFileContents, 0, tgaFileContents.size) - val thumbTex = Texture(thumbPixmap) - thumbTex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) - thumb = TextureRegion(thumbTex) - thumb!!.setRegion(0, (thumbTex.height - 2 * height) / 2, width * 2, height * 2) - } } @@ -372,7 +388,29 @@ class UIItemDemoSaveCells( LoadSavegame(VDUtil.readDiskArchive(skimmer.diskFile, Level.INFO)) } + internal var hasTexture = false + private set + override fun render(batch: SpriteBatch, camera: Camera) { + // try to generate a texture + if (skimmer.initialised && !hasTexture) { + // load thumbnail or use stock if the file is not there + skimmer.requestFile(-2)?.let { + val zippedTga = (it.contents as EntryFile).bytes + val gzin = GZIPInputStream(ByteArray64InputStream(zippedTga)) + val tgaFileContents = gzin.readAllBytes(); gzin.close() + + thumbPixmap = Pixmap(tgaFileContents, 0, tgaFileContents.size) + val thumbTex = Texture(thumbPixmap) + thumbTex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + thumb = TextureRegion(thumbTex) + thumb!!.setRegion(0, (thumbTex.height - 2 * height) / 2, width * 2, height * 2) + } + + + hasTexture = true + } + val highlightCol = if (mouseUp) UIItemTextButton.defaultActiveCol else Color.WHITE val x = posX.toFloat() val y = posY.toFloat() diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIRemoCon.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIRemoCon.kt index 607f356db..fb1ea2917 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIRemoCon.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIRemoCon.kt @@ -5,8 +5,11 @@ import com.badlogic.gdx.Input import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch -import net.torvald.terrarum.* +import net.torvald.terrarum.App import net.torvald.terrarum.App.printdbgerr +import net.torvald.terrarum.QNDTreeNode +import net.torvald.terrarum.TitleScreen +import net.torvald.terrarum.Yaml import net.torvald.terrarum.serialise.WriteConfig import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.ui.UIItemTextButton @@ -85,69 +88,71 @@ open class UIRemoCon(val parent: TitleScreen, treeRepresentation: QNDTreeNode selectedIndex ?: 0x7FFFFFFF) { + else if (it.labelText.startsWith("MENU_LABEL_RETURN")) { + val tag = it.tags + if (tag.contains("WRITETOCONFIG")) WriteConfig() - val newCurrentRemoConContents = currentRemoConContents.children[selectedIndex!!] - - // only go deeper if that node has child to navigate - if (currentRemoConContents.children[selectedIndex].children.size != 0) { + if (currentRemoConContents.parent != null) { remoConTray.consume() - remoConTray = generateNewRemoCon(newCurrentRemoConContents) - currentRemoConContents = newCurrentRemoConContents + + currentRemoConContents = currentRemoConContents.parent!! + currentlySelectedRemoConItem = currentRemoConContents.data + remoConTray = generateNewRemoCon(currentRemoConContents) + + parent.uiFakeBlurOverlay.setAsClose() + } + else { + throw NullPointerException("No parent node to return") } - - currentlySelectedRemoConItem = newCurrentRemoConContents.data } else { - throw RuntimeException("Index: $selectedIndex, Size: ${currentRemoConContents.children.size}") + // check if target exists + //println("current node: ${currentRemoConContents.data}") + //currentRemoConContents.children.forEach { println("- ${it.data}") } + + if (currentRemoConContents.children.size > selectedIndex ?: 0x7FFFFFFF) { + + + val newCurrentRemoConContents = currentRemoConContents.children[selectedIndex!!] + + // only go deeper if that node has child to navigate + if (currentRemoConContents.children[selectedIndex].children.size != 0) { + remoConTray.consume() + remoConTray = generateNewRemoCon(newCurrentRemoConContents) + currentRemoConContents = newCurrentRemoConContents + } + + currentlySelectedRemoConItem = newCurrentRemoConContents.data + } + else { + throw RuntimeException("Index: $selectedIndex, Size: ${currentRemoConContents.children.size}") + } } - } - // do something with the actual selection - //printdbg(this, "$currentlySelectedRemoConItem") + // do something with the actual selection + //printdbg(this, "$currentlySelectedRemoConItem") - screens.forEach { - //printdbg(this, "> ${it.first}") + screens.forEach { + //printdbg(this, "> ${it.first}") - if (currentlySelectedRemoConItem == it.first) { - parent.uiFakeBlurOverlay.setAsOpen() - it.second.setAsOpen() + if (currentlySelectedRemoConItem == it.first) { + parent.uiFakeBlurOverlay.setAsOpen() + it.second.setAsOpen() - //printdbg(this, ">> ding - ${it.second.javaClass.canonicalName}") - } - else { - it.second.setAsClose() + //printdbg(this, ">> ding - ${it.second.javaClass.canonicalName}") + } + else { + it.second.setAsClose() + } } } } @@ -277,30 +282,11 @@ open class UIRemoCon(val parent: TitleScreen, treeRepresentation: QNDTreeNode spinnerInterval) { - spinnerFrame = (spinnerFrame + 1) % 32 - spinnerTimer -= spinnerInterval - } - menubar.update(delta) } fun render(batch: SpriteBatch, camera: Camera) { - val spin = spinner.get(spinnerFrame % 8, spinnerFrame / 8) - - val inlineOffsetY = if (App.GAME_LOCALE.startsWith("th")) 0f - else if (App.GAME_LOCALE.startsWith("ko")) 0f - else 1f - - batch.draw(spin, menubar.posX + paddingLeft - 5f, menubar.posY + (lineHeight - 20) / 2 - inlineOffsetY) - menubar.render(batch, camera) } diff --git a/src/net/torvald/terrarum/ui/UIAutosaveNotifier.kt b/src/net/torvald/terrarum/ui/UIAutosaveNotifier.kt new file mode 100644 index 000000000..691df41d1 --- /dev/null +++ b/src/net/torvald/terrarum/ui/UIAutosaveNotifier.kt @@ -0,0 +1,58 @@ +package net.torvald.terrarum.ui + +import com.badlogic.gdx.graphics.Camera +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import net.torvald.terrarum.App +import net.torvald.terrarum.CommonResourcePool + +/** + * Created by minjaesong on 2021-10-01. + */ +class UIAutosaveNotifier : UICanvas() { + + override var width: Int + get() = TODO("Not yet implemented") + set(value) {} + override var height: Int + get() = TODO("Not yet implemented") + set(value) {} + override var openCloseTime = 0.2f + + private val spinner = CommonResourcePool.getAsTextureRegionPack("inline_loading_spinner") + private var spinnerTimer = 0f + private var spinnerFrame = 0 + private val spinnerInterval = 1f / 60f + + override fun updateUI(delta: Float) { + spinnerTimer += delta + if (spinnerTimer > spinnerInterval) { + spinnerFrame = (spinnerFrame + 1) % 32 + spinnerTimer -= spinnerInterval + } + } + + override fun renderUI(batch: SpriteBatch, camera: Camera) { + val spin = spinner.get(spinnerFrame % 8, spinnerFrame / 8) + + val inlineOffsetY = if (App.GAME_LOCALE.startsWith("th")) 0f + else if (App.GAME_LOCALE.startsWith("ko")) 0f + else 1f + + batch.draw(spin, posX.toFloat(), posY.toFloat()) + } + + override fun doOpening(delta: Float) { + } + + override fun doClosing(delta: Float) { + } + + override fun endOpening(delta: Float) { + } + + override fun endClosing(delta: Float) { + } + + override fun dispose() { + } +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/ui/UIHandler.kt b/src/net/torvald/terrarum/ui/UIHandler.kt index 3ce472f2a..75edabd7b 100644 --- a/src/net/torvald/terrarum/ui/UIHandler.kt +++ b/src/net/torvald/terrarum/ui/UIHandler.kt @@ -118,7 +118,7 @@ void main() { private val shader = App.loadShaderInline(SHADER_PROG_VERT, SHADER_PROG_FRAG) - private var uiToggleLocked = false + var uiToggleLocked = false; private set init { //UI.handler = this