From b37c782b4eae933bb6659c6cad4a8a9b06bdfd73 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Fri, 19 Jul 2019 23:19:25 +0900 Subject: [PATCH] ingame computer wip; gamepad deadzone disp on f3 --- assets/mods/dwarventech/gui/6440_textonly.png | Bin 0 -> 18635 bytes src/net/torvald/terrarum/AppLoader.java | 22 +- src/net/torvald/terrarum/Terrarum.kt | 12 +- .../terrarum/controller/VirtualKeyboard.kt | 4 +- .../controller/XinputControllerAdapter.kt | 2 +- .../terrarum/modulebasegame/TerrarumIngame.kt | 4 +- .../virtualcomputer/assets/common/common.lua | 27 + .../assets/loots/lunados/command.lua | 58 +++ .../assets/{lua => luaold}/BOOT.lua | 0 .../assets/{lua => luaold}/BRAINFUCK.lua | 0 .../assets/{lua => luaold}/CCAPI.lua | 0 .../assets/{lua => luaold}/ROMLIB.lua | 0 .../assets/{lua => luaold}/TBASEXEC.lua | 0 .../assets/{lua => luaold}/TBASEXTN.lua | 0 .../assets/{lua => luaold}/TBASIC.lua | 0 .../assets/{lua => luaold}/TBASINCL.lua | 0 .../assets/{lua => luaold}/rombasicman.txt | 0 .../computer/LoadTerrarumIOLib.kt | 12 + .../virtualcomputer/computer/LuaComputerVM.kt | 472 ++++++++++++++++-- .../virtualcomputer/computer/MDA.kt | 4 +- .../standalone/StandaloneApp.kt | 67 +-- .../terrarum/ui/BasicDebugInfoWindow.kt | 5 + work_files/UI/crt_560x650.psd | 3 + 23 files changed, 614 insertions(+), 78 deletions(-) create mode 100644 assets/mods/dwarventech/gui/6440_textonly.png create mode 100644 src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/common/common.lua create mode 100644 src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/loots/lunados/command.lua rename src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/{lua => luaold}/BOOT.lua (100%) rename src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/{lua => luaold}/BRAINFUCK.lua (100%) rename src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/{lua => luaold}/CCAPI.lua (100%) rename src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/{lua => luaold}/ROMLIB.lua (100%) rename src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/{lua => luaold}/TBASEXEC.lua (100%) rename src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/{lua => luaold}/TBASEXTN.lua (100%) rename src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/{lua => luaold}/TBASIC.lua (100%) rename src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/{lua => luaold}/TBASINCL.lua (100%) rename src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/{lua => luaold}/rombasicman.txt (100%) create mode 100644 src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/LoadTerrarumIOLib.kt create mode 100644 work_files/UI/crt_560x650.psd diff --git a/assets/mods/dwarventech/gui/6440_textonly.png b/assets/mods/dwarventech/gui/6440_textonly.png new file mode 100644 index 0000000000000000000000000000000000000000..a343e46ef7ae5362534ceec1982ada28f7dc1362 GIT binary patch literal 18635 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 BKKuXx literal 0 HcmV?d00001 diff --git a/src/net/torvald/terrarum/AppLoader.java b/src/net/torvald/terrarum/AppLoader.java index 51104ef08..7a5bc7b14 100644 --- a/src/net/torvald/terrarum/AppLoader.java +++ b/src/net/torvald/terrarum/AppLoader.java @@ -208,7 +208,7 @@ public class AppLoader implements ApplicationListener { /** A gamepad. Multiple gamepads may controll this single virtualised gamepad. */ public static TerrarumController gamepad = null; - public static float gamepadDeadzone = 0.3f; + public static float gamepadDeadzone = 0.2f; /** @@ -295,7 +295,11 @@ public class AppLoader implements ApplicationListener { public static char gamepadLabelRStick = 0xE045; public static char gamepadLabelLStickPush = 0xE046; public static char gamepadLabelRStickPush = 0xE047; - + + public static String[] gamepadWhitelist = { + "xinput", "xbox", "game", "joy", "pad" + }; + public static void main(String[] args) { // load configs getDefaultDirectory(); @@ -441,7 +445,19 @@ public class AppLoader implements ApplicationListener { } + // tell the game that we have a gamepad + environment = RunningEnvironment.PC; + if (gamepad != null) { + String name = gamepad.getName().toLowerCase(); + for (String allowedName : gamepadWhitelist) { + if (name.contains(allowedName)) { + environment = RunningEnvironment.CONSOLE; + break; + } + } + } + /*if (gamepad != null) { environment = RunningEnvironment.CONSOLE; // calibrate the sticks @@ -460,7 +476,7 @@ public class AppLoader implements ApplicationListener { } else { environment = RunningEnvironment.PC; - } + }*/ // make loading list diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 5f013d2ea..201a0e113 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -83,13 +83,13 @@ object Terrarum : Disposable { var ingame: IngameInstance? = null private set - private val javaHeapCircularArray = CircularArray(64) - private val nativeHeapCircularArray = CircularArray(64) - private val updateRateCircularArray = CircularArray(16) + private val javaHeapCircularArray = CircularArray(64, true) + private val nativeHeapCircularArray = CircularArray(64, true) + private val updateRateCircularArray = CircularArray(16, true) val memJavaHeap: Int get() { - javaHeapCircularArray.add((Gdx.app.javaHeap shr 20).toInt()) + javaHeapCircularArray.appendHead((Gdx.app.javaHeap shr 20).toInt()) var acc = 0 javaHeapCircularArray.forEach { acc = maxOf(acc, it) } @@ -97,7 +97,7 @@ object Terrarum : Disposable { } val memNativeHeap: Int get() { - nativeHeapCircularArray.add((Gdx.app.javaHeap shr 20).toInt()) + nativeHeapCircularArray.appendHead((Gdx.app.javaHeap shr 20).toInt()) var acc = 0 nativeHeapCircularArray.forEach { acc = maxOf(acc, it) } @@ -107,7 +107,7 @@ object Terrarum : Disposable { get() = (Runtime.getRuntime().maxMemory() shr 20).toInt() val updateRateStr: String get() { - updateRateCircularArray.add(updateRate) + updateRateCircularArray.appendHead(updateRate) var acc = 0.0 updateRateCircularArray.forEach { acc = maxOf(acc, it) } diff --git a/src/net/torvald/terrarum/controller/VirtualKeyboard.kt b/src/net/torvald/terrarum/controller/VirtualKeyboard.kt index 23a705228..1f3c5542a 100644 --- a/src/net/torvald/terrarum/controller/VirtualKeyboard.kt +++ b/src/net/torvald/terrarum/controller/VirtualKeyboard.kt @@ -7,12 +7,12 @@ import net.torvald.util.CircularArray */ abstract class VirtualKeyboard(val BUFFER_SIZE: Int = DEFAULT_BUFFER_SIZE) { - val inputBuffer = CircularArray(BUFFER_SIZE) + val inputBuffer = CircularArray(BUFFER_SIZE, false) abstract fun takeFromInputBuffer() fun addToBuffer(char: Char) { - inputBuffer.add(char) + inputBuffer.appendHead(char) } companion object { diff --git a/src/net/torvald/terrarum/controller/XinputControllerAdapter.kt b/src/net/torvald/terrarum/controller/XinputControllerAdapter.kt index 7e3251f54..0a84a45da 100644 --- a/src/net/torvald/terrarum/controller/XinputControllerAdapter.kt +++ b/src/net/torvald/terrarum/controller/XinputControllerAdapter.kt @@ -74,7 +74,7 @@ class XinputControllerAdapter(val c: XInputDevice): TerrarumController { } override fun getName(): String { - return "(XB360 Compatible)" + return "(XINPUT Compatible)" } override fun setRumble(left: Float, right: Float) { diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index e40088fbf..1095083b3 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -57,7 +57,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { val PARTICLES_MAX = AppLoader.getConfigInt("maxparticles") //val actorContainerActive = ArrayList(ACTORCONTAINER_INITIAL_SIZE) //val actorContainerInactive = ArrayList(ACTORCONTAINER_INITIAL_SIZE) - val particlesContainer = CircularArray(PARTICLES_MAX) + val particlesContainer = CircularArray(PARTICLES_MAX, true) val uiContainer = ArrayList() private val actorsRenderBehind = ArrayList(ACTORCONTAINER_INITIAL_SIZE) @@ -960,7 +960,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { } fun addParticle(particle: ParticleBase) { - particlesContainer.add(particle) + particlesContainer.appendHead(particle) } fun addUI(ui: UICanvas) { diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/common/common.lua b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/common/common.lua new file mode 100644 index 000000000..7ef1ffb3d --- /dev/null +++ b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/common/common.lua @@ -0,0 +1,27 @@ +_G.parsecmd = function(str) + local parsetable = {} + local quotemode = false + local wordbuffer = "" + + for c = 1, #str do + local char = str:byte(c) + if not quotemode and char == 32 then -- quotestack is empty and char is a space + table.insert(parsetable, wordbuffer) + wordbuffer = "" + elseif char == 34 then -- " + quotemode = not quotemode + else + wordbuffer = wordbuffer..string.char(char) + end + end + + if #wordbuffer ~= 0 then + table.insert(parsetable, wordbuffer) + end + + return parsetable +end + +_G.TODO = function(str) + error("Not implemented: "..str or "TODO", 2) +end diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/loots/lunados/command.lua b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/loots/lunados/command.lua new file mode 100644 index 000000000..c5665e596 --- /dev/null +++ b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/loots/lunados/command.lua @@ -0,0 +1,58 @@ +print("") +print("Starting Lunados...") + +------------------ +--- INITIALISE --- +------------------ + +require "common" + +local prompt = "> " + +_G.dos = {} +_G.dos.version = "0.1" +_G.dos.copyright = "Copyright (C) 2019 CuriousTorvald. Distributed under GNU GPL 3." +_G.dos.currentpath = {} + +--- appends the directory into the current path +_G.dos.currentpath.push = function(name) + table.insert(dos.path, name) +end + +--- removes the current directory from the current path and returns what has been removed +_G.dos.currentpath.pop = function() + return table.remove(dos.path) +end + +_G.dos.envpath = "C:\\lunados\\bin;" -- must be a sting and not a table + + + + + + + + + + + + +-------------------------- +--- LET THE SHOW BEGIN --- +-------------------------- + +print("Lunados Version "..dos.version) +print(dos.copyright) + +--- PARSE AND RUN COMMANDS --- + +local exit = false + +while not exit do + io.write(table.concat(dos.path, '\\')) + io.write(prompt) + local cmd = io.read() + local commands = parsecmd(cmd) + + TODO() +end \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/BOOT.lua b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/BOOT.lua similarity index 100% rename from src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/BOOT.lua rename to src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/BOOT.lua diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/BRAINFUCK.lua b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/BRAINFUCK.lua similarity index 100% rename from src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/BRAINFUCK.lua rename to src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/BRAINFUCK.lua diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/CCAPI.lua b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/CCAPI.lua similarity index 100% rename from src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/CCAPI.lua rename to src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/CCAPI.lua diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/ROMLIB.lua b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/ROMLIB.lua similarity index 100% rename from src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/ROMLIB.lua rename to src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/ROMLIB.lua diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/TBASEXEC.lua b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/TBASEXEC.lua similarity index 100% rename from src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/TBASEXEC.lua rename to src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/TBASEXEC.lua diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/TBASEXTN.lua b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/TBASEXTN.lua similarity index 100% rename from src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/TBASEXTN.lua rename to src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/TBASEXTN.lua diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/TBASIC.lua b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/TBASIC.lua similarity index 100% rename from src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/TBASIC.lua rename to src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/TBASIC.lua diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/TBASINCL.lua b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/TBASINCL.lua similarity index 100% rename from src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/TBASINCL.lua rename to src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/TBASINCL.lua diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/rombasicman.txt b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/rombasicman.txt similarity index 100% rename from src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/lua/rombasicman.txt rename to src/net/torvald/terrarum/modulecomputers/virtualcomputer/assets/luaold/rombasicman.txt diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/LoadTerrarumIOLib.kt b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/LoadTerrarumIOLib.kt new file mode 100644 index 000000000..e370728bf --- /dev/null +++ b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/LoadTerrarumIOLib.kt @@ -0,0 +1,12 @@ +package net.torvald.terrarum.modulecomputers.virtualcomputer.computer + +import java.io.RandomAccessFile + +/** + * Created by minjaesong on 2019-07-13. + */ +class TEVDFile(path: String, mode: String) : RandomAccessFile(path, mode) { + + + +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/LuaComputerVM.kt b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/LuaComputerVM.kt index c6a56c351..c57de864e 100644 --- a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/LuaComputerVM.kt +++ b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/LuaComputerVM.kt @@ -1,69 +1,473 @@ package net.torvald.terrarum.modulecomputers.virtualcomputer.computer +import net.torvald.terrarum.KVHashMap +import net.torvald.terrarum.Second +import net.torvald.terrarum.ceilInt import org.luaj.vm2.Globals import org.luaj.vm2.LoadState +import org.luaj.vm2.LuaError import org.luaj.vm2.LuaValue import org.luaj.vm2.compiler.LuaC 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 org.luaj.vm2.lib.jse.* +import org.lwjgl.BufferUtils +import org.lwjgl.openal.AL10 import java.io.InputStream - - +import java.io.OutputStream +import java.io.PrintStream +import java.io.Reader +import java.nio.ByteBuffer +import java.util.* /** - * New plan: screw teletype and gui; only the simple 80*24 (size may mary) dumb terminal + * A part that makes "computer fixture" actually work * - * Created by minjaesong on 2019-07-09. + * @param avFixtureComputer : actor values for FixtureComputerBase + * + * @param term : terminal that is connected to the computer fixtures, null if not connected any. + * Created by minjaesong on 2016-09-10. */ class LuaComputerVM(val display: MDA) { - val luaInstance: Globals// = JsePlatform.standardGlobals() + val DEBUG = true - val stdout = MDAPrintStream(display) - val stderr = MDAPrintStream(display) - val stdin = LuaComputerInputStream(this) + lateinit private var luaJ_globals: Globals + + var stdout: PrintStream? = null + private set + var stderr: PrintStream? = null + private set + var stdin: InputStream? = null + private set + + + val UUID = java.util.UUID.randomUUID().toString() + + val computerValue = KVHashMap() + + var isHalted = false + + var stdinInput: Int = -1 + private set + + + // os-related functions. These are called "machine" library-wise. + private val startupTimestamp: Long = System.currentTimeMillis() + /** Time elapsed since the power is on. */ + val milliTime: Int + get() = (System.currentTimeMillis() - startupTimestamp).toInt() 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()) + initSandbox() + } - LoadTerrarumTermLib(luaInstance, display) + fun initSandbox() { + val luaJ_globals = Globals() + luaJ_globals.load(JseBaseLib()) + luaJ_globals.load(PackageLib()) + luaJ_globals.load(Bit32Lib()) + luaJ_globals.load(TableLib()) + luaJ_globals.load(JseStringLib()) + luaJ_globals.load(CoroutineLib()) + luaJ_globals.load(JseMathLib()) + luaJ_globals.load(JseIoLib()) + luaJ_globals.load(JseOsLib()) + luaJ_globals.load(LuajavaLib()) + LoadState.install(luaJ_globals) + LuaC.install(luaJ_globals) - LoadState.install(luaInstance) - LuaC.install(luaInstance) + stdout = TerminalPrintStream(this) + stderr = TerminalPrintStream(this) + stdin = TerminalInputStream(this) - // bit-bit32 alias - luaInstance["bit"] = luaInstance["bit32"] + luaJ_globals.STDOUT = stdout + luaJ_globals.STDERR = stderr + luaJ_globals.STDIN = stdin - // set input/outputstreams - luaInstance.STDOUT = stdout - luaInstance.STDERR = stderr - luaInstance.STDIN = stdin + luaJ_globals["bit"] = luaJ_globals["bit32"] + + // load libraries + LoadTerrarumTermLib(luaJ_globals, display) + + // secure the sandbox + //luaJ_globals["io"] = LuaValue.NIL + // dubug should be sandboxed in BOOT.lua (use OpenComputers code) + //val sethook = luaJ_globals["debug"]["sethook"] + //luaJ_globals["debug"] = LuaValue.NIL } + fun update(delta: Float) { + + if (currentExecutionThread.state == Thread.State.TERMINATED) { + threadRun = false + } + + + + + if (!isHalted) { + runBeepQueueManager(delta) + } + } + + fun keyPressed(c: Int) { + stdinInput = c + + // wake thread + runnableRunCommand.resume() + + synchronized(stdin!!) { + (stdin as java.lang.Object).notifyAll() + } + } + + fun openStdin() { + stdinInput = -1 + // sleep the thread + runnableRunCommand.pause() + } + + lateinit var currentExecutionThread: Thread + private set + lateinit var runnableRunCommand: ThreadRunCommand + private set + private var threadRun = false + + fun runCommand(line: String, env: String) { + if (!threadRun) { + runnableRunCommand = ThreadRunCommand(luaJ_globals, line, env) + currentExecutionThread = Thread(null, runnableRunCommand, "LuaJ Separated") + currentExecutionThread.start() + threadRun = true + } + } + + fun runCommand(reader: Reader, filename: String) { + if (!threadRun) { + runnableRunCommand = ThreadRunCommand(luaJ_globals, reader, filename) + currentExecutionThread = Thread(null, runnableRunCommand, "LuaJ Separated") + currentExecutionThread.start() + threadRun = true + } + } + + /** + * @link https://stackoverflow.com/questions/16758346/how-pause-and-then-resume-a-thread#16758373 + */ + class ThreadRunCommand : Runnable { + + private val mode: Int + private val arg1: Any + private val arg2: String + private val lua: Globals + + @Volatile private var running = true + @Volatile private var paused = false + private val pauseLock = java.lang.Object() + + constructor(luaInstance: Globals, line: String, env: String) { + mode = 0 + arg1 = line + arg2 = env + lua = luaInstance + } + + constructor(luaInstance: Globals, reader: Reader, filename: String) { + mode = 1 + arg1 = reader + arg2 = filename + lua = luaInstance + } + + override fun run() { + synchronized(pauseLock) { + if (!running) { // may have changed while waiting to + // synchronize on pauseLock + return + } + if (paused) { + try { + pauseLock.wait() // will cause this Thread to block until + // another thread calls pauseLock.notifyAll() + // Note that calling wait() will + // relinquish the synchronized lock that this + // thread holds on pauseLock so another thread + // can acquire the lock to call notifyAll() + // (link with explanation below this code) + } + catch (ex: InterruptedException) { + return + } + + if (!running) { // running might have changed since we paused + return + } + } + } + + + try { + val chunk: LuaValue + if (mode == 0) + chunk = lua.load(arg1 as String, arg2) + else if (mode == 1) + chunk = lua.load(arg1 as Reader, arg2) + else + throw IllegalArgumentException("Unsupported mode: $mode") + + + chunk.call() + } + catch (e: LuaError) { + e.printStackTrace(System.err) + //lua.STDERR.println("${SimpleTextTerminal.ASCII_DLE}${e.message}${SimpleTextTerminal.ASCII_DC4}") + } + } + + fun stop() { + running = false + // you might also want to do this: + //interrupt() + } + + fun pause() { + // you may want to throw an IllegalStateException if !running + paused = true + } + + fun resume() { + synchronized(pauseLock) { + paused = false + pauseLock.notifyAll() // Unblocks thread + } + } + } + + class ComputerEmitTone(val computer: LuaComputerVM) : TwoArgFunction() { + override fun call(millisec: LuaValue, freq: LuaValue): LuaValue { + computer.playTone(millisec.checkdouble().toFloat(), freq.checkdouble()) + return LuaValue.NONE + } + } + + /////////////////// + // BEEPER DRIVER // + /////////////////// + + private val beepMaxLen = 10f + // let's regard it as a tracker... + private val beepQueue = ArrayList>() + private var beepCursor = -1 + private var beepQueueLineExecTimer: Second = 0f + private var beepQueueFired = false + + private fun runBeepQueueManager(delta: Float) { + // start emitTone queue + if (beepQueue.size > 0 && beepCursor == -1) { + beepCursor = 0 + } + + // advance emitTone queue + if (beepCursor >= 0 && beepQueueLineExecTimer >= beepQueueGetLenOfPtn(beepCursor)) { + beepQueueLineExecTimer -= beepQueueGetLenOfPtn(beepCursor) + beepCursor += 1 + beepQueueFired = false + } + + // complete emitTone queue + if (beepCursor >= beepQueue.size) { + clearBeepQueue() + } + + // actually play queue + if (beepCursor >= 0 && beepQueue.size > 0 && !beepQueueFired) { + playTone(beepQueue[beepCursor].first, beepQueue[beepCursor].second) + beepQueueFired = true + + // delete sources that is finished. AL is limited to 256 sources. If you exceed it, + // we won't get any more sounds played. + AL10.alSourcei(oldBeepSource, AL10.AL_BUFFER, 0) + AL10.alDeleteSources(oldBeepSource) + AL10.alDeleteBuffers(oldBeepBuffer) + } + + if (beepQueueFired) beepQueueLineExecTimer += delta + } + + fun clearBeepQueue() { + beepQueue.clear() + beepCursor = -1 + beepQueueLineExecTimer = 0f + + //AL.destroy() + + if (DEBUG) println("[TerrarumComputerOld] !! Beep queue clear") + } + + fun enqueueBeep(duration: Double, freq: Double) { + beepQueue.add(Pair(Math.min(duration.toFloat(), beepMaxLen), freq)) + } + + fun beepQueueGetLenOfPtn(ptnIndex: Int) = beepQueue[ptnIndex].first + + + //////////////////// + // TONE GENERATOR // + //////////////////// + + private val sampleRate = 44100 + private var beepSource: Int = -1 + private var beepBuffer: Int = -1 + private var oldBeepSource: Int = -1 + private var oldBeepBuffer: Int = -1 + var audioData: ByteBuffer? = null + + /** + * @param duration : milliseconds + * @param rampUp + * @param rampDown + * + * ,---. (true, true) ,---- (true, false) ----. (false, true) ----- (false, false) + */ + private fun makeAudioData(duration: Second, freq: Double, + rampUp: Boolean = true, rampDown: Boolean = true): ByteBuffer { + + TODO("with duration as Seconds") + + val audioDataSize = duration.times(sampleRate).ceilInt() + val audioData = BufferUtils.createByteBuffer(audioDataSize) + + /*val realDuration = duration * sampleRate / 1000 + val chopSize = freq / sampleRate + + val amp = Math.max(4600.0 / freq, 1.0) + val nHarmonics = if (freq >= 22050.0) 1 + else if (freq >= 11025.0) 2 + else if (freq >= 5512.5) 3 + else if (freq >= 2756.25) 4 + else if (freq >= 1378.125) 5 + else if (freq >= 689.0625) 6 + else 7 + + val transitionThre = 974.47218 + + // TODO volume ramping? + if (freq == 0.0) { + for (_ in 0..audioDataSize - 1) { + audioData.put(0x00.toByte()) + } + } + else if (freq < transitionThre) { // chopper generator (for low freq) + for (tsart in 0..audioDataSize - 1) { + var sine: Double = amp * Math.cos(Math.PI * 2 * () * chopSize) + if (sine > 0.79) sine = 0.79 + else if (sine < -0.79) sine = -0.79 + audioData.put( + (0.5 + 0.5 * sine).times(0xFF).roundInt().toByte() + ) + } + } + else { // harmonics generator (for high freq) + for (x in 0..realDuration - 1) { + var sine: Double = 0.0 + for (k in 1..nHarmonics) { // mix only odd harmonics in order to make a squarewave + sine += Math.sin(Math.PI * 2 * (2*k - 1) * chopSize * x) / (2*k - 1) + } + audioData.put( + (0.5 + 0.5 * sine).times(0xFF).roundInt().toByte() + ) + } + }*/ + + audioData.rewind() + + return audioData + } + + private fun playTone(length: Second, freq: Double) { + /*audioData = makeAudioData(leninmilli, freq) + + + if (!AL.isCreated()) AL.create() + + + // Clear error stack. + AL10.alGetError() + + oldBeepBuffer = beepBuffer + beepBuffer = AL10.alGenBuffers() + checkALError() + + try { + AL10.alBufferData(beepBuffer, AL10.AL_FORMAT_MONO8, audioData, sampleRate) + checkALError() + + oldBeepSource = beepSource + beepSource = AL10.alGenSources() + checkALError() + + try { + AL10.alSourceQueueBuffers(beepSource, beepBuffer) + checkALError() + + AL10.alSource3f(beepSource, AL10.AL_POSITION, 0f, 0f, 1f) + AL10.alSourcef(beepSource, AL10.AL_REFERENCE_DISTANCE, 1f) + AL10.alSourcef(beepSource, AL10.AL_MAX_DISTANCE, 1f) + AL10.alSourcef(beepSource, AL10.AL_GAIN, 0.3f) + checkALError() + + AL10.alSourcePlay(beepSource) + checkALError() + } + catch (e: ALException) { + AL10.alDeleteSources(beepSource) + } + } + catch (e: ALException) { + AL10.alDeleteSources(beepSource) + }*/ + } + + // Custom implementation of Util.checkALError() that uses our custom exception. + private fun checkALError() { + val errorCode = AL10.alGetError() + if (errorCode != AL10.AL_NO_ERROR) { + throw ALException(errorCode) + } + } + } -class LuaComputerInputStream(val host: LuaComputerVM) : InputStream() { +class TerminalPrintStream(val host: LuaComputerVM) : PrintStream(TerminalOutputStream(host)) + +class TerminalOutputStream(val host: LuaComputerVM) : OutputStream() { + override fun write(b: Int) = host.display.write(b.and(0xFF).toByte()) +} + +class TerminalInputStream(val host: LuaComputerVM) : InputStream() { + override fun read(): Int { - TODO("not implemented") + //System.err.println(Thread.currentThread().name) + // would display "LuaJ Separated", which means this InputStream will not block main thread + + /*host.openStdin() + synchronized(this) { + (this as java.lang.Object).wait() + }*/ + + return 65//host.stdinInput } + } +class ALException(errorCode: Int) : Exception("ALerror: $errorCode") { + +} + + /** * Install a function into the lua. * @param identifier How you might call this lua function. E.g. "term.println" diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/MDA.kt b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/MDA.kt index a66170701..50dfe1c2c 100644 --- a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/MDA.kt +++ b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/MDA.kt @@ -37,8 +37,8 @@ class MDA(val width: Int, val height: Int) { var blink = true init { - //glyphs.fillWith(0) - //attributes.fillWith(1) + glyphs.fillWith(0) + attributes.fillWith(1) } /* diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/standalone/StandaloneApp.kt b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/standalone/StandaloneApp.kt index 6fe0ea711..c2d08d765 100644 --- a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/standalone/StandaloneApp.kt +++ b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/standalone/StandaloneApp.kt @@ -2,6 +2,7 @@ package net.torvald.terrarum.modulecomputers.virtualcomputer.standalone import com.badlogic.gdx.Game import com.badlogic.gdx.Gdx +import com.badlogic.gdx.InputProcessor import com.badlogic.gdx.backends.lwjgl.LwjglApplication import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration import com.badlogic.gdx.graphics.Color @@ -24,26 +25,19 @@ class StandaloneApp : Game() { lateinit var batch: SpriteBatch - lateinit var vmThread: Thread - - val display = MDA(80, 25) + val display = MDA(64, 40) val vm = LuaComputerVM(display) override fun create() { font = TextureRegionPack(Gdx.files.internal("assets/mods/dwarventech/gui/lcd.tga"), 12, 16) - background = Texture(Gdx.files.internal("assets/mods/dwarventech/gui/8025_textonly.png")) + background = Texture(Gdx.files.internal("assets/mods/dwarventech/gui/6440_textonly.png")) execLed = Texture(Gdx.files.internal("assets/mods/dwarventech/gui/led_green.tga")) waitLed = Texture(Gdx.files.internal("assets/mods/dwarventech/gui/led_orange.tga")) batch = SpriteBatch() - //Gdx.input.inputProcessor = TVMInputProcessor() - - - //vmThread = Thread(vm) - //vmThread.start() - + Gdx.input.inputProcessor = StandaloneAppInputProcessor(vm) } private val height: Int; get() = Gdx.graphics.height @@ -60,6 +54,26 @@ class StandaloneApp : Game() { private var textCursorDrawTimer = 0f // 0f..0.5f: not draw + init { + vm.runCommand(""" + print("Hello, world!") + while true do + local s = io.read() + print(s) + end + """.trimIndent(), "") + + /*vm.runCommand(""" + a = 0 + while true do + print(a) + a = a + 1 + end + """.trimIndent(), "")*/ + } + + + override fun render() { Gdx.graphics.setTitle("Terrarum Lua Computer Standalone — F: ${Gdx.graphics.framesPerSecond}") @@ -130,51 +144,48 @@ class StandaloneApp : Game() { this.end() } - - /*class TVMInputProcessor(val vm: TerranVM) : InputProcessor { - override fun touchUp(p0: Int, p1: Int, p2: Int, p3: Int): Boolean { + private class StandaloneAppInputProcessor(private val vm: LuaComputerVM) : InputProcessor { + override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { return false } - override fun mouseMoved(p0: Int, p1: Int): Boolean { + override fun mouseMoved(screenX: Int, screenY: Int): Boolean { return false } - override fun keyTyped(p0: Char): Boolean { - - - return true - } - - override fun scrolled(p0: Int): Boolean { + override fun keyTyped(character: Char): Boolean { return false } - override fun keyUp(p0: Int): Boolean { + override fun scrolled(amount: Int): Boolean { return false } - override fun touchDragged(p0: Int, p1: Int, p2: Int): Boolean { + override fun keyUp(keycode: Int): Boolean { return false } - override fun keyDown(p0: Int): Boolean { + override fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean { return false } - override fun touchDown(p0: Int, p1: Int, p2: Int, p3: Int): Boolean { + override fun keyDown(keycode: Int): Boolean { + vm.keyPressed(keycode) return false } - }*/ + override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { + return false + } + } private fun Byte.toUint() = java.lang.Byte.toUnsignedInt(this) } fun main(args: Array) { val config = LwjglApplicationConfiguration() - config.width = 1106 - config.height = 556 + config.width = 914 + config.height = 796 config.foregroundFPS = 100 config.vSyncEnabled = false config.resizable = false diff --git a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt index f957aaa7f..3b17e1db7 100644 --- a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt +++ b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt @@ -321,6 +321,7 @@ class BasicDebugInfoWindow : UICanvas() { private fun drawGamepadAxis(gamepad: TerrarumController, batch: SpriteBatch, axisX: Float, axisY: Float, uiX: Int, uiY: Int) { val uiColour = ItemSlotImageFactory.CELLCOLOUR_BLACK + val deadzoneColour = Color(0xaa0000aa.toInt()) val w = 128f val h = 128f val halfW = w / 2f @@ -329,6 +330,8 @@ class BasicDebugInfoWindow : UICanvas() { val pointDX = axisX * halfW val pointDY = -axisY * halfH + val deadzone = AppLoader.gamepadDeadzone + blendNormal(batch) batch.end() @@ -336,6 +339,8 @@ class BasicDebugInfoWindow : UICanvas() { Terrarum.inShapeRenderer { it.color = uiColour it.rect(uiX.toFloat(), AppLoader.screenH - uiY.toFloat(), w, -h) + it.color = deadzoneColour + it.rect(uiX + halfW - (halfW * deadzone), AppLoader.screenH - (uiY + halfH - halfH * deadzone), w * deadzone, -h * deadzone) it.color = Color.WHITE it.line(uiX + halfW, AppLoader.screenH - (uiY + halfH), uiX + halfW + pointDX, AppLoader.screenH - (uiY + halfH + pointDY)) it.color = Color.GRAY diff --git a/work_files/UI/crt_560x650.psd b/work_files/UI/crt_560x650.psd new file mode 100644 index 000000000..671273969 --- /dev/null +++ b/work_files/UI/crt_560x650.psd @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b8002073dbffb84528d09af09ba389a7a844a19da89dbd5425f5ebba3d31d817 +size 536327