Lua Computer: collection of minor updates, none notable (read romapidoc)

Former-commit-id: 80e3f0d13c2dc5bcff0843e509f416e9314cd52e
Former-commit-id: e7e35bfd23d70db84f568f0c5388f3a1d89222bc
This commit is contained in:
Song Minjae
2016-09-26 12:15:45 +09:00
parent 29db14d184
commit 75d73f7d18
76 changed files with 2326 additions and 781 deletions

View File

@@ -15,13 +15,10 @@ class StateFontTester : BasicGameState() {
val textToPrint = "Font printer 서체 인쇄기"
lateinit var canvas: Graphics
lateinit var gameFont: Font
override fun init(gc: GameContainer, game: StateBasedGame) {
canvas = Graphics(1024, 1024)
gameFont = GameFontWhite()
Terrarum.gameLocale = "fiFI"
}
@@ -30,7 +27,7 @@ class StateFontTester : BasicGameState() {
}
override fun render(gc: GameContainer, game: StateBasedGame, g: Graphics) {
g.font = gameFont
g.font = Terrarum.fontGame
val text = arrayOf(
Lang["APP_WARNING_HEALTH_AND_SAFETY"],
@@ -46,6 +43,11 @@ class StateFontTester : BasicGameState() {
for (i in 0..text.size - 1) {
g.drawString(text[i], 10f, 10f + (g.font.lineHeight * i))
}
g.font = Terrarum.fontSmallNumbers
g.drawString("The true master needs but one channel", 0f, 64f)
g.drawString("Press a key to start", 0f, 64f + 16f)
}
override fun getID(): Int = Terrarum.STATE_ID_TEST_FONT

View File

@@ -19,8 +19,8 @@ import org.newdawn.slick.state.StateBasedGame
*/
class StateVTTest : BasicGameState() {
// HiRes: 100x62, LoRes: 80x25
val vt = SimpleTextTerminal(SimpleTextTerminal.ELECTRIC_BLUE, 80, 25, colour = false, hires = false)
// HiRes: 100x64, LoRes: 80x25
val vt = SimpleTextTerminal(SimpleTextTerminal.GREEN, 80, 25, colour = false, hires = false)
val computerInside = BaseTerrarumComputer(vt)
val vtUI = Image(vt.displayW, vt.displayH)

View File

@@ -13,6 +13,9 @@ object Key {
val SPACE = 57
val CAPS_LOCK = 58
val L_CONTROL = 29
// same position keys
val L_ALT = 56
val L_COMMAND = 219 // Mac
val DELETE = 211

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,7 @@
if term.isTeletype() then error("This is a teletype; cannot use CCAPI layer") end
table.insert(_COMPUTER.loadedCLayer, "CCAPI")
table.insert(computer.loadedCLayer, "CCAPI")
local function intLog2(i)
@@ -34,7 +34,7 @@ _G.bit = {} -- CC's weird BIT API
bit.blshift = function(n, bits) bit32.lshift(n, bits) end
bit.brshift = function(n, bits) bit32.arshift(n, bits) end
bit.blogic_rshift = function(n, bits) bit32.brshift(n, bits) end
bit.blogic_rshift = function(n, bits) bit32.rshift(n, bits) end
bit.bxor = function(m, n) bit32.bxor(m, n) end
bit.bor = function(m, n) bit32.bor(m, n) end
bit.band = function(m, n) bit32.band(m, n) end
@@ -162,4 +162,4 @@ fs.run = function(p) fs.dofile(p) end
-- DOWN AND OUT --
------------------
if _COMPUTER.verbose then print("ComputerCraft compatibility layer successfully loaded.") end
if computer.verbose then print("ComputerCraft compatibility layer successfully loaded.") end

View File

@@ -6,6 +6,8 @@
-- ALIASES --
-------------
_G.io = {}
fs.dofile = function(p, ...)
local f = fs.open(p, "r")
local s = f.readAll()
@@ -14,12 +16,8 @@ end
_G.loadstring = _G.load
_G.print = term.print
--_G.dofile = function(f) fs.dofile(f) end
_G.boot = function() fs.dofile("/boot/efi") end
fs.fetchText = function(p)
local file = fs.open(p, "r")
@@ -60,7 +58,7 @@ _G.__scanforline__ = function(echo) -- pass '1' to not echo; pass nothing to ech
end
-- use Keys API to identify the keycode
_G.__scanforkey__ = function(echo) -- pass '1' to not echo; pass nothing to echo
--[[_G.__scanforkey__ = function(echo) -- pass '1' to not echo; pass nothing to echo
native.closeInputString()
native.openInput(echo or 0)
_G.__scanMode__ = "a_key"
@@ -70,11 +68,12 @@ _G.__scanforkey__ = function(echo) -- pass '1' to not echo; pass nothing to echo
until key
-- input is closed when any key is hit. See above comments.
return key
end
end]] -- DELETED: use _G.input.isKeyDown(keycode)
input.readLine = _G.__scanforline__
io.read = _G.__scanforline__
-----------------
-- PRINTSTREAM --
-----------------
@@ -82,7 +81,12 @@ io.read = _G.__scanforline__
io.write = function(...)
local args = {...}
for _, v in ipairs(args) do
local s = tostring(v)
local s
if v == nil then
s = "nil"
else
s = tostring(v)
end
term.write(s)
end
end
@@ -111,7 +115,22 @@ end
_G.shell = {}
shell.status = shell.ok
shell.run = function(p) fs.dofile(p) end
shell.run = function(path)
-- check for interpreter key "#!"
local f = fs.open(path, "r")
local s = ""
repeat
s = f.readLine()
if (s == nil) then return end -- empty file
until #s > 0
if s:sub(1,2) == "#!" then
local interpreter = s:sub(3)
fs.dofile(interpreter..".lua", path)
else
fs.dofile(path)
end
end
shell.ok = 0
@@ -167,123 +186,193 @@ end
-- 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",
local keycodeNumToName = {
["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",
["87"] = "f11",
["88"] = "f12",
["89"] = "f13",
["90"] = "f14",
["91"] = "f15",
["144"] = "cimcumflex",
["145"] = "at",
["146"] = "colon",
["147"] = "underscore",
["157"] = "rightCtrl",
["184"] = "rightAlt",
["197"] = "pause",
["199"] = "home",
["200"] = "up",
["201"] = "pageUp",
["203"] = "left",
["208"] = "right",
["207"] = "end",
["205"] = "down",
["209"] = "pageDown",
["210"] = "insert",
["211"] = "delete",
["219"] = "leftCommand"
}
_G.keys = {}
_G.keys.getName = function(code) return keycodeDic[tostring(code)] end
_G.keys = {
["a"] = 30,
["b"] = 48,
["c"] = 46,
["d"] = 32,
["e"] = 18,
["f"] = 33,
["g"] = 34,
["h"] = 35,
["i"] = 23,
["j"] = 36,
["k"] = 37,
["l"] = 38,
["m"] = 50,
["n"] = 49,
["o"] = 24,
["p"] = 25,
["q"] = 16,
["r"] = 19,
["s"] = 31,
["t"] = 20,
["u"] = 22,
["v"] = 47,
["w"] = 17,
["x"] = 45,
["y"] = 21,
["z"] = 44,
["one"] = 2,
["two"] = 3,
["three"] = 4,
["four"] = 5,
["five"] = 6,
["six"] = 7,
["seven"] = 8,
["eight"] = 9,
["nine"] = 10,
["zero"] = 11,
["minus"] = 12,
["equals"] = 13,
["backspace"] = 14,
["tab"] = 15,
["leftBracket"] = 26,
["rightBracket"] = 27,
["enter"] = 28,
["leftCtrl"] = 29,
["semiColon"] = 39,
["apostrophe"] = 40,
["grave"] = 41,
["leftShift"] = 42,
["backslash"] = 43,
["comma"] = 51,
["period"] = 52,
["slash"] = 53,
["rightShift"] = 54,
["multiply"] = 55,
["leftAlt"] = 56,
["space"] = 57,
["capsLock"] = 58,
["f1"] = 59,
["f2"] = 60,
["f3"] = 61,
["f4"] = 62,
["f5"] = 63,
["f6"] = 64,
["f7"] = 65,
["f8"] = 66,
["f9"] = 67,
["f10"] = 68,
["numLock"] = 69,
["scollLock"] = 70,
["f11"] = 87,
["f12"] = 88,
["f13"] = 89,
["f14"] = 90,
["f15"] = 91,
["cimcumflex"] = 144,
["at"] = 145,
["colon"] = 146,
["underscore"] = 147,
["rightCtrl"] = 157,
["rightAlt"] = 184,
["pause"] = 197,
["home"] = 199,
["up"] = 200,
["pageUp"] = 201,
["left"] = 203,
["right"] = 208,
["end"] = 207,
["down"] = 205,
["pageDown"] = 209,
["insert"] = 210,
["delete"] = 211,
["leftCommand"] = 219
}
_G.keys.getName = function(code) return keycodeNumToName[tostring(code)] end

View File

@@ -2,19 +2,18 @@ package net.torvald.terrarum.virtualcomputer.computer
import li.cil.repack.org.luaj.vm2.Globals
import li.cil.repack.org.luaj.vm2.LuaError
import li.cil.repack.org.luaj.vm2.LuaTable
import li.cil.repack.org.luaj.vm2.LuaValue
import li.cil.repack.org.luaj.vm2.lib.ZeroArgFunction
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.HostAccessProvider
import net.torvald.terrarum.virtualcomputer.luaapi.Security
import net.torvald.terrarum.virtualcomputer.luaapi.Term
import net.torvald.terrarum.virtualcomputer.luaapi.*
import net.torvald.terrarum.virtualcomputer.terminal.*
import net.torvald.terrarum.virtualcomputer.worldobject.ComputerPartsCodex
import net.torvald.terrarum.virtualcomputer.worldobject.FixtureComputerBase
import org.newdawn.slick.GameContainer
import org.newdawn.slick.Input
import java.io.*
/**
@@ -40,15 +39,14 @@ class BaseTerrarumComputer(val term: Teletype? = null) {
val processorCycle: Int // number of Lua statement to process per tick (1/100 s)
get() = ComputerPartsCodex.getProcessorCycles(computerValue.getAsInt("processor") ?: 0)
val memSize: Int // max: 8 GB
val memSize: Int // in bytes; max: 8 GB
get() {
if (DEBUG_UNLIMITED_MEM) return 1.shl(30)// 1 GB
if (DEBUG_UNLIMITED_MEM) return 16.shl(20)// 16 MB
var size = 0
for (i in 0..3)
size += ComputerPartsCodex.getRamSize(computerValue.getAsInt("memSlot$i") ?: 0)
size += ComputerPartsCodex.getRamSize(computerValue.getAsInt("memSlot$i")!!)
return 16.shl(20)
return size
}
@@ -58,6 +56,9 @@ class BaseTerrarumComputer(val term: Teletype? = null) {
var isHalted = false
lateinit var input: Input
private set
init {
computerValue["memslot0"] = 4864 // -1 indicates mem slot is empty
computerValue["memslot1"] = -1 // put index of item here
@@ -83,34 +84,47 @@ class BaseTerrarumComputer(val term: Teletype? = null) {
computerValue["boot"] = computerValue.getAsString("hda")!!
if (term != null) {
termOut = TerminalPrintStream(term)
termErr = TerminalPrintStream(term)
termIn = TerminalInputStream(term)
if (term != null) initSandbox(term)
}
luaJ_globals.STDOUT = termOut
luaJ_globals.STDERR = termErr
luaJ_globals.STDIN = termIn
fun initSandbox(term: Teletype) {
termOut = TerminalPrintStream(term)
termErr = TerminalPrintStream(term)
termIn = TerminalInputStream(term)
// load libraries
Term(luaJ_globals, term)
Security(luaJ_globals)
Filesystem(luaJ_globals, this)
HostAccessProvider(luaJ_globals, this)
}
luaJ_globals.STDOUT = termOut
luaJ_globals.STDERR = termErr
luaJ_globals.STDIN = termIn
// load libraries
Term(luaJ_globals, term)
Security(luaJ_globals)
Filesystem(luaJ_globals, this)
HostAccessProvider(luaJ_globals, this)
Input(luaJ_globals, this)
Http(luaJ_globals, this)
// secure the sandbox
luaJ_globals["io"] = LuaValue.NIL
// dubug is sandboxed in OpenComputers code
//val sethook = luaJ_globals["debug"]["sethook"]
//luaJ_globals["debug"] = LuaValue.NIL
// ROM BASIC
val inputStream = javaClass.getResourceAsStream("/net/torvald/terrarum/virtualcomputer/assets/lua/BOOT.lua")
runCommand(InputStreamReader(inputStream), "=boot")
// computer-related global functions
luaJ_globals["getTotalMem"] = LuaFunGetTotalMem(this)
luaJ_globals["totalMemory"] = LuaFunGetTotalMem(this)
}
var threadTimer = 0
val threadMaxTime = 2000
fun update(gc: GameContainer, delta: Int) {
input = gc.input
if (currentExecutionThread.state == Thread.State.TERMINATED)
unsetThreadRun()

View File

@@ -456,6 +456,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
}
}
/** returns NO line separator! */
private class FileClassReadLine(val fr: FileReader) : ZeroArgFunction() {
val scanner = Scanner(fr.readText()) // no closing; keep the scanner status persistent

View File

@@ -37,7 +37,10 @@ internal class HostAccessProvider(globals: Globals, computer: BaseTerrarumComput
class PrintLn(): OneArgFunction() {
override fun call(p0: LuaValue): LuaValue {
println(p0.checkIBM437())
if (p0.isnumber())
println(p0.checkdouble())
else
println(p0.checkIBM437())
return LuaValue.NONE
}
}
@@ -91,7 +94,7 @@ internal class HostAccessProvider(globals: Globals, computer: BaseTerrarumComput
class HaltComputer(val computer: BaseTerrarumComputer) : ZeroArgFunction() {
override fun call() : LuaValue {
computer.isHalted = true
computer.luaJ_globals.load("""print("system halted")""").call()
computer.luaJ_globals.load("""print(DC4.."system halted")""").call()
return LuaValue.NONE
}
}

View File

@@ -0,0 +1,12 @@
package net.torvald.terrarum.virtualcomputer.luaapi
import li.cil.repack.org.luaj.vm2.Globals
import net.torvald.terrarum.virtualcomputer.computer.BaseTerrarumComputer
/**
* Provides internet access, if @param computer has internet card(s).
*
* Created by minjaesong on 16-09-24.
*/
internal class Http(globals: Globals, computer: BaseTerrarumComputer) {
}

View File

@@ -0,0 +1,48 @@
package net.torvald.terrarum.virtualcomputer.luaapi
import li.cil.repack.org.luaj.vm2.Globals
import li.cil.repack.org.luaj.vm2.LuaTable
import li.cil.repack.org.luaj.vm2.LuaValue
import li.cil.repack.org.luaj.vm2.lib.OneArgFunction
import net.torvald.terrarum.gamecontroller.Key
import net.torvald.terrarum.virtualcomputer.computer.BaseTerrarumComputer
/**
* Created by minjaesong on 16-09-25.
*/
class Input(globals: Globals, computer: BaseTerrarumComputer) {
init {
globals["input"] = LuaTable()
globals["input"]["isKeyDown"] = IsKeyDown(computer)
}
companion object {
val keys_alt = intArrayOf(Key.L_ALT, Key.L_COMMAND)
val keys_caps = intArrayOf(Key.CAPS_LOCK, Key.BACKSPACE, Key.L_CONTROL)
}
class IsKeyDown(val computer: BaseTerrarumComputer) : OneArgFunction() {
override fun call(keyCode: LuaValue): LuaValue {
val key = keyCode.checkint()
// L_Alt and L_COMMAND are homogeneous
if (keys_alt.contains(key)) {
for (k in keys_alt) {
val down = computer.input.isKeyDown(k)
if (down) return LuaValue.valueOf(true)
}
}
// Caps, Backspace, L_Control, for Colemak and HHKB
if (keys_caps.contains(key)) {
for (k in keys_caps) {
val down = computer.input.isKeyDown(k)
if (down) return LuaValue.valueOf(true)
}
}
return LuaValue.valueOf(computer.input.isKeyDown(keyCode.checkint()))
}
}
}

View File

@@ -9,6 +9,8 @@ import org.apache.commons.codec.digest.DigestUtils
import java.security.SecureRandom
/**
* Hashes, CSPRNG, Base64
*
* Created by minjaesong on 16-09-15.
*/
internal class Security(globals: Globals) {

View File

@@ -7,7 +7,8 @@ import net.torvald.terrarum.virtualcomputer.terminal.Terminal
import java.nio.charset.Charset
/**
* APIs must have some extent of compatibility with ComputerCraft by dan200
* Controls terminal as if it was a monitor
* (not sending control sequences but just drives it, as if it was not a terminal @ 9600 baud)
*
* Created by minjaesong on 16-09-12.
*/

View File

@@ -91,8 +91,8 @@ 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)
val phosphor = if (colour) WHITE7500 else phosphorColour
open protected val colourScreen = if (colour) Color(8, 8, 8) else Color(19, 19, 19)
@@ -447,10 +447,11 @@ open class SimpleTextTerminal(
companion object {
val AMBER = Color(255, 183, 0) // P3, 602 nm
val IBM_GREEN = Color(74, 255, 0) // P39, 525 nm
val WHITE = Color(228, 234, 255) // P4, 7 500 K
val GREEN = Color(74, 255, 0) // P39, 525 nm
val WHITE = Color(204, 223, 255) // approximation of white CRT I own
val WHITE7500 = Color(0xe4eaff)
val ELECTRIC_BLUE = Color(0, 226, 255) // imaginary, 483 nm
val RED = Color(250, 0, 0) // <= 645 nm
val RED = Color(250, 51, 0) // 632 nm
val ASCII_NUL = 0.toChar()
val ASCII_BEL = 7.toChar() // *BEEP!*

View File

@@ -14,14 +14,14 @@ object ComputerPartsCodex {
init {
// in kilobytes
rams.put(4864, 16.MiB())
rams.put(4865, 24.MiB())
rams.put(4866, 32.MiB())
rams.put(4867, 64.MiB())
rams.put(4868, 96.MiB())
rams.put(4869, 128.MiB())
rams.put(4870, 160.MiB())
rams.put(4871, 256.MiB())
rams.put(4864, 128.KiB())
rams.put(4865, 192.KiB())
rams.put(4866, 256.KiB())
rams.put(4867, 384.KiB())
rams.put(4868, 512.KiB())
rams.put(4869, 768.KiB())
rams.put(4870, 1024.KiB())
rams.put(4871, 2048.KiB())
processors.put(4872, 1000)
processors.put(4873, 2000)
@@ -51,6 +51,6 @@ object ComputerPartsCodex {
private fun Int.MB() = this * 1000000 // 1 MB == 1 000 000 bytes, bitches!
private fun Int.kB() = this * 1000
private fun Int.KiB() = this.shr(10)
private fun Int.MiB() = this.shr(20)
private fun Int.KiB() = this.shl(10)
private fun Int.MiB() = this.shl(20)
}