From f12271f087d28a98b48f932bb068fc0610bd6f45 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Mon, 25 Feb 2019 02:07:39 +0900 Subject: [PATCH] WriteWorldInfo: actually working thumbnail export --- src/com/badlogic/gdx/graphics/PixmapIO2.java | 4 +- ...mbleFrameGdx.kt => AssembleSheetPixmap.kt} | 0 src/net/torvald/terrarum/AppLoader.java | 2 +- src/net/torvald/terrarum/IngameInstance.kt | 3 +- .../torvald/terrarum/modulebasegame/Ingame.kt | 11 ++-- .../terrarum/serialise/WriteWorldInfo.kt | 62 +++++++++++++++++++ work_files/DataFormats/Savegame metadata.txt | 9 +-- 7 files changed, 78 insertions(+), 13 deletions(-) rename src/net/torvald/spriteassembler/{AssembleFrameGdx.kt => AssembleSheetPixmap.kt} (100%) diff --git a/src/com/badlogic/gdx/graphics/PixmapIO2.java b/src/com/badlogic/gdx/graphics/PixmapIO2.java index 848545b93..0cfbd8c02 100644 --- a/src/com/badlogic/gdx/graphics/PixmapIO2.java +++ b/src/com/badlogic/gdx/graphics/PixmapIO2.java @@ -13,6 +13,8 @@ public class PixmapIO2 { // REMEMBER: to the GL's perspective, this game's FBOs are always Y-flipped. // + public static int HEADER_FOOTER_SIZE = 18 + 26; + public static void writeTGAHappy(FileHandle file, Pixmap pixmap, boolean flipY) throws IOException { OutputStream output = file.write(false); @@ -33,7 +35,7 @@ public class PixmapIO2 { } } - private static void _writeTGA(OutputStream out, Pixmap pixmap, boolean verbatim, boolean flipY) throws IOException { + public static void _writeTGA(OutputStream out, Pixmap pixmap, boolean verbatim, boolean flipY) throws IOException { byte[] width = toShortLittle(pixmap.getWidth()); byte[] height = toShortLittle(pixmap.getHeight()); byte[] zero = toShortLittle(0); diff --git a/src/net/torvald/spriteassembler/AssembleFrameGdx.kt b/src/net/torvald/spriteassembler/AssembleSheetPixmap.kt similarity index 100% rename from src/net/torvald/spriteassembler/AssembleFrameGdx.kt rename to src/net/torvald/spriteassembler/AssembleSheetPixmap.kt diff --git a/src/net/torvald/terrarum/AppLoader.java b/src/net/torvald/terrarum/AppLoader.java index 6f08e1273..892d0bb4c 100644 --- a/src/net/torvald/terrarum/AppLoader.java +++ b/src/net/torvald/terrarum/AppLoader.java @@ -219,7 +219,7 @@ public class AppLoader implements ApplicationListener { ShaderProgram.pedantic = false; LwjglApplicationConfiguration appConfig = new LwjglApplicationConfiguration(); - //appConfig.useGL30 = true; // used: loads GL 3.2, unused: loads GL 4.6; what the fuck? + appConfig.useGL30 = true; // utilising some GL trickeries, need this to be TRUE appConfig.vSyncEnabled = getConfigBoolean("usevsync"); appConfig.resizable = false;//true; //appConfig.width = 1110; // photographic ratio (1.5:1) diff --git a/src/net/torvald/terrarum/IngameInstance.kt b/src/net/torvald/terrarum/IngameInstance.kt index ff05972b9..d1c70128c 100644 --- a/src/net/torvald/terrarum/IngameInstance.kt +++ b/src/net/torvald/terrarum/IngameInstance.kt @@ -39,7 +39,8 @@ open class IngameInstance(val batch: SpriteBatch) : Screen { /** * The actual gamer */ - open var actorGamer: ActorHumanoid? = null + val actorGamer: ActorHumanoid + get() = getActorByID(Terrarum.PLAYER_REF_ID) as ActorHumanoid open var gameInitialised = false internal set diff --git a/src/net/torvald/terrarum/modulebasegame/Ingame.kt b/src/net/torvald/terrarum/modulebasegame/Ingame.kt index ef01885c4..8ab5ee929 100644 --- a/src/net/torvald/terrarum/modulebasegame/Ingame.kt +++ b/src/net/torvald/terrarum/modulebasegame/Ingame.kt @@ -155,12 +155,7 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) { lateinit var gameLoadInfoPayload: Any lateinit var gameworld: GameWorldExtension lateinit var theRealGamer: IngamePlayer - - override var actorGamer: ActorHumanoid? - get() = theRealGamer - set(value) { - throw UnsupportedOperationException() - } + // get() = actorGamer as IngamePlayer enum class GameLoadMode { CREATE_NEW, LOAD_FROM @@ -202,6 +197,10 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) { ) private fun setTheRealGamerFirstTime(actor: IngamePlayer) { + if (actor.referenceID != Terrarum.PLAYER_REF_ID) { + throw Error() + } + actorNowPlaying = actor theRealGamer = actor addNewActor(actorNowPlaying) diff --git a/src/net/torvald/terrarum/serialise/WriteWorldInfo.kt b/src/net/torvald/terrarum/serialise/WriteWorldInfo.kt index 253a7d767..f7778fba4 100644 --- a/src/net/torvald/terrarum/serialise/WriteWorldInfo.kt +++ b/src/net/torvald/terrarum/serialise/WriteWorldInfo.kt @@ -1,8 +1,18 @@ package net.torvald.terrarum.serialise +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.graphics.GL30 +import com.badlogic.gdx.graphics.OrthographicCamera +import com.badlogic.gdx.graphics.Pixmap +import com.badlogic.gdx.graphics.PixmapIO2 +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import com.badlogic.gdx.graphics.glutils.FrameBuffer +import com.badlogic.gdx.utils.ScreenUtils import net.torvald.terrarum.ModMgr import net.torvald.terrarum.Terrarum import net.torvald.terrarum.gameworld.GameWorld +import net.torvald.terrarum.inAction +import net.torvald.terrarum.inUse import net.torvald.terrarum.modulebasegame.gameworld.GameWorldExtension import net.torvald.terrarum.modulebasegame.weather.WeatherMixer import net.torvald.terrarum.modulebasegame.worldgenerator.RoguelikeRandomiser @@ -10,6 +20,9 @@ import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64 import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64GrowableOutputStream import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64InputStream import org.apache.commons.codec.digest.DigestUtils +import java.io.ByteArrayOutputStream +import java.util.zip.Deflater +import java.util.zip.DeflaterOutputStream object WriteWorldInfo { @@ -111,6 +124,55 @@ object WriteWorldInfo { metaOut.write(it) } + // thumbnail + val texreg = Terrarum.ingame!!.actorGamer.sprite?.textureRegion + if (texreg != null) { + val batch = SpriteBatch() + val camera = OrthographicCamera(texreg.tileW.toFloat(), texreg.tileH.toFloat()) + val fbo = FrameBuffer(Pixmap.Format.RGBA8888, texreg.tileW, texreg.tileH, false) + + fbo.inAction(camera, batch) { + batch.inUse { + batch.draw(texreg.get(0, 0), 0f, 0f) + } + } + + // bind and unbind the fbo so that I can get the damned Pixmap using ScreenUtils + // NullPointerException if not appconfig.useGL30 + Gdx.gl30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, fbo.framebufferHandle) + Gdx.gl30.glReadBuffer(GL30.GL_COLOR_ATTACHMENT0) + + val outpixmap = ScreenUtils.getFrameBufferPixmap(0, 0, fbo.width, fbo.height) + + Gdx.gl30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, 0) + Gdx.gl30.glReadBuffer(GL30.GL_BACK) + + + val tgaSize = PixmapIO2.HEADER_FOOTER_SIZE + outpixmap.width * outpixmap.height * 4 + val byteArrayOS = ByteArrayOutputStream(tgaSize) + PixmapIO2._writeTGA(byteArrayOS, outpixmap, true, true) + byteArrayOS.flush() + byteArrayOS.close() + + + //PixmapIO2.writeTGA(Gdx.files.absolute(AppLoader.defaultDir+"/tmp_writeworldinfo+outpixmap.tga"), outpixmap, true) + + + outpixmap.dispose() + batch.dispose() + fbo.dispose() + + + + // write uncompressed size + metaOut.write(tgaSize.toULittleShort()) + // write compressed tga + val deflater = DeflaterOutputStream(metaOut, Deflater(Deflater.BEST_COMPRESSION, true), false) + deflater.write(byteArrayOS.toByteArray()) + deflater.flush(); deflater.finish() + // write footer + metaOut.write(-1); metaOut.write(-2) + } // more data goes here // diff --git a/work_files/DataFormats/Savegame metadata.txt b/work_files/DataFormats/Savegame metadata.txt index b3ce69bd6..f37b907cd 100644 --- a/work_files/DataFormats/Savegame metadata.txt +++ b/work_files/DataFormats/Savegame metadata.txt @@ -35,7 +35,8 @@ n-1 00 String terminator 72 SHA-256 hash of worldinfo2 (32 bytes) A4 SHA-256 hash of worldinfo3 (32 bytes) -D6 Compressed size (2 bytes) -D8 Gzipped thumbnail image in TGA format - (it's gzipped so that it saves faster, so no Lzma) - +D6 Uncompressed size (2 bytes) +D8 Deflated thumbnail image in TGA format +p-2 (it's deflated so that it saves faster, so no Lzma) +p-2 0xFF +p-1 0xFE