diff --git a/assets/mods/dwarventech/gui/6440_textonly.png b/assets/mods/dwarventech/gui/6440_textonly.png new file mode 100644 index 000000000..a343e46ef Binary files /dev/null and b/assets/mods/dwarventech/gui/6440_textonly.png differ 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