diff --git a/src/main/java/li/cil/oc/util/NbtDataStream.java b/src/main/java/li/cil/oc/util/NbtDataStream.java index 343c8fcf8c..933a16ca1d 100644 --- a/src/main/java/li/cil/oc/util/NbtDataStream.java +++ b/src/main/java/li/cil/oc/util/NbtDataStream.java @@ -12,30 +12,30 @@ public final class NbtDataStream { private NbtDataStream() { } - public static boolean getShortArray(CompoundTag nbt, String key, short[][] array, int width, int height) + public static boolean getIntArray(CompoundTag nbt, String key, int[][] array, int width, int height) throws IOException { if (!nbt.contains(key)) return false; DataInputStream input = new DataInputStream(new ByteArrayInputStream(nbt.getByteArray(key))); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { - if (input.available() < Short.BYTES) return true; - array[y][x] = input.readShort(); + if (input.available() < Integer.BYTES) return true; + array[y][x] = input.readInt(); } } return true; } - public static boolean getIntArrayLegacy(CompoundTag nbt, String key, short[][] array, int width, int height) { + public static boolean getIntArrayLegacy(CompoundTag nbt, String key, int[][] array, int width, int height) { if (!nbt.contains(key)) return false; int[] colors = nbt.getIntArray(key); for (int y = 0; y < height; y++) { - short[] row = array[y]; + int[] row = array[y]; for (int x = 0; x < width; x++) { int index = x + y * width; if (index >= colors.length) return true; - row[x] = (short) colors[index]; + row[x] = (int) colors[index]; } } return true; diff --git a/src/main/scala/li/cil/oc/common/component/traits/TextBufferProxy.scala b/src/main/scala/li/cil/oc/common/component/traits/TextBufferProxy.scala index 4c2910bd9a..b947b20d48 100644 --- a/src/main/scala/li/cil/oc/common/component/traits/TextBufferProxy.scala +++ b/src/main/scala/li/cil/oc/common/component/traits/TextBufferProxy.scala @@ -195,7 +195,7 @@ trait TextBufferProxy extends api.internal.TextBuffer { } } - private def color(column: Int, row: Int): Short = { + private def color(column: Int, row: Int): Int = { if (column < 0 || column >= getWidth || row < 0 || row >= getHeight) throw new IndexOutOfBoundsException() else data.color(row)(column) diff --git a/src/main/scala/li/cil/oc/common/datacomponents/Migrators.scala b/src/main/scala/li/cil/oc/common/datacomponents/Migrators.scala index 3cc6ad0fa9..950ff6a70e 100644 --- a/src/main/scala/li/cil/oc/common/datacomponents/Migrators.scala +++ b/src/main/scala/li/cil/oc/common/datacomponents/Migrators.scala @@ -6,7 +6,7 @@ import li.cil.oc.Settings import li.cil.oc.api.ImmutableItemStack import li.cil.oc.api.network.Visibility import li.cil.oc.common.datacomponents.MachineData.Signal -import li.cil.oc.common.datacomponents.TextBufferContents.ShortArray +import li.cil.oc.common.datacomponents.TextBufferContents.IntArray import li.cil.oc.common.item.data.PrintData import li.cil.oc.server.component.DebugCard.AccessContext import li.cil.oc.server.machine.Machine @@ -435,15 +435,15 @@ private object Migrators { val background = by(de.int("background") orElse 0) val backgroundIsPalette = by(de.boolean("backgroundIsPalette") orElse false) - val color = Array.fill[Short](height, width)(0) - if (!NbtDataStream.getShortArray(de.tag, "colors", color, width, height)) { + val color = Array.fill[Int](height, width)(0) + if (!NbtDataStream.getIntArray(de.tag, "colors", color, width, height)) { NbtDataStream.getIntArrayLegacy(de.tag, "color", color, width, height) by(de.tag("color")) } else { by(de.tag("colors")) } - TextBufferContents(width, height, depth, foreground, foregroundIsPalette, background, backgroundIsPalette, buffer, new ShortArray(color)) + TextBufferContents(width, height, depth, foreground, foregroundIsPalette, background, backgroundIsPalette, buffer, new IntArray(color)) } } register(OCComponents.IS_ON) { _.boolean(oc -> "isOn").andRemove } diff --git a/src/main/scala/li/cil/oc/common/datacomponents/TextBufferContents.scala b/src/main/scala/li/cil/oc/common/datacomponents/TextBufferContents.scala index da46067101..0e4939ca0f 100644 --- a/src/main/scala/li/cil/oc/common/datacomponents/TextBufferContents.scala +++ b/src/main/scala/li/cil/oc/common/datacomponents/TextBufferContents.scala @@ -2,9 +2,9 @@ package li.cil.oc.common.datacomponents import com.mojang.serialization.Codec import com.mojang.serialization.codecs.RecordCodecBuilder -import li.cil.oc.common.datacomponents.TextBufferContents.ShortArray +import li.cil.oc.common.datacomponents.TextBufferContents.IntArray -import java.nio.{ByteBuffer, ShortBuffer} +import java.nio.{ByteBuffer, IntBuffer} case class TextBufferContents(width: Int, height: Int, @@ -14,45 +14,45 @@ case class TextBufferContents(width: Int, background: Int, backgroundIsPalette: Boolean, buffer: List[String], - colors: ShortArray) + colors: IntArray) object TextBufferContents { - final class ShortArray(values: Array[Short]) { + final class IntArray(values: Array[Int]) { private val array = values.clone() - def this(array: Array[Array[Short]]) = this(array.flatten) + def this(array: Array[Array[Int]]) = this(array.flatten) - def this(buf: ShortBuffer) = { - this(Array.fill[Short](buf.remaining()) { 0 }) + def this(buf: IntBuffer) = { + this(Array.fill[Int](buf.remaining()) { 0 }) buf.get(array) } def this(buf: ByteBuffer) = { - this(buf.asShortBuffer()) + this(buf.asIntBuffer()) } def intoByteBuffer(): ByteBuffer = { - val bytes = ByteBuffer.allocate(array.length * 2) - bytes.asShortBuffer().put(array) + val bytes = ByteBuffer.allocate(array.length * 4) + bytes.asIntBuffer().put(array) bytes } - def sized(width: Int, height: Int): Array[Array[Short]] = - Array.tabulate[Short](height, width) { (y, x) => + def sized(width: Int, height: Int): Array[Array[Int]] = + Array.tabulate[Int](height, width) { (y, x) => val index = y * width + x if (index < array.length) array(index) else 0 } override def equals(other: Any): Boolean = other match { - case that: ShortArray => java.util.Arrays.equals(array, that.array) + case that: IntArray => java.util.Arrays.equals(array, that.array) case _ => false } override def hashCode(): Int = java.util.Arrays.hashCode(array) } - object ShortArray { - val CODEC: Codec[ShortArray] = Codec.BYTE_BUFFER.xmap(buf => new ShortArray(buf), array => array.intoByteBuffer()) + object IntArray { + val CODEC: Codec[IntArray] = Codec.BYTE_BUFFER.xmap(buf => new IntArray(buf), array => array.intoByteBuffer()) } val CODEC: Codec[TextBufferContents] = RecordCodecBuilder.create(inst => inst.group( @@ -64,6 +64,6 @@ object TextBufferContents { ScalaCodec.INT.fieldOf("background").forGetter(_.background), ScalaCodec.BOOL.fieldOf("backgroundIsPalette").forGetter(_.backgroundIsPalette), ScalaCodec.list(Codec.STRING).fieldOf("buffer").forGetter(_.buffer), - ShortArray.CODEC.fieldOf("colors").forGetter(_.colors) + IntArray.CODEC.fieldOf("colors").forGetter(_.colors) ).apply(inst, TextBufferContents.apply _)) } diff --git a/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala b/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala index 2a647360bc..c4058d228b 100644 --- a/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala +++ b/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala @@ -154,7 +154,7 @@ class GraphicsCard(val tier: Int, val vramScreens: Option[Double] = None, val vi def buffers(context: Context, args: Arguments): Array[AnyRef] = { result(bufferIndexes()) } - + @Callback(direct = true, doc = """function([width: number, height: number]): number -- allocates a new buffer with dimensions width*height (defaults to max resolution) and appends it to the buffer list. Returns the index of the new buffer and returns nil with an error message on failure. A buffer can be allocated even when there is no screen bound to this gpu. Index 0 is always reserved for the screen and thus the lowest index of an allocated buffer is always 1.""") def allocateBuffer(context: Context, args: Arguments): Array[AnyRef] = { val width: Int = args.optInteger(0, maxResolution._1) @@ -410,6 +410,7 @@ class GraphicsCard(val tier: Int, val vramScreens: Option[Double] = None, val vi case 1 => s.setColorDepth(api.internal.TextBuffer.ColorDepth.OneBit) case 4 if maxDepth.ordinal >= api.internal.TextBuffer.ColorDepth.FourBit.ordinal => s.setColorDepth(api.internal.TextBuffer.ColorDepth.FourBit) case 8 if maxDepth.ordinal >= api.internal.TextBuffer.ColorDepth.EightBit.ordinal => s.setColorDepth(api.internal.TextBuffer.ColorDepth.EightBit) + case 16 if maxDepth.ordinal >= api.internal.TextBuffer.ColorDepth.SixteenBit.ordinal => s.setColorDepth(api.internal.TextBuffer.ColorDepth.SixteenBit) case _ => throw new IllegalArgumentException("unsupported depth") } result(oldDepth) diff --git a/src/main/scala/li/cil/oc/util/PackedColor.scala b/src/main/scala/li/cil/oc/util/PackedColor.scala index abcaa93642..8f51d1004c 100644 --- a/src/main/scala/li/cil/oc/util/PackedColor.scala +++ b/src/main/scala/li/cil/oc/util/PackedColor.scala @@ -50,7 +50,7 @@ object PackedColor { } } - def deflate(value: Color): Byte + def deflate(value: Color): Short def isFromPalette(value: Int): Boolean = false @@ -209,12 +209,12 @@ object PackedColor { if (isFromPalette(value)) super.inflate(value) else fromRGB565(value - palette.length) - override def deflate(value: Color): Byte = { + override def deflate(value: Color): Short = { val paletteIndex = super.deflate(value) if (value.isPalette) paletteIndex else { - val deflated = (palette.length + toRGB565(value.value)).toByte - if (delta(inflate(deflated & 0xFF), value.value) < delta(inflate(paletteIndex & 0xFF), value.value)) + val deflated = (palette.length + toRGB565(value.value)).toShort + if (delta(inflate(deflated & 0xFFFF), value.value) < delta(inflate(paletteIndex & 0xFFFF), value.value)) deflated else paletteIndex @@ -226,21 +226,21 @@ object PackedColor { case class Color(value: Int, isPalette: Boolean = false) - // Colors are packed: 0xFFBB (F = foreground, B = background) - val ForegroundShift = 8 - val BackgroundMask = 0x000000FF + // Colors are packed: 0xFFFFBBBB (F = foreground, B = background) + val ForegroundShift = 16 + val BackgroundMask = 0x0000FFFF def pack(foreground: Color, background: Color, format: ColorFormat) = { - (((format.deflate(foreground) & 0xFF) << ForegroundShift) | (format.deflate(background) & 0xFF)).toShort + (((format.deflate(foreground) & 0xFFFF) << ForegroundShift) | (format.deflate(background) & 0xFFFF)).toInt } - def extractForeground(color: Short) = (color & 0xFFFF) >>> ForegroundShift + def extractForeground(color: Int) = (color & 0xFFFFFFFF) >>> ForegroundShift - def extractBackground(color: Short) = color & BackgroundMask + def extractBackground(color: Int) = color & BackgroundMask - def unpackForeground(color: Short, format: ColorFormat) = + def unpackForeground(color: Int, format: ColorFormat) = format.inflate(extractForeground(color)) - def unpackBackground(color: Short, format: ColorFormat) = + def unpackBackground(color: Int, format: ColorFormat) = format.inflate(extractBackground(color)) } diff --git a/src/main/scala/li/cil/oc/util/TextBuffer.scala b/src/main/scala/li/cil/oc/util/TextBuffer.scala index 32b4138fca..df3df7f084 100644 --- a/src/main/scala/li/cil/oc/util/TextBuffer.scala +++ b/src/main/scala/li/cil/oc/util/TextBuffer.scala @@ -69,7 +69,7 @@ class TextBuffer(var width: Int, var height: Int, initialFormat: PackedColor.Col else false } - var color: Array[Array[Short]] = Array.fill(height, width)(packed) + var color: Array[Array[Int]] = Array.fill(height, width)(packed) var buffer: Array[Array[Int]] = Array.fill(height, width)(0x20) @@ -256,7 +256,7 @@ class TextBuffer(var width: Int, var height: Int, initialFormat: PackedColor.Col changed } - private def setChar(line: Array[Int], lineColor: Array[Short], x: Int, c: Int): Unit = { + private def setChar(line: Array[Int], lineColor: Array[Int], x: Int, c: Int): Unit = { if (FontUtils.wcwidth(c) > 1 && x >= line.length - 1) { // Don't allow setting wide chars in right-most col. return @@ -307,7 +307,7 @@ class TextBuffer(var width: Int, var height: Int, initialFormat: PackedColor.Col _background.value, _background.isPalette, List.tabulate[String](height) { lineToString }, - new TextBufferContents.ShortArray(color) + new TextBufferContents.IntArray(color) )) // Palette formats keep their mutable palette outside TextBufferContents. // Persist it alongside the buffer so palette reads remain available after