just updating things so that I can have a backup point...

Former-commit-id: 0a5a6d7f68ee1a96562532572c8d45fe102d3c25
Former-commit-id: a1a78f61f2fe2a8707e47633caa6cd67a829b35e
This commit is contained in:
Song Minjae
2017-01-26 16:58:06 +09:00
parent 06296983b5
commit 2203f74429
16 changed files with 1765 additions and 1226 deletions

View File

@@ -34,7 +34,7 @@ constructor(var width: Int, var height: Int, var terminal: SimpleTextTerminal) {
throw ArrayIndexOutOfBoundsException("x: $x, y; $y") throw ArrayIndexOutOfBoundsException("x: $x, y; $y")
frameBuffer[y * width + x] = ((c.toInt().and(0xFF)) + colourKey.shl(8)).toChar() frameBuffer[y * width + x] = ((c.toInt().and(0xFF)) + colourKey.shl(8)).toChar()
terminal.redraw() //terminal.redraw()
} }
fun drawBuffer(x: Int, y: Int, raw: Char): Boolean = fun drawBuffer(x: Int, y: Int, raw: Char): Boolean =
@@ -42,7 +42,7 @@ constructor(var width: Int, var height: Int, var terminal: SimpleTextTerminal) {
false false
else { else {
frameBuffer[y * width + x] = raw frameBuffer[y * width + x] = raw
terminal.redraw() //terminal.redraw()
true true
} }
@@ -51,7 +51,7 @@ constructor(var width: Int, var height: Int, var terminal: SimpleTextTerminal) {
val char = (other[i].toUint().shl(8) + other[i + 1].toUint()).toChar() val char = (other[i].toUint().shl(8) + other[i + 1].toUint()).toChar()
frameBuffer[i.ushr(1)] = char frameBuffer[i.ushr(1)] = char
} }
terminal.redraw() //terminal.redraw()
} }
fun getBackgroundColour(x: Int, y: Int): Int { fun getBackgroundColour(x: Int, y: Int): Int {
@@ -78,7 +78,7 @@ constructor(var width: Int, var height: Int, var terminal: SimpleTextTerminal) {
drawBuffer(x, y, 0.toChar(), background.shl(4)) drawBuffer(x, y, 0.toChar(), background.shl(4))
} }
} }
terminal.redraw() //terminal.redraw()
} }
fun drawFromOther(other: AAFrame) { fun drawFromOther(other: AAFrame) {
@@ -88,7 +88,7 @@ constructor(var width: Int, var height: Int, var terminal: SimpleTextTerminal) {
frameBuffer[y * width + x] = other.getRaw(x, y)!! frameBuffer[y * width + x] = other.getRaw(x, y)!!
} }
} }
terminal.redraw() //terminal.redraw()
} }
private fun checkOOB(x: Int, y: Int) = (x < 0 || y < 0 || x >= width || y >= height) private fun checkOOB(x: Int, y: Int) = (x < 0 || y < 0 || x >= width || y >= height)

View File

@@ -4,8 +4,6 @@
package net.torvald.spriteanimation package net.torvald.spriteanimation
import net.torvald.terrarum.StateInGame
import net.torvald.terrarum.Terrarum
import com.jme3.math.FastMath import com.jme3.math.FastMath
import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.ActorWithSprite
import org.newdawn.slick.Graphics import org.newdawn.slick.Graphics
@@ -214,26 +212,6 @@ class SpriteAnimation(val parentActor: ActorWithSprite, val cellWidth: Int, val
private fun getScaledSprite(scale: Float): Image { private fun getScaledSprite(scale: Float): Image {
val selectedImage = spriteImage!!.getSprite(currentFrame - 1, currentRow - 1) val selectedImage = spriteImage!!.getSprite(currentFrame - 1, currentRow - 1)
//Image selectedImage = sprites[currentRow - 1][currentFrame - 1];
// resample
/*float nearestResampleScale = (scale > 1) ? Math.round(scale) : 1;
float linearResampleScale = scale / nearestResampleScale;
// scale 1.8 -> resample in 2(nearest), then resample in 0.9(linear)
// scale by nearestResampleScale (2, 3, ...)
selectedImage.setFilter(Image.FILTER_NEAREST);
Image selImgNearestScaled = selectedImage.getScaledCopy(nearestResampleScale);
// scale by linearResampleScale (.x)
Image selImgLinearScaled;
if (scale % 1 > 0) {
selImgNearestScaled.setFilter(Image.FILTER_LINEAR);
selImgLinearScaled = selImgNearestScaled.getScaledCopy(linearResampleScale);
return selImgLinearScaled;
}
else {
return selImgNearestScaled;
}*/
selectedImage.filter = Image.FILTER_NEAREST selectedImage.filter = Image.FILTER_NEAREST
return selectedImage.getScaledCopy(scale) return selectedImage.getScaledCopy(scale)
} }

View File

@@ -14,16 +14,23 @@ class StateFontTester : BasicGameState() {
lateinit var canvas: Graphics lateinit var canvas: Graphics
lateinit var segfont: Font //lateinit var segfont: Font
lateinit var mtfont: Font
override fun init(gc: GameContainer, game: StateBasedGame) { override fun init(gc: GameContainer, game: StateBasedGame) {
canvas = Graphics(1024, 1024) canvas = Graphics(1024, 1024)
Terrarum.gameLocale = "fiFI" Terrarum.gameLocale = "fiFI"
segfont = SpriteSheetFont( /*segfont = SpriteSheetFont(
SpriteSheet("./assets/graphics/fonts/24-seg_red.tga", 22, 31), SpriteSheet("./assets/graphics/fonts/24-seg_red.tga", 22, 31),
' ' ' '
)*/
mtfont = SpriteSheetFont(
SpriteSheet("./assets/graphics/fonts/mt-32.tga", 12, 16),
0.toChar()
) )
} }
@@ -50,9 +57,10 @@ class StateFontTester : BasicGameState() {
}*/ }*/
//g.font = Terrarum.fontSmallNumbers //g.font = Terrarum.fontSmallNumbers
g.font = segfont //g.font = segfont
g.font = mtfont
val line = """print("Lua is copyrighted (C) 1994-2013 Lua.org, PUC-Rio")""" val line = " **** TERRAN BASIC V0.5 **** "
g.drawString(line, 10f, 10f) g.drawString(line, 10f, 10f)
} }

View File

@@ -38,7 +38,7 @@ class StateVTTest : BasicGameState() {
override fun update(container: GameContainer, game: StateBasedGame, delta: Int) { override fun update(container: GameContainer, game: StateBasedGame, delta: Int) {
Terrarum.appgc.setTitle("VT — F: ${container.fps}" + Terrarum.appgc.setTitle("VT — F: ${container.fps}" +
" — M: ${Terrarum.memInUse}M / ${Terrarum.totalVMMem}M") " — M: ${Terrarum.memInUse}M / ${Terrarum.memXmx}M")
vt.update(container, delta) vt.update(container, delta)
computerInside.update(container, delta) computerInside.update(container, delta)
} }

View File

@@ -195,8 +195,10 @@ constructor(gamename: String) : StateBasedGame(gamename) {
private set private set
val memInUse: Long val memInUse: Long
get() = ManagementFactory.getMemoryMXBean().heapMemoryUsage.used shr 20 get() = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) shr 20
val totalVMMem: Long val memTotal: Long
get() = Runtime.getRuntime().totalMemory() shr 20
val memXmx: Long
get() = Runtime.getRuntime().maxMemory() shr 20 get() = Runtime.getRuntime().maxMemory() shr 20
lateinit var environment: RunningEnvironment lateinit var environment: RunningEnvironment

View File

@@ -18,7 +18,7 @@ object AVTracker : ConsoleCommand {
try { try {
val actorID = args[1].toInt() val actorID = args[1].toInt()
if (Terrarum.ingame.hasActor(actorID)) { if (Terrarum.ingame.theGameHasActor(actorID)) {
jPanelInstances.add(ActorValueTracker(Terrarum.ingame.getActorByID(actorID))) jPanelInstances.add(ActorValueTracker(Terrarum.ingame.getActorByID(actorID)))
} }
else { else {

View File

@@ -39,8 +39,8 @@ abstract class Actor(val renderOrder: ActorOrder) : Comparable<Actor>, Runnable
* override var referenceID: Int = generateUniqueReferenceID() * override var referenceID: Int = generateUniqueReferenceID()
*/ */
fun generateUniqueReferenceID(): Int { fun generateUniqueReferenceID(): Int {
fun checkForCollision(value: Int) = fun itIsNotValid(value: Int) =
Terrarum.ingame.hasActor(value) || Terrarum.ingame.theGameHasActor(value) ||
value < ItemCodex.ITEM_COUNT_MAX || value < ItemCodex.ITEM_COUNT_MAX ||
value < when (renderOrder) { value < when (renderOrder) {
ActorOrder.BEHIND -> ItemCodex.ITEM_COUNT_MAX ActorOrder.BEHIND -> ItemCodex.ITEM_COUNT_MAX
@@ -58,7 +58,7 @@ abstract class Actor(val renderOrder: ActorOrder) : Comparable<Actor>, Runnable
var ret: Int var ret: Int
do { do {
ret = HQRNG().nextInt().and(0x7FFFFFFF) // set new ID ret = HQRNG().nextInt().and(0x7FFFFFFF) // set new ID
} while (checkForCollision(ret)) // check for collision } while (itIsNotValid(ret)) // check for collision
return ret return ret
} }

View File

@@ -31,7 +31,7 @@ open class ParticleBase(renderOrder: ActorOrder, maxLifeTime: Int? = null) : Run
open val velocity = Vector2(0.0, 0.0) open val velocity = Vector2(0.0, 0.0)
open val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0) open val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0)
open lateinit var body: Image open lateinit var body: Image // you might want to use SpriteAnimation
open var glow: Image? = null open var glow: Image? = null
init { init {

View File

@@ -66,7 +66,7 @@ class WorldTime {
val YEAR_DAYS: Int = 365 val YEAR_DAYS: Int = 365
fun parseTime(s: String): Int = fun parseTime(s: String): Int =
if (s.length >= 4) { if (s.length >= 4 && s.contains('h')) {
s.toLowerCase().substringBefore('h').toInt() * WorldTime.HOUR_SEC + s.toLowerCase().substringBefore('h').toInt() * WorldTime.HOUR_SEC +
s.toLowerCase().substringAfter('h').toInt() * WorldTime.MINUTE_SEC s.toLowerCase().substringAfter('h').toInt() * WorldTime.MINUTE_SEC
} }

View File

@@ -11,6 +11,7 @@ import net.torvald.terrarum.concurrent.ThreadParallel
import net.torvald.terrarum.blendMul import net.torvald.terrarum.blendMul
import net.torvald.terrarum.blendNormal import net.torvald.terrarum.blendNormal
import net.torvald.terrarum.mapdrawer.FeaturesDrawer.TILE_SIZE import net.torvald.terrarum.mapdrawer.FeaturesDrawer.TILE_SIZE
import net.torvald.terrarum.mapdrawer.LightmapRenderer.normaliseToColour
import net.torvald.terrarum.mapdrawer.MapCamera.x import net.torvald.terrarum.mapdrawer.MapCamera.x
import net.torvald.terrarum.mapdrawer.MapCamera.y import net.torvald.terrarum.mapdrawer.MapCamera.y
import net.torvald.terrarum.mapdrawer.MapCamera.height import net.torvald.terrarum.mapdrawer.MapCamera.height

View File

@@ -48,7 +48,7 @@ object TilePropCSV {
"8"; "4";"TILE_GEM_DIAMOND" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "4"; "0"; "0"; "N/A"; "0";"16" "8"; "4";"TILE_GEM_DIAMOND" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "4"; "0"; "0"; "N/A"; "0";"16"
"8"; "5";"TILE_GEM_AMETHYST" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "5"; "0"; "0"; "N/A"; "0";"16" "8"; "5";"TILE_GEM_AMETHYST" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "5"; "0"; "0"; "N/A"; "0";"16"
"9"; "0";"TILE_SNOW" ; "33587232"; "6"; "500";"snow"; "0"; "1"; "1"; "0"; "9"; "0"; "0"; "0"; "N/A"; "0";"16" "9"; "0";"TILE_SNOW" ; "33587232"; "6"; "500";"snow"; "0"; "1"; "1"; "0"; "9"; "0"; "0"; "0"; "N/A"; "0";"16"
"9"; "1";"TILE_ICE_FRAGILE" ; "13644813"; "1"; "930";"icei"; "0"; "1"; "0"; "0"; "9"; "1"; "0"; "0"; "N/A"; "0";"16" "9"; "1";"TILE_ICE_FRAGILE" ; "13644813"; "1"; "930";"icei"; "0"; "1"; "0"; "0"; "9"; "1"; "0"; "0"; "N/A"; "0"; "4"
"9"; "2";"TILE_ICE_NATURAL" ; "27289626"; "25"; "930";"icei"; "0"; "1"; "1"; "0"; "9"; "2"; "0"; "0"; "N/A"; "0"; "4" "9"; "2";"TILE_ICE_NATURAL" ; "27289626"; "25"; "930";"icei"; "0"; "1"; "1"; "0"; "9"; "2"; "0"; "0"; "N/A"; "0"; "4"
"9"; "3";"TILE_ICE_CLEAR_MAGICAL" ; "33587232"; "25";"3720";"icex"; "0"; "1"; "1"; "19955770"; "9"; "3"; "0"; "0"; "N/A"; "0"; "4" "9"; "3";"TILE_ICE_CLEAR_MAGICAL" ; "33587232"; "25";"3720";"icex"; "0"; "1"; "1"; "19955770"; "9"; "3"; "0"; "0"; "N/A"; "0"; "4"
"9"; "4";"TILE_GLASS_CRUDE" ; "3146755"; "1";"2500";"glas"; "0"; "1"; "1"; "0"; "9"; "4"; "0"; "0"; "N/A"; "0";"16" "9"; "4";"TILE_GLASS_CRUDE" ; "3146755"; "1";"2500";"glas"; "0"; "1"; "1"; "0"; "9"; "4"; "0"; "0"; "N/A"; "0";"16"
@@ -135,7 +135,7 @@ object TilePropCSV {
"255"; "13";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" "255"; "13";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16"
"255"; "14";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" "255"; "14";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16"
"255"; "15";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" "255"; "15";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16"
"256"; "0";"TILE_NULL" ; "0"; "-1";"2600";"null"; "0"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "N/A"; "0";"16" "256"; "0";"TILE_NULL" ;"1073741823"; "-1";"2600";"null"; "0"; "0"; "1"; "0"; "N/A"; "N/A"; "0"; "0"; "N/A"; "0";"16"
## Notes ## ## Notes ##

View File

@@ -153,16 +153,19 @@ class BasicDebugInfoWindow : UICanvas {
*/ */
g.color = GameFontBase.codeToCol["y"] g.color = GameFontBase.codeToCol["y"]
g.drawString("${ccY}MEM ", (Terrarum.WIDTH - 15 * 8 - 2).toFloat(), 2f) g.drawString("${ccY}MEM ", (Terrarum.WIDTH - 21 * 8 - 2).toFloat(), 2f)
//g.drawString("${ccY}FPS $ccG${Terrarum.appgc.fps}", (Terrarum.WIDTH - 6 * 8 - 2).toFloat(), 10f) //g.drawString("${ccY}FPS $ccG${Terrarum.appgc.fps}", (Terrarum.WIDTH - 6 * 8 - 2).toFloat(), 10f)
g.drawString("${ccY}CPUs ${if (Terrarum.MULTITHREAD) ccG else ccR}${Terrarum.THREADS}", g.drawString("${ccY}CPUs ${if (Terrarum.MULTITHREAD) ccG else ccR}${Terrarum.THREADS}",
(Terrarum.WIDTH - 2 - 6*8).toFloat(), 10f) (Terrarum.WIDTH - 2 - 6*8).toFloat(), 10f)
g.color = GameFontBase.codeToCol["g"] g.color = GameFontBase.codeToCol["g"]
g.drawString("${Terrarum.memInUse}M", g.drawString("${Terrarum.memInUse}M",
(Terrarum.WIDTH - 11 * 8 - 2).toFloat(), 2f) (Terrarum.WIDTH - 17 * 8 - 2).toFloat(), 2f)
g.drawString("/${Terrarum.totalVMMem}M", g.drawString("/${Terrarum.memTotal}M/",
(Terrarum.WIDTH - 6 * 8 - 2).toFloat(), 2f) (Terrarum.WIDTH - 12 * 8 - 2).toFloat(), 2f)
g.color = GameFontBase.codeToCol["m"]
g.drawString("${Terrarum.memXmx}M",
(Terrarum.WIDTH - 5 * 8 - 2).toFloat(), 2f)
/** /**
* Bottom left * Bottom left
@@ -174,7 +177,7 @@ class BasicDebugInfoWindow : UICanvas {
(2 + 17*8).toFloat(), Terrarum.HEIGHT - 10f) (2 + 17*8).toFloat(), Terrarum.HEIGHT - 10f)
g.drawString("${ccY}Dormant $ccG${Terrarum.ingame.actorContainerInactive.size}", g.drawString("${ccY}Dormant $ccG${Terrarum.ingame.actorContainerInactive.size}",
(2 + 28*8).toFloat(), Terrarum.HEIGHT - 10f) (2 + 28*8).toFloat(), Terrarum.HEIGHT - 10f)
g.drawString("${ccM}Particles $ccG${Terrarum.ingame.particlesContainer.elemCount}", g.drawString("${ccM}Particles $ccG${Terrarum.ingame.particlesActive}",
(2 + 41*8).toFloat(), Terrarum.HEIGHT - 10f) (2 + 41*8).toFloat(), Terrarum.HEIGHT - 10f)
} }

View File

@@ -32,6 +32,16 @@ table.concat = function(t, delimeter)
return outstr return outstr
end end
-- Copy from TBASINCL; looks like OpenComputers has a bug...
function string_hash(str)
local hash = 2166136261
for i = 1, #str do
hash = hash * 16777619
hash = bit.bxor(hash, str:byte(i))
end
return hash
end
@@ -53,7 +63,7 @@ local function appendcommand(lineno, statement)
end end
do -- Avoid heap allocs for performance do -- Avoid heap allocs for performance
local tokens = {" ", "\t"} -- initial obvious tokens local tokens = {" ", "\t", ",", "(", ")"} -- initial obvious tokens
local longest_token_len = 0 local longest_token_len = 0
-- build 'tokens' table from list of operators from the language -- build 'tokens' table from list of operators from the language
for _, v in ipairs(_TBASIC._OPERATR) do for _, v in ipairs(_TBASIC._OPERATR) do
@@ -67,7 +77,7 @@ do -- Avoid heap allocs for performance
end end
end end
-- sort them out using ther hash for binary search -- sort them out using ther hash for binary search
table.sort(tokens, function(a, b) return string.hash(a) < string.hash(b) end) table.sort(tokens, function(a, b) return string_hash(a) < string_hash(b) end)
function parsewords(line) function parsewords(line)
@@ -78,12 +88,12 @@ do -- Avoid heap allocs for performance
----------------------- -----------------------
-- filter for IF statement -- filter for IF statement
if line:match("[Ii][Ff]") then if line:sub(1, 2):upper() == "IF" then
-- no matching THEN -- no matching THEN
if not line:match("[Tt][Hh][Ee][Nn]") then if not line:match("[Tt][Hh][Ee][Nn]") then
_TBASIC._ERROR.NOMATCHING("IF", "THEN") _TBASIC._ERROR.NOMATCHING("IF", "THEN")
-- assignment on IF clause -- assignment on IF clause
elseif line:match("[Ii][Ff][^\n]+[Tt][Hh][Ee][Nn]"):match("[^=]=[^=]") or elseif line:match("[Ii][Ff][^\n]+[Tt][Hh][Ee][Nn]"):match("[^=+%-*/%%<>!]=[^=<>]") or
line:match("[Ii][Ff][^\n]+[Tt][Hh][Ee][Nn]"):match(":=") then line:match("[Ii][Ff][^\n]+[Tt][Hh][Ee][Nn]"):match(":=") then
_TBASIC._ERROR.ASGONIF() _TBASIC._ERROR.ASGONIF()
end end
@@ -95,15 +105,14 @@ do -- Avoid heap allocs for performance
-- (This is starting to get dirty...) -- (This is starting to get dirty...)
-- unary minus -- unary minus
local matchobj = line:find("%-[0-9]") for matchobj in line:gmatch("%-[0-9]+") do
if matchobj then -- in this pattern, it always returns a number local newline = line:gsub(matchobj, "MINUS "..matchobj:sub(2, #matchobj))
local newline = line:sub(1, matchobj - 1) .. "MINUS " .. line:sub(matchobj + 1, #line)
line = newline line = newline
end end
-- conditional for IF -- conditional for IF
-- if IF statement has no appended paren -- if IF statement has no appended paren
if not line:match("[Ii][Ff][ ]*%(") then if line:sub(1, 2):upper() == "IF" and not line:match("[Ii][Ff][ ]*%(") then
local newline = line:gsub("[Ii][Ff]", "IF ( "):gsub("[Tt][Hh][Ee][Nn]", " ) THEN") local newline = line:gsub("[Ii][Ff]", "IF ( ", 1):gsub("[Tt][Hh][Ee][Nn]", " ) THEN", 1)
line = newline line = newline
end end
-- special treatment for FOR -- special treatment for FOR
@@ -157,7 +166,7 @@ do -- Avoid heap allocs for performance
-- return: lookless_count on success, nil on failure -- return: lookless_count on success, nil on failure
local function isdelimeter(string) local function isdelimeter(string)
local cmpval = function(table_elem) return string.hash(table_elem) end local cmpval = function(table_elem) return string_hash(table_elem) end
local lookless_count = #string local lookless_count = #string
local ret = nil local ret = nil
repeat repeat
@@ -247,6 +256,8 @@ do -- Avoid heap allocs for performance
end end
local isvariable = _TBASIC.isvariable local isvariable = _TBASIC.isvariable
local isnumber = _TBASIC.isnumber
local isstring = _TBASIC.isstring
local function isuserfunc(word) local function isuserfunc(word)
if type(word) == "table" then return false end if type(word) == "table" then return false end
@@ -270,54 +281,15 @@ do -- Avoid heap allocs for performance
return word ~= "==" and word ~= ">=" and word ~= "<=" and word:byte(#word) == 61 return word ~= "==" and word ~= ">=" and word ~= "<=" and word:byte(#word) == 61
end end
local function isnoresolvevar(word) -- returns truthy value "terminate_loop" upon termination of loop; nil otherwise.
local novarresolve = {"NEXT"}
for _, w in ipairs(novarresolve) do -- linear search, because the array is small
if word:upper() == w then
return true
end
end
return false
end
local function execword(word, args) local function execword(word, args)
if not _TBASIC.__appexit then if not _TBASIC.__appexit then
printdbg("--> execword", word) printdbg("--> execword", word)
printdbg("--> inargs", table.unpack(args)) printdbg("--> execword_args", table.unpack(args))
-- selectively resolve variable (if it's assign func, bottommost var -- target of assignation -- will not be resolved)
-- for command "NEXT": DO NOT RESOLVE, pass its name (Call by Name)
if not isnoresolvevar(word) then
for i = isassign(word) and 2 or 1, #args do
arg = args[i]
printdbg("--> resolvevar arg", arg)
if isvariable(arg) then
var = unmark(arg)
if type(var) ~= "table" then
value = _TBASIC._INTPRTR.CNSTANTS[var:upper()] -- try for pre-def
if value == nil then
value = _TBASIC._INTPRTR.VARTABLE[var:upper()] -- try for user-def
end
if value == nil then
_TBASIC._ERROR.NULVAR(var)
end
args[i] = value
end
end
end
end
if word == "IF" then if word == "IF" then
printdbg("--> branch statement 'IF'") printdbg("--> branch statement 'IF'")
if not args[1] then -- if condition 'false' if not _TBASIC.__readvar(args[1]) then -- if condition 'false'
printdbg("--> if condition 'false'", table.unpack(args)) printdbg("--> if condition 'false'", table.unpack(args))
return "terminate_loop" -- evaluated as 'true' to Lua return "terminate_loop" -- evaluated as 'true' to Lua
else else
@@ -325,7 +297,7 @@ do -- Avoid heap allocs for performance
end end
end end
printdbg("--> execword outarg", table.unpack(args)) printdbg("--> execword_outarg", table.unpack(args))
result = _TBASIC.LUAFN[word][1](table.unpack(args)) result = _TBASIC.LUAFN[word][1](table.unpack(args))
printdbg("--> result", result) printdbg("--> result", result)
@@ -399,7 +371,11 @@ do -- Avoid heap allocs for performance
else else
-- consume entire stack -- consume entire stack
local reversedargs = {} local reversedargs = {}
while #execstack > 0 and isvariable(stackpeek(execstack)) do
while #execstack > 0 and
(isvariable(stackpeek(execstack)) or isnumber(stackpeek(execstack)) or
isstring(stackpeek(execstack)))
do
stackpush(reversedargs, stackpop(execstack)) stackpush(reversedargs, stackpop(execstack))
end end
-- reverse 'args' -- reverse 'args'
@@ -407,7 +383,9 @@ do -- Avoid heap allocs for performance
stackpush(args, stackpop(reversedargs)) stackpush(args, stackpop(reversedargs))
end end
end end
local terminate_loop = execword(funcname, args) local terminate_loop = execword(funcname, args)
if terminate_loop then if terminate_loop then
printdbg("--> termination of loop") printdbg("--> termination of loop")
printdbg("--------") printdbg("--------")
@@ -438,7 +416,6 @@ end
local function termination_condition() local function termination_condition()
return terminated or return terminated or
_TBASIC._INTPRTR.GOTOCNTR > _TBASIC._INTPRTR.GOTOLMIT or
_TBASIC.__appexit or _TBASIC.__appexit or
#_TBASIC._INTPRTR.CALLSTCK > _TBASIC._INTPRTR.STACKMAX #_TBASIC._INTPRTR.CALLSTCK > _TBASIC._INTPRTR.STACKMAX
end end
@@ -472,18 +449,17 @@ local function interpretall()
repeat repeat
interpretline(fetchnextcmd()) interpretline(fetchnextcmd())
until termination_condition() until termination_condition()
if _TBASIC._INTPRTR.GOTOCNTR > _TBASIC._INTPRTR.GOTOLMIT then
_TBASIC._ERROR.TOOLONGEXEC()
end
end end
-- END OF LEXER --------------------------------------------------------------- -- END OF LEXER ---------------------------------------------------------------
-- _TBASIC.SHOWLUAERROR = false -- commented; let the shell handle it
local testprogram = nil
_G._TBASIC.EXEC = function(cmdstring) -- you can access this interpreter with this global function _G._TBASIC.EXEC = function(cmdstring) -- you can access this interpreter with this global function
_TBASIC._INTPRTR.RESET() _TBASIC._INTPRTR.RESET()
programlist = {} programlist = {} -- wipe out previous commands from interpreter (do not delete)
readprogram(cmdstring) readprogram(cmdstring)
interpretall() interpretall()
end end
@@ -491,7 +467,7 @@ end
if testprogram then if testprogram then
_TBASIC._INTPRTR.RESET() _TBASIC._INTPRTR.RESET()
programlist = {} programlist = {} -- wipe out previous commands from interpreter (do not delete)
readprogram(testprogram) readprogram(testprogram)
interpretall() interpretall()
end end

View File

@@ -17,11 +17,23 @@ end
args = {...} args = {...}
print(_G._TBASIC._VERSION) print(_G._TBASIC._HEADER)
_TBASIC.PROMPT() _TBASIC.PROMPT()
_TBASIC.SHOWLUAERROR = false _TBASIC.SHOWLUAERROR = false
local function concat_lines(lines, startindex, endindex)
local out = ""
for i = startindex or 1, endindex or _TBASIC._INTPRTR.MAXLINES do
if lines[i] ~= nil then
out = out.."\n"..tostring(i).." "..lines[i]
end
end
return out
end
if args[1] then if args[1] then
local prog = nil local prog = nil
if fs and fs.open then -- ComputerCraft if fs and fs.open then -- ComputerCraft
@@ -38,34 +50,211 @@ if args[1] then
else else
local terminate_app = false local terminate_app = false
local ptn_nums = "[0-9]+"
local renum_targets = {"GOTO[ ]+"..ptn_nums, "GOSUB[ ]+"..ptn_nums }
local lines = {} local lines = {}
local lineno = 1
local linenum_match = "[0-9]+ "
local get_linenum = function(line) return line:sub(1,6):match(linenum_match, 1) end -- line:sub(1,6) limits max linumber to be 99999
local split_num_and_statements = function(line)
local linenum = get_linenum(line)
local statements = line:sub(#linenum + 1)
return tonumber(linenum), statements
end
while not terminate_app do while not terminate_app do
local __read = false local __read = false
line = io.read() line = io.read()
if line:upper() == "NEW" then -- tokenise line by " "
args = {}
for word in line:gmatch("[^ ]+") do
table.insert(args, word:upper())
end
-- TODO more elegant code than IF-ELSEIF-ELSE
-- massive if-else for running command, cos implementing proper command executor is too expensive here
if line:sub(1,6):match(linenum_match) then -- enter new command
local linenum, statements = split_num_and_statements(line)
lines[tonumber(linenum)] = statements
__read = true
elseif args[1] == "NEW" then
lines = {} lines = {}
lineno = 1 elseif args[1] == "RUN" then
elseif line:upper() == "RUN" then _TBASIC.EXEC(concat_lines(lines))
_TBASIC.EXEC(table.concat(lines, "\n")) elseif args[1] == "LIST" then -- LIST, LIST 42, LIST 10-80
elseif line:upper() == "LIST" then if not args[2] then
print() print(concat_lines(lines))
print(table.concat(lines, "\n")) else
if args[2]:match("-") then -- ranged
range = {}
for n in args[2]:gmatch("[^-]+") do
table.insert(range, n)
end
local rangestart = tonumber(range[1])
local rangeend = tonumber(range[2])
if not rangestart or not rangeend then
_TBASIC._ERROR.ILLEGALARG()
else
print(concat_lines(lines, rangestart, rangeend))
end
else
local linenum = tonumber(args[2])
if not linenum then
_TBASIC._ERROR.ILLEGALARG()
else
print(concat_lines(lines, linenum, linenum))
end
end
end
_TBASIC.PROMPT() _TBASIC.PROMPT()
__read = true __read = true
elseif line:upper() == "EXIT" then elseif args[1] == "DELETE" then -- DELETE 30, DELETE 454-650
if not args[2] then
_TBASIC._ERROR.ILLEGALARG()
else
if args[2]:match("-") then -- ranged
range = {}
for n in args[2]:gmatch("[^-]+") do
table.insert(range, n)
end
local rangestart = tonumber(range[1])
local rangeend = tonumber(range[2])
if not rangestart or not rangeend then
_TBASIC._ERROR.ILLEGALARG()
else
for i = rangestart, rangeend do
lines[i] = nil
end
end
else
local linenum = tonumber(args[2])
if not linenum then
_TBASIC._ERROR.ILLEGALARG()
else
lines[linenum] = nil
end
end
end
elseif args[1] == "EXIT" then
terminate_app = true terminate_app = true
break break
elseif line:match("[0-9]+ ") then elseif args[1] == "SAVE" then
table.insert(lines, line) local status, err = pcall(function()
lineno = lineno + 1 if fs and fs.open then -- computercraft
__read = true local file = fs.open(args[2], "w")
file.write(concat_lines(lines))
file.close()
else
local file = assert(io.open(args[2], "w"))
file:write(concat_lines(lines))
file:close()
end
end
)
if err then
if _TBASIC.SHOWLUAERROR then
print(err)
end
_TBASIC._ERROR.IOERR()
else
print("FILE SAVED")
end
elseif args[1] == "LOAD" then
local status, err = pcall(function()
lines = {}
if fs and fs.open then -- computercraft
local file = fs.open(args[2], "r")
local data = file.readAll("*all")
for dataline in data:gmatch("[^\n]+") do
if #dataline > 0 then
local linenum, statements = split_num_and_statements(dataline)
lines[linenum] = statements
end
end
file.close()
else
local file = assert(io.open(args[2], "r"))
local data = file:read("*all")
for dataline in data:gmatch("[^\n]+") do
if #dataline > 0 then
local linenum, statements = split_num_and_statements(dataline)
lines[linenum] = statements
end
end
file:close()
end
end
)
if err then
if _TBASIC.SHOWLUAERROR then
error(err)
end
_TBASIC._ERROR.IOERR()
else
print("FILE LOADED")
end
elseif args[1] == "RENUM" then
local statement_table = {}
local renumbering_table = {}
local new_linenum_counter = 10
-- first, get the list of commands, without line number indexing
for i = 1, _TBASIC._INTPRTR.MAXLINES do
if lines[i] ~= nil then
--table.insert(statement_table, lines[i])
statement_table[new_linenum_counter] = lines[i]
renumbering_table[i] = new_linenum_counter
-- test
--print("old line", i, "new line", new_linenum_counter)
new_linenum_counter = new_linenum_counter + 10
end
end
-- copy statement_table into lines table
lines = statement_table
-- re-number GOTO and GOSUB line numbers
local line_counter = 0 -- loop counter
for line_pc = 0, _TBASIC._INTPRTR.MAXLINES do
local line = lines[line_pc]
if line then
line_counter = line_counter + 1
-- replace
-- extract a <- "GOTO 320"
-- extract n_from from a (320), make n_to from it
-- make new string b <- "GOTO "..n_to
for _, match_string in ipairs(renum_targets) do
local match = line:match(match_string)
if match then
local matching_statement = match:gsub("[ ]+"..ptn_nums, "")
local target_line_old = tonumber(match:match(ptn_nums))
local target_line_new = renumbering_table[target_line_old]
local gsub_from = match
local gsub_to = matching_statement.." "..target_line_new
-- test
--print("matching_statement", matching_statement, "target_line_old", target_line_old, "target_line_new", target_line_new)
--print("gsub_from", gsub_from, "gsub_to", gsub_to)
-- substitute
lines[line_pc] = line:gsub(gsub_from, gsub_to)
end
end
end
end
elseif #line == 0 and line:byte(1) ~= 10 and line:byte(1) ~= 13 then elseif #line == 0 and line:byte(1) ~= 10 and line:byte(1) ~= 13 then
__read = true __read = true
else else
_TBASIC.EXEC("1 "..line) _TBASIC.EXEC("1 "..line) -- execute command right away
end end
-- reset -- reset

View File

@@ -4,6 +4,7 @@ import net.torvald.aa.AAFrame
import net.torvald.aa.ColouredFastFont import net.torvald.aa.ColouredFastFont
import net.torvald.terrarum.* import net.torvald.terrarum.*
import net.torvald.terrarum.gameactors.abs import net.torvald.terrarum.gameactors.abs
import net.torvald.terrarum.gamecontroller.Key
import net.torvald.terrarum.virtualcomputer.computer.BaseTerrarumComputer import net.torvald.terrarum.virtualcomputer.computer.BaseTerrarumComputer
import org.lwjgl.BufferUtils import org.lwjgl.BufferUtils
import org.lwjgl.openal.AL import org.lwjgl.openal.AL
@@ -106,8 +107,6 @@ open class SimpleTextTerminal(
private set private set
private var redrawSemaphore = false
override fun getColor(index: Int): Color = colours[index] override fun getColor(index: Int): Color = colours[index]
@@ -142,13 +141,9 @@ open class SimpleTextTerminal(
* pass UIcanvas to the parameter "g" * pass UIcanvas to the parameter "g"
*/ */
override fun render(gc: GameContainer, g: Graphics) { override fun render(gc: GameContainer, g: Graphics) {
// FIXME don't redraw every time it's slow
g.font = font g.font = font
// don't redraw() every fucking time, you're wasting your precious process cycle
if (redrawSemaphore) {
blendNormal() blendNormal()
// black background (this is mandatory) // black background (this is mandatory)
@@ -176,11 +171,10 @@ open class SimpleTextTerminal(
} }
} }
}
// cursor // cursor
if (cursorBlinkOn) { if (cursorBlinkOn) {
g.color = getColor(if (cursorBlink) foreDefault else backDefault) screen colourScreen mul phosphor g.color = getColor(if (cursorBlink) foreDefault else backDefault)
g.fillRect( g.fillRect(
fontW * cursorX.toFloat() + borderSize, fontW * cursorX.toFloat() + borderSize,
@@ -189,26 +183,7 @@ open class SimpleTextTerminal(
fontH.toFloat() fontH.toFloat()
) )
} }
else {
val x = cursorX
val y = cursorY
val ch = screenBuffer.getChar(x, y)
// background
g.color = getColor(screenBuffer.getBackgroundColour(x, y)) screen colourScreen mul phosphor
g.fillRect(fontW * x.toFloat() + borderSize, fontH * y.toFloat() + borderSize,
fontW.toFloat(), fontH.toFloat())
// foreground
if (ch.toInt() != 0 && ch.toInt() != 32) {
g.color = getColor(screenBuffer.getForegroundColour(x, y)) screen colourScreen mul phosphor
g.drawString(
Character.toString(ch),
fontW * x.toFloat() + borderSize, fontH * y.toFloat() + borderSize)
}
}
if (redrawSemaphore) {
// colour base // colour base
g.color = colourScreen g.color = colourScreen
blendScreen() blendScreen()
@@ -220,17 +195,11 @@ open class SimpleTextTerminal(
g.fillRect(0f, 0f, fontW * width.toFloat() + 2 * borderSize, fontH * height.toFloat() + 2 * borderSize) g.fillRect(0f, 0f, fontW * width.toFloat() + 2 * borderSize, fontH * height.toFloat() + 2 * borderSize)
redrawSemaphore = false
}
blendNormal() blendNormal()
} }
fun redraw() {
redrawSemaphore = true
}
/** Unlike lua function, this one in Zero-based. */ /** Unlike lua function, this one in Zero-based. */
override fun setCursor(x: Int, y: Int) { override fun setCursor(x: Int, y: Int) {
cursorX = x cursorX = x
@@ -444,7 +413,7 @@ open class SimpleTextTerminal(
else if (keyPressVisible) else if (keyPressVisible)
printChar(c) printChar(c)
if (!asciiControlInUse.contains(c)) sb.append(c) if (!asciiControlInUse.contains(c)) sb.append(c)
else if (c == ASCII_DEL && sb.length > 0) sb.deleteCharAt(sb.length - 1) else if (key == Key.BACKSPACE && sb.isNotEmpty()) sb.deleteCharAt(sb.length - 1)
} }
} }