mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-13 17:28:52 -04:00
remove packet sync for invisible gpu change - make free more free
This commit is contained in:
parent
4a3b53d760
commit
9d38ecb51d
@ -34,18 +34,19 @@ import net.minecraft.entity.player.EntityPlayer
|
|||||||
import net.minecraft.nbt.NBTTagCompound
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
import net.minecraftforge.event.world.ChunkEvent
|
import net.minecraftforge.event.world.ChunkEvent
|
||||||
import net.minecraftforge.event.world.WorldEvent
|
import net.minecraftforge.event.world.WorldEvent
|
||||||
|
import tconstruct.client.tabs.InventoryTabVanilla
|
||||||
|
|
||||||
import scala.collection.convert.WrapAsJava._
|
import scala.collection.convert.WrapAsJava._
|
||||||
import scala.collection.convert.WrapAsScala._
|
import scala.collection.convert.WrapAsScala._
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
|
|
||||||
class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment with api.internal.TextBuffer with DeviceInfo {
|
class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment with traits.TextBufferProxy with DeviceInfo {
|
||||||
override val node = api.Network.newNode(this, Visibility.Network).
|
override val node = api.Network.newNode(this, Visibility.Network).
|
||||||
withComponent("screen").
|
withComponent("screen").
|
||||||
withConnector().
|
withConnector().
|
||||||
create()
|
create()
|
||||||
|
|
||||||
private var maxResolution = Settings.screenResolutionsByTier(Tier.One)
|
private var maxResolution: (Int, Int) = Settings.screenResolutionsByTier(Tier.One)
|
||||||
|
|
||||||
private var maxDepth = Settings.screenDepthsByTier(Tier.One)
|
private var maxDepth = Settings.screenDepthsByTier(Tier.One)
|
||||||
|
|
||||||
@ -77,26 +78,26 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
|||||||
pb
|
pb
|
||||||
}
|
}
|
||||||
|
|
||||||
var fullyLitCost = computeFullyLitCost()
|
var fullyLitCost: Double = computeFullyLitCost()
|
||||||
|
|
||||||
// This computes the energy cost (per tick) to keep the screen running if
|
// This computes the energy cost (per tick) to keep the screen running if
|
||||||
// every single "pixel" is lit. This cost increases with higher tiers as
|
// every single "pixel" is lit. This cost increases with higher tiers as
|
||||||
// their maximum resolution (pixel density) increases. For a basic screen
|
// their maximum resolution (pixel density) increases. For a basic screen
|
||||||
// this is simply the configured cost.
|
// this is simply the configured cost.
|
||||||
def computeFullyLitCost() = {
|
def computeFullyLitCost(): Double = {
|
||||||
val (w, h) = Settings.screenResolutionsByTier(0)
|
val (w, h) = Settings.screenResolutionsByTier(0)
|
||||||
val mw = getMaximumWidth
|
val mw = getMaximumWidth
|
||||||
val mh = getMaximumHeight
|
val mh = getMaximumHeight
|
||||||
powerConsumptionPerTick * (mw * mh) / (w * h)
|
powerConsumptionPerTick * (mw * mh) / (w * h)
|
||||||
}
|
}
|
||||||
|
|
||||||
val proxy =
|
val proxy: TextBuffer.Proxy =
|
||||||
if (SideTracker.isClient) new TextBuffer.ClientProxy(this)
|
if (SideTracker.isClient) new TextBuffer.ClientProxy(this)
|
||||||
else new TextBuffer.ServerProxy(this)
|
else new TextBuffer.ServerProxy(this)
|
||||||
|
|
||||||
val data = new util.TextBuffer(maxResolution, PackedColor.Depth.format(maxDepth))
|
val data = new util.TextBuffer(maxResolution, PackedColor.Depth.format(maxDepth))
|
||||||
|
|
||||||
var viewport = data.size
|
var viewport: (Int, Int) = data.size
|
||||||
|
|
||||||
def markInitialized(): Unit = {
|
def markInitialized(): Unit = {
|
||||||
syncCooldown = -1 // Stop polling for init state.
|
syncCooldown = -1 // Stop polling for init state.
|
||||||
@ -225,7 +226,7 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
|||||||
fullyLitCost = computeFullyLitCost()
|
fullyLitCost = computeFullyLitCost()
|
||||||
}
|
}
|
||||||
|
|
||||||
override def getEnergyCostPerTick = powerConsumptionPerTick
|
override def getEnergyCostPerTick: Double = powerConsumptionPerTick
|
||||||
|
|
||||||
override def setPowerState(value: Boolean) {
|
override def setPowerState(value: Boolean) {
|
||||||
if (isDisplaying != value) {
|
if (isDisplaying != value) {
|
||||||
@ -238,7 +239,7 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override def getPowerState = isDisplaying
|
override def getPowerState: Boolean = isDisplaying
|
||||||
|
|
||||||
override def setMaximumResolution(width: Int, height: Int) {
|
override def setMaximumResolution(width: Int, height: Int) {
|
||||||
if (width < 1) throw new IllegalArgumentException("width must be larger or equal to one")
|
if (width < 1) throw new IllegalArgumentException("width must be larger or equal to one")
|
||||||
@ -248,15 +249,15 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
|||||||
proxy.onBufferMaxResolutionChange(width, width)
|
proxy.onBufferMaxResolutionChange(width, width)
|
||||||
}
|
}
|
||||||
|
|
||||||
override def getMaximumWidth = maxResolution._1
|
override def getMaximumWidth: Int = maxResolution._1
|
||||||
|
|
||||||
override def getMaximumHeight = maxResolution._2
|
override def getMaximumHeight: Int = maxResolution._2
|
||||||
|
|
||||||
override def setAspectRatio(width: Double, height: Double) = this.synchronized(aspectRatio = (width, height))
|
override def setAspectRatio(width: Double, height: Double): Unit = this.synchronized(aspectRatio = (width, height))
|
||||||
|
|
||||||
override def getAspectRatio = aspectRatio._1 / aspectRatio._2
|
override def getAspectRatio: Double = aspectRatio._1 / aspectRatio._2
|
||||||
|
|
||||||
override def setResolution(w: Int, h: Int) = {
|
override def setResolution(w: Int, h: Int): Boolean = {
|
||||||
val (mw, mh) = maxResolution
|
val (mw, mh) = maxResolution
|
||||||
if (w < 1 || h < 1 || w > mw || h > mw || h * w > mw * mh)
|
if (w < 1 || h < 1 || w > mw || h > mw || h * w > mw * mh)
|
||||||
throw new IllegalArgumentException("unsupported resolution")
|
throw new IllegalArgumentException("unsupported resolution")
|
||||||
@ -275,10 +276,6 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
|||||||
else false
|
else false
|
||||||
}
|
}
|
||||||
|
|
||||||
override def getWidth = data.width
|
|
||||||
|
|
||||||
override def getHeight = data.height
|
|
||||||
|
|
||||||
override def setViewport(w: Int, h: Int): Boolean = {
|
override def setViewport(w: Int, h: Int): Boolean = {
|
||||||
val (mw, mh) = data.size
|
val (mw, mh) = data.size
|
||||||
if (w < 1 || h < 1 || w > mw || h > mh)
|
if (w < 1 || h < 1 || w > mw || h > mh)
|
||||||
@ -300,185 +297,136 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
|||||||
|
|
||||||
override def getViewportHeight: Int = viewport._2
|
override def getViewportHeight: Int = viewport._2
|
||||||
|
|
||||||
override def setMaximumColorDepth(depth: api.internal.TextBuffer.ColorDepth) = maxDepth = depth
|
override def setMaximumColorDepth(depth: api.internal.TextBuffer.ColorDepth): Unit = maxDepth = depth
|
||||||
|
|
||||||
override def getMaximumColorDepth = maxDepth
|
override def getMaximumColorDepth: api.internal.TextBuffer.ColorDepth = maxDepth
|
||||||
|
|
||||||
override def setColorDepth(depth: api.internal.TextBuffer.ColorDepth) = {
|
override def setColorDepth(depth: api.internal.TextBuffer.ColorDepth): Boolean = {
|
||||||
if (depth.ordinal > maxDepth.ordinal)
|
val colorDepthChanged: Boolean = super.setColorDepth(depth)
|
||||||
throw new IllegalArgumentException("unsupported depth")
|
|
||||||
// Always send to clients, their state might be dirty.
|
// Always send to clients, their state might be dirty.
|
||||||
proxy.onBufferDepthChange(depth)
|
proxy.onBufferDepthChange(depth)
|
||||||
data.format = PackedColor.Depth.format(depth)
|
colorDepthChanged
|
||||||
}
|
}
|
||||||
|
|
||||||
override def getColorDepth = data.format.depth
|
override def onBufferColorChange(): Unit =
|
||||||
|
proxy.onBufferColorChange()
|
||||||
|
|
||||||
override def setPaletteColor(index: Int, color: Int) = data.format match {
|
class ViewportBox(val x1: Int, val y1: Int, val x2: Int, val y2: Int) {
|
||||||
case palette: PackedColor.MutablePaletteFormat =>
|
def width: Int = (x2 - x1 + 1) max 0
|
||||||
palette(index) = color
|
def height: Int = (y2 - y1 + 1) max 0
|
||||||
proxy.onBufferPaletteChange(index)
|
def isVisible: Boolean = width > 0 && height > 0
|
||||||
case _ => throw new Exception("palette not available")
|
def isEmpty: Boolean = !isVisible
|
||||||
}
|
}
|
||||||
|
|
||||||
override def getPaletteColor(index: Int) = data.format match {
|
// return box within viewport
|
||||||
case palette: PackedColor.MutablePaletteFormat => palette(index)
|
private def truncateToViewport(x1: Int, y1: Int, x2: Int, y2: Int): ViewportBox = {
|
||||||
case _ => throw new Exception("palette not available")
|
val x: Int = (x1 min x2) max 0
|
||||||
|
val y: Int = (y1 min y2) max 0
|
||||||
|
val lastX: Int = ((x1 max x2) max 0) min (viewport._1 - 1)
|
||||||
|
val lastY: Int = ((y1 max y2) max 0) min (viewport._2 - 1)
|
||||||
|
new ViewportBox(x, y, lastX, lastY)
|
||||||
}
|
}
|
||||||
|
|
||||||
override def setForegroundColor(color: Int) = setForegroundColor(color, isFromPalette = false)
|
override def onBufferCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int): Unit = {
|
||||||
|
// only notify about viewport changes
|
||||||
override def setForegroundColor(color: Int, isFromPalette: Boolean) {
|
val box = truncateToViewport(col + tx, row + ty, col + tx + w - 1, row + ty + h - 1)
|
||||||
val value = PackedColor.Color(color, isFromPalette)
|
if (box.isVisible) {
|
||||||
if (data.foreground != value) {
|
proxy.onBufferCopy(col, row, box.width, box.height, tx, ty)
|
||||||
data.foreground = value
|
|
||||||
proxy.onBufferColorChange()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override def getForegroundColor = data.foreground.value
|
override def onBufferFill(col: Int, row: Int, w: Int, h: Int, c: Char): Unit = {
|
||||||
|
val box = truncateToViewport(col, row, col + w - 1, row + h - 1)
|
||||||
override def isForegroundFromPalette = data.foreground.isPalette
|
if (box.isVisible) {
|
||||||
|
proxy.onBufferFill(col, row, box.width, box.height, c)
|
||||||
override def setBackgroundColor(color: Int) = setBackgroundColor(color, isFromPalette = false)
|
|
||||||
|
|
||||||
override def setBackgroundColor(color: Int, isFromPalette: Boolean) {
|
|
||||||
val value = PackedColor.Color(color, isFromPalette)
|
|
||||||
if (data.background != value) {
|
|
||||||
data.background = value
|
|
||||||
proxy.onBufferColorChange()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override def getBackgroundColor = data.background.value
|
private def truncateToViewport(col: Int, row: Int, s: String, vertical: Boolean): String = {
|
||||||
|
var start: Int = 0
|
||||||
override def isBackgroundFromPalette = data.background.isPalette
|
var last: Int = -1
|
||||||
|
if (vertical) {
|
||||||
def copy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) =
|
val box = truncateToViewport(col, row, col, row + s.length - 1)
|
||||||
if (data.copy(col, row, w, h, tx, ty))
|
if (box.isVisible) {
|
||||||
proxy.onBufferCopy(col, row, w, h, tx, ty)
|
start = box.y1 - row
|
||||||
|
last = box.y2 - row
|
||||||
def fill(col: Int, row: Int, w: Int, h: Int, c: Char) =
|
}
|
||||||
if (data.fill(col, row, w, h, c))
|
} else {
|
||||||
proxy.onBufferFill(col, row, w, h, c)
|
val box = truncateToViewport(col, row, col + s.length - 1, row)
|
||||||
|
if (box.isVisible) {
|
||||||
def set(col: Int, row: Int, s: String, vertical: Boolean): Unit =
|
start = box.x1 - col
|
||||||
if (col < data.width && (col >= 0 || -col < s.length)) {
|
last = box.x2 - col
|
||||||
// Make sure the string isn't longer than it needs to be, in particular to
|
}
|
||||||
// avoid sending too much data to our clients.
|
|
||||||
val (x, y, truncated) =
|
|
||||||
if (vertical) {
|
|
||||||
if (row < 0) (col, 0, s.substring(-row))
|
|
||||||
else (col, row, s.substring(0, math.min(s.length, data.height - row)))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (col < 0) (0, row, s.substring(-col))
|
|
||||||
else (col, row, s.substring(0, math.min(s.length, data.width - col)))
|
|
||||||
}
|
|
||||||
if (data.set(x, y, truncated, vertical))
|
|
||||||
proxy.onBufferSet(x, row, truncated, vertical)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def get(col: Int, row: Int) = data.get(col, row)
|
if (last >= start && start >= 0 && last < s.length) {
|
||||||
|
s.substring(start, last + 1)
|
||||||
override def getForegroundColor(column: Int, row: Int) =
|
} else {
|
||||||
if (isForegroundFromPalette(column, row)) {
|
""
|
||||||
PackedColor.extractForeground(color(column, row))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PackedColor.unpackForeground(color(column, row), data.format)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override def isForegroundFromPalette(column: Int, row: Int) =
|
override def onBufferSet(col: Int, row: Int, s: String, vertical: Boolean): Unit = {
|
||||||
data.format.isFromPalette(PackedColor.extractForeground(color(column, row)))
|
// only notify about viewport changes
|
||||||
|
val truncatedString = truncateToViewport(col, row, s, vertical)
|
||||||
override def getBackgroundColor(column: Int, row: Int) =
|
if (!truncatedString.isEmpty) {
|
||||||
if (isBackgroundFromPalette(column, row)) {
|
proxy.onBufferSet(col, row, truncatedString, vertical)
|
||||||
PackedColor.extractBackground(color(column, row))
|
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
PackedColor.unpackBackground(color(column, row), data.format)
|
|
||||||
}
|
|
||||||
|
|
||||||
override def isBackgroundFromPalette(column: Int, row: Int) =
|
|
||||||
data.format.isFromPalette(PackedColor.extractBackground(color(column, row)))
|
|
||||||
|
|
||||||
override def rawSetText(col: Int, row: Int, text: Array[Array[Char]]): Unit = {
|
override def rawSetText(col: Int, row: Int, text: Array[Array[Char]]): Unit = {
|
||||||
for (y <- row until ((row + text.length) min data.height)) {
|
super.rawSetText(col, row, text)
|
||||||
val line = text(y - row)
|
|
||||||
Array.copy(line, 0, data.buffer(y), col, line.length min data.width)
|
|
||||||
}
|
|
||||||
proxy.onBufferRawSetText(col, row, text)
|
proxy.onBufferRawSetText(col, row, text)
|
||||||
}
|
}
|
||||||
|
|
||||||
override def rawSetBackground(col: Int, row: Int, color: Array[Array[Int]]): Unit = {
|
override def rawSetBackground(col: Int, row: Int, color: Array[Array[Int]]): Unit = {
|
||||||
for (y <- row until ((row + color.length) min data.height)) {
|
super.rawSetBackground(col, row, color)
|
||||||
val line = color(y - row)
|
|
||||||
for (x <- col until ((col + line.length) min data.width)) {
|
|
||||||
val packedBackground = data.color(row)(col) & 0x00FF
|
|
||||||
val packedForeground = (data.format.deflate(PackedColor.Color(line(x - col))) << PackedColor.ForegroundShift) & 0xFF00
|
|
||||||
data.color(row)(col) = (packedForeground | packedBackground).toShort
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Better for bandwidth to send packed shorts here. Would need a special case for handling on client,
|
// Better for bandwidth to send packed shorts here. Would need a special case for handling on client,
|
||||||
// though, so let's be wasteful for once...
|
// though, so let's be wasteful for once...
|
||||||
proxy.onBufferRawSetBackground(col, row, color)
|
proxy.onBufferRawSetBackground(col, row, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
override def rawSetForeground(col: Int, row: Int, color: Array[Array[Int]]): Unit = {
|
override def rawSetForeground(col: Int, row: Int, color: Array[Array[Int]]): Unit = {
|
||||||
for (y <- row until ((row + color.length) min data.height)) {
|
super.rawSetForeground(col, row, color)
|
||||||
val line = color(y - row)
|
|
||||||
for (x <- col until ((col + line.length) min data.width)) {
|
|
||||||
val packedBackground = data.format.deflate(PackedColor.Color(line(x - col))) & 0x00FF
|
|
||||||
val packedForeground = data.color(row)(col) & 0xFF00
|
|
||||||
data.color(row)(col) = (packedForeground | packedBackground).toShort
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Better for bandwidth to send packed shorts here. Would need a special case for handling on client,
|
// Better for bandwidth to send packed shorts here. Would need a special case for handling on client,
|
||||||
// though, so let's be wasteful for once...
|
// though, so let's be wasteful for once...
|
||||||
proxy.onBufferRawSetForeground(col, row, color)
|
proxy.onBufferRawSetForeground(col, row, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
private def color(column: Int, row: Int) = {
|
@SideOnly(Side.CLIENT)
|
||||||
if (column < 0 || column >= getWidth || row < 0 || row >= getHeight)
|
override def renderText: Boolean = relativeLitArea != 0 && proxy.render()
|
||||||
throw new IndexOutOfBoundsException()
|
|
||||||
else data.color(row)(column)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
override def renderText() = relativeLitArea != 0 && proxy.render()
|
override def renderWidth: Int = TextBufferRenderCache.renderer.charRenderWidth * getViewportWidth
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
override def renderWidth = TextBufferRenderCache.renderer.charRenderWidth * getViewportWidth
|
override def renderHeight: Int = TextBufferRenderCache.renderer.charRenderHeight * getViewportHeight
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
override def renderHeight = TextBufferRenderCache.renderer.charRenderHeight * getViewportHeight
|
override def setRenderingEnabled(enabled: Boolean): Unit = isRendering = enabled
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
override def setRenderingEnabled(enabled: Boolean) = isRendering = enabled
|
override def isRenderingEnabled: Boolean = isRendering
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
override def keyDown(character: Char, code: Int, player: EntityPlayer): Unit =
|
||||||
override def isRenderingEnabled = isRendering
|
|
||||||
|
|
||||||
override def keyDown(character: Char, code: Int, player: EntityPlayer) =
|
|
||||||
proxy.keyDown(character, code, player)
|
proxy.keyDown(character, code, player)
|
||||||
|
|
||||||
override def keyUp(character: Char, code: Int, player: EntityPlayer) =
|
override def keyUp(character: Char, code: Int, player: EntityPlayer): Unit =
|
||||||
proxy.keyUp(character, code, player)
|
proxy.keyUp(character, code, player)
|
||||||
|
|
||||||
override def clipboard(value: String, player: EntityPlayer) =
|
override def clipboard(value: String, player: EntityPlayer): Unit =
|
||||||
proxy.clipboard(value, player)
|
proxy.clipboard(value, player)
|
||||||
|
|
||||||
override def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer) =
|
override def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer): Unit =
|
||||||
proxy.mouseDown(x, y, button, player)
|
proxy.mouseDown(x, y, button, player)
|
||||||
|
|
||||||
override def mouseDrag(x: Double, y: Double, button: Int, player: EntityPlayer) =
|
override def mouseDrag(x: Double, y: Double, button: Int, player: EntityPlayer): Unit =
|
||||||
proxy.mouseDrag(x, y, button, player)
|
proxy.mouseDrag(x, y, button, player)
|
||||||
|
|
||||||
override def mouseUp(x: Double, y: Double, button: Int, player: EntityPlayer) =
|
override def mouseUp(x: Double, y: Double, button: Int, player: EntityPlayer): Unit =
|
||||||
proxy.mouseUp(x, y, button, player)
|
proxy.mouseUp(x, y, button, player)
|
||||||
|
|
||||||
override def mouseScroll(x: Double, y: Double, delta: Int, player: EntityPlayer) =
|
override def mouseScroll(x: Double, y: Double, delta: Int, player: EntityPlayer): Unit =
|
||||||
proxy.mouseScroll(x, y, delta, player)
|
proxy.mouseScroll(x, y, delta, player)
|
||||||
|
|
||||||
def copyToAnalyzer(line: Int, player: EntityPlayer): Unit = {
|
def copyToAnalyzer(line: Int, player: EntityPlayer): Unit = {
|
||||||
@ -542,7 +490,7 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Null check for Waila (and other mods that may call this client side).
|
// Null check for Waila (and other mods that may call this client side).
|
||||||
override def save(nbt: NBTTagCompound) = if (node != null) {
|
override def save(nbt: NBTTagCompound): Unit = if (node != null) {
|
||||||
super.save(nbt)
|
super.save(nbt)
|
||||||
// Happy thread synchronization hack! Here's the problem: GPUs allow direct
|
// Happy thread synchronization hack! Here's the problem: GPUs allow direct
|
||||||
// calls for modifying screens to give a more responsive experience. This
|
// calls for modifying screens to give a more responsive experience. This
|
||||||
@ -930,4 +878,4 @@ object TextBuffer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,154 @@
|
|||||||
|
package li.cil.oc.common.component.traits
|
||||||
|
|
||||||
|
import li.cil.oc.util
|
||||||
|
import li.cil.oc.api
|
||||||
|
import li.cil.oc.api.internal.TextBuffer
|
||||||
|
import li.cil.oc.util.PackedColor
|
||||||
|
|
||||||
|
trait TextBufferProxy extends api.internal.TextBuffer {
|
||||||
|
def data: util.TextBuffer
|
||||||
|
|
||||||
|
override def getWidth: Int = data.width
|
||||||
|
|
||||||
|
override def getHeight: Int = data.height
|
||||||
|
|
||||||
|
override def setColorDepth(depth: api.internal.TextBuffer.ColorDepth): Boolean = {
|
||||||
|
if (depth.ordinal > getMaximumColorDepth.ordinal)
|
||||||
|
throw new IllegalArgumentException("unsupported depth")
|
||||||
|
data.format = PackedColor.Depth.format(depth)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def getColorDepth: TextBuffer.ColorDepth = data.format.depth
|
||||||
|
|
||||||
|
override def setPaletteColor(index: Int, color: Int): Unit = data.format match {
|
||||||
|
case palette: PackedColor.MutablePaletteFormat =>
|
||||||
|
palette(index) = color
|
||||||
|
case _ => throw new Exception("palette not available")
|
||||||
|
}
|
||||||
|
|
||||||
|
override def getPaletteColor(index: Int): Int = data.format match {
|
||||||
|
case palette: PackedColor.MutablePaletteFormat => palette(index)
|
||||||
|
case _ => throw new Exception("palette not available")
|
||||||
|
}
|
||||||
|
|
||||||
|
def onBufferColorChange(): Unit = {}
|
||||||
|
|
||||||
|
override def setForegroundColor(color: Int): Unit = setForegroundColor(color, isFromPalette = false)
|
||||||
|
|
||||||
|
override def setForegroundColor(color: Int, isFromPalette: Boolean) {
|
||||||
|
val value = PackedColor.Color(color, isFromPalette)
|
||||||
|
if (data.foreground != value) {
|
||||||
|
data.foreground = value
|
||||||
|
onBufferColorChange()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def getForegroundColor: Int = data.foreground.value
|
||||||
|
|
||||||
|
override def isForegroundFromPalette: Boolean = data.foreground.isPalette
|
||||||
|
|
||||||
|
override def setBackgroundColor(color: Int): Unit = setBackgroundColor(color, isFromPalette = false)
|
||||||
|
|
||||||
|
override def setBackgroundColor(color: Int, isFromPalette: Boolean) {
|
||||||
|
val value = PackedColor.Color(color, isFromPalette)
|
||||||
|
if (data.background != value) {
|
||||||
|
data.background = value
|
||||||
|
onBufferColorChange()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def getBackgroundColor: Int = data.background.value
|
||||||
|
|
||||||
|
override def isBackgroundFromPalette: Boolean = data.background.isPalette
|
||||||
|
|
||||||
|
def onBufferCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int): Unit = {}
|
||||||
|
|
||||||
|
def copy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int): Unit =
|
||||||
|
if (data.copy(col, row, w, h, tx, ty))
|
||||||
|
onBufferCopy(col, row, w, h, tx, ty)
|
||||||
|
|
||||||
|
def onBufferFill(col: Int, row: Int, w: Int, h: Int, c: Char): Unit = {}
|
||||||
|
|
||||||
|
def fill(col: Int, row: Int, w: Int, h: Int, c: Char): Unit =
|
||||||
|
if (data.fill(col, row, w, h, c))
|
||||||
|
onBufferFill(col, row, w, h, c)
|
||||||
|
|
||||||
|
def onBufferSet(col: Int, row: Int, s: String, vertical: Boolean): Unit = {}
|
||||||
|
|
||||||
|
def set(col: Int, row: Int, s: String, vertical: Boolean): Unit =
|
||||||
|
if (col < data.width && (col >= 0 || -col < s.length)) {
|
||||||
|
// Make sure the string isn't longer than it needs to be, in particular to
|
||||||
|
// avoid sending too much data to our clients.
|
||||||
|
val (x, y, truncated) =
|
||||||
|
if (vertical) {
|
||||||
|
if (row < 0) (col, 0, s.substring(-row))
|
||||||
|
else (col, row, s.substring(0, math.min(s.length, data.height - row)))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (col < 0) (0, row, s.substring(-col))
|
||||||
|
else (col, row, s.substring(0, math.min(s.length, data.width - col)))
|
||||||
|
}
|
||||||
|
if (data.set(x, y, truncated, vertical))
|
||||||
|
onBufferSet(x, row, truncated, vertical)
|
||||||
|
}
|
||||||
|
|
||||||
|
def get(col: Int, row: Int): Char = data.get(col, row)
|
||||||
|
|
||||||
|
override def getForegroundColor(column: Int, row: Int): Int =
|
||||||
|
if (isForegroundFromPalette(column, row)) {
|
||||||
|
PackedColor.extractForeground(color(column, row))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PackedColor.unpackForeground(color(column, row), data.format)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def isForegroundFromPalette(column: Int, row: Int): Boolean =
|
||||||
|
data.format.isFromPalette(PackedColor.extractForeground(color(column, row)))
|
||||||
|
|
||||||
|
override def getBackgroundColor(column: Int, row: Int): Int =
|
||||||
|
if (isBackgroundFromPalette(column, row)) {
|
||||||
|
PackedColor.extractBackground(color(column, row))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PackedColor.unpackBackground(color(column, row), data.format)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def isBackgroundFromPalette(column: Int, row: Int): Boolean =
|
||||||
|
data.format.isFromPalette(PackedColor.extractBackground(color(column, row)))
|
||||||
|
|
||||||
|
override def rawSetText(col: Int, row: Int, text: Array[Array[Char]]): Unit = {
|
||||||
|
for (y <- row until ((row + text.length) min data.height)) {
|
||||||
|
val line = text(y - row)
|
||||||
|
Array.copy(line, 0, data.buffer(y), col, line.length min data.width)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def rawSetForeground(col: Int, row: Int, color: Array[Array[Int]]): Unit = {
|
||||||
|
for (y <- row until ((row + color.length) min data.height)) {
|
||||||
|
val line = color(y - row)
|
||||||
|
for (x <- col until ((col + line.length) min data.width)) {
|
||||||
|
val packedBackground = data.format.deflate(PackedColor.Color(line(x - col))) & 0x00FF
|
||||||
|
val packedForeground = data.color(row)(col) & 0xFF00
|
||||||
|
data.color(row)(col) = (packedForeground | packedBackground).toShort
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def rawSetBackground(col: Int, row: Int, color: Array[Array[Int]]): Unit = {
|
||||||
|
for (y <- row until ((row + color.length) min data.height)) {
|
||||||
|
val line = color(y - row)
|
||||||
|
for (x <- col until ((col + line.length) min data.width)) {
|
||||||
|
val packedBackground = data.color(row)(col) & 0x00FF
|
||||||
|
val packedForeground = (data.format.deflate(PackedColor.Color(line(x - col))) << PackedColor.ForegroundShift) & 0xFF00
|
||||||
|
data.color(row)(col) = (packedForeground | packedBackground).toShort
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private def color(column: Int, row: Int): Short = {
|
||||||
|
if (column < 0 || column >= getWidth || row < 0 || row >= getHeight)
|
||||||
|
throw new IndexOutOfBoundsException()
|
||||||
|
else data.color(row)(column)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user