blob: 246a6d82e8d9ab430a1e97afb0d230ce1728ea4c [file] [log] [blame] [raw]
package li.cil.oc.server.component
import li.cil.oc.api.network.{Node, Visibility, Message}
import li.cil.oc.common.component.ScreenEnvironment
import net.minecraft.nbt.NBTTagCompound
class GraphicsCard extends Node {
val supportedResolutions = List(List(40, 24), List(80, 24))
private var screen: Option[String] = None
// ----------------------------------------------------------------------- //
override def name = "gpu"
override def visibility = Visibility.Neighbors
override def receive(message: Message) = {
super.receive(message)
message.data match {
case Array(address: Array[Byte]) if message.name == "gpu.bind" =>
network.fold(None: Option[Array[Any]])(network => {
network.node(new String(address, "UTF-8")) match {
case None => Some(Array(Unit, "invalid address"))
case Some(node: ScreenEnvironment) =>
screen = node.address
Some(Array(true.asInstanceOf[Any]))
case _ => Some(Array(Unit, "not a screen"))
}
})
case Array() if message.name == "network.disconnect" && message.source.address == screen => screen = None; None
case Array(w: Double, h: Double) if message.name == "gpu.resolution=" =>
if (supportedResolutions.contains((w.toInt, h.toInt)))
trySend("screen.resolution=", w.toInt, h.toInt)
else
Some(Array(Unit, "unsupported resolution"))
case Array() if message.name == "gpu.resolution" => trySend("screen.resolution")
case Array() if message.name == "gpu.resolutions" => trySend("screen.resolutions") match {
case Some(Array(resolutions@_*)) =>
Some(Array(supportedResolutions.intersect(resolutions): _*))
case _ => None
}
case Array(x: Double, y: Double, value: Array[Byte]) if message.name == "gpu.set" =>
trySend("screen.set", x.toInt - 1, y.toInt - 1, new String(value, "UTF-8"))
case Array(x: Double, y: Double, w: Double, h: Double, value: Array[Byte]) if message.name == "gpu.fill" =>
val s = new String(value, "UTF-8")
if (s.length == 1)
trySend("screen.fill", x.toInt - 1, y.toInt - 1, w.toInt, h.toInt, s.charAt(0))
else
Some(Array(Unit, "invalid fill value"))
case Array(x: Double, y: Double, w: Double, h: Double, tx: Double, ty: Double) if message.name == "gpu.copy" =>
trySend("screen.copy", x.toInt - 1, y.toInt - 1, w.toInt, h.toInt, tx.toInt, ty.toInt)
case _ => None
}
}
override protected def onDisconnect() = {
super.onDisconnect()
screen = None
}
override def load(nbt: NBTTagCompound) = {
super.load(nbt)
if (nbt.hasKey("screen"))
screen = Some(nbt.getString("screen"))
}
override def save(nbt: NBTTagCompound) = {
super.save(nbt)
if (screen.isDefined)
nbt.setString("screen", screen.get)
}
// ----------------------------------------------------------------------- //
private def trySend(name: String, data: Any*): Option[Array[Any]] =
screen match {
case None => Some(Array(Unit, "no screen"))
case Some(screenAddress) => network.fold(None: Option[Array[Any]])(net => {
net.sendToAddress(this, screenAddress, name, data: _*)
})
}
}