save load screen

This commit is contained in:
minjaesong
2021-09-12 22:47:31 +09:00
parent cdf82270dc
commit b99d1a760e
10 changed files with 296 additions and 137 deletions

View File

@@ -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")
}

View File

@@ -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();

View File

@@ -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()}"

View File

@@ -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,

View File

@@ -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 //

View File

@@ -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 {

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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()