new module info ui

This commit is contained in:
minjaesong
2021-12-12 16:25:42 +09:00
parent e5b4e76d39
commit b0d648547b
5 changed files with 291 additions and 100 deletions

Binary file not shown.

View File

@@ -23,7 +23,7 @@ uniform sampler2D u_texture;
uniform sampler2D u_pattern; uniform sampler2D u_pattern;
uniform ivec2 rnd = ivec2(0,0); uniform ivec2 rnd = ivec2(0,0);
float quant = 127.0; // 64 steps -> 63.0; 256 steps -> 255.0 float quant = 255.0; // 64 steps -> 63.0; 256 steps -> 255.0
vec4 quantiser = vec4(quant); vec4 quantiser = vec4(quant);
vec4 quantiserDivider = vec4(1.0 / quant); vec4 quantiserDivider = vec4(1.0 / quant);

View File

@@ -83,6 +83,7 @@ object ModMgr {
/** Module name (directory name), ModuleMetadata */ /** Module name (directory name), ModuleMetadata */
val moduleInfo = HashMap<String, ModuleMetadata>() val moduleInfo = HashMap<String, ModuleMetadata>()
val moduleInfoErrored = HashMap<String, ModuleMetadata>()
val entryPointClasses = ArrayList<ModuleEntryPoint>() val entryPointClasses = ArrayList<ModuleEntryPoint>()
val moduleClassloader = HashMap<String, URLClassLoader>() val moduleClassloader = HashMap<String, URLClassLoader>()
@@ -169,7 +170,7 @@ object ModMgr {
logError(LoadErrorType.YOUR_FAULT, moduleName, e) logError(LoadErrorType.YOUR_FAULT, moduleName, e)
moduleInfo.remove(moduleName) moduleInfo.remove(moduleName)?.let { moduleInfoErrored[moduleName] = it }
} }
if (newClass != null) { if (newClass != null) {
@@ -182,7 +183,7 @@ object ModMgr {
printdbg(this, "$moduleName loaded successfully") printdbg(this, "$moduleName loaded successfully")
} }
else { else {
moduleInfo.remove(moduleName) moduleInfo.remove(moduleName)?.let { moduleInfoErrored[moduleName] = it }
printdbg(this, "$moduleName did not load...") printdbg(this, "$moduleName did not load...")
} }
@@ -195,7 +196,7 @@ object ModMgr {
logError(LoadErrorType.NOT_EVEN_THERE, moduleName) logError(LoadErrorType.NOT_EVEN_THERE, moduleName)
moduleInfo.remove(moduleName) moduleInfo.remove(moduleName)?.let { moduleInfoErrored[moduleName] = it }
} }
catch (e: Throwable) { catch (e: Throwable) {
printdbgerr(this, "There was an error while loading module $moduleName") printdbgerr(this, "There was an error while loading module $moduleName")
@@ -204,7 +205,7 @@ object ModMgr {
logError(LoadErrorType.YOUR_FAULT, moduleName, e) logError(LoadErrorType.YOUR_FAULT, moduleName, e)
moduleInfo.remove(moduleName) moduleInfo.remove(moduleName)?.let { moduleInfoErrored[moduleName] = it }
} }
finally { finally {

View File

@@ -1,72 +1,235 @@
package net.torvald.terrarum.modulebasegame.ui package net.torvald.terrarum.modulebasegame.ui
import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.Input
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.*
import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.App import com.badlogic.gdx.graphics.glutils.FrameBuffer
import net.torvald.terrarum.ModMgr import com.badlogic.gdx.graphics.glutils.ShapeRenderer
import net.torvald.terrarum.Second import net.torvald.getKeycapConsole
import net.torvald.terrarum.blendNormal import net.torvald.getKeycapPC
import net.torvald.terrarum.*
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.ui.Movement
import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.ui.UICanvas
import net.torvald.terrarum.ui.UIItemList
import net.torvald.terrarum.ui.UIItemModuleInfoCell import net.torvald.terrarum.ui.UIItemModuleInfoCell
import kotlin.math.roundToInt
val MODULEINFO_CELL_WIDTH = 480
val MODULEINFO_CELL_HEIGHT = 48
/** /**
* Created by minjaesong on 2017-08-01. * Created by minjaesong on 2017-08-01.
*/ */
class UITitleModules(val remoCon: UIRemoCon) : UICanvas() { class UITitleModules(val remoCon: UIRemoCon) : UICanvas() {
override var width: Int
get() = Toolkit.drawWidth
set(value) {}
override var height: Int
get() = App.scr.height
set(value) {}
override var openCloseTime: Second = 0f override var openCloseTime: Second = 0f
private val moduleAreaHMargin = 48
private val moduleAreaBorder = 8
override var width = 600//App.scr.width - UIRemoCon.remoConWidth - moduleAreaHMargin private val shapeRenderer = ShapeRenderer()
override var height = App.scr.height - moduleAreaHMargin * 2
private val moduleInfoCells = ArrayList<UIItemModuleInfoCell>() internal val uiWidth = MODULEINFO_CELL_WIDTH
// build module list internal val uiX = (width - uiWidth) / 2
internal val textH = App.fontGame.lineHeight.toInt()
internal val cellGap = 20
internal val cellInterval = cellGap + MODULEINFO_CELL_HEIGHT
internal val gradAreaHeight = 32
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
get() = if (App.environment == RunningEnvironment.PC)
"${getKeycapPC(App.getConfigInt("control_key_up"))}${getKeycapPC(App.getConfigInt("control_key_down"))}" +
" ${Lang["MENU_CONTROLS_SCROLL"]}"
else
"${getKeycapConsole('R')} ${Lang["MENU_CONTROLS_SCROLL"]}"
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 val moduleCells = ArrayList<UIItemModuleInfoCell>()
private var showSpinner = false
init { init {
ModMgr.moduleInfo.toList().sortedBy { it.second.order }.forEachIndexed { index, it -> try {
moduleInfoCells.add(UIItemModuleInfoCell( // read savegames
this, var savegamesCount = 0
it.first, ModMgr.loadOrder.forEachIndexed { index, s ->
width - 2 * moduleAreaBorder, val x = uiX + if (App.getConfigBoolean("fx_streamerslayout")) App.scr.chatWidth / 2 else 0
0, 0 // placeholder val y = titleTopGradEnd + cellInterval * savegamesCount
)) try {
moduleCells.add(UIItemModuleInfoCell(this, index, x, y))
savegamesCount += 1
}
catch (e: Throwable) {
System.err.println("[UILoadDemoSavefiles] Error while loading module info for '$s'")
e.printStackTrace()
}
}
} }
} catch (e: UninitializedPropertyAccessException) {}
private val moduleArea = UIItemList<UIItemModuleInfoCell>(
this,
moduleInfoCells,
(App.scr.width - this.width) / 2, moduleAreaHMargin,
width,
height,
inactiveCol = Color.WHITE,
border = moduleAreaBorder
)
init {
uiItems.add(moduleArea)
} }
override fun updateUI(delta: Float) { override fun updateUI(delta: Float) {
moduleArea.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
}
}
for (index in 0 until moduleCells.size) {
val it = moduleCells[index]
if (index in listScroll - 2 until listScroll + savesVisible + 2) {
// re-position
it.posY = (it.initialY - uiScroll).roundToInt()
it.update(delta)
}
}
}
override fun hide() {
moduleCells.forEach { it.dispose() }
moduleCells.clear()
} }
override fun renderUI(batch: SpriteBatch, camera: Camera) { override fun renderUI(batch: SpriteBatch, camera: Camera) {
batch.color = Color.WHITE batch.end()
blendNormal(batch)
Toolkit.drawBoxBorder(batch, moduleArea.posX, moduleArea.posY, width, height) lateinit var savePixmap: Pixmap
moduleArea.render(batch, camera) sliderFBO.inAction(camera as OrthographicCamera, batch) {
gdxClearAndSetBlend(0f, 0f, 0f, 0f)
setCameraPosition(batch, camera, 0f, 0f)
batch.color = Color.WHITE
batch.inUse {
for (index in 0 until moduleCells.size) {
val it = moduleCells[index]
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.color = Color.WHITE
batch.draw(saveTex, (width - uiWidth - 10) / 2f, 0f)
// draw texts
val loadGameTitleStr = Lang["MENU_MODULES"]// + "$EMDASH$hash"
// "Game Load"
App.fontUITitle.draw(batch, loadGameTitleStr, (width - App.fontGame.getWidth(loadGameTitleStr)).div(2).toFloat(), titleTextPosY.toFloat())
// Control help
App.fontGame.draw(batch, controlHelp, uiX.toFloat(), controlHelperY.toFloat())
}
saveTex.dispose()
savePixmap.dispose()
batch.begin()
} }
override fun doOpening(delta: Float) { override fun keyDown(keycode: Int): Boolean {
if (this.isVisible) {
if ((keycode == Input.Keys.UP || keycode == App.getConfigInt("control_key_up")) && scrollTarget > 0) {
scrollFrom = listScroll
scrollTarget -= 1
scrollAnimCounter = 0f
}
else if ((keycode == Input.Keys.DOWN || keycode == App.getConfigInt("control_key_down")) && scrollTarget < moduleCells.size - savesVisible) {
scrollFrom = listScroll
scrollTarget += 1
scrollAnimCounter = 0f
}
}
return true
}
override fun scrolled(amountX: Float, amountY: Float): Boolean {
if (this.isVisible) {
if (amountY <= -1f && scrollTarget > 0) {
scrollFrom = listScroll
scrollTarget -= 1
scrollAnimCounter = 0f
}
else if (amountY >= 1f && scrollTarget < moduleCells.size - savesVisible) {
scrollFrom = listScroll
scrollTarget += 1
scrollAnimCounter = 0f
}
}
return true
}
override fun doOpening(delta: Float) {
} }
override fun doClosing(delta: Float) { override fun doClosing(delta: Float) {
@@ -76,9 +239,32 @@ class UITitleModules(val remoCon: UIRemoCon) : UICanvas() {
} }
override fun endClosing(delta: Float) { override fun endClosing(delta: Float) {
listScroll = 0
scrollTarget = 0
uiScroll = 0f
} }
override fun dispose() { override fun dispose() {
try { shapeRenderer.dispose() } catch (e: IllegalArgumentException) {}
try { sliderFBO.dispose() } catch (e: IllegalArgumentException) {}
} }
override fun resize(width: Int, height: Int) {
super.resize(width, height)
scrollAreaHeight = height - 2 * App.scr.tvSafeGraphicsHeight - 64
savesVisible = (scrollAreaHeight + cellInterval) / (cellInterval + MODULEINFO_CELL_HEIGHT)
listScroll = 0
scrollTarget = 0
uiScroll = 0f
sliderFBO.dispose()
sliderFBO = FrameBuffer(Pixmap.Format.RGBA8888, uiWidth + 10, 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
}
} }

View File

@@ -2,83 +2,84 @@ package net.torvald.terrarum.ui
import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.terrarum.App import net.torvald.terrarum.App
import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.ModMgr import net.torvald.terrarum.ModMgr
import net.torvald.terrarum.blendNormal import net.torvald.terrarum.blendNormal
import net.torvald.terrarum.floor import net.torvald.terrarum.modulebasegame.ui.MODULEINFO_CELL_HEIGHT
import net.torvald.terrarum.modulebasegame.ui.MODULEINFO_CELL_WIDTH
class UIItemModuleInfoCell( class UIItemModuleInfoCell(
parent: UICanvas, parent: UICanvas,
var moduleName: String, var order: Int,
override val width: Int,
initialX: Int, initialX: Int,
initialY: Int initialY: Int
) : UIItem(parent, initialX, initialY) { ) : UIItem(parent, initialX, initialY) {
override val height: Int = App.fontGame.lineHeight.toInt() * 2 override val width = MODULEINFO_CELL_WIDTH
override val height = MODULEINFO_CELL_HEIGHT
private val numberAreaWidth = App.fontSmallNumbers.W * 3 + 4 private val modName = ModMgr.loadOrder[order]
private val modProp = ModMgr.moduleInfo[modName] ?: ModMgr.moduleInfoErrored[modName]!!
private val modErrored = (ModMgr.moduleInfo[modName] == null)
private val modIcon = TextureRegion(Texture(modProp.iconFile))
private val modVer = modProp.version
private val modDate = modProp.releaseDate
private val modAuthor = modProp.author
init {
modIcon.flip(false, true)
CommonResourcePool.addToLoadingList("basegame_errored_icon32") {
val t = TextureRegion(Texture(ModMgr.getGdxFile("basegame", "gui/modwitherror.tga")))
t.flip(false, true)
t
}
CommonResourcePool.loadAll()
}
private val ccZero = App.fontGame.toColorCode(15,15,15)
private val ccZero2 = App.fontGame.toColorCode(12,12,12)
private val ccNum = App.fontGame.toColorCode(15,14,6)
private val ccNum2 = App.fontGame.toColorCode(12,11,4)
override fun render(batch: SpriteBatch, camera: Camera) { override fun render(batch: SpriteBatch, camera: Camera) {
blendNormal(batch) blendNormal(batch)
if (ModMgr.moduleInfo.containsKey(moduleName)) { batch.color = Toolkit.Theme.COL_CELL_FILL
val modInfo = ModMgr.moduleInfo[moduleName]!! Toolkit.fillArea(batch, initialX, initialY, 32, 48)
Toolkit.fillArea(batch, initialX + 35, initialY, 48, 48)
Toolkit.fillArea(batch, initialX + 86, initialY, width - 86, 48)
// print load order index batch.color = Toolkit.Theme.COL_INACTIVE
batch.color = Color(0xccccccff.toInt()) Toolkit.drawBoxBorder(batch, initialX - 1, initialY - 1, width + 2, height + 2)
var strlen = App.fontSmallNumbers.getWidth(modInfo.order.toString()) Toolkit.fillArea(batch, initialX + 33, initialY, 1, 48)
App.fontSmallNumbers.draw(batch, Toolkit.fillArea(batch, initialX + 84, initialY, 1, 48)
modInfo.order.toString(),
posX + (numberAreaWidth - strlen).div(2f).floor(),
posY + (height - App.fontSmallNumbers.H).div(2f).floor()
)
// print module name if (order < 9)
batch.color = Color.WHITE App.fontSmallNumbers.draw(batch, "${order+1}", initialX + 13f, initialY + 18f)
App.fontGame.draw(batch, else if (order < 99)
"${modInfo.properName} (${modInfo.version})", App.fontSmallNumbers.draw(batch, "${order+1}", initialX + 9f, initialY + 18f)
posX + numberAreaWidth.toFloat(), else
posY.toFloat() App.fontSmallNumbers.draw(batch, "${order+1}", initialX + 6f, initialY + 18f)
)
// print author name batch.color = Color.WHITE
strlen = App.fontGame.getWidth(modInfo.author) batch.draw(modIcon, initialX + 35f, initialY.toFloat())
App.fontGame.draw(batch, App.fontGame.draw(batch, "$ccZero${modName.toUpperCase()}$ccNum $modVer", initialX + 86f + 6f, initialY + 2f)
modInfo.author, App.fontGame.draw(batch, "$ccZero2$modAuthor$ccNum2 $modDate", initialX + 86f + 6f, initialY + 26f)
posX + width - strlen.toFloat(),
posY.toFloat()
)
// print description if (modErrored) {
App.fontGame.draw(batch, batch.draw(CommonResourcePool.getAsTextureRegion("basegame_errored_icon32"), initialX + width - 40f, initialY + 8f)
modInfo.description,
posX + numberAreaWidth.toFloat(),
posY + App.fontGame.lineHeight
)
// print releasedate
strlen = App.fontGame.getWidth(modInfo.releaseDate)
App.fontGame.draw(batch,
modInfo.releaseDate,
posX + width - strlen.toFloat(),
posY + App.fontGame.lineHeight
)
}
else {
batch.color = Color(0xff8080_ff.toInt())
val str = "InternalError: no such module: '$moduleName'"
val strlen = App.fontSmallNumbers.getWidth(str)
App.fontSmallNumbers.draw(batch,
str,
posX + (width - numberAreaWidth - strlen).div(2f).floor() + numberAreaWidth,
posY + (height - App.fontSmallNumbers.H).div(2f).floor()
)
} }
} }
override fun dispose() { override fun dispose() {
modIcon.texture.dispose()
} }
} }