From 19bc779ae1ee73f7b879c995eaf225595a409f38 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 8 Mar 2025 22:17:36 +0900 Subject: [PATCH] more token ring stuff --- .../gameactors/FixtureRingBusCore.kt | 14 +++-- .../gameactors/FixtureRingBusExerciser.kt | 20 ++++++- .../gameactors/RingBusFirmware.kt | 60 +++++++++++++++++++ .../terrarum/gameactors/ActorWithBody.kt | 28 ++++++++- .../terrarum/modulebasegame/IngameRenderer.kt | 14 ++--- 5 files changed, 121 insertions(+), 15 deletions(-) create mode 100644 ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/RingBusFirmware.kt diff --git a/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/FixtureRingBusCore.kt b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/FixtureRingBusCore.kt index e77ca2bbc..5531958d0 100644 --- a/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/FixtureRingBusCore.kt +++ b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/FixtureRingBusCore.kt @@ -19,7 +19,7 @@ open class FixtureRingBusCore : Electric { @Transient private val rng = HQRNG() - private val mac = rng.nextInt() + val mac = rng.nextInt() companion object { const val INITIAL_LISTENING_TIMEOUT = 300 @@ -64,14 +64,16 @@ open class FixtureRingBusCore : Electric { internal val msgQueue = Queue>() internal val msgLog = Queue>() - private var statusAbort = false // will "eat away" any receiving frames unless the frame is a ballot frame + private var statusAbort = false private var activeMonitorStatus = 0 // 0: unknown, 1: known and not me, 2: known and it's me private var lastAccessTime = -1L + open protected val ringBusFirmware = RingBusFirmware(0) + private enum class RingBusState { NORMAL, - ABORT, + ABORT, // will "eat away" any receiving frames unless the frame is a ballot frame ELECTING, IVE_GOT_ELECTED } @@ -219,8 +221,12 @@ open class FixtureRingBusCore : Electric { if (rec == mac) { msgLog.addLast(rec to incomingFrame) + val datagramme = incomingFrame.getDataContents() + + val (ret, nextMsg) = if (datagramme == null) (-1 to null) else ringBusFirmware.workWithDataFrame(mac, datagramme) + // make ack - return emitNewFrame(NetFrame.makeAck(mac, incomingFrame.getSender())) + return emitNewFrame(NetFrame.makeAck(mac, incomingFrame.getSender(), ret)) } else return null } diff --git a/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/FixtureRingBusExerciser.kt b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/FixtureRingBusExerciser.kt index cbd659984..322ffa5a2 100644 --- a/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/FixtureRingBusExerciser.kt +++ b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/FixtureRingBusExerciser.kt @@ -1,8 +1,12 @@ package net.torvald.terrarum.modulecomputers.gameactors +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import net.torvald.terrarum.App import net.torvald.terrarum.Point2i +import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.modulebasegame.gameactors.BlockBox +import net.torvald.terrarum.modulebasegame.gameworld.NetFrame.Companion.toMAC import net.torvald.terrarum.modulecomputers.ui.UIRingBusAnalyser import net.torvald.terrarum.modulecomputers.ui.UIRingBusExerciser @@ -20,7 +24,14 @@ class FixtureRingBusExerciser : FixtureRingBusCore { this.mainUI = UIRingBusExerciser(this) } + override fun drawBody(frameDelta: Float, batch: SpriteBatch) { + super.drawBody(frameDelta, batch) + // draw its own MAC address + drawUsingDrawFunInGoodPosition(frameDelta) { x, y -> + App.fontSmallNumbers.draw(batch, super.mac.toMAC(), x, y + 2*TILE_SIZE - 12) + } + } } @@ -34,11 +45,18 @@ class FixtureRingBusAnalyser : FixtureRingBusCore { portEmit = Point2i(0, 0), portSink = Point2i(1, 0), blockBox = BlockBox(BlockBox.NO_COLLISION, 2, 1), - nameFun = { Lang["ITEM_DEBUG_RING_BUS_Analyser"] }, + nameFun = { Lang["ITEM_DEBUG_RING_BUS_ANALYSER"] }, ) { this.mainUI = UIRingBusAnalyser(this) } + override fun drawBody(frameDelta: Float, batch: SpriteBatch) { + super.drawBody(frameDelta, batch) + // draw its own MAC address + drawUsingDrawFunInGoodPosition(frameDelta) { x, y -> + App.fontSmallNumbers.draw(batch, super.mac.toMAC(), x, y + 1*TILE_SIZE - 12) + } + } } diff --git a/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/RingBusFirmware.kt b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/RingBusFirmware.kt new file mode 100644 index 000000000..a129ebe60 --- /dev/null +++ b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/RingBusFirmware.kt @@ -0,0 +1,60 @@ +package net.torvald.terrarum.modulecomputers.gameactors + +import net.torvald.terrarum.serialise.* + + +open class RingBusFirmware(val devtype: Int) { + + fun workWithDataFrame(hostMAC: Int, datagramme: ByteArray): Pair { + if (datagramme.size < 12) return -1 to null + + val protocol = datagramme[0].toUint() + val mode = datagramme[1].toUint() + val arg1 = datagramme.toBigInt16(2) + val recipient = datagramme.toBigInt32(4) + val sender = datagramme.toBigInt32(8) + val body = datagramme.sliceArray(12 until datagramme.size) + + return invoke(hostMAC, protocol, mode, arg1, recipient, sender, body, datagramme) + } + + open fun invoke(hostMAC: Int, protocol: Int, mode: Int, arg1: Int, recipient: Int, sender: Int, body: ByteArray, datagramme: ByteArray): Pair { + return when (protocol) { + 1 -> 0 to echo(recipient, sender, body) + 2 -> 0 to blockTransfer(arg1, recipient, sender, body) + 4 -> 0 to deviceDiscovery(hostMAC, datagramme) + else -> -1 to null + } + } + + open fun echo(recipient: Int, sender: Int, body: ByteArray): ByteArray { + return ByteArray(8 + body.size).makeEmptyPacket(1, 1, 0, recipient, sender).also { + it.writeBigInt48(System.currentTimeMillis(), 12) + System.arraycopy(body, 6, this, 6, body.size - 6) + } + } + + open fun blockTransfer(sequence: Int, recipient: Int, sender: Int, body: ByteArray): ByteArray { + return ByteArray(12).makeEmptyPacket(2, 1, sequence, recipient, sender) // always ACK + } + + open fun deviceDiscovery(host: Int, wholeMessage: ByteArray): ByteArray { + return ByteArray(wholeMessage.size + 6).also { + System.arraycopy(wholeMessage, 0, it, 0, wholeMessage.size) + it[it.size - 5] = devtype.toByte() + it.writeBigInt32(host, it.size - 4) + } + } + + + + private fun ByteArray.makeEmptyPacket(protocol: Int, mode: Int, arg1: Int, recipient: Int, sender: Int): ByteArray { + this[0] = protocol.toByte() + this[1] = mode.toByte() + this.writeBigInt16(arg1, 2) + this.writeBigInt32(recipient, 4) + this.writeBigInt32(sender, 8) + + return this + } +} diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index c5d1fd75b..94a72e95f 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -13,6 +13,7 @@ import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.blockproperties.BlockProp +import net.torvald.terrarum.gameactors.ActorWithBody.Companion.PHYS_EPSILON_DIST import net.torvald.terrarum.gamecontroller.KeyToggler import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameparticles.createRandomBlockParticle @@ -1860,6 +1861,11 @@ open class ActorWithBody : Actor { BlendMode.resolve(drawMode, batch) drawSpriteInGoodPosition(frameDelta, sprite!!, batch) } + } + + + internal fun drawBody1(frameDelta: Float, batch: SpriteBatch) { + drawBody(frameDelta, batch) // debug display of hIntTilewiseHitbox if (KeyToggler.isOn(Input.Keys.F9)) { @@ -1869,8 +1875,8 @@ open class ActorWithBody : Actor { batch.color = if (y == intTilewiseHitbox.height.toInt() + 1) HITBOX_COLOURS1 else HITBOX_COLOURS0 for (x in 0..intTilewiseHitbox.width.toInt()) { batch.draw(blockMark, - (intTilewiseHitbox.startX.toFloat() + x) * TILE_SIZEF, - (intTilewiseHitbox.startY.toFloat() + y) * TILE_SIZEF + (intTilewiseHitbox.startX.toFloat() + x) * TILE_SIZEF, + (intTilewiseHitbox.startY.toFloat() + y) * TILE_SIZEF ) } } @@ -1910,6 +1916,22 @@ open class ActorWithBody : Actor { } } + fun drawUsingDrawFunInGoodPosition(frameDelta: Float, drawFun: (x: Float, y: Float) -> Unit) { + if (world == null) return + + val offsetX = 0f + val offsetY = 0f // for some reason this value must be zero to draw the actor planted to the ground + + val posX = hitbox.startX.plus(PHYS_EPSILON_DIST).toFloat() + val posY = hitbox.startY.plus(PHYS_EPSILON_DIST).toFloat() + + drawBodyInGoodPosition(posX, posY) { x, y -> + drawFun(posX + offsetX + x, posY + offsetY + y) + } + } + + + override fun onActorValueChange(key: String, value: Any?) { // do nothing } @@ -2332,4 +2354,4 @@ inline fun drawBodyInGoodPosition(startX: Float, startY: Float, drawFun: (x: Flo // App.batch.color = Color.WHITE drawFun(startX , startY) } -} \ No newline at end of file +} diff --git a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt index 07a79039b..39c618fe9 100644 --- a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt +++ b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt @@ -524,8 +524,8 @@ object IngameRenderer : Disposable { batch.shader = shaderForActors batch.color = Color.WHITE moveCameraToWorldCoord() - actorsRenderFarBehind?.forEach { it.drawBody(frameDelta, batch) } - actorsRenderBehind?.forEach { it.drawBody(frameDelta, batch) } + actorsRenderFarBehind?.forEach { it.drawBody1(frameDelta, batch) } + actorsRenderBehind?.forEach { it.drawBody1(frameDelta, batch) } } } BlurMgr.makeBlurSmall(fboRGBactorsBehind, fboRGBactorsBehindShadow, 1f) @@ -539,7 +539,7 @@ object IngameRenderer : Disposable { batch.shader = shaderForActors batch.color = Color.WHITE moveCameraToWorldCoord() - actorsRenderMiddle?.forEach { it.drawBody(frameDelta, batch) } + actorsRenderMiddle?.forEach { it.drawBody1(frameDelta, batch) } } } BlurMgr.makeBlur(fboRGBactorsMiddle, fboRGBactorsMiddleShadow, 2.5f) @@ -628,9 +628,9 @@ object IngameRenderer : Disposable { batch.drawFlipped(fboRGBactorsMiddle.colorBufferTexture, 0f, 0f) moveCameraToWorldCoord() - actorsRenderMidTop?.forEach { it.drawBody(frameDelta, batch) } - player?.drawBody(frameDelta, batch) - actorsRenderFront?.forEach { it.drawBody(frameDelta, batch) } + actorsRenderMidTop?.forEach { it.drawBody1(frameDelta, batch) } + player?.drawBody1(frameDelta, batch) + actorsRenderFront?.forEach { it.drawBody1(frameDelta, batch) } // --> Change of blend mode <-- introduced by children of ActorWithBody // } @@ -859,7 +859,7 @@ object IngameRenderer : Disposable { moveCameraToWorldCoord() actors?.forEach { - it.drawBody(frameDelta, batch) + it.drawBody1(frameDelta, batch) } }