From 22d020004c7580253eee1220a23c58b620162dac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sat, 31 May 2014 01:02:42 +0200 Subject: [PATCH] Bind GPU to screen in kernel, to allow boot errors to show up on the screen before an OS binds it. Set resolution and depth to max in GPU's crash display (bluescreen). --- .../assets/opencomputers/lua/kernel.lua | 29 +++++---- .../oc/server/component/GraphicsCard.scala | 62 ++++++++++--------- 2 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/main/resources/assets/opencomputers/lua/kernel.lua b/src/main/resources/assets/opencomputers/lua/kernel.lua index 492144cbf..15373d6f2 100644 --- a/src/main/resources/assets/opencomputers/lua/kernel.lua +++ b/src/main/resources/assets/opencomputers/lua/kernel.lua @@ -538,28 +538,35 @@ sandbox.unicode = libunicode ------------------------------------------------------------------------------- local function bootstrap() - local function tryLoadFrom(address) - function boot_invoke(method, ...) - local result = table.pack(pcall(invoke, component, true, address, method, ...)) - if not result[1] then - return nil, result[2] - else - return table.unpack(result, 2, result.n) - end + function boot_invoke(address, method, ...) + local result = table.pack(pcall(invoke, component, true, address, method, ...)) + if not result[1] then + return nil, result[2] + else + return table.unpack(result, 2, result.n) end - local handle, reason = boot_invoke("open", "/init.lua") + end + do + local screen = libcomponent.list("screen")() + local gpu = libcomponent.list("gpu")() + if gpu and screen then + boot_invoke(gpu, "bind", screen) + end + end + local function tryLoadFrom(address) + local handle, reason = boot_invoke(address, "open", "/init.lua") if not handle then return nil, reason end local buffer = "" repeat - local data, reason = boot_invoke("read", handle, math.huge) + local data, reason = boot_invoke(address, "read", handle, math.huge) if not data and reason then return nil, reason end buffer = buffer .. (data or "") until not data - boot_invoke("close", handle) + boot_invoke(address, "close", handle) return load(buffer, "=init", "t", sandbox) end local init, reason 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 1f866baf8..1d9a22715 100644 --- a/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala +++ b/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala @@ -2,13 +2,14 @@ package li.cil.oc.server.component import li.cil.oc.Settings import li.cil.oc.api.Network +import li.cil.oc.api.component.TextBuffer import li.cil.oc.api.component.TextBuffer.ColorDepth import li.cil.oc.api.network._ import li.cil.oc.common.component import li.cil.oc.util.PackedColor import net.minecraft.nbt.NBTTagCompound import net.minecraft.util.StatCollector -import li.cil.oc.api.component.TextBuffer +import scala.collection.convert.WrapAsScala._ abstract class GraphicsCard extends component.ManagedComponent { val node = Network.newNode(this, Visibility.Neighbors). @@ -233,36 +234,39 @@ abstract class GraphicsCard extends component.ManagedComponent { override def onMessage(message: Message) { super.onMessage(message) if (message.name == "computer.stopped" && node.isNeighborOf(message.source)) { - screenInstance match { - case Some(buffer) => buffer.synchronized { - val w = buffer.getWidth - val h = buffer.getHeight - buffer.setForegroundColor(0xFFFFFF) - message.source.host match { - case machine: machine.Machine if machine.lastError != null => - if (buffer.getColorDepth.ordinal > ColorDepth.OneBit.ordinal) buffer.setBackgroundColor(0x0000FF) - else buffer.setBackgroundColor(0x000000) - buffer.fill(0, 0, w, h, ' ') - try { - val message = "Unrecoverable error:\n" + StatCollector.translateToLocal(machine.lastError) + "\n" - val wrapRegEx = s"(.{1,${math.max(1, w - 2)}})\\s".r - val lines = wrapRegEx.replaceAllIn(message, m => m.group(1) + "\n").lines.toArray - for ((line, idx) <- lines.zipWithIndex) { - val col = (w - line.length) / 2 - val row = (h - lines.length) / 2 + idx - buffer.set(col, row, line, false) - } + screen(s => { + val (gmw, gmh) = maxResolution + val smw = s.getMaximumWidth + val smh = s.getMaximumHeight + s.setResolution(math.min(gmw, smw), math.min(gmh, smh)) + s.setColorDepth(ColorDepth.values.apply(math.min(maxDepth.ordinal, s.getMaximumColorDepth.ordinal))) + s.setForegroundColor(0xFFFFFF) + val w = s.getWidth + val h = s.getHeight + message.source.host match { + case machine: machine.Machine if machine.lastError != null => + if (s.getColorDepth.ordinal > ColorDepth.OneBit.ordinal) s.setBackgroundColor(0x0000FF) + else s.setBackgroundColor(0x000000) + s.fill(0, 0, w, h, ' ') + try { + val message = "Unrecoverable error:\n" + StatCollector.translateToLocal(machine.lastError) + "\n" + val wrapRegEx = s"(.{1,${math.max(1, w - 2)}})\\s".r + val lines = wrapRegEx.replaceAllIn(message, m => m.group(1) + "\n").lines.toArray + for ((line, idx) <- lines.zipWithIndex) { + val col = (w - line.length) / 2 + val row = (h - lines.length) / 2 + idx + s.set(col, row, line, false) } - catch { - case t: Throwable => t.printStackTrace() - } - case _ => - buffer.setBackgroundColor(0x000000) - buffer.fill(0, 0, w, h, ' ') - } + } + catch { + case t: Throwable => t.printStackTrace() + } + case _ => + s.setBackgroundColor(0x000000) + s.fill(0, 0, w, h, ' ') } - case _ => - } + null // For screen() + }) } }