more token ring stuff

This commit is contained in:
minjaesong
2025-03-08 22:17:36 +09:00
parent 16cac2f1ab
commit 19bc779ae1
5 changed files with 121 additions and 15 deletions

View File

@@ -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<Pair<Int, ByteArray>>()
internal val msgLog = Queue<Pair<Int, NetFrame>>()
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
}

View File

@@ -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)
}
}
}

View File

@@ -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<Int, ByteArray?> {
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<Int, ByteArray?> {
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
}
}

View File

@@ -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)) {
@@ -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
}

View File

@@ -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)
}
}