diff --git a/src/main/scala/ocelot/desktop/node/nodes/ScreenNode.scala b/src/main/scala/ocelot/desktop/node/nodes/ScreenNode.scala index 1cc24a9..67ae020 100644 --- a/src/main/scala/ocelot/desktop/node/nodes/ScreenNode.scala +++ b/src/main/scala/ocelot/desktop/node/nodes/ScreenNode.scala @@ -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) }