From c0e8c2f85b480500b1278b04b077c05d517bd5ce Mon Sep 17 00:00:00 2001 From: minjaesong Date: Tue, 12 Oct 2021 10:32:19 +0900 Subject: [PATCH] manual saving works? --- src/net/torvald/terrarum/DefaultConfig.kt | 1 + src/net/torvald/terrarum/IngameInstance.kt | 5 ++-- .../terrarum/modulebasegame/TerrarumIngame.kt | 13 ++++++--- .../modulebasegame/ui/UIInventoryEscMenu.kt | 29 +++++++++++++++---- .../terrarum/serialise/GameSavingThread.kt | 28 +++++++++++++++--- .../terrarum/serialise/QuickSaveThread.kt | 17 ++++++++--- .../terrarum/serialise/WriteSavegame.kt | 20 ++++++------- 7 files changed, 84 insertions(+), 29 deletions(-) diff --git a/src/net/torvald/terrarum/DefaultConfig.kt b/src/net/torvald/terrarum/DefaultConfig.kt index 4e8785a9b..67859b03d 100644 --- a/src/net/torvald/terrarum/DefaultConfig.kt +++ b/src/net/torvald/terrarum/DefaultConfig.kt @@ -97,6 +97,7 @@ object DefaultConfig { "fx_retro" to false, "fx_backgroundblur" to true, "fx_streamerslayout" to false, + "fx_differential" to false, //"fx_3dlut" to false, diff --git a/src/net/torvald/terrarum/IngameInstance.kt b/src/net/torvald/terrarum/IngameInstance.kt index 11fbe3562..961279a1b 100644 --- a/src/net/torvald/terrarum/IngameInstance.kt +++ b/src/net/torvald/terrarum/IngameInstance.kt @@ -51,8 +51,9 @@ open class IngameInstance(val batch: SpriteBatch, val isMultiplayer: Boolean = f lateinit var worldDisk: VirtualDisk; internal set lateinit var playerDisk: VirtualDisk; internal set - var savegameNickname: String = "SplinesReticulated" - internal set + lateinit var worldSavefileName: String; internal set + lateinit var playerSavefileName: String; internal set + var savegameNickname: String = "SplinesReticulated"; internal set var screenZoom = 1.0f val ZOOM_MAXIMUM = 4.0f diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index bdf4c3cd8..262943bbe 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -38,6 +38,7 @@ import net.torvald.terrarum.serialise.ReadActor import net.torvald.terrarum.serialise.WriteSavegame import net.torvald.terrarum.tvda.DiskSkimmer import net.torvald.terrarum.tvda.VDUtil +import net.torvald.terrarum.tvda.VirtualDisk import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.ui.UIAutosaveNotifier import net.torvald.terrarum.ui.UICanvas @@ -201,6 +202,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { internal set + ////////////// // GDX code // ////////////// @@ -328,8 +330,8 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { // go to spawn position printdbg(this, "World Spawn position: (${world.spawnX}, ${world.spawnY})") - val worldSavefileName = "$savegameNickname-${world.worldIndex}" - val playerSavefileName = (actorGamer.actorValue.getAsString(AVKey.NAME) ?: "Player") + "-${actorGamer.uuid}" + worldSavefileName = "$savegameNickname-${world.worldIndex}" + playerSavefileName = (actorGamer.actorValue.getAsString(AVKey.NAME) ?: "Player") + "-${actorGamer.uuid}" worldDisk = VDUtil.createNewDisk( 1L shl 60, @@ -347,6 +349,9 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { world.spawnX * TILE_SIZED, world.spawnY * TILE_SIZED ) + actorGamer.backupPlayerProps(isMultiplayer) + + val onError = { e: Throwable -> uiAutosaveNotifier.setAsError() } // make initial savefile // we're not writing multiple files at one go because: @@ -354,10 +359,10 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { // 2. cannot sync up the "counter" to determine whether both are finished uiAutosaveNotifier.setAsOpen() val saveTime_t = App.getTIME_T() - WriteSavegame.immediate(saveTime_t, WriteSavegame.SaveMode.PLAYER, playerDisk, getPlayerSaveFiledesc(playerSavefileName), this, false, true) { + WriteSavegame.immediate(saveTime_t, WriteSavegame.SaveMode.PLAYER, playerDisk, getPlayerSaveFiledesc(playerSavefileName), this, true, onError) { makeSavegameBackupCopy(getPlayerSaveFiledesc(playerSavefileName)) - WriteSavegame.immediate(saveTime_t, WriteSavegame.SaveMode.WORLD, worldDisk, getWorldSaveFiledesc(worldSavefileName), this, false, true) { + WriteSavegame.immediate(saveTime_t, WriteSavegame.SaveMode.WORLD, worldDisk, getWorldSaveFiledesc(worldSavefileName), this, true, onError) { makeSavegameBackupCopy(getWorldSaveFiledesc(worldSavefileName)) // don't put it on the postInit() or render(); must be called using callback uiAutosaveNotifier.setAsClose() } diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryEscMenu.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryEscMenu.kt index 9e1bd790a..be26423e0 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryEscMenu.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryEscMenu.kt @@ -8,8 +8,10 @@ import net.torvald.terrarum.App import net.torvald.terrarum.INGAME import net.torvald.terrarum.TitleScreen import net.torvald.terrarum.blendNormal +import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_Y import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_UI_HEIGHT +import net.torvald.terrarum.serialise.WriteSavegame import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.ui.UIItem @@ -87,16 +89,33 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() { full.handler.lockToggle() full.lockTransition() - INGAME.makeSavegameBackupCopy() // save the game - /*WriteSavegame(INGAME.savegameArchive, File(App.saveDir, INGAME.savegameNickname), Terrarum.ingame!! as TerrarumIngame, false) { - // callback: - System.gc() + val onError = { _: Throwable -> + // TODO: show some error indicator screen = 0 full.handler.unlockToggle() full.unlockTransition() - }*/ + } + + val saveTime_t = App.getTIME_T() + val playerSavefile = INGAME.getPlayerSaveFiledesc(INGAME.playerSavefileName) + val worldSavefile = INGAME.getWorldSaveFiledesc(INGAME.worldSavefileName) + + + INGAME.makeSavegameBackupCopy(playerSavefile) + WriteSavegame(saveTime_t, WriteSavegame.SaveMode.PLAYER, INGAME.playerDisk, playerSavefile, INGAME as TerrarumIngame, false, onError) { + + INGAME.makeSavegameBackupCopy(worldSavefile) + WriteSavegame(saveTime_t, WriteSavegame.SaveMode.WORLD, INGAME.worldDisk, worldSavefile, INGAME as TerrarumIngame, false, onError) { + // callback: + System.gc() + screen = 0 + full.handler.unlockToggle() + full.unlockTransition() + } + } + } 2 -> { screen = 4; gameMenuButtons.deselect() diff --git a/src/net/torvald/terrarum/serialise/GameSavingThread.kt b/src/net/torvald/terrarum/serialise/GameSavingThread.kt index d529b41e5..84bfca070 100644 --- a/src/net/torvald/terrarum/serialise/GameSavingThread.kt +++ b/src/net/torvald/terrarum/serialise/GameSavingThread.kt @@ -24,7 +24,7 @@ private fun addFile(disk: VirtualDisk, file: DiskEntry) { if (!dir.contains(file.entryID)) dir.add(file.entryID) } -abstract class SavingThread(private val ingame: TerrarumIngame) : Runnable { +abstract class SavingThread(private val errorHandler: (Throwable) -> Unit) : Runnable { abstract fun save() override fun run() { @@ -33,7 +33,7 @@ abstract class SavingThread(private val ingame: TerrarumIngame) : Runnable { } catch (e: Throwable) { e.printStackTrace() - ingame.uiAutosaveNotifier.setAsError() + errorHandler(e) } } } @@ -41,7 +41,16 @@ abstract class SavingThread(private val ingame: TerrarumIngame) : Runnable { /** * Created by minjaesong on 2021-09-14. */ -class WorldSavingThread(val time_t: Long, val disk: VirtualDisk, val outFile: File, val ingame: TerrarumIngame, val hasThumbnail: Boolean, val isAuto: Boolean, val callback: () -> Unit) : SavingThread(ingame) { +class WorldSavingThread( + val time_t: Long, + val disk: VirtualDisk, + val outFile: File, + val ingame: TerrarumIngame, + val hasThumbnail: Boolean, + val isAuto: Boolean, + val callback: () -> Unit, + val errorHandler: (Throwable) -> Unit +) : SavingThread(errorHandler) { override fun save() { @@ -155,12 +164,23 @@ class WorldSavingThread(val time_t: Long, val disk: VirtualDisk, val outFile: Fi * * Created by minjaesong on 2021-10-08 */ -class PlayerSavingThread(val time_t: Long, val disk: VirtualDisk, val outFile: File, val ingame: TerrarumIngame, val hasThumbnail: Boolean, val isAuto: Boolean, val callback: () -> Unit) : SavingThread(ingame) { +class PlayerSavingThread( + val time_t: Long, + val disk: VirtualDisk, + val outFile: File, + val ingame: TerrarumIngame, + val hasThumbnail: Boolean, + val isAuto: Boolean, + val callback: () -> Unit, + val errorHandler: (Throwable) -> Unit +) : SavingThread(errorHandler) { override fun save() { disk.saveMode = 2 * isAuto.toInt() // no quick disk.capacity = 0L + WriteSavegame.saveProgress = 0f + Echo("Writing The Player...") WritePlayer(ingame.actorGamer, disk, ingame, time_t) VDUtil.dumpToRealMachine(disk, outFile) diff --git a/src/net/torvald/terrarum/serialise/QuickSaveThread.kt b/src/net/torvald/terrarum/serialise/QuickSaveThread.kt index 91341f0b7..40bded0a9 100644 --- a/src/net/torvald/terrarum/serialise/QuickSaveThread.kt +++ b/src/net/torvald/terrarum/serialise/QuickSaveThread.kt @@ -17,7 +17,16 @@ import java.util.zip.GZIPOutputStream /** * Created by minjaesong on 2021-09-29. */ -class QuickSingleplayerWorldSavingThread(val time_t: Long, val disk: VirtualDisk, val file: File, val ingame: TerrarumIngame, val hasThumbnail: Boolean, val isAuto: Boolean, val callback: () -> Unit) : Runnable { +class QuickSingleplayerWorldSavingThread( + val time_t: Long, + val disk: VirtualDisk, + val outFile: File, + val ingame: TerrarumIngame, + val hasThumbnail: Boolean, + val isAuto: Boolean, + val callback: () -> Unit, + val errorHandler: (Throwable) -> Unit +) : SavingThread(errorHandler) { /** * Will happily overwrite existing entry @@ -34,8 +43,8 @@ class QuickSingleplayerWorldSavingThread(val time_t: Long, val disk: VirtualDisk private val actorProgressMultiplier = 1f - override fun run() { - val skimmer = DiskSkimmer(file, Common.CHARSET) + override fun save() { + val skimmer = DiskSkimmer(outFile, Common.CHARSET) if (hasThumbnail) { while (!IngameRenderer.fboRGBexportedLatch) { @@ -133,7 +142,7 @@ class QuickSingleplayerWorldSavingThread(val time_t: Long, val disk: VirtualDisk skimmer.injectDiskCRC(disk.hashCode()) skimmer.setSaveMode(1 + 2 * isAuto.toInt()) - Echo ("${ccW}Game saved with size of $ccG${file.length()}$ccW bytes") + Echo ("${ccW}Game saved with size of $ccG${outFile.length()}$ccW bytes") if (hasThumbnail) IngameRenderer.fboRGBexportedLatch = false diff --git a/src/net/torvald/terrarum/serialise/WriteSavegame.kt b/src/net/torvald/terrarum/serialise/WriteSavegame.kt index 9b1eb955f..bb591217f 100644 --- a/src/net/torvald/terrarum/serialise/WriteSavegame.kt +++ b/src/net/torvald/terrarum/serialise/WriteSavegame.kt @@ -30,14 +30,14 @@ object WriteSavegame { @Volatile var saveProgress = 0f @Volatile var saveProgressMax = 1f - private fun getSaveThread(time_t: Long, mode: SaveMode, disk: VirtualDisk, outFile: File, ingame: TerrarumIngame, hasThumbnail: Boolean, isAuto: Boolean, callback: () -> Unit = {}) = when (mode) { - SaveMode.WORLD -> WorldSavingThread(time_t, disk, outFile, ingame, hasThumbnail, isAuto, callback) - SaveMode.PLAYER -> PlayerSavingThread(time_t, disk, outFile, ingame, hasThumbnail, isAuto, callback) - SaveMode.QUICK_PLAYER -> QuickSingleplayerWorldSavingThread(time_t, disk, outFile, ingame, hasThumbnail, isAuto, callback) + private fun getSaveThread(time_t: Long, mode: SaveMode, disk: VirtualDisk, outFile: File, ingame: TerrarumIngame, hasThumbnail: Boolean, isAuto: Boolean, errorHandler: (Throwable) -> Unit, callback: () -> Unit) = when (mode) { + SaveMode.WORLD -> WorldSavingThread(time_t, disk, outFile, ingame, hasThumbnail, isAuto, callback, errorHandler) + SaveMode.PLAYER -> PlayerSavingThread(time_t, disk, outFile, ingame, hasThumbnail, isAuto, callback, errorHandler) + SaveMode.QUICK_PLAYER -> QuickSingleplayerWorldSavingThread(time_t, disk, outFile, ingame, hasThumbnail, isAuto, callback, errorHandler) else -> throw IllegalArgumentException("$mode") } - operator fun invoke(time_t: Long, mode: SaveMode, disk: VirtualDisk, outFile: File, ingame: TerrarumIngame, isAuto: Boolean, callback: () -> Unit = {}) { + operator fun invoke(time_t: Long, mode: SaveMode, disk: VirtualDisk, outFile: File, ingame: TerrarumIngame, isAuto: Boolean, errorHandler: (Throwable) -> Unit, callback: () -> Unit) { savingStatus = 0 Echo("Save queued") @@ -57,7 +57,7 @@ object WriteSavegame { } IngameRenderer.screencapRequested = true - val savingThread = Thread(getSaveThread(time_t, mode, disk, outFile, ingame, true, isAuto, callback), "TerrarumBasegameGameSaveThread") + val savingThread = Thread(getSaveThread(time_t, mode, disk, outFile, ingame, true, isAuto, errorHandler, callback), "TerrarumBasegameGameSaveThread") savingThread.start() // it is caller's job to keep the game paused or keep a "save in progress" ui up @@ -65,20 +65,20 @@ object WriteSavegame { } - fun immediate(time_t: Long, mode: SaveMode, disk: VirtualDisk, outFile: File, ingame: TerrarumIngame, hasThumbnail: Boolean, isAuto: Boolean, callback: () -> Unit = {}) { + fun immediate(time_t: Long, mode: SaveMode, disk: VirtualDisk, outFile: File, ingame: TerrarumIngame, isAuto: Boolean, errorHandler: (Throwable) -> Unit, callback: () -> Unit) { savingStatus = 0 Echo("Immediate save fired") - val savingThread = Thread(getSaveThread(time_t, mode, disk, outFile, ingame, false, isAuto, callback), "TerrarumBasegameGameSaveThread") + val savingThread = Thread(getSaveThread(time_t, mode, disk, outFile, ingame, false, isAuto, errorHandler, callback), "TerrarumBasegameGameSaveThread") savingThread.start() // it is caller's job to keep the game paused or keep a "save in progress" ui up // use field 'savingStatus' to know when the saving is done } - fun quick(time_t: Long, mode: SaveMode, disk: VirtualDisk, outFile: File, ingame: TerrarumIngame, isAuto: Boolean, callback: () -> Unit = {}) { + fun quick(time_t: Long, mode: SaveMode, disk: VirtualDisk, outFile: File, ingame: TerrarumIngame, isAuto: Boolean, callback: () -> Unit, errorHandler: (Throwable) -> Unit) { if (ingame.isMultiplayer) TODO() return // TODO // @@ -102,7 +102,7 @@ object WriteSavegame { } IngameRenderer.screencapRequested = true - val savingThread = Thread(getSaveThread(time_t, mode, disk, outFile, ingame, false, isAuto, callback), "TerrarumBasegameGameSaveThread") + val savingThread = Thread(getSaveThread(time_t, mode, disk, outFile, ingame, false, isAuto, errorHandler, callback), "TerrarumBasegameGameSaveThread") savingThread.start() // it is caller's job to keep the game paused or keep a "save in progress" ui up