diff --git a/src/net/torvald/terrarum/IngameInstance.kt b/src/net/torvald/terrarum/IngameInstance.kt index bfcb67404..c74a1ee3f 100644 --- a/src/net/torvald/terrarum/IngameInstance.kt +++ b/src/net/torvald/terrarum/IngameInstance.kt @@ -194,7 +194,22 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo gameInitialised = true } - override fun render(updateRate: Float) { + private var prerenderCalled = false + + open fun preRender() { + + } + + final override fun render(updateRate: Float) { + if (!prerenderCalled) { + preRender() + prerenderCalled = true + } + + renderImpl(updateRate) + } + + open fun renderImpl(updateRate: Float) { } diff --git a/src/net/torvald/terrarum/NoModuleDefaultTitlescreen.kt b/src/net/torvald/terrarum/NoModuleDefaultTitlescreen.kt index 4e42bf805..dbb12170c 100644 --- a/src/net/torvald/terrarum/NoModuleDefaultTitlescreen.kt +++ b/src/net/torvald/terrarum/NoModuleDefaultTitlescreen.kt @@ -57,8 +57,8 @@ class NoModuleDefaultTitlescreen(batch: FlippingSpriteBatch) : IngameInstance(ba App.setConfig("screenmagnifyingfilter", "bilinear") } - override fun render(updateRate: Float) { - super.render(updateRate) + override fun renderImpl(updateRate: Float) { + super.renderImpl(updateRate) gdxClearAndEnableBlend(0f, 0f, 0f, 0f) diff --git a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt index a9a24e749..d31d0a7ca 100644 --- a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt +++ b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt @@ -305,10 +305,10 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { private var disableMouseClick = false var mousePrimaryJustDown = false; private set - override fun render(updateRate: Float) { + override fun renderImpl(updateRate: Float) { IngameRenderer.setRenderedWorld(gameWorld) - super.render(updateRate) + super.renderImpl(updateRate) diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index c3bb7ab0a..b155f16eb 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -820,7 +820,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { internal var autosaveTimer: Second = 0f - override fun render(updateRate: Float) { + override fun renderImpl(updateRate: Float) { // Q&D solution for LoadScreen and Ingame, where while LoadScreen is working, Ingame now no longer has GL Context // there's still things to load which needs GL context to be present if (!gameFullyLoaded) { @@ -848,7 +848,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { IngameRenderer.setRenderedWorld(world) // this doesn't slow down the game and prevents world-changing related bugs } - super.render(updateRate) + super.renderImpl(updateRate) ingameController.update() diff --git a/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt b/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt index fae83d629..e042e40d0 100644 --- a/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt +++ b/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt @@ -310,10 +310,10 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) { private val introUncoverTime: Second = 0.3f private var introUncoverDeltaCounter = 0f - override fun render(updateRate: Float) { + override fun renderImpl(updateRate: Float) { IngameRenderer.setRenderedWorld(demoWorld) - super.render(updateRate) + super.renderImpl(updateRate) // async update and render gameUpdateGovernor.update(Gdx.graphics.deltaTime, App.UPDATE_RATE, updateScreen, renderScreen) } diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIProxyNewBTeXTest.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIProxyNewBTeXTest.kt new file mode 100644 index 000000000..c84c1b2ef --- /dev/null +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIProxyNewBTeXTest.kt @@ -0,0 +1,250 @@ +package net.torvald.terrarum.modulebasegame.ui + +import com.badlogic.gdx.ApplicationAdapter +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.Input +import com.badlogic.gdx.InputAdapter +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.graphics.OrthographicCamera +import com.badlogic.gdx.graphics.Texture +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import com.badlogic.gdx.graphics.g2d.TextureRegion +import net.torvald.btex.BTeXDocViewer +import net.torvald.btex.BTeXParser +import net.torvald.terrarum.* +import net.torvald.terrarum.btex.BTeXDocument +import net.torvald.terrarum.imagefont.TinyAlphNum +import net.torvald.terrarum.langpack.Lang +import net.torvald.terrarum.ui.Toolkit +import net.torvald.terrarum.ui.UICanvas +import net.torvald.unicode.EMDASH +import java.util.concurrent.atomic.AtomicInteger +import java.util.concurrent.atomic.AtomicReference +import kotlin.system.measureTimeMillis + +/** + * Created by minjaesong on 2024-05-22. + */ +class UIProxyBTeXTest(val remoCon: UIRemoCon) : UICanvas() { + override var width: Int = 0 + override var height: Int = 0 + override var openCloseTime: Second = 0f + + override fun updateImpl(delta: Float) { + } + + override fun renderImpl(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) { + } + + override fun doOpening(delta: Float) { + } + + override fun doClosing(delta: Float) { + } + + override fun endOpening(delta: Float) { + val ingame = BTeXTest(App.batch) + + Terrarum.setCurrentIngameInstance(ingame) + SanicLoadScreen.screenToLoad = ingame + App.setLoadScreen(SanicLoadScreen) + } + + override fun endClosing(delta: Float) { + } + + override fun dispose() { + } +} + + +/** + * Created by minjaesong on 2023-10-28. + */ +class BTeXTest(batch: FlippingSpriteBatch) : IngameInstance(batch) { + + // val filePath = "btex.xml" +// val filePath = "btex_ko.xml" + val filePath = "test.xml" +// val filePath = "literature/en/daniel_defoe_robinson_crusoe.xml" +// val filePath = "literature/ruRU/anton_chekhov_palata_no_6.xml" +// val filePath = "literature/koKR/yisang_nalgae.xml" +// val filePath = "literature/koKR/yisang_geonchukmuhanyukmyeongakche.xml" + + + private lateinit var document: BTeXDocument + private lateinit var documentHandler: BTeXParser.BTeXHandler + private lateinit var camera: OrthographicCamera + + private lateinit var bg: TextureRegion + + private val varMap = hashMapOf( + "terrarumver" to "Alpha 1.3", + "bucks" to "121687" + ) + + private val errorInfo = AtomicReference().also { + it.set(null) + } + + private val typesetProgress = AtomicInteger(0) + private val renderProgress = AtomicInteger(0) + + override fun preRender() { + Lang + TinyAlphNum + Toolkit + BTeXParser.BTeXHandler.preloadFonts() + + camera = OrthographicCamera(1280f, 720f) + camera.setToOrtho(true) // some elements are pre-flipped, while some are not. The statement itself is absolutely necessary to make edge of the screen as the origin + camera.update() + batch.projectionMatrix = camera.combined + + bg = TextureRegion(Texture(Gdx.files.internal("test_assets/real_bg_with_guides.png"))) + + val isBookFinalised = filePath.endsWith(".btxbook") + + if (!isBookFinalised) { + Thread { + try { + measureTimeMillis { + val f = BTeXParser.invoke(Gdx.files.internal("./assets/mods/basegame/books/$filePath"), varMap, typesetProgress) + document = f.first + documentHandler = f.second + }.also { + println("Time spent on typesetting [ms]: $it") + } + + measureTimeMillis { + document.finalise(renderProgress, true) + }.also { + println("Time spent on finalising [ms]: $it") + } + + /*measureTimeMillis { + document.serialise(File("./assets/mods/basegame/books/${filePath.replace(".xml", ".btxbook")}")) + }.also { + println("Time spent on serialisation [ms]: $it") + }*/ + } + catch (e: Throwable) { + errorInfo.set(e) + e.printStackTrace() + } + }.start() + } + else { + measureTimeMillis { + document = BTeXDocument.fromFile(Gdx.files.internal("./assets/mods/basegame/books/$filePath")) + }.also { + println("Time spent on loading [ms]: $it") + } + } + + + Gdx.input.inputProcessor = object : InputAdapter() { + override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { + if (::viewer.isInitialized) + viewer.touchDown(screenX, screenY, pointer, button) + return true + } + + override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { + if (::viewer.isInitialized) + viewer.touchUp(screenX, screenY, pointer, button) + return true + } + } + } + + var init = false + private lateinit var viewer: BTeXDocViewer + + private val drawY = 24 + + private fun drawLoadingMsg(batch: SpriteBatch, stage: String) { + val e = errorInfo.get() + if (e != null) { + val st = e.message!!.split('\n').let { + val idx = it.indexOfFirst { it.startsWith("Caused by: ") } + it.subList(idx, it.size) + } + val th = 14 * st.size + val tw = st.maxOf { it.length } * 7 + + val tx = (1280 - tw) / 2 + val ty = (720 - th) / 2 + + batch.color = Color.CORAL + st.forEachIndexed { i, s -> + TinyAlphNum.draw(batch, s, tx.toFloat(), ty + 14f*i) + } + } + else { + batch.color = Color.WHITE + Toolkit.drawTextCentered(batch, TinyAlphNum, stage, 1280, 0, 354) + + if (stage.lowercase().startsWith("typesetting")) { + val pgCnt = typesetProgress.get() + Toolkit.drawTextCentered(batch, TinyAlphNum, "Pages: $pgCnt", 1280, 0, 375) + } + else if (stage.lowercase().startsWith("rendering")) { + val pgCnt = document.pages.size + val renderCnt = renderProgress.get() + Toolkit.drawTextCentered(batch, TinyAlphNum, "Pages: $renderCnt/$pgCnt", 1280, 0, 375) + } + } + } + + override fun renderImpl(updateRate: Float) { + Gdx.graphics.setTitle("BTeXTest $EMDASH F: ${Gdx.graphics.framesPerSecond}") + + gdxClearAndEnableBlend(.063f, .070f, .086f, 1f) + + + if (::document.isInitialized) { + if (!init) { + init = true + viewer = BTeXDocViewer(document) + } + else { + if (document.isFinalised || document.fromArchive) { + batch.inUse { + batch.draw(bg, 0f, 0f) + viewer.render(batch, 640f, drawY.toFloat()) + + batch.color = Color.WHITE + val pageText = "${viewer.currentPageStr()}/${viewer.pageCount}" + Toolkit.drawTextCentered( + batch, TinyAlphNum, pageText, + 1280, 0, drawY + document.pageDimensionHeight + 12 + ) + } + } + else { + batch.inUse { + drawLoadingMsg(batch, "Rendering...") + } + } + + // control + if (Gdx.input.isKeyJustPressed(Input.Keys.LEFT)) + viewer.prevPage() + else if (Gdx.input.isKeyJustPressed(Input.Keys.RIGHT)) + viewer.nextPage() + else if (Gdx.input.isKeyJustPressed(Input.Keys.PAGE_UP)) + viewer.gotoFirstPage() + else if (Gdx.input.isKeyJustPressed(Input.Keys.PAGE_DOWN)) + viewer.gotoLastPage() + } + } + else { + batch.inUse { + drawLoadingMsg(batch, "Typesetting...") + } + } + } + + +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UITitleRemoConYaml.kt b/src/net/torvald/terrarum/modulebasegame/ui/UITitleRemoConYaml.kt index 88250d8bf..dc6a8cd24 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UITitleRemoConYaml.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UITitleRemoConYaml.kt @@ -34,6 +34,7 @@ object UITitleRemoConYaml { """ val menuBaseDev = """ +- MENU_MODE_BTEXTYPESETTER : net.torvald.terrarum.modulebasegame.ui.UIProxyBTeXTest - MENU_MODE_BUILDINGMAKER : net.torvald.terrarum.modulebasegame.ui.UIProxyNewBuildingMaker """ + menuBase