mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
fixed MDA scroll behaviour
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package net.torvald.terrarum.gameactors.ai
|
package net.torvald.terrarum.gameactors.ai
|
||||||
|
|
||||||
|
import org.luaj.vm2.LuaTable
|
||||||
import org.luaj.vm2.LuaValue
|
import org.luaj.vm2.LuaValue
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -385,6 +386,13 @@ import org.luaj.vm2.LuaValue
|
|||||||
fun Double.toLua() = LuaValue.valueOf(this)
|
fun Double.toLua() = LuaValue.valueOf(this)
|
||||||
fun Int.toLua() = LuaValue.valueOf(this)
|
fun Int.toLua() = LuaValue.valueOf(this)
|
||||||
fun String.toLua() = LuaValue.valueOf(this)
|
fun String.toLua() = LuaValue.valueOf(this)
|
||||||
|
fun Boolean.toLua() = LuaValue.valueOf(this)
|
||||||
fun Double?.toLua() = if (this == null) LuaValue.NIL else this.toLua()
|
fun Double?.toLua() = if (this == null) LuaValue.NIL else this.toLua()
|
||||||
fun Int?.toLua() = if (this == null) LuaValue.NIL else this.toLua()
|
fun Int?.toLua() = if (this == null) LuaValue.NIL else this.toLua()
|
||||||
fun String?.toLua() = if (this == null) LuaValue.NIL else this.toLua()
|
fun String?.toLua() = if (this == null) LuaValue.NIL else this.toLua()
|
||||||
|
fun Boolean?.toLua() = if (this == null) LuaValue.NIL else this.toLua()
|
||||||
|
fun luaTableOf(vararg luaValues: LuaValue): LuaTable {
|
||||||
|
val t = LuaTable.tableOf()
|
||||||
|
luaValues.forEachIndexed { index, luaValue -> t[index + 1] = luaValue }
|
||||||
|
return t
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package net.torvald.terrarum.modulecomputers.virtualcomputer.computer
|
||||||
|
|
||||||
|
import net.torvald.terrarum.gameactors.ai.luaTableOf
|
||||||
|
import net.torvald.terrarum.gameactors.ai.toLua
|
||||||
|
import org.luaj.vm2.Globals
|
||||||
|
import org.luaj.vm2.LuaError
|
||||||
|
import org.luaj.vm2.LuaValue
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2019-07-10.
|
||||||
|
*/
|
||||||
|
object LoadTerrarumTermLib {
|
||||||
|
|
||||||
|
operator fun invoke(globals: Globals, terminal: MDA) {
|
||||||
|
globals.addZeroArgFun("term.getCursor") {
|
||||||
|
luaTableOf(
|
||||||
|
(terminal.cursor % terminal.width).toLua(),
|
||||||
|
(terminal.cursor / terminal.height).toLua()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
globals.addTwoArgFun("term.setCursor") { p0, p1 ->
|
||||||
|
terminal.setCursor(p0.checkint(), p1.checkint())
|
||||||
|
LuaValue.NIL
|
||||||
|
}
|
||||||
|
globals.addZeroArgFun("term.getCursorBlink") {
|
||||||
|
terminal.blink.toLua()
|
||||||
|
}
|
||||||
|
globals.addOneArgFun("term.setCursorBlink") { p0 ->
|
||||||
|
terminal.blink = p0.checkboolean()
|
||||||
|
LuaValue.NIL
|
||||||
|
}
|
||||||
|
globals.addZeroArgFun("term.getTextColor") {
|
||||||
|
terminal.foreground.toLua()
|
||||||
|
}
|
||||||
|
globals.addZeroArgFun("term.getBackgroundColor") {
|
||||||
|
terminal.background.toLua()
|
||||||
|
}
|
||||||
|
globals.addOneArgFun("term.setTextColor") { p0 ->
|
||||||
|
terminal.foreground = p0.checkint()
|
||||||
|
LuaValue.NIL
|
||||||
|
}
|
||||||
|
globals.addOneArgFun("term.setBackgroundColor") { p0 ->
|
||||||
|
terminal.background = p0.checkint()
|
||||||
|
LuaValue.NIL
|
||||||
|
}
|
||||||
|
globals.addZeroArgFun("term.getSize") {
|
||||||
|
luaTableOf(
|
||||||
|
(terminal.width).toLua(),
|
||||||
|
(terminal.height).toLua()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
globals.addZeroArgFun("term.clear") {
|
||||||
|
terminal.clear()
|
||||||
|
LuaValue.NIL
|
||||||
|
}
|
||||||
|
globals.addZeroArgFun("term.clearLine") {
|
||||||
|
terminal.clearCurrentLine()
|
||||||
|
LuaValue.NIL
|
||||||
|
}
|
||||||
|
globals.addOneArgFun("term.scroll") { p0 ->
|
||||||
|
if (p0.checkint() < 0)
|
||||||
|
throw LuaError("Scroll amount must be a positive number")
|
||||||
|
terminal.scroll(p0.toint())
|
||||||
|
LuaValue.NIL
|
||||||
|
}
|
||||||
|
globals.addOneArgFun("term.write") { p0 ->
|
||||||
|
terminal.print(p0.checkjstring())
|
||||||
|
LuaValue.NIL
|
||||||
|
}
|
||||||
|
globals.addThreeArgFun("term.setText") { p0, p1, p2 ->
|
||||||
|
terminal.setOneText(p0.checkint(), p1.checkint(), p2.checkint().toByte())
|
||||||
|
LuaValue.NIL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,11 +1,17 @@
|
|||||||
package net.torvald.terrarum.modulecomputers.virtualcomputer.computer
|
package net.torvald.terrarum.modulecomputers.virtualcomputer.computer
|
||||||
|
|
||||||
import org.luaj.vm2.Globals
|
import org.luaj.vm2.Globals
|
||||||
|
import org.luaj.vm2.LoadState
|
||||||
import org.luaj.vm2.LuaValue
|
import org.luaj.vm2.LuaValue
|
||||||
import org.luaj.vm2.lib.OneArgFunction
|
import org.luaj.vm2.compiler.LuaC
|
||||||
import org.luaj.vm2.lib.jse.JsePlatform
|
import org.luaj.vm2.lib.*
|
||||||
|
import org.luaj.vm2.lib.jse.JseBaseLib
|
||||||
|
import org.luaj.vm2.lib.jse.JseMathLib
|
||||||
|
import org.luaj.vm2.lib.jse.JseStringLib
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New plan: screw teletype and gui; only the simple 80*24 (size may mary) dumb terminal
|
* New plan: screw teletype and gui; only the simple 80*24 (size may mary) dumb terminal
|
||||||
*
|
*
|
||||||
@@ -13,7 +19,7 @@ import java.io.InputStream
|
|||||||
*/
|
*/
|
||||||
class LuaComputerVM(val display: MDA) {
|
class LuaComputerVM(val display: MDA) {
|
||||||
|
|
||||||
val luaInstance: Globals = JsePlatform.standardGlobals()
|
val luaInstance: Globals// = JsePlatform.standardGlobals()
|
||||||
|
|
||||||
val stdout = MDAPrintStream(display)
|
val stdout = MDAPrintStream(display)
|
||||||
val stderr = MDAPrintStream(display)
|
val stderr = MDAPrintStream(display)
|
||||||
@@ -21,6 +27,24 @@ class LuaComputerVM(val display: MDA) {
|
|||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
// initialise the lua instance
|
||||||
|
luaInstance = Globals()
|
||||||
|
luaInstance.load(JseBaseLib())
|
||||||
|
luaInstance.load(PackageLib())
|
||||||
|
luaInstance.load(Bit32Lib())
|
||||||
|
luaInstance.load(TableLib())
|
||||||
|
luaInstance.load(JseStringLib())
|
||||||
|
luaInstance.load(CoroutineLib())
|
||||||
|
luaInstance.load(JseMathLib())
|
||||||
|
//luaInstance.load(JseIoLib())
|
||||||
|
//luaInstance.load(JseOsLib())
|
||||||
|
//luaInstance.load(LuajavaLib())
|
||||||
|
|
||||||
|
LoadTerrarumTermLib(luaInstance, display)
|
||||||
|
|
||||||
|
LoadState.install(luaInstance)
|
||||||
|
LuaC.install(luaInstance)
|
||||||
|
|
||||||
// bit-bit32 alias
|
// bit-bit32 alias
|
||||||
luaInstance["bit"] = luaInstance["bit32"]
|
luaInstance["bit"] = luaInstance["bit32"]
|
||||||
|
|
||||||
@@ -29,26 +53,7 @@ class LuaComputerVM(val display: MDA) {
|
|||||||
luaInstance.STDERR = stderr
|
luaInstance.STDERR = stderr
|
||||||
luaInstance.STDIN = stdin
|
luaInstance.STDIN = stdin
|
||||||
|
|
||||||
luaInstance.addOneArgFun("upgoer") { p0 ->
|
|
||||||
display.println("Up-goer ${p0.toint()} goes up!")
|
|
||||||
LuaValue.NIL
|
|
||||||
}
|
|
||||||
|
|
||||||
luaInstance.addOneArgFun("perkele.upgoer") { p0 ->
|
|
||||||
display.println("Up-goer ${p0.toint()} goes up!")
|
|
||||||
LuaValue.NIL
|
|
||||||
}
|
|
||||||
|
|
||||||
luaInstance.addOneArgFun("perkele.saatana.jumalauta.vittu.upgoer") { p0 ->
|
|
||||||
display.println("Up-goer ${p0.toint()} goes up!")
|
|
||||||
LuaValue.NIL
|
|
||||||
}
|
|
||||||
|
|
||||||
luaInstance.load("""print('Hello, world!') print('Ready.')""").invoke()
|
|
||||||
luaInstance.load("""print(upgoer)""").invoke()
|
|
||||||
luaInstance.load("""upgoer(1)""").invoke()
|
|
||||||
luaInstance.load("""perkele.upgoer(2)""").invoke()
|
|
||||||
luaInstance.load("""perkele.saatana.jumalauta.vittu.upgoer(5)""").invoke()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -100,7 +105,7 @@ fun Globals.addOneArgFun(identifier: String, function: (p0: LuaValue) -> LuaValu
|
|||||||
|
|
||||||
// actually put the function onto the target
|
// actually put the function onto the target
|
||||||
// for some reason, memoisation doesn't work here so we use recursion to reach the target table as generated above
|
// for some reason, memoisation doesn't work here so we use recursion to reach the target table as generated above
|
||||||
fun putIntoTheTableRec(luaTable: LuaValue, recursionCount: Int) {
|
tailrec fun putIntoTheTableRec(luaTable: LuaValue, recursionCount: Int) {
|
||||||
if (recursionCount == tableNames.lastIndex - 1) {
|
if (recursionCount == tableNames.lastIndex - 1) {
|
||||||
luaTable[tableNames[tableNames.lastIndex]] = theActualFun
|
luaTable[tableNames[tableNames.lastIndex]] = theActualFun
|
||||||
}
|
}
|
||||||
@@ -116,4 +121,173 @@ fun Globals.addOneArgFun(identifier: String, function: (p0: LuaValue) -> LuaValu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't add ZeroArgFun, TwoArgFun, ThreeArgFun until you make sure addOneArgFun to work!
|
/**
|
||||||
|
* Install a function into the lua.
|
||||||
|
* @param identifier How you might call this lua function. E.g. "term.println"
|
||||||
|
*/
|
||||||
|
fun Globals.addZeroArgFun(identifier: String, function: () -> LuaValue) {
|
||||||
|
val theActualFun = object : ZeroArgFunction() {
|
||||||
|
override fun call(): LuaValue {
|
||||||
|
return function()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val tableNames = identifier.split('.')
|
||||||
|
|
||||||
|
if (tableNames.isEmpty()) throw IllegalArgumentException("Identifier is empty")
|
||||||
|
|
||||||
|
//println(tableNames)
|
||||||
|
|
||||||
|
if (this[tableNames[0]].isnil()) {
|
||||||
|
this[tableNames[0]] = LuaValue.tableOf()
|
||||||
|
}
|
||||||
|
else if (!this[tableNames[0]].istable()) {
|
||||||
|
throw IllegalStateException("Redefinition: '${tableNames[0]}' (${this[tableNames[0]]})")
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentTable = this[tableNames[0]]
|
||||||
|
|
||||||
|
// turn nils into tables
|
||||||
|
if (tableNames.size > 1) {
|
||||||
|
tableNames.slice(1..tableNames.lastIndex).forEachIndexed { index, it ->
|
||||||
|
if (currentTable[it].isnil()) {
|
||||||
|
currentTable[it] = LuaValue.tableOf()
|
||||||
|
}
|
||||||
|
else if (!currentTable[it].istable()) {
|
||||||
|
throw IllegalStateException("Redefinition: '${tableNames.slice(0..(index + 1)).joinToString(".")}' (${currentTable[it]})")
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTable = currentTable[it]
|
||||||
|
}
|
||||||
|
|
||||||
|
// actually put the function onto the target
|
||||||
|
// for some reason, memoisation doesn't work here so we use recursion to reach the target table as generated above
|
||||||
|
tailrec fun putIntoTheTableRec(luaTable: LuaValue, recursionCount: Int) {
|
||||||
|
if (recursionCount == tableNames.lastIndex - 1) {
|
||||||
|
luaTable[tableNames[tableNames.lastIndex]] = theActualFun
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
putIntoTheTableRec(luaTable[tableNames[recursionCount + 1]], recursionCount + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
putIntoTheTableRec(this[tableNames[0]], 0)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this[tableNames[0]] = theActualFun
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install a function into the lua.
|
||||||
|
* @param identifier How you might call this lua function. E.g. "term.println"
|
||||||
|
*/
|
||||||
|
fun Globals.addTwoArgFun(identifier: String, function: (p0: LuaValue, p1: LuaValue) -> LuaValue) {
|
||||||
|
val theActualFun = object : TwoArgFunction() {
|
||||||
|
override fun call(p0: LuaValue, p1: LuaValue): LuaValue {
|
||||||
|
return function(p0, p1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val tableNames = identifier.split('.')
|
||||||
|
|
||||||
|
if (tableNames.isEmpty()) throw IllegalArgumentException("Identifier is empty")
|
||||||
|
|
||||||
|
//println(tableNames)
|
||||||
|
|
||||||
|
if (this[tableNames[0]].isnil()) {
|
||||||
|
this[tableNames[0]] = LuaValue.tableOf()
|
||||||
|
}
|
||||||
|
else if (!this[tableNames[0]].istable()) {
|
||||||
|
throw IllegalStateException("Redefinition: '${tableNames[0]}' (${this[tableNames[0]]})")
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentTable = this[tableNames[0]]
|
||||||
|
|
||||||
|
// turn nils into tables
|
||||||
|
if (tableNames.size > 1) {
|
||||||
|
tableNames.slice(1..tableNames.lastIndex).forEachIndexed { index, it ->
|
||||||
|
if (currentTable[it].isnil()) {
|
||||||
|
currentTable[it] = LuaValue.tableOf()
|
||||||
|
}
|
||||||
|
else if (!currentTable[it].istable()) {
|
||||||
|
throw IllegalStateException("Redefinition: '${tableNames.slice(0..(index + 1)).joinToString(".")}' (${currentTable[it]})")
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTable = currentTable[it]
|
||||||
|
}
|
||||||
|
|
||||||
|
// actually put the function onto the target
|
||||||
|
// for some reason, memoisation doesn't work here so we use recursion to reach the target table as generated above
|
||||||
|
tailrec fun putIntoTheTableRec(luaTable: LuaValue, recursionCount: Int) {
|
||||||
|
if (recursionCount == tableNames.lastIndex - 1) {
|
||||||
|
luaTable[tableNames[tableNames.lastIndex]] = theActualFun
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
putIntoTheTableRec(luaTable[tableNames[recursionCount + 1]], recursionCount + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
putIntoTheTableRec(this[tableNames[0]], 0)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this[tableNames[0]] = theActualFun
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install a function into the lua.
|
||||||
|
* @param identifier How you might call this lua function. E.g. "term.println"
|
||||||
|
*/
|
||||||
|
fun Globals.addThreeArgFun(identifier: String, function: (p0: LuaValue, p1: LuaValue, p2: LuaValue) -> LuaValue) {
|
||||||
|
val theActualFun = object : ThreeArgFunction() {
|
||||||
|
override fun call(p0: LuaValue, p1: LuaValue, p2: LuaValue): LuaValue {
|
||||||
|
return function(p0, p1, p2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val tableNames = identifier.split('.')
|
||||||
|
|
||||||
|
if (tableNames.isEmpty()) throw IllegalArgumentException("Identifier is empty")
|
||||||
|
|
||||||
|
//println(tableNames)
|
||||||
|
|
||||||
|
if (this[tableNames[0]].isnil()) {
|
||||||
|
this[tableNames[0]] = LuaValue.tableOf()
|
||||||
|
}
|
||||||
|
else if (!this[tableNames[0]].istable()) {
|
||||||
|
throw IllegalStateException("Redefinition: '${tableNames[0]}' (${this[tableNames[0]]})")
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentTable = this[tableNames[0]]
|
||||||
|
|
||||||
|
// turn nils into tables
|
||||||
|
if (tableNames.size > 1) {
|
||||||
|
tableNames.slice(1..tableNames.lastIndex).forEachIndexed { index, it ->
|
||||||
|
if (currentTable[it].isnil()) {
|
||||||
|
currentTable[it] = LuaValue.tableOf()
|
||||||
|
}
|
||||||
|
else if (!currentTable[it].istable()) {
|
||||||
|
throw IllegalStateException("Redefinition: '${tableNames.slice(0..(index + 1)).joinToString(".")}' (${currentTable[it]})")
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTable = currentTable[it]
|
||||||
|
}
|
||||||
|
|
||||||
|
// actually put the function onto the target
|
||||||
|
// for some reason, memoisation doesn't work here so we use recursion to reach the target table as generated above
|
||||||
|
tailrec fun putIntoTheTableRec(luaTable: LuaValue, recursionCount: Int) {
|
||||||
|
if (recursionCount == tableNames.lastIndex - 1) {
|
||||||
|
luaTable[tableNames[tableNames.lastIndex]] = theActualFun
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
putIntoTheTableRec(luaTable[tableNames[recursionCount + 1]], recursionCount + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
putIntoTheTableRec(this[tableNames[0]], 0)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this[tableNames[0]] = theActualFun
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ class MDA(val width: Int, val height: Int) {
|
|||||||
|
|
||||||
private val arrayElemOffset = 8L * if (AppLoader.is32BitJVM) 1 else 2 // 8 for 32-bit, 16 for 64-bit
|
private val arrayElemOffset = 8L * if (AppLoader.is32BitJVM) 1 else 2 // 8 for 32-bit, 16 for 64-bit
|
||||||
|
|
||||||
private val glyphs = UnsafeHelper.allocate(width.toLong() * height)
|
private val glyphs = UnsafeHelper.allocate(width.toLong() * height + 1) // extra one byte is absolutely needed
|
||||||
private val attributes = UnsafeHelper.allocate(width.toLong() * height)
|
private val attributes = UnsafeHelper.allocate(width.toLong() * height + 1)
|
||||||
|
|
||||||
var cursor = 0
|
var cursor = 0
|
||||||
private set
|
private set
|
||||||
@@ -37,8 +37,8 @@ class MDA(val width: Int, val height: Int) {
|
|||||||
var blink = true
|
var blink = true
|
||||||
|
|
||||||
init {
|
init {
|
||||||
glyphs.fillWith(0)
|
//glyphs.fillWith(0)
|
||||||
attributes.fillWith(1)
|
//attributes.fillWith(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -116,10 +116,16 @@ class MDA(val width: Int, val height: Int) {
|
|||||||
|
|
||||||
/** Bulk write method. Any control characers will be represented as a glyph, rather than an actual control sequence.
|
/** Bulk write method. Any control characers will be represented as a glyph, rather than an actual control sequence.
|
||||||
* E.g. '\n' will print a symbol. */
|
* E.g. '\n' will print a symbol. */
|
||||||
fun setText(x: Int, y: Int, text: ByteArray) {
|
inline fun setText(x: Int, y: Int, text: ByteArray) {
|
||||||
setText(x, y, text, toAttribute(background, foreground))
|
setText(x, y, text, toAttribute(background, foreground))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setOneText(x: Int, y: Int, text: Byte, attribute: Byte = toAttribute(background, foreground)) {
|
||||||
|
val o = wrapAround(x, y).toAddress()
|
||||||
|
glyphs[o] = text
|
||||||
|
attributes[o] = attribute
|
||||||
|
}
|
||||||
|
|
||||||
private fun setOneText(offset: Int, text: Byte, attribute: Byte = toAttribute(background, foreground)) {
|
private fun setOneText(offset: Int, text: Byte, attribute: Byte = toAttribute(background, foreground)) {
|
||||||
glyphs[offset.toLong()] = text
|
glyphs[offset.toLong()] = text
|
||||||
attributes[offset.toLong()] = attribute
|
attributes[offset.toLong()] = attribute
|
||||||
@@ -131,7 +137,7 @@ class MDA(val width: Int, val height: Int) {
|
|||||||
print(text)
|
print(text)
|
||||||
write(0x0A)
|
write(0x0A)
|
||||||
}
|
}
|
||||||
fun print(text: String) {
|
inline fun print(text: String) {
|
||||||
print(text.toByteArray(charset))
|
print(text.toByteArray(charset))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,12 +150,11 @@ class MDA(val width: Int, val height: Int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun write(text: Byte) {
|
fun write(text: Byte) {
|
||||||
|
|
||||||
when (text) {
|
when (text) {
|
||||||
// CR
|
|
||||||
0x0D.toByte() -> { /* do nothing */ }
|
|
||||||
// LF
|
// LF
|
||||||
0x0A.toByte() -> newline()
|
0x0A.toByte() -> newline()
|
||||||
|
// all others (e.g. CR)
|
||||||
|
in 0x00.toByte()..0x0D.toByte() -> { /* do nothing */ }
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
setOneText(cursor, text)
|
setOneText(cursor, text)
|
||||||
@@ -163,6 +168,30 @@ class MDA(val width: Int, val height: Int) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clear() {
|
||||||
|
glyphs.fillWith(0)
|
||||||
|
attributes.fillWith(toAttribute(background, foreground))
|
||||||
|
cursor = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearCurrentLine() {
|
||||||
|
clearLine(cursor / width)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearLine(line: Int) {
|
||||||
|
val lineOffset = line * width
|
||||||
|
for (i in 0L until width) {
|
||||||
|
glyphs[lineOffset + i] = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearLineAfterCursor() {
|
||||||
|
val lineOffset = (cursor / width) * width
|
||||||
|
for (i in (cursor % width).toLong() until width) {
|
||||||
|
glyphs[lineOffset + i] = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* moves text and the current cursor position
|
* moves text and the current cursor position
|
||||||
*/
|
*/
|
||||||
@@ -175,6 +204,8 @@ class MDA(val width: Int, val height: Int) {
|
|||||||
|
|
||||||
cursor -= offset.toInt()
|
cursor -= offset.toInt()
|
||||||
if (cursor < 0) cursor = 0
|
if (cursor < 0) cursor = 0
|
||||||
|
|
||||||
|
clearLineAfterCursor()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,6 +219,7 @@ class MDA(val width: Int, val height: Int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cursor = (cursor / width) * width // set cursorX to 0
|
cursor = (cursor / width) * width // set cursorX to 0
|
||||||
|
clearLineAfterCursor()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dispose() {
|
fun dispose() {
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package net.torvald.terrarum.modulecomputers.virtualcomputer.peripheral
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstraction of the communication line. (e.g. serial cable)
|
||||||
|
*
|
||||||
|
* A cable may have multiple of CommLines (e.g. serial cable need two for Tx and Rx)
|
||||||
|
*
|
||||||
|
* Created by minjaesong on 2019-07-10.
|
||||||
|
*/
|
||||||
|
open class CommLine(val bandwidth: Int) {
|
||||||
|
|
||||||
|
open val postbox = StringBuilder()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns how many bytes are actually posted, e.g. 0 when band limit is exceeded.
|
||||||
|
*/
|
||||||
|
open fun post(msg: String): Int {
|
||||||
|
if (bandwidth >= msg.length) {
|
||||||
|
postbox.append(msg)
|
||||||
|
return msg.length
|
||||||
|
}
|
||||||
|
else if (postbox.length >= bandwidth) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
postbox.append(msg.substring(0 until (bandwidth - postbox.length)))
|
||||||
|
return bandwidth - postbox.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun get(): String {
|
||||||
|
val s = postbox.toString()
|
||||||
|
postbox.clear()
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -64,6 +64,7 @@ class StandaloneApp : Game() {
|
|||||||
Gdx.graphics.setTitle("Terrarum Lua Computer Standalone — F: ${Gdx.graphics.framesPerSecond}")
|
Gdx.graphics.setTitle("Terrarum Lua Computer Standalone — F: ${Gdx.graphics.framesPerSecond}")
|
||||||
|
|
||||||
//display.print(ByteArray(1){ (Math.random() * 255).toByte() })
|
//display.print(ByteArray(1){ (Math.random() * 255).toByte() })
|
||||||
|
//display.print("@")
|
||||||
|
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
batch.color = Color.WHITE
|
batch.color = Color.WHITE
|
||||||
|
|||||||
Reference in New Issue
Block a user