Update screen contents once per tick

Fixes #117. Closes #103.
This commit is contained in:
Fingercomp 2024-08-25 22:50:52 +07:00
parent 6bc51ba1a9
commit 2efec95103
No known key found for this signature in database
GPG Key ID: BBC71CEE45D86E37

View File

@ -7,7 +7,7 @@ import ocelot.desktop.node.Node.{HighlightThickness, NoHighlightSize, Size}
import ocelot.desktop.node.nodes.ScreenNode.{BorderSize, FontHeight, FontWidth}
import ocelot.desktop.node.{EntityNode, LabeledEntityNode, WindowedNode}
import ocelot.desktop.ui.event.ClickEvent
import ocelot.desktop.ui.widget.ScreenAspectRatioDialog
import ocelot.desktop.ui.widget.{ScreenAspectRatioDialog, TickUpdatable}
import ocelot.desktop.ui.widget.contextmenu.{ContextMenu, ContextMenuEntry}
import ocelot.desktop.util.TierColor
import ocelot.desktop.windows.ScreenWindow
@ -16,7 +16,12 @@ import totoro.ocelot.brain.entity.{Keyboard, Screen}
import totoro.ocelot.brain.nbt.NBTTagCompound
import totoro.ocelot.brain.util.PackedColor
class ScreenNode(val screen: Screen) extends EntityNode(screen) with LabeledEntityNode with WindowedNode[ScreenWindow] {
class ScreenNode(val screen: Screen)
extends EntityNode(screen)
with LabeledEntityNode
with WindowedNode[ScreenWindow]
with TickUpdatable {
override def minimumSize: Size2D = Size2D(
Size * screen.aspectRatio._1,
Size * screen.aspectRatio._2
@ -28,6 +33,11 @@ class ScreenNode(val screen: Screen) extends EntityNode(screen) with LabeledEnti
private val viewport = new ScreenViewport(160 * 8, 160 * 8)
// the cached contents of the screen, updated every tick to synchronize with the TPS rate
private var colorBuffer = Array.fill[Short](screen.getHeight, screen.getWidth)(0)
private var textBuffer = Array.fill[Int](screen.getHeight, screen.getWidth)(0x20)
private var bufferRendered = false
private var keyboard: Option[Keyboard] = None
private val keyboardNBTKey: String = "keyboard"
@ -105,7 +115,8 @@ class ScreenNode(val screen: Screen) extends EntityNode(screen) with LabeledEnti
}
private def drawScreenTexture(): Unit = {
// TODO: cache
if (bufferRendered) return
val width = (screen.getWidth * FontWidth).toInt
val height = (screen.getHeight * FontHeight).toInt
@ -126,6 +137,8 @@ class ScreenNode(val screen: Screen) extends EntityNode(screen) with LabeledEnti
}
}
bufferRendered = true
viewport.flush()
}
@ -352,6 +365,29 @@ class ScreenNode(val screen: Screen) extends EntityNode(screen) with LabeledEnti
}
}
override def tickUpdate(): Unit = {
super.tickUpdate()
val newWidth = screen.getWidth
val newHeight = screen.getHeight
if (textBuffer.length != newHeight || textBuffer(0).length != newWidth) {
// create new arrays
colorBuffer = Array.tabulate(newHeight, newWidth)((y, x) => screen.data.color(y)(x))
textBuffer = Array.tabulate(newHeight, newWidth)((y, x) => screen.data.buffer(y)(x))
} else {
// reuse existing arrays
for (y <- 0 until newHeight) {
for (x <- 0 until newWidth) {
colorBuffer(y)(x) = screen.data.color(y)(x)
textBuffer(y)(x) = screen.data.buffer(y)(x)
}
}
}
bufferRendered = false
}
override def createWindow(): ScreenWindow = new ScreenWindow(this)
}