diff --git a/src/net/torvald/terrarum/StateVTTest.kt b/src/net/torvald/terrarum/StateVTTest.kt index bddead353..1390ff503 100644 --- a/src/net/torvald/terrarum/StateVTTest.kt +++ b/src/net/torvald/terrarum/StateVTTest.kt @@ -2,7 +2,6 @@ package net.torvald.terrarum import net.torvald.terrarum.gamecontroller.Key import net.torvald.terrarum.virtualcomputer.computer.BaseTerrarumComputer -import net.torvald.terrarum.virtualcomputer.terminal.ColouredTextTerminal import net.torvald.terrarum.virtualcomputer.terminal.SimpleTextTerminal import net.torvald.terrarum.virtualcomputer.terminal.Teletype import net.torvald.terrarum.virtualcomputer.terminal.TeletypeTerminal @@ -20,7 +19,7 @@ import org.newdawn.slick.state.StateBasedGame */ class StateVTTest : BasicGameState() { - val vt = SimpleTextTerminal(SimpleTextTerminal.AMBER, 80, 25) + val vt = SimpleTextTerminal(SimpleTextTerminal.WHITE, 80, 43, colour = true) val computerInside = BaseTerrarumComputer(vt) val vtUI = Image(vt.displayW, vt.displayH) @@ -65,7 +64,8 @@ class StateVTTest : BasicGameState() { vt.openInput() - computerInside.runCommand("io.write(_COMPUTER.prompt)", "=prompt") + if (!computerInside.isHalted) + computerInside.runCommand("io.write(_COMPUTER.prompt)", "=prompt") } } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/virtualcomputer/assets/lua/ROMBASIC.lua b/src/net/torvald/terrarum/virtualcomputer/assets/lua/ROMBASIC.lua index 7d3086535..effcb4e81 100644 --- a/src/net/torvald/terrarum/virtualcomputer/assets/lua/ROMBASIC.lua +++ b/src/net/torvald/terrarum/virtualcomputer/assets/lua/ROMBASIC.lua @@ -20,18 +20,20 @@ _COMPUTER.prompt = function() end _COMPUTER.verbose = true -- print debug info _COMPUTER.loadedCLayer = {} -- list of loaded compatibility layers +_COMPUTER.bootloader = "/boot/efi" +_COMPUTER.OEM = "" -- load libraries that coded in Lua require("ROMLIB") - -- load bios, if any - - - --- load Lua prompt, if bios is not found -print("Rom basic " .. _COMPUTER.DC2 .. _VERSION .. _COMPUTER.DC4) --- print(_COMPUTER.DC2 .. freemem .. _COMPUTER.DC4 .. " bytes free" -print("Ok") --- prompt start ---_COMPUTER.prompt() +if fs.exists(_COMPUTER.bootloader) then shell.run(_COMPUTER.bootloader) end +if shell.status == shell.halt then + __haltsystemexplicit__() +else + -- load Lua prompt, if bios is not found + if (#_COMPUTER.OEM > 0) then print(_COMPUTER.OEM) end + print("Rom basic " .. _COMPUTER.DC2 .. _VERSION .. _COMPUTER.DC4) + -- print(_COMPUTER.DC2 .. freemem .. _COMPUTER.DC4 .. " bytes free" + print("Ok") +end diff --git a/src/net/torvald/terrarum/virtualcomputer/assets/lua/ROMLIB.lua b/src/net/torvald/terrarum/virtualcomputer/assets/lua/ROMLIB.lua index 531adbd89..e67ddc263 100644 --- a/src/net/torvald/terrarum/virtualcomputer/assets/lua/ROMLIB.lua +++ b/src/net/torvald/terrarum/virtualcomputer/assets/lua/ROMLIB.lua @@ -3,6 +3,13 @@ --]] +fs.run = function(p) + local f = fs.open(p, "r") + local s = f.readAll() + fs.dostring(s) +end + + -------------- -- HEXUTILS -- -------------- @@ -46,3 +53,143 @@ _G.hexutils.toHexString = function(byteString) return ret end + + +--------------- +-- SHELL API -- +--------------- + +_G.shell = {} +shell.status = shell.ok + +shell.run = function(p) fs.run(p) end + + +shell.ok = 0 +shell.halt = 127 + + +-------------- +-- KEYS API -- +-------------- +-- ComputerCraft compliant +local keycodeDic = { +["30"] = "a", +["48"] = "b", +["46"] = "c", +["32"] = "d", +["18"] = "e", +["33"] = "f", +["34"] = "g", +["35"] = "h", +["23"] = "i", +["36"] = "j", +["37"] = "k", +["38"] = "l", +["50"] = "m", +["49"] = "n", +["24"] = "o", +["25"] = "p", +["16"] = "q", +["19"] = "r", +["31"] = "s", +["20"] = "t", +["22"] = "u", +["47"] = "v", +["17"] = "w", +["45"] = "x", +["21"] = "y", +["44"] = "z", +["2"] = "one", +["3"] = "two", +["4"] = "three", +["5"] = "four", +["6"] = "five", +["7"] = "six", +["8"] = "seven", +["9"] = "eight", +["10"] = "nine", +["11"] = "zero", +["12"] = "minus", +["13"] = "equals", +["14"] = "backspace", +["15"] = "tab", +["26"] = "leftBracket", +["27"] = "rightBracket", +["28"] = "enter", +["29"] = "leftCtrl", +["39"] = "semiColon", +["40"] = "apostrophe", +["41"] = "grave", +["42"] = "leftShift", +["43"] = "backslash", +["51"] = "comma", +["52"] = "period", +["53"] = "slash", +["54"] = "rightShift", +["55"] = "multiply", +["56"] = "leftAlt", +["57"] = "space", +["58"] = "capsLock", +["59"] = "f1", +["60"] = "f2", +["61"] = "f3", +["62"] = "f4", +["63"] = "f5", +["64"] = "f6", +["65"] = "f7", +["66"] = "f8", +["67"] = "f9", +["68"] = "f10", +["69"] = "numLock", +["70"] = "scollLock", +["71"] = "numPad7", +["72"] = "numPad8", +["73"] = "numPad9", +["74"] = "numPadSubtract", +["75"] = "numPad4", +["76"] = "numPad5", +["77"] = "numPad6", +["78"] = "numPadAdd", +["79"] = "numPad1", +["80"] = "numPad2", +["81"] = "numPad3", +["82"] = "numPad0", +["83"] = "numPadDecimal", +["87"] = "f11", +["88"] = "f12", +["89"] = "f13", +["90"] = "f14", +["91"] = "f15", +["-1"] = "kana", +["-1"] = "convert", +["-1"] = "noconvert", +["-1"] = "yen", +["-1"] = "numPadEquals", +["144"] = "cimcumflex", +["145"] = "at", +["146"] = "colon", +["147"] = "underscore", +["-1"] = "kanji", +["-1"] = "stop", +["-1"] = "ax", +["156"] = "numPadEnter", +["157"] = "rightCtrl", +["-1"] = "numPadComma", +["181"] = "numPadDivide", +["184"] = "rightAlt", +["197"] = "pause", +["199"] = "home", +["200"] = "up", +["201"] = "pageUp", +["203"] = "left", +["208"] = "right", +["207"] = "end", +["205"] = "down", +["209"] = "pageDown", +["210"] = "insert", +["211"] = "delete", +} + +_G.keys = {} +_G.keys.getName = function(code) return keycodeDic[tostring(code)] end diff --git a/src/net/torvald/terrarum/virtualcomputer/computer/BaseTerrarumComputer.kt b/src/net/torvald/terrarum/virtualcomputer/computer/BaseTerrarumComputer.kt index cf4e7bf46..476ac120a 100644 --- a/src/net/torvald/terrarum/virtualcomputer/computer/BaseTerrarumComputer.kt +++ b/src/net/torvald/terrarum/virtualcomputer/computer/BaseTerrarumComputer.kt @@ -7,6 +7,7 @@ import li.cil.repack.org.luaj.vm2.lib.jse.JsePlatform import net.torvald.terrarum.KVHashMap import net.torvald.terrarum.gameactors.ActorValue import net.torvald.terrarum.virtualcomputer.luaapi.Filesystem +import net.torvald.terrarum.virtualcomputer.luaapi.Security import net.torvald.terrarum.virtualcomputer.luaapi.Term import net.torvald.terrarum.virtualcomputer.terminal.* import net.torvald.terrarum.virtualcomputer.worldobject.FixtureComputerBase @@ -32,10 +33,12 @@ class BaseTerrarumComputer(term: Teletype? = null) { var termIn: InputStream? = null private set - val UUID = "testsession"//java.util.UUID.randomUUID().toString() + val UUID = java.util.UUID.randomUUID().toString() val computerValue = KVHashMap() - + + var isHalted = false + init { computerValue["memslot0"] = -1 // -1 indicates mem slot is empty computerValue["memslot1"] = -1 // put index of item here @@ -72,6 +75,7 @@ class BaseTerrarumComputer(term: Teletype? = null) { // load libraries Term(luaJ_globals, term) + Security(luaJ_globals) Filesystem(luaJ_globals, this) } @@ -104,7 +108,7 @@ class BaseTerrarumComputer(term: Teletype? = null) { var threadRun = false fun runCommand(line: String, env: String) { - if (!threadRun) { + if (!threadRun && !isHalted) { currentExecutionThread = Thread(ThreadRunCommand(luaJ_globals, line, env)) currentExecutionThread.start() threadRun = true @@ -112,7 +116,7 @@ class BaseTerrarumComputer(term: Teletype? = null) { } fun runCommand(reader: Reader, filename: String) { - if (!threadRun) { + if (!threadRun && !isHalted) { currentExecutionThread = Thread(ThreadRunCommand(luaJ_globals, reader, filename)) currentExecutionThread.start() threadRun = true @@ -158,7 +162,7 @@ class BaseTerrarumComputer(term: Teletype? = null) { chunk.call() } catch (e: LuaError) { - lua.STDERR.println("${SimpleTextTerminal.ASCII_DC2}${e.message}${SimpleTextTerminal.ASCII_DC4}") + lua.STDERR.println("${SimpleTextTerminal.ASCII_DLE}${e.message}${SimpleTextTerminal.ASCII_DC4}") if (DEBUGTHRE) e.printStackTrace(System.err) } diff --git a/src/net/torvald/terrarum/virtualcomputer/luaapi/Filesystem.kt b/src/net/torvald/terrarum/virtualcomputer/luaapi/Filesystem.kt index cd1d45648..3865547b7 100644 --- a/src/net/torvald/terrarum/virtualcomputer/luaapi/Filesystem.kt +++ b/src/net/torvald/terrarum/virtualcomputer/luaapi/Filesystem.kt @@ -7,6 +7,8 @@ import li.cil.repack.org.luaj.vm2.lib.ZeroArgFunction import net.torvald.terrarum.Terrarum import net.torvald.terrarum.virtualcomputer.computer.BaseTerrarumComputer import java.io.* +import java.nio.file.Files +import java.nio.file.Path import java.util.* /** @@ -24,7 +26,9 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { globals["fs"]["list"] = ListFiles(computer) globals["fs"]["exists"] = FileExists(computer) globals["fs"]["isDir"] = IsDirectory(computer) + globals["fs"]["isFile"] = IsFile(computer) globals["fs"]["isReadOnly"] = IsReadOnly(computer) + globals["fs"]["getSize"] = GetSize(computer) globals["fs"]["listFiles"] = ListFiles(computer) globals["fs"]["mkdir"] = Mkdir(computer) globals["fs"]["mv"] = Mv(computer) @@ -33,6 +37,9 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { globals["fs"]["concat"] = ConcatPath(computer) globals["fs"]["open"] = OpenFile(computer) globals["fs"]["parent"] = GetParentDir(computer) + globals["__haltsystemexplicit__"] = HaltComputer(computer) + globals["fs"]["dostring"] = DoString(computer) + // fs.run defined in ROMLIB } companion object { @@ -250,29 +257,54 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { when (mode) { "r" -> { - val fr = FileReader(file) - luaClass["close"] = FileClassClose(fr) - luaClass["readLine"] = FileClassReadLine(fr) - luaClass["readAll"] = FileClassReadAll(fr) + try { + val fr = FileReader(file) + luaClass["close"] = FileClassClose(fr) + luaClass["readLine"] = FileClassReadLine(fr) + luaClass["readAll"] = FileClassReadAll(file.toPath()) + } + catch (e: FileNotFoundException) { + e.printStackTrace() + throw LuaError("$path: No such file.") + } } "rb" -> { - val fis = FileInputStream(file) - luaClass["close"] = FileClassClose(fis) - luaClass["read"] = FileClassReadByte(fis) + try { + val fis = FileInputStream(file) + luaClass["close"] = FileClassClose(fis) + luaClass["read"] = FileClassReadByte(fis) + luaClass["readAll"] = FileClassReadAll(file.toPath()) + } + catch (e: FileNotFoundException) { + e.printStackTrace() + throw LuaError("$path: No such file.") + } } "w", "a" -> { - val fw = FileWriter(file, (mode.startsWith('a'))) - luaClass["close"] = FileClassClose(fw) - luaClass["write"] = FileClassPrintText(fw) - luaClass["writeLine"] = FileClassPrintlnText(fw) - luaClass["flush"] = FileClassFlush(fw) + try { + val fw = FileWriter(file, (mode.startsWith('a'))) + luaClass["close"] = FileClassClose(fw) + luaClass["write"] = FileClassPrintText(fw) + luaClass["writeLine"] = FileClassPrintlnText(fw) + luaClass["flush"] = FileClassFlush(fw) + } + catch (e: FileNotFoundException) { + e.printStackTrace() + throw LuaError("$path: Is a directory.") + } } "wb", "ab" -> { - val fos = FileOutputStream(file, (mode.startsWith('a'))) - luaClass["close"] = FileClassClose(fos) - luaClass["write"] = FileClassWriteByte(fos) - luaClass["writeBytes"] = FileClassWriteBytes(fos) - luaClass["flush"] = FileClassFlush(fos) + try { + val fos = FileOutputStream(file, (mode.startsWith('a'))) + luaClass["close"] = FileClassClose(fos) + luaClass["write"] = FileClassWriteByte(fos) + luaClass["writeBytes"] = FileClassWriteBytes(fos) + luaClass["flush"] = FileClassFlush(fos) + } + catch (e: FileNotFoundException) { + e.printStackTrace() + throw LuaError("$path: Is a directory.") + } } } @@ -296,6 +328,21 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { } } + class HaltComputer(val computer: BaseTerrarumComputer): ZeroArgFunction() { + override fun call(): LuaValue { + computer.isHalted = true + computer.luaJ_globals.load("""print("system halted.")""", "=").call() + return LuaValue.NONE + } + } + + class DoString(val computer: BaseTerrarumComputer): OneArgFunction() { + override fun call(script: LuaValue): LuaValue { + computer.luaJ_globals.load(script.checkjstring()).call() + return LuaValue.NONE + } + } + ////////////////////////////// @@ -373,14 +420,22 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) { } } - private class FileClassReadAll(val fr: FileReader): ZeroArgFunction() { + private class FileClassReadAllBytes(val path: Path): ZeroArgFunction() { override fun call(): LuaValue { - return LuaValue.valueOf(fr.readText()) + val byteArr = Files.readAllBytes(path) + val s: String = java.lang.String(byteArr, "ISO-8859-1").toString() + return LuaValue.valueOf(s) + } + } + + private class FileClassReadAll(val path: Path): ZeroArgFunction() { + override fun call(): LuaValue { + return FileClassReadAllBytes(path).call() } } private class FileClassReadLine(val fr: FileReader): ZeroArgFunction() { - val scanner = Scanner(fr.readText()) // keeps the scanner status persistent + val scanner = Scanner(fr.readText()) // no closing; keep the scanner status persistent override fun call(): LuaValue { return if (scanner.hasNextLine()) LuaValue.valueOf(scanner.nextLine()) diff --git a/src/net/torvald/terrarum/virtualcomputer/terminal/ColouredTextTerminal.kt b/src/net/torvald/terrarum/virtualcomputer/terminal/ColouredTextTerminal.kt deleted file mode 100644 index 14f65ed35..000000000 --- a/src/net/torvald/terrarum/virtualcomputer/terminal/ColouredTextTerminal.kt +++ /dev/null @@ -1,53 +0,0 @@ -package net.torvald.terrarum.virtualcomputer.terminal - -import net.torvald.aa.ColouredFastFont -import org.newdawn.slick.Color -import org.newdawn.slick.GameContainer -import org.newdawn.slick.Graphics -import org.newdawn.slick.Image - -/** - * Created by minjaesong on 16-09-12. - */ -class ColouredTextTerminal( - override val width: Int, override val height: Int -) : SimpleTextTerminal(Color.white, width, height) { - override val colours = arrayOf( - Color(0x00, 0x00, 0x00), // 0 black - Color(0xff, 0xff, 0xff), // 1 white - Color(0x55, 0x55, 0x55), // 2 dim grey - Color(0xaa, 0xaa, 0xaa), // 3 light grey - - Color(0xff, 0xff, 0x00), // 4 yellow - Color(0xff, 0x66, 0x00), // 5 orange - Color(0xdd, 0x00, 0x00), // 6 red - Color(0xff, 0x00, 0x99), // 7 magenta - - Color(0x33, 0x00, 0x99), // 8 purple - Color(0x00, 0x00, 0xcc), // 9 blue - Color(0x00, 0x99, 0xff), //10 cyan - Color(0x66, 0xff, 0x33), //11 lime - - Color(0x00, 0xaa, 0x00), //12 green - Color(0x00, 0x66, 0x00), //13 dark green - Color(0x66, 0x33, 0x00), //14 brown - Color(0x99, 0x66, 0x33) //15 tan - ) // THESE ARE THE STANDARD - - override val coloursCount: Int - get() = colours.size - - override val backDefault = 0 - override val foreDefault = 3 - - override var backColour = backDefault - override var foreColour = foreDefault - - override val fontRef = "./assets/graphics/fonts/cp949.png" - override val fontImg = Image(fontRef) - override val fontW = fontImg.width / 16 - override val fontH = fontImg.height / 16 - override val font = ColouredFastFont(this, fontRef, fontW, fontH) - - override val colourScreen: Color = Color.black -} \ No newline at end of file diff --git a/src/net/torvald/terrarum/virtualcomputer/terminal/SimpleTextTerminal.kt b/src/net/torvald/terrarum/virtualcomputer/terminal/SimpleTextTerminal.kt index 019bfe545..c2dd26a7b 100644 --- a/src/net/torvald/terrarum/virtualcomputer/terminal/SimpleTextTerminal.kt +++ b/src/net/torvald/terrarum/virtualcomputer/terminal/SimpleTextTerminal.kt @@ -18,22 +18,47 @@ import java.nio.ByteBuffer * Created by minjaesong on 16-09-07. */ open class SimpleTextTerminal( - val phosphor: Color, override val width: Int, override val height: Int + phosphorColour: Color, override val width: Int, override val height: Int, colour: Boolean = false ) : Terminal { /** * Terminals must support AT LEAST 4 colours. * Color index 0 must be default background, index 3 must be default foreground */ - open protected val colours = arrayOf( - Color(0x00, 0x00, 0x00), // black - Color(0xff, 0xff, 0xff), // white - Color(0x55, 0x55, 0x55), // dim grey - Color(0xaa, 0xaa, 0xaa) // light grey - ) // THESE ARE THE STANDARD + open protected val colours = if (colour) + arrayOf( + Color(0x00, 0x00, 0x00), // 0 black + Color(0xff, 0xff, 0xff), // 1 white + Color(0x55, 0x55, 0x55), // 2 dim grey + Color(0xaa, 0xaa, 0xaa), // 3 light grey + + Color(0xff, 0xff, 0x00), // 4 yellow + Color(0xff, 0x66, 0x00), // 5 orange + Color(0xdd, 0x00, 0x00), // 6 red + Color(0xff, 0x00, 0x99), // 7 magenta + + Color(0x33, 0x00, 0x99), // 8 purple + Color(0x00, 0x00, 0xcc), // 9 blue + Color(0x00, 0x99, 0xff), //10 cyan + Color(0x66, 0xff, 0x33), //11 lime + + Color(0x00, 0xaa, 0x00), //12 green + Color(0x00, 0x66, 0x00), //13 dark green + Color(0x66, 0x33, 0x00), //14 brown + Color(0x99, 0x66, 0x33) //15 tan + ) // THESE ARE THE STANDARD + else + arrayOf( + Color(0x00, 0x00, 0x00), // black + Color(0xff, 0xff, 0xff), // white + Color(0x55, 0x55, 0x55), // dim grey + Color(0xaa, 0xaa, 0xaa) // light grey + ) // THESE ARE THE STANDARD override val coloursCount: Int get() = colours.size + val errorColour = if (coloursCount > 4) 6 else 1 + open protected val backDefault = 0 // STANDARD open protected val foreDefault = 3 // STANDARD @@ -48,7 +73,7 @@ open class SimpleTextTerminal( val screenBuffer = AAFrame(width, height) - open protected val fontRef = "./assets/graphics/fonts/MDA.png" + open protected val fontRef = "./assets/graphics/fonts/cp949.png" open protected val fontImg = Image(fontRef) open protected val fontW = fontImg.width / 16 open protected val fontH = fontImg.height / 16 @@ -64,6 +89,9 @@ open class SimpleTextTerminal( private val cursorBlinkLen = 250 private var cursorBlinkOn = true + val phosphor = if (colour) WHITE else phosphorColour + open protected val colourScreen = if (colour) Color(4, 4, 4) else Color(19, 19, 19) + override fun getColor(index: Int): Color = colours[index] @@ -102,8 +130,6 @@ open class SimpleTextTerminal( } } - open protected val colourScreen = Color(0x191919) - /** * pass UIcanvas to the parameter "g" */ @@ -192,6 +218,7 @@ open class SimpleTextTerminal( ASCII_CR -> { cursorX = 0 } ASCII_DEL -> { cursorX -= 1; wrap(); emitChar(colourKey.shl(8)) } ASCII_DC1, ASCII_DC2, ASCII_DC3, ASCII_DC4 -> { foreColour = c - ASCII_DC1 } + ASCII_DLE -> { foreColour = errorColour } } } } @@ -407,6 +434,7 @@ open class SimpleTextTerminal( val ASCII_DC2 = 18.toChar() // foreground colour 1 val ASCII_DC3 = 19.toChar() // foreground colour 2 val ASCII_DC4 = 20.toChar() // foreground colour 3 + val ASCII_DLE = 16.toChar() // error message colour val asciiControlInUse = charArrayOf( ASCII_NUL, @@ -420,7 +448,8 @@ open class SimpleTextTerminal( ASCII_DC1, ASCII_DC2, ASCII_DC3, - ASCII_DC4 + ASCII_DC4, + ASCII_DLE ) }