Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/main/java/li/cil/oc/util/NbtDataStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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(
Expand All @@ -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 _))
}
3 changes: 2 additions & 1 deletion src/main/scala/li/cil/oc/server/component/GraphicsCard.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
24 changes: 12 additions & 12 deletions src/main/scala/li/cil/oc/util/PackedColor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ object PackedColor {
}
}

def deflate(value: Color): Byte
def deflate(value: Color): Short

def isFromPalette(value: Int): Boolean = false

Expand Down Expand Up @@ -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
Expand All @@ -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))
}
6 changes: 3 additions & 3 deletions src/main/scala/li/cil/oc/util/TextBuffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading