From b99d1a760e7c276ed1d99e9a61bdca18df2f7d38 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sun, 12 Sep 2021 22:47:31 +0900 Subject: [PATCH] save load screen --- src/net/torvald/UniTextShortcuts.kt | 15 + src/net/torvald/terrarum/App.java | 3 +- src/net/torvald/terrarum/CustomSymbol.kt | 63 ----- src/net/torvald/terrarum/DefaultConfig.kt | 1 + src/net/torvald/terrarum/Terrarum.kt | 9 +- .../terrarum/modulebasegame/IngameRenderer.kt | 1 + .../gameactors/FixtureStorageChest.kt | 21 +- .../modulebasegame/ui/UIInventoryFull.kt | 51 ++-- .../modulebasegame/ui/UILoadDemoSavefiles.kt | 265 ++++++++++++++++-- .../modulebasegame/ui/UIScreenZoom.kt | 4 +- 10 files changed, 296 insertions(+), 137 deletions(-) delete mode 100644 src/net/torvald/terrarum/CustomSymbol.kt diff --git a/src/net/torvald/UniTextShortcuts.kt b/src/net/torvald/UniTextShortcuts.kt index b041051dc..cd04817df 100644 --- a/src/net/torvald/UniTextShortcuts.kt +++ b/src/net/torvald/UniTextShortcuts.kt @@ -11,3 +11,18 @@ const val MIDDOT = 0xB7.toChar() const val ENDASH = 0x2013.toChar() const val EMDASH = 0x2014.toChar() const val ELLIPSIS = 0x2026.toChar() + +fun getKeycapPC(c: Char) = when (c.uppercaseChar()) { + in ' '..'_' -> (0xE000 + c.code - 32).toChar() + else -> throw IllegalArgumentException("Not in range: ${c.code - 32}") +} +fun getKeycapPC(keycode: Int) = getKeycapPC(com.badlogic.gdx.Input.Keys.toString(keycode)[0]) +fun getKeycapConsole(c: Char) = when (c.uppercaseChar()) { + in ' '..'_' -> (0xE040 + c.code - 32).toChar() + else -> throw IllegalArgumentException("Not in range: ${c.code - 32}") +} +fun getKeycapFkeys(n: Int) = when (n) { + in 1..9 -> "\uE090${(0xE090 + n).toChar()}" + in 10..12 -> "\uE09D${(0xE090 + n).toChar()}" + else -> throw IllegalArgumentException("Not in range: $n") +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/App.java b/src/net/torvald/terrarum/App.java index 8a580d7ba..67c68d1c7 100644 --- a/src/net/torvald/terrarum/App.java +++ b/src/net/torvald/terrarum/App.java @@ -15,7 +15,6 @@ import com.badlogic.gdx.graphics.glutils.ShaderProgram; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.JsonValue; -import com.badlogic.gdx.utils.ScreenUtils; import com.github.strikerx3.jxinput.XInputDevice; import net.torvald.gdx.graphics.PixmapIO2; import net.torvald.getcpuname.GetCpuName; @@ -535,7 +534,7 @@ public class App implements ApplicationListener { screenshotRequested = false; try { - Pixmap p = ScreenUtils.getFrameBufferPixmap(0, 0, scr.getWidth(), scr.getHeight()); + Pixmap p = Pixmap.createFromFrameBuffer(0, 0, scr.getWidth(), scr.getHeight()); PixmapIO2.writeTGA(Gdx.files.absolute(defaultDir+"/Screenshot-"+String.valueOf(System.currentTimeMillis())+".tga"), p, true); p.dispose(); diff --git a/src/net/torvald/terrarum/CustomSymbol.kt b/src/net/torvald/terrarum/CustomSymbol.kt deleted file mode 100644 index 7419e9654..000000000 --- a/src/net/torvald/terrarum/CustomSymbol.kt +++ /dev/null @@ -1,63 +0,0 @@ -package net.torvald.terrarum - -import com.badlogic.gdx.Input - -/** - * Created by minjaesong on 2019-08-11. - */ - -private val keyToIcon = hashMapOf( - Input.Keys.NUM_0 to 0xE010.toChar(), - Input.Keys.NUM_1 to 0xE011.toChar(), - Input.Keys.NUM_2 to 0xE012.toChar(), - Input.Keys.NUM_3 to 0xE013.toChar(), - Input.Keys.NUM_4 to 0xE014.toChar(), - Input.Keys.NUM_5 to 0xE015.toChar(), - Input.Keys.NUM_6 to 0xE016.toChar(), - Input.Keys.NUM_7 to 0xE017.toChar(), - Input.Keys.NUM_8 to 0xE018.toChar(), - Input.Keys.NUM_9 to 0xE019.toChar(), - - Input.Keys.A to 0xE021.toChar(), - Input.Keys.B to 0xE022.toChar(), - Input.Keys.C to 0xE023.toChar(), - Input.Keys.D to 0xE024.toChar(), - Input.Keys.E to 0xE025.toChar(), - Input.Keys.F to 0xE026.toChar(), - Input.Keys.G to 0xE027.toChar(), - Input.Keys.H to 0xE028.toChar(), - Input.Keys.I to 0xE029.toChar(), - Input.Keys.J to 0xE02A.toChar(), - Input.Keys.K to 0xE02B.toChar(), - Input.Keys.L to 0xE02C.toChar(), - Input.Keys.M to 0xE02D.toChar(), - - Input.Keys.N to 0xE02E.toChar(), - Input.Keys.O to 0xE02E.toChar(), - Input.Keys.P to 0xE030.toChar(), - Input.Keys.Q to 0xE031.toChar(), - Input.Keys.R to 0xE032.toChar(), - Input.Keys.S to 0xE033.toChar(), - Input.Keys.T to 0xE034.toChar(), - Input.Keys.U to 0xE035.toChar(), - Input.Keys.V to 0xE036.toChar(), - Input.Keys.W to 0xE037.toChar(), - Input.Keys.X to 0xE038.toChar(), - Input.Keys.Y to 0xE039.toChar(), - Input.Keys.Z to 0xE03A.toChar() -) - -fun keyToIcon(key: Int) = keyToIcon[key]!! - -const val F1 = "${0xE090.toChar()}${0xE091.toChar()}" -const val F2 = "${0xE090.toChar()}${0xE092.toChar()}" -const val F3 = "${0xE090.toChar()}${0xE093.toChar()}" -const val F4 = "${0xE090.toChar()}${0xE094.toChar()}" -const val F5 = "${0xE090.toChar()}${0xE095.toChar()}" -const val F6 = "${0xE090.toChar()}${0xE096.toChar()}" -const val F7 = "${0xE090.toChar()}${0xE097.toChar()}" -const val F8 = "${0xE090.toChar()}${0xE098.toChar()}" -const val F9 = "${0xE090.toChar()}${0xE099.toChar()}" -const val F10 = "${0xE09D.toChar()}${0xE09A.toChar()}" -const val F11 = "${0xE09D.toChar()}${0xE09B.toChar()}" -const val F12 = "${0xE09D.toChar()}${0xE09C.toChar()}" diff --git a/src/net/torvald/terrarum/DefaultConfig.kt b/src/net/torvald/terrarum/DefaultConfig.kt index b1b8d58b4..227d00696 100644 --- a/src/net/torvald/terrarum/DefaultConfig.kt +++ b/src/net/torvald/terrarum/DefaultConfig.kt @@ -62,6 +62,7 @@ object DefaultConfig { "config_keymovementaux" to Input.Keys.A, // movement-auxiliary, or hookshot "config_keyinventory" to Input.Keys.Q, "config_keyinteract" to Input.Keys.R, + "config_keydiscard" to Input.Keys.T, "config_keyclose" to Input.Keys.C, // this or hard-coded ESC "config_keyzoom" to Input.Keys.Z, diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 0736abc34..a85dad810 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -375,7 +375,8 @@ infix fun Color.mulAndAssign(other: Color): Color { fun blendMul(batch: SpriteBatch) { // will break if the colour image contains semitransparency batch.enableBlending() - batch.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_ONE_MINUS_SRC_ALPHA) +// batch.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_ONE_MINUS_SRC_ALPHA) + batch.setBlendFunctionSeparate(GL20.GL_DST_COLOR, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_DST_ALPHA, GL20.GL_SRC_ALPHA) } fun blendScreen(batch: SpriteBatch) { @@ -390,7 +391,7 @@ fun blendDisable(batch: SpriteBatch) { fun blendNormal(batch: SpriteBatch) { batch.enableBlending() - batch.setBlendFunctionSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_SRC_ALPHA, GL20.GL_ONE) + batch.setBlendFunctionSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE) // ALPHA *MUST BE* PREMULTIPLIED // @@ -424,8 +425,8 @@ fun gdxSetBlend() { fun gdxSetBlendNormal() { gdxSetBlend() - Gdx.gl.glBlendFuncSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_SRC_ALPHA, GL20.GL_ONE) - //Gdx.gl.glBlendEquationSeparate(GL20.GL_FUNC_ADD, GL30.GL_MAX) // batch.flush does not touch blend equation + Gdx.gl.glBlendFuncSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE) +// Gdx.gl.glBlendFuncSeparate(GL20.GL_SRC_COLOR, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_SRC_ALPHA, GL20.GL_ONE) // ALPHA *MUST BE* PREMULTIPLIED // diff --git a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt index 1732bd33a..cb6885ff2 100644 --- a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt +++ b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt @@ -85,6 +85,7 @@ object IngameRenderer : Disposable { private var newWorldLoadedLatch = false + // these codes will run regardless of the invocation of the "initialise()" function // the "initialise()" function will also be called init { diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureStorageChest.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureStorageChest.kt index 32502d4a8..81b7a5665 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureStorageChest.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureStorageChest.kt @@ -188,26 +188,7 @@ internal class UIStorageChest : UICanvas( override fun renderUI(batch: SpriteBatch, camera: Camera) { // background fill - /*batch.end() - gdxSetBlendNormal() - - - val gradTopStart = (App.scr.height - internalHeight).div(2).toFloat() - val gradBottomEnd = App.scr.height - gradTopStart - - shapeRenderer.inUse { - shapeRenderer.rect(0f, gradTopStart, App.scr.wf, gradHeight, gradStartCol, gradStartCol, gradEndCol, gradEndCol) - shapeRenderer.rect(0f, gradBottomEnd, App.scr.wf, -gradHeight, gradStartCol, gradStartCol, gradEndCol, gradEndCol) - - shapeRenderer.rect(0f, gradTopStart + gradHeight, App.scr.wf, internalHeight - (2 * gradHeight), gradEndCol, gradEndCol, gradEndCol, gradEndCol) - - shapeRenderer.rect(0f, 0f, App.scr.wf, gradTopStart, gradStartCol, gradStartCol, gradStartCol, gradStartCol) - shapeRenderer.rect(0f, App.scr.hf, App.scr.wf, -(App.scr.hf - gradBottomEnd), gradStartCol, gradStartCol, gradStartCol, gradStartCol) - } - - - - batch.begin()*/ + UIInventoryFull.drawBackground(batch, shapeRenderer) // UI items batch.color = Color.WHITE diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryFull.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryFull.kt index 883105aee..b8f368d80 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryFull.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryFull.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.ShapeRenderer import net.torvald.ENDASH +import net.torvald.getKeycapPC import net.torvald.terrarum.* import net.torvald.terrarum.App.* import net.torvald.terrarum.blockstats.MinimapComposer @@ -58,6 +59,29 @@ class UIInventoryFull( val gradHeight = 48f val controlHelpHeight = App.fontGame.lineHeight + + fun drawBackground(batch: SpriteBatch, shapeRenderer: ShapeRenderer) { + batch.end() + gdxSetBlendNormal() + + + val gradTopStart = (App.scr.height - internalHeight).div(2).toFloat() + val gradBottomEnd = App.scr.height - gradTopStart + + shapeRenderer.inUse { + // shaperender starts at bottom-left! + + shapeRenderer.rect(0f, gradTopStart, App.scr.wf, gradHeight, gradStartCol, gradStartCol, gradEndCol, gradEndCol) + shapeRenderer.rect(0f, gradBottomEnd, App.scr.wf, -gradHeight, gradStartCol, gradStartCol, gradEndCol, gradEndCol) + + shapeRenderer.rect(0f, gradTopStart + gradHeight, App.scr.wf, internalHeight - (2 * gradHeight), gradEndCol, gradEndCol, gradEndCol, gradEndCol) + + shapeRenderer.rect(0f, 0f, App.scr.wf, gradTopStart, gradStartCol, gradStartCol, gradStartCol, gradStartCol) + shapeRenderer.rect(0f, App.scr.hf, App.scr.wf, -(App.scr.hf - gradBottomEnd), gradStartCol, gradStartCol, gradStartCol, gradStartCol) + } + + batch.begin() + } } //val REQUIRED_MARGIN: Int = 138 // hard-coded value. Don't know the details. Range: [91-146]. I chose MAX-8 because cell gap is 8 @@ -85,13 +109,13 @@ class UIInventoryFull( CommonResourcePool.loadAll() } - private val SP = "${0x3000.toChar()} " + private val SP = "\u3000 " val listControlHelp: String get() = if (App.environment == RunningEnvironment.PC) - "${0xe031.toChar()} ${Lang["GAME_ACTION_CLOSE"]}$SP" + + "${getKeycapPC(App.getConfigInt("config_keyinventory"))} ${Lang["GAME_ACTION_CLOSE"]}$SP" + "${0xe006.toChar()} ${Lang["GAME_INVENTORY_USE"]}$SP" + "${0xe011.toChar()}$ENDASH${0x2009.toChar()}${0xe010.toChar()} ${Lang["GAME_INVENTORY_REGISTER"]}$SP" + - "${0xe034.toChar()} ${Lang["GAME_INVENTORY_DROP"]}" + "${getKeycapPC(App.getConfigInt("config_keydiscard"))} ${Lang["GAME_INVENTORY_DROP"]}" else "$gamepadLabelStart ${Lang["GAME_ACTION_CLOSE"]}$SP" + "$gamepadLabelLT ${Lang["CONTEXT_ITEM_MAP"]}$SP" + @@ -182,26 +206,7 @@ class UIInventoryFull( override fun renderUI(batch: SpriteBatch, camera: Camera) { - // background fill - batch.end() - gdxSetBlendNormal() - - - val gradTopStart = (App.scr.height - internalHeight).div(2).toFloat() - val gradBottomEnd = App.scr.height - gradTopStart - - shapeRenderer.inUse { - shapeRenderer.rect(0f, gradTopStart, App.scr.wf, gradHeight, gradStartCol, gradStartCol, gradEndCol, gradEndCol) - shapeRenderer.rect(0f, gradBottomEnd, App.scr.wf, -gradHeight, gradStartCol, gradStartCol, gradEndCol, gradEndCol) - - shapeRenderer.rect(0f, gradTopStart + gradHeight, App.scr.wf, internalHeight - (2 * gradHeight), gradEndCol, gradEndCol, gradEndCol, gradEndCol) - - shapeRenderer.rect(0f, 0f, App.scr.wf, gradTopStart, gradStartCol, gradStartCol, gradStartCol, gradStartCol) - shapeRenderer.rect(0f, App.scr.hf, App.scr.wf, -(App.scr.hf - gradBottomEnd), gradStartCol, gradStartCol, gradStartCol, gradStartCol) - } - - - batch.begin() + drawBackground(batch, shapeRenderer) // UI items catBar.render(batch, camera) diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt b/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt index 2f48c1ab5..e581efa0a 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt @@ -1,11 +1,14 @@ package net.torvald.terrarum.modulebasegame.ui -import com.badlogic.gdx.graphics.Camera -import com.badlogic.gdx.graphics.Color -import com.badlogic.gdx.graphics.Pixmap -import com.badlogic.gdx.graphics.Texture +import com.badlogic.gdx.Input +import com.badlogic.gdx.graphics.* import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.TextureRegion +import com.badlogic.gdx.graphics.glutils.FrameBuffer +import com.badlogic.gdx.graphics.glutils.ShaderProgram +import com.badlogic.gdx.graphics.glutils.ShapeRenderer +import net.torvald.getKeycapConsole +import net.torvald.getKeycapPC import net.torvald.terrarum.* import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.serialise.Common @@ -14,15 +17,13 @@ import net.torvald.terrarum.serialise.ReadMeta import net.torvald.terrarum.tvda.ByteArray64InputStream import net.torvald.terrarum.tvda.VDUtil import net.torvald.terrarum.tvda.VirtualDisk -import net.torvald.terrarum.ui.Toolkit -import net.torvald.terrarum.ui.UICanvas -import net.torvald.terrarum.ui.UIItem -import net.torvald.terrarum.ui.UIItemTextButton +import net.torvald.terrarum.ui.* import java.io.File import java.time.Instant import java.time.format.DateTimeFormatter import java.util.* import java.util.zip.GZIPInputStream +import kotlin.math.roundToInt /** * Created by minjaesong on 2021-09-09. @@ -37,6 +38,38 @@ class UILoadDemoSavefiles : UICanvas() { set(value) {} override var openCloseTime: Second = 0f + + private val shaderAlfamul = ShaderProgram(vert, frag) + + private val shapeRenderer = ShapeRenderer() + private val transparent = Color(1f,1f,1f,0f) + private val white = Color(1f, 1f, 1f, 1f) + + + private val uiWidth = UIItemDemoSaveCells.WIDTH // 480 + private val uiX = (width - uiWidth) / 2 + + private val textH = App.fontGame.lineHeight.toInt() + + private val cellGap = 24 + private val cellInterval = cellGap + UIItemDemoSaveCells.HEIGHT + private 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 + + + private val controlHelp: String + get() = if (App.environment == RunningEnvironment.PC) + "${getKeycapPC(App.getConfigInt("config_keyup"))}${getKeycapPC(App.getConfigInt("config_keydown"))}" + + " ${Lang["MENU_CONTROLS_SCROLL"]}" + else + "${getKeycapConsole('R')} ${Lang["MENU_CONTROLS_SCROLL"]}" + // read savegames init { File(App.defaultSaveDir).listFiles().map { file -> @@ -48,23 +81,139 @@ class UILoadDemoSavefiles : UICanvas() { null } }.filter { it != null }.sortedByDescending { (it as VirtualDisk).entries[0]!!.modificationDate }.forEachIndexed { index, disk -> - val x = (width - UIItemDemoSaveCells.WIDTH) / 2 - val y = 144 + (24 + UIItemDemoSaveCells.HEIGHT) * index + val x = uiX + val y = titleTopGradEnd + cellInterval * index addUIitem(UIItemDemoSaveCells(this, x, y, disk as VirtualDisk)) } } + private var scrollAreaHeight = height - 2 * App.scr.tvSafeGraphicsHeight - 64 + private var listScroll = 0 // only update when animation is finished + private var savesVisible = (scrollAreaHeight + cellGap) / cellInterval + + private var uiScroll = 0f + private var scrollFrom = 0 + private var scrollTarget = 0 + private var scrollAnimCounter = 0f + private val scrollAnimLen = 0.1f + + private var sliderFBO = FrameBuffer(Pixmap.Format.RGBA8888, uiWidth + 10, height, true) + private var sliderFBO2 = FrameBuffer(Pixmap.Format.RGBA8888, width, height, true) + override fun updateUI(delta: Float) { - uiItems.forEach { it.update(delta) } + + if (scrollTarget != listScroll) { + if (scrollAnimCounter < scrollAnimLen) { + scrollAnimCounter += delta + uiScroll = Movement.fastPullOut( + scrollAnimCounter / scrollAnimLen, + listScroll * cellInterval.toFloat(), + scrollTarget * cellInterval.toFloat() + ) + } + else { + scrollAnimCounter = 0f + listScroll = scrollTarget + uiScroll = cellInterval.toFloat() * scrollTarget + } + } + + + uiItems.forEachIndexed { index, it -> + if (index in listScroll - 2 until listScroll + savesVisible + 2) { + // re-position + it.posY = (it.initialY - uiScroll).roundToInt() + it.update(delta) + } + } } override fun renderUI(batch: SpriteBatch, camera: Camera) { - uiItems.forEach { it.render(batch, camera) } - val loadGameTitleStr = Lang["MENU_IO_LOAD_GAME"] - App.fontGame.draw(batch, loadGameTitleStr, (width - App.fontGame.getWidth(loadGameTitleStr)).div(2).toFloat(), 62f) + + + batch.end() + + lateinit var savePixmap: Pixmap + sliderFBO.inAction(camera as OrthographicCamera, batch) { + gdxClearAndSetBlend(0f,0f,0f,0f) + + setCameraPosition(batch, camera, 0f, 0f) + batch.color = Color.WHITE + batch.inUse { + uiItems.forEachIndexed { index, it -> + if (index in listScroll - 2 until listScroll + savesVisible + 2) { + it.render(batch, camera) + } + } + } + savePixmap = Pixmap.createFromFrameBuffer(0, 0, sliderFBO.width, sliderFBO.height) + savePixmap.blending = Pixmap.Blending.None + } + + + // implement "wipe-out" by CPU-rendering (*deep exhale*) + //savePixmap.setColor(1f,1f,1f,0f) + savePixmap.setColor(0f,0f,0f,0f) + savePixmap.fillRectangle(0, savePixmap.height - titleTopGradStart, savePixmap.width, titleTopGradStart) + // top grad + for (y in titleTopGradStart until titleTopGradEnd) { + val alpha = (y - titleTopGradStart).toFloat() / gradAreaHeight + for (x in 0 until savePixmap.width) { + val col = savePixmap.getPixel(x, savePixmap.height - y) + val blendAlpha = (col.and(0xFF) * alpha).roundToInt() + savePixmap.drawPixel(x, savePixmap.height - y, col.and(0xFFFFFF00.toInt()) or blendAlpha) + } + } + // bottom grad + for (y in titleBottomGradStart until titleBottomGradEnd) { + val alpha = 1f - ((y - titleBottomGradStart).toFloat() / gradAreaHeight) + for (x in 0 until savePixmap.width) { + val col = savePixmap.getPixel(x, savePixmap.height - y) + val blendAlpha = (col.and(0xFF) * alpha).roundToInt() + savePixmap.drawPixel(x, savePixmap.height - y, col.and(0xFFFFFF00.toInt()) or blendAlpha) + } + } + savePixmap.setColor(0f,0f,0f,0f) + savePixmap.fillRectangle(0, 0, savePixmap.width, height - titleBottomGradEnd + 1) + + + + setCameraPosition(batch, camera, 0f, 0f) + val saveTex = Texture(savePixmap) + batch.inUse { + batch.draw(saveTex, (width - uiWidth - 10) / 2f, 0f) + + // draw texts + val loadGameTitleStr = Lang["MENU_IO_LOAD_GAME"] + App.fontGame.draw(batch, loadGameTitleStr, (width - App.fontGame.getWidth(loadGameTitleStr)).div(2).toFloat(), titleTextPosY.toFloat()) + App.fontGame.draw(batch, controlHelp, uiX.toFloat(), controlHelperY.toFloat()) + } + + saveTex.dispose() + savePixmap.dispose() + + batch.begin() } + + override fun keyDown(keycode: Int): Boolean { + if (this.isVisible) { + if ((keycode == Input.Keys.UP || keycode == App.getConfigInt("config_keyup")) && scrollTarget > 0) { + scrollFrom = listScroll + scrollTarget -= 1 + scrollAnimCounter = 0f + } + else if ((keycode == Input.Keys.DOWN || keycode == App.getConfigInt("config_keydown")) && scrollTarget < uiItems.size - savesVisible) { + scrollFrom = listScroll + scrollTarget += 1 + scrollAnimCounter = 0f + } + } + return true + } + + override fun doOpening(delta: Float) { } @@ -75,9 +224,80 @@ class UILoadDemoSavefiles : UICanvas() { } override fun endClosing(delta: Float) { + listScroll = 0 + scrollTarget = 0 + uiScroll = 0f } - override fun dispose() {} + override fun dispose() { + shapeRenderer.dispose() + sliderFBO.dispose() + sliderFBO2.dispose() + shaderAlfamul.dispose() + } + + override fun resize(width: Int, height: Int) { + super.resize(width, height) + scrollAreaHeight = height - 2 * App.scr.tvSafeGraphicsHeight - 64 + savesVisible = (scrollAreaHeight + cellInterval) / (cellInterval + UIItemDemoSaveCells.HEIGHT) + + listScroll = 0 + scrollTarget = 0 + uiScroll = 0f + + sliderFBO.dispose() + sliderFBO = FrameBuffer(Pixmap.Format.RGBA8888, uiWidth + 10, height, true) + + sliderFBO2.dispose() + sliderFBO2 = FrameBuffer(Pixmap.Format.RGBA8888, width, height, true) + } + + private fun setCameraPosition(batch: SpriteBatch, camera: Camera, newX: Float, newY: Float) { + camera.position.set((-newX + App.scr.halfw).round(), (-newY + App.scr.halfh).round(), 0f) + camera.update() + batch.projectionMatrix = camera.combined + } + + companion object { + private val vert = """ +attribute vec4 a_position; +attribute vec4 a_color; +attribute vec2 a_texCoord0; + +uniform mat4 u_projTrans; // camera.combined + +varying vec4 v_color; +varying vec2 v_texCoords; + +void main() { + v_color = a_color; + v_texCoords = a_texCoord0; + gl_Position = u_projTrans * a_position; +} + """.trimIndent() + + private val frag = """ +#version 120 +#ifdef GL_ES + precision mediump float; +#endif + + +varying vec4 v_color; +varying vec2 v_texCoords; +uniform sampler2D u_texture; + +uniform sampler2D tex1; + +void main(void) { + vec4 colorTex0 = texture2D(u_texture, v_texCoords); // dest + vec4 colorTex1 = texture2D(tex1, v_texCoords); // src mask; must be (1,1,1,a) + +// gl_FragColor = colorTex0 * colorTex1; + gl_FragColor = colorTex1.aaar; +} + """.trimIndent() + } } class UIItemDemoSaveCells( @@ -88,7 +308,7 @@ class UIItemDemoSaveCells( companion object { const val WIDTH = 480 - const val HEIGHT = 160 + const val HEIGHT = 120 } override val width: Int = WIDTH @@ -100,9 +320,6 @@ class UIItemDemoSaveCells( private val meta = ReadMeta(disk) - private val x = initialX.toFloat() - private val y = initialY.toFloat() - private fun parseDuration(seconds: Long): String { val s = seconds % 60 val m = (seconds / 60) % 60 @@ -130,7 +347,7 @@ class UIItemDemoSaveCells( val thumbTex = Texture(thumbPixmap) thumbTex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) thumb = TextureRegion(thumbTex) - thumb.setRegion(0, thumbTex.height / 4, thumbTex.width, thumbTex.height / 2) + thumb.setRegion(0, (thumbTex.height - 2 * height) / 2, width * 2, height * 2) } catch (e: NullPointerException) { // use stock texture @@ -145,11 +362,13 @@ class UIItemDemoSaveCells( override fun render(batch: SpriteBatch, camera: Camera) { val highlightCol = if (mouseUp) UIItemTextButton.defaultActiveCol else Color.WHITE + val x = posX.toFloat() + val y = posY.toFloat() // TODO draw border batch.color = highlightCol - Toolkit.drawBoxBorder(batch, x.toInt()-1, y.toInt()-1, width+2, height+2) + Toolkit.drawBoxBorder(batch, posX-1, posY-1, width+2, height+2) // draw thumbnail batch.color = Color.WHITE @@ -157,14 +376,14 @@ class UIItemDemoSaveCells( batch.draw(thumb, x, y + height, width.toFloat(), -height.toFloat()) // draw gradient blendMul(batch) - batch.draw(grad, x + width, y, -width.toFloat(), height.toFloat()) + batch.draw(grad, x + width.toFloat(), y, -width.toFloat(), height.toFloat()) // draw texts batch.color = highlightCol // draw timestamp blendNormal(batch) val tlen = App.fontSmallNumbers.getWidth(lastPlayedTimestamp) - App.fontSmallNumbers.draw(batch, lastPlayedTimestamp, posX + (width - tlen) - 3f, posY + height - 16f) + App.fontSmallNumbers.draw(batch, lastPlayedTimestamp, x + (width - tlen) - 3f, y + height - 16f) // draw savegame name // App.fontGame.draw(batch, disk.getDiskNameString(Common.CHARSET), posX + 3f, posY + 1f) diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIScreenZoom.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIScreenZoom.kt index 5aac168f5..1b13819b6 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIScreenZoom.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIScreenZoom.kt @@ -4,10 +4,10 @@ import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch import net.torvald.EMDASH +import net.torvald.getKeycapPC import net.torvald.terrarum.App import net.torvald.terrarum.Terrarum import net.torvald.terrarum.TerrarumScreenSize -import net.torvald.terrarum.keyToIcon import net.torvald.terrarum.ui.Movement import net.torvald.terrarum.ui.UICanvas @@ -20,7 +20,7 @@ class UIScreenZoom : UICanvas( App.getConfigInt("config_keyzoom") ) { - val zoomText = "${keyToIcon(handler.toggleKeyLiteral!!)} $EMDASH Zoom Out" + val zoomText = "${getKeycapPC(handler.toggleKeyLiteral!!)} $EMDASH Zoom Out" override var width = App.fontGame.getWidth(zoomText) override var height = App.fontGame.lineHeight.toInt()