From fc40ec48f1061ab71e02f11507b8d841ab148aad Mon Sep 17 00:00:00 2001 From: minjaesong Date: Wed, 8 Sep 2021 20:36:49 +0900 Subject: [PATCH] savegame to save with the thumbnail --- src/net/torvald/terrarum/PostProcessor.kt | 3 +- src/net/torvald/terrarum/TitleScreen.kt | 5 +- .../terrarum/console/ScreencapNogui.kt | 11 +- .../terrarum/modulebasegame/IngameRenderer.kt | 21 ++-- .../terrarum/modulebasegame/console/Save.kt | 8 +- .../terrarum/serialise/WriteSavegame.kt | 112 +++++++++++------- 6 files changed, 93 insertions(+), 67 deletions(-) diff --git a/src/net/torvald/terrarum/PostProcessor.kt b/src/net/torvald/terrarum/PostProcessor.kt index 4e78d2717..8460feeb9 100644 --- a/src/net/torvald/terrarum/PostProcessor.kt +++ b/src/net/torvald/terrarum/PostProcessor.kt @@ -14,7 +14,6 @@ import com.badlogic.gdx.math.Matrix4 import com.badlogic.gdx.utils.Disposable import net.torvald.terrarum.gamecontroller.KeyToggler import net.torvald.terrarum.ui.BasicDebugInfoWindow -import net.torvald.terrarum.worlddrawer.BlocksDrawer /** * Must be called by the App Loader @@ -216,7 +215,7 @@ object PostProcessor : Disposable { private val currentResStr = "${AppLoader.screenSize.screenW}x${AppLoader.screenSize.screenH}" private val safeAreaStr = "TV Safe Area" private val versionStr = "Version ${AppLoader.getVERSION_STRING()}" - private val thisIsDebugStr = "${AppLoader.GAME_NAME} Develoment Build $versionStr" + internal val thisIsDebugStr = "${AppLoader.GAME_NAME} Develoment Build $versionStr" /** * Camera will be moved so that (newX, newY) would be sit on the top-left edge. diff --git a/src/net/torvald/terrarum/TitleScreen.kt b/src/net/torvald/terrarum/TitleScreen.kt index fd0c592a6..2979f1a4e 100644 --- a/src/net/torvald/terrarum/TitleScreen.kt +++ b/src/net/torvald/terrarum/TitleScreen.kt @@ -285,10 +285,7 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) { ) } - AppLoader.fontGame.draw(batch, "${AppLoader.GAME_NAME} ${AppLoader.getVERSION_STRING()}", - 1f.toInt().toFloat(), - (AppLoader.screenSize.screenH - AppLoader.fontGame.lineHeight - 1f).toInt().toFloat() - ) + AppLoader.fontGame.draw(batch, PostProcessor.thisIsDebugStr, 5f, AppLoader.screenSize.screenH - 24f) } diff --git a/src/net/torvald/terrarum/console/ScreencapNogui.kt b/src/net/torvald/terrarum/console/ScreencapNogui.kt index 276f0ef56..bbf4ec665 100644 --- a/src/net/torvald/terrarum/console/ScreencapNogui.kt +++ b/src/net/torvald/terrarum/console/ScreencapNogui.kt @@ -1,5 +1,8 @@ package net.torvald.terrarum.console +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.graphics.Pixmap +import net.torvald.gdx.graphics.PixmapIO2 import net.torvald.terrarum.AppLoader import net.torvald.terrarum.ccG import net.torvald.terrarum.modulebasegame.IngameRenderer @@ -8,7 +11,13 @@ object ScreencapNogui: ConsoleCommand { override fun execute(args: Array) { if (args.size == 2) { - IngameRenderer.fboRGBexportPath = AppLoader.defaultDir + "/Exports/${args[1]}.tga" + IngameRenderer.fboRGBexportCallback = { + val w = 960 + val h = 640 + val p = Pixmap.createFromFrameBuffer((it.width - w).ushr(1), (it.height - h).ushr(1), w, h) + PixmapIO2.writeTGA(Gdx.files.absolute(AppLoader.defaultDir + "/Exports/${args[1]}.tga"), p, true) + p.dispose() + } IngameRenderer.fboRGBexportRequested = true Echo("FBO exported to$ccG Exports/${args[1]}.tga") } diff --git a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt index 78ee41c9e..2763644d3 100644 --- a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt +++ b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt @@ -8,23 +8,22 @@ 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.utils.Disposable -import com.badlogic.gdx.utils.ScreenUtils -import net.torvald.gdx.graphics.PixmapIO2 import net.torvald.terrarum.* import net.torvald.terrarum.AppLoader.measureDebugTime -import net.torvald.terrarum.AppLoader.printdbg import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.gamecontroller.KeyToggler +import net.torvald.terrarum.gameparticles.ParticleBase import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.gameworld.fmod -import net.torvald.terrarum.gameparticles.ParticleBase -import net.torvald.terrarum.weather.WeatherMixer import net.torvald.terrarum.ui.UICanvas -import net.torvald.terrarum.worlddrawer.* +import net.torvald.terrarum.weather.WeatherMixer +import net.torvald.terrarum.worlddrawer.BlocksDrawer +import net.torvald.terrarum.worlddrawer.FeaturesDrawer +import net.torvald.terrarum.worlddrawer.LightmapRenderer +import net.torvald.terrarum.worlddrawer.WorldCamera import net.torvald.util.CircularArray -import javax.swing.JFileChooser import kotlin.system.exitProcess /** @@ -335,11 +334,7 @@ object IngameRenderer : Disposable { if (fboRGBexportRequested) { fboRGBexportRequested = false try { - val w = 960 - val h = 640 - val p = Pixmap.createFromFrameBuffer((fboRGB.width - w).ushr(1), (fboRGB.height - h).ushr(1), w, h) - PixmapIO2.writeTGA(Gdx.files.absolute(fboRGBexportPath), p, true) - p.dispose() + fboRGBexportCallback(fboRGB) } catch (e: Throwable) { e.printStackTrace() @@ -383,7 +378,7 @@ object IngameRenderer : Disposable { } internal var fboRGBexportRequested = false - internal var fboRGBexportPath = "" + internal var fboRGBexportCallback: (FrameBuffer) -> Unit = {} private fun drawToRGB( actorsRenderBehind: List?, diff --git a/src/net/torvald/terrarum/modulebasegame/console/Save.kt b/src/net/torvald/terrarum/modulebasegame/console/Save.kt index 1eaf867cb..7a44c1b9f 100644 --- a/src/net/torvald/terrarum/modulebasegame/console/Save.kt +++ b/src/net/torvald/terrarum/modulebasegame/console/Save.kt @@ -1,6 +1,9 @@ package net.torvald.terrarum.modulebasegame.console -import net.torvald.terrarum.* +import net.torvald.terrarum.AppLoader +import net.torvald.terrarum.CommonResourcePool +import net.torvald.terrarum.ReferencingRanges +import net.torvald.terrarum.Terrarum import net.torvald.terrarum.console.ConsoleCommand import net.torvald.terrarum.console.Echo import net.torvald.terrarum.gameactors.Actor @@ -39,9 +42,8 @@ object Save : ConsoleCommand { val disk = VDUtil.createNewDisk(1L shl 60, savename, Common.CHARSET) val file = File(AppLoader.defaultDir + "/Exports/${args[1]}") - WriteSavegame(disk, file, ingame) - Echo ("${ccW}Saved with size of $ccG${file.length()}$ccW bytes") + } catch (e: IOException) { Echo("Save: IOException raised.") diff --git a/src/net/torvald/terrarum/serialise/WriteSavegame.kt b/src/net/torvald/terrarum/serialise/WriteSavegame.kt index 6c54a328d..f0629a264 100644 --- a/src/net/torvald/terrarum/serialise/WriteSavegame.kt +++ b/src/net/torvald/terrarum/serialise/WriteSavegame.kt @@ -1,10 +1,11 @@ package net.torvald.terrarum.serialise -import net.torvald.ELLIPSIS +import com.badlogic.gdx.graphics.Pixmap +import net.torvald.gdx.graphics.PixmapIO2 import net.torvald.terrarum.* import net.torvald.terrarum.AppLoader.printdbg import net.torvald.terrarum.console.Echo -import net.torvald.terrarum.gameactors.AVKey +import net.torvald.terrarum.modulebasegame.IngameRenderer import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.* @@ -13,6 +14,7 @@ import net.torvald.terrarum.serialise.Common.zip import net.torvald.terrarum.serialise.WriteWorld.actorAcceptable import java.io.File import java.io.Reader +import java.util.zip.GZIPOutputStream /** * It's your responsibility to create a new VirtualDisk if your save is new, and create a backup for modifying existing save. @@ -32,69 +34,91 @@ object WriteSavegame { } operator fun invoke(disk: VirtualDisk, outFile: File, ingame: TerrarumIngame) { - val creation_t = ingame.world.creationTime - val time_t = AppLoader.getTIME_T() - val currentPlayTime_t = time_t - ingame.loadedTime_t + val tgaout = ByteArray64GrowableOutputStream() + val gzout = GZIPOutputStream(tgaout) + IngameRenderer.fboRGBexportCallback = { + val w = 960 + val h = 640 + val p = Pixmap.createFromFrameBuffer((it.width - w).ushr(1), (it.height - h).ushr(1), w, h) + PixmapIO2._writeTGA(gzout, p, true, true) + p.dispose() + + + val creation_t = ingame.world.creationTime + val time_t = AppLoader.getTIME_T() + val currentPlayTime_t = time_t - ingame.loadedTime_t - // Write Meta // - val metaContent = EntryFile(WriteMeta.encodeToByteArray64(ingame, currentPlayTime_t)) - val meta = DiskEntry(-1, 0, "savegame".toByteArray(), creation_t, time_t, metaContent) - addFile(disk, meta) + // Write Meta // + val metaContent = EntryFile(WriteMeta.encodeToByteArray64(ingame, currentPlayTime_t)) + val meta = DiskEntry(-1, 0, "savegame".toByteArray(Common.CHARSET), creation_t, time_t, metaContent) + addFile(disk, meta) + + + val thumbContent = EntryFile(tgaout.toByteArray64()) + val thumb = DiskEntry(-2, 0, "thumb".toByteArray(Common.CHARSET), creation_t, time_t, thumbContent) + addFile(disk, thumb) + - // Write BlockCodex// + // Write BlockCodex// // val blockCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(BlockCodex).toByteArray(Common.CHARSET)))) -// val blocks = DiskEntry(-16, 0, "blocks".toByteArray(), creation_t, time_t, blockCodexContent) +// val blocks = DiskEntry(-16, 0, "blocks".toByteArray(Common.CHARSET), creation_t, time_t, blockCodexContent) // addFile(disk, blocks) - // Commented out; nothing to write + // Commented out; nothing to write - // Write ItemCodex// - val itemCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(ItemCodex).toByteArray(Common.CHARSET)))) - val items = DiskEntry(-17, 0, "items".toByteArray(), creation_t, time_t, itemCodexContent) - addFile(disk, items) - // Gotta save dynamicIDs + // Write ItemCodex// + val itemCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(ItemCodex).toByteArray(Common.CHARSET)))) + val items = DiskEntry(-17, 0, "items".toByteArray(Common.CHARSET), creation_t, time_t, itemCodexContent) + addFile(disk, items) + // Gotta save dynamicIDs - // Write WireCodex// + // Write WireCodex// // val wireCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(WireCodex).toByteArray(Common.CHARSET)))) -// val wires = DiskEntry(-18, 0, "wires".toByteArray(), creation_t, time_t, wireCodexContent) +// val wires = DiskEntry(-18, 0, "wires".toByteArray(Common.CHARSET), creation_t, time_t, wireCodexContent) // addFile(disk, wires) - // Commented out; nothing to write + // Commented out; nothing to write - // Write MaterialCodex// + // Write MaterialCodex// // val materialCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(MaterialCodex).toByteArray(Common.CHARSET)))) -// val materials = DiskEntry(-19, 0, "materials".toByteArray(), creation_t, time_t, materialCodexContent) +// val materials = DiskEntry(-19, 0, "materials".toByteArray(Common.CHARSET), creation_t, time_t, materialCodexContent) // addFile(disk, materials) - // Commented out; nothing to write + // Commented out; nothing to write - // Write FactionCodex// + // Write FactionCodex// // val factionCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(FactionCodex).toByteArray(Common.CHARSET)))) -// val factions = DiskEntry(-20, 0, "factions".toByteArray(), creation_t, time_t, factionCodexContent) +// val factions = DiskEntry(-20, 0, "factions".toByteArray(Common.CHARSET), creation_t, time_t, factionCodexContent) // addFile(disk, factions) - // Write Apocryphas// - val apocryphasContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(Apocryphas).toByteArray(Common.CHARSET)))) - val apocryphas = DiskEntry(-1024, 0, "modprops".toByteArray(), creation_t, time_t, apocryphasContent) - addFile(disk, apocryphas) + // Write Apocryphas// + val apocryphasContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(Apocryphas).toByteArray(Common.CHARSET)))) + val apocryphas = DiskEntry(-1024, 0, "modprops".toByteArray(Common.CHARSET), creation_t, time_t, apocryphasContent) + addFile(disk, apocryphas) - // Write World // - val worldNum = ingame.world.worldIndex - val worldContent = EntryFile(WriteWorld.encodeToByteArray64(ingame)) - val world = DiskEntry(worldNum, 0, "world${worldNum}".toByteArray(), creation_t, time_t, worldContent) - addFile(disk, world) + // Write World // + val worldNum = ingame.world.worldIndex + val worldContent = EntryFile(WriteWorld.encodeToByteArray64(ingame)) + val world = DiskEntry(worldNum, 0, "world${worldNum}".toByteArray(Common.CHARSET), creation_t, time_t, worldContent) + addFile(disk, world) - // Write Actors // - listOf(ingame.actorContainerActive, ingame.actorContainerInactive).forEach { actors -> - actors.forEach { - if (actorAcceptable(it)) { - val actorContent = EntryFile(WriteActor.encodeToByteArray64(it)) - val actor = DiskEntry(it.referenceID, 0, "actor${it.referenceID}".toByteArray(), creation_t, time_t, actorContent) - addFile(disk, actor) + // Write Actors // + listOf(ingame.actorContainerActive, ingame.actorContainerInactive).forEach { actors -> + actors.forEach { + if (actorAcceptable(it)) { + val actorContent = EntryFile(WriteActor.encodeToByteArray64(it)) + val actor = DiskEntry(it.referenceID, 0, "actor${it.referenceID}".toByteArray(Common.CHARSET), creation_t, time_t, actorContent) + addFile(disk, actor) + } } } - } - disk.capacity = 0 - VDUtil.dumpToRealMachine(disk, outFile) + disk.capacity = 0 + VDUtil.dumpToRealMachine(disk, outFile) + + + + Echo ("${ccW}Game saved with size of $ccG${outFile.length()}$ccW bytes") + } + IngameRenderer.fboRGBexportRequested = true } }