mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-12 14:51:51 +09:00
ingame computer wip; gamepad deadzone disp on f3
This commit is contained in:
BIN
assets/mods/dwarventech/gui/6440_textonly.png
Normal file
BIN
assets/mods/dwarventech/gui/6440_textonly.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -208,7 +208,7 @@ public class AppLoader implements ApplicationListener {
|
|||||||
|
|
||||||
/** A gamepad. Multiple gamepads may controll this single virtualised gamepad. */
|
/** A gamepad. Multiple gamepads may controll this single virtualised gamepad. */
|
||||||
public static TerrarumController gamepad = null;
|
public static TerrarumController gamepad = null;
|
||||||
public static float gamepadDeadzone = 0.3f;
|
public static float gamepadDeadzone = 0.2f;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -296,6 +296,10 @@ public class AppLoader implements ApplicationListener {
|
|||||||
public static char gamepadLabelLStickPush = 0xE046;
|
public static char gamepadLabelLStickPush = 0xE046;
|
||||||
public static char gamepadLabelRStickPush = 0xE047;
|
public static char gamepadLabelRStickPush = 0xE047;
|
||||||
|
|
||||||
|
public static String[] gamepadWhitelist = {
|
||||||
|
"xinput", "xbox", "game", "joy", "pad"
|
||||||
|
};
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// load configs
|
// load configs
|
||||||
getDefaultDirectory();
|
getDefaultDirectory();
|
||||||
@@ -441,7 +445,19 @@ public class AppLoader implements ApplicationListener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tell the game that we have a gamepad
|
||||||
|
environment = RunningEnvironment.PC;
|
||||||
|
|
||||||
if (gamepad != null) {
|
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;
|
environment = RunningEnvironment.CONSOLE;
|
||||||
|
|
||||||
// calibrate the sticks
|
// calibrate the sticks
|
||||||
@@ -460,7 +476,7 @@ public class AppLoader implements ApplicationListener {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
environment = RunningEnvironment.PC;
|
environment = RunningEnvironment.PC;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// make loading list
|
// make loading list
|
||||||
|
|
||||||
|
|||||||
@@ -83,13 +83,13 @@ object Terrarum : Disposable {
|
|||||||
var ingame: IngameInstance? = null
|
var ingame: IngameInstance? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
private val javaHeapCircularArray = CircularArray<Int>(64)
|
private val javaHeapCircularArray = CircularArray<Int>(64, true)
|
||||||
private val nativeHeapCircularArray = CircularArray<Int>(64)
|
private val nativeHeapCircularArray = CircularArray<Int>(64, true)
|
||||||
private val updateRateCircularArray = CircularArray<Double>(16)
|
private val updateRateCircularArray = CircularArray<Double>(16, true)
|
||||||
|
|
||||||
val memJavaHeap: Int
|
val memJavaHeap: Int
|
||||||
get() {
|
get() {
|
||||||
javaHeapCircularArray.add((Gdx.app.javaHeap shr 20).toInt())
|
javaHeapCircularArray.appendHead((Gdx.app.javaHeap shr 20).toInt())
|
||||||
|
|
||||||
var acc = 0
|
var acc = 0
|
||||||
javaHeapCircularArray.forEach { acc = maxOf(acc, it) }
|
javaHeapCircularArray.forEach { acc = maxOf(acc, it) }
|
||||||
@@ -97,7 +97,7 @@ object Terrarum : Disposable {
|
|||||||
}
|
}
|
||||||
val memNativeHeap: Int
|
val memNativeHeap: Int
|
||||||
get() {
|
get() {
|
||||||
nativeHeapCircularArray.add((Gdx.app.javaHeap shr 20).toInt())
|
nativeHeapCircularArray.appendHead((Gdx.app.javaHeap shr 20).toInt())
|
||||||
|
|
||||||
var acc = 0
|
var acc = 0
|
||||||
nativeHeapCircularArray.forEach { acc = maxOf(acc, it) }
|
nativeHeapCircularArray.forEach { acc = maxOf(acc, it) }
|
||||||
@@ -107,7 +107,7 @@ object Terrarum : Disposable {
|
|||||||
get() = (Runtime.getRuntime().maxMemory() shr 20).toInt()
|
get() = (Runtime.getRuntime().maxMemory() shr 20).toInt()
|
||||||
val updateRateStr: String
|
val updateRateStr: String
|
||||||
get() {
|
get() {
|
||||||
updateRateCircularArray.add(updateRate)
|
updateRateCircularArray.appendHead(updateRate)
|
||||||
|
|
||||||
var acc = 0.0
|
var acc = 0.0
|
||||||
updateRateCircularArray.forEach { acc = maxOf(acc, it) }
|
updateRateCircularArray.forEach { acc = maxOf(acc, it) }
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ import net.torvald.util.CircularArray
|
|||||||
*/
|
*/
|
||||||
abstract class VirtualKeyboard(val BUFFER_SIZE: Int = DEFAULT_BUFFER_SIZE) {
|
abstract class VirtualKeyboard(val BUFFER_SIZE: Int = DEFAULT_BUFFER_SIZE) {
|
||||||
|
|
||||||
val inputBuffer = CircularArray<Char>(BUFFER_SIZE)
|
val inputBuffer = CircularArray<Char>(BUFFER_SIZE, false)
|
||||||
|
|
||||||
abstract fun takeFromInputBuffer()
|
abstract fun takeFromInputBuffer()
|
||||||
|
|
||||||
fun addToBuffer(char: Char) {
|
fun addToBuffer(char: Char) {
|
||||||
inputBuffer.add(char)
|
inputBuffer.appendHead(char)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ class XinputControllerAdapter(val c: XInputDevice): TerrarumController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getName(): String {
|
override fun getName(): String {
|
||||||
return "(XB360 Compatible)"
|
return "(XINPUT Compatible)"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setRumble(left: Float, right: Float) {
|
override fun setRumble(left: Float, right: Float) {
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
val PARTICLES_MAX = AppLoader.getConfigInt("maxparticles")
|
val PARTICLES_MAX = AppLoader.getConfigInt("maxparticles")
|
||||||
//val actorContainerActive = ArrayList<Actor>(ACTORCONTAINER_INITIAL_SIZE)
|
//val actorContainerActive = ArrayList<Actor>(ACTORCONTAINER_INITIAL_SIZE)
|
||||||
//val actorContainerInactive = ArrayList<Actor>(ACTORCONTAINER_INITIAL_SIZE)
|
//val actorContainerInactive = ArrayList<Actor>(ACTORCONTAINER_INITIAL_SIZE)
|
||||||
val particlesContainer = CircularArray<ParticleBase>(PARTICLES_MAX)
|
val particlesContainer = CircularArray<ParticleBase>(PARTICLES_MAX, true)
|
||||||
val uiContainer = ArrayList<UICanvas>()
|
val uiContainer = ArrayList<UICanvas>()
|
||||||
|
|
||||||
private val actorsRenderBehind = ArrayList<ActorWithBody>(ACTORCONTAINER_INITIAL_SIZE)
|
private val actorsRenderBehind = ArrayList<ActorWithBody>(ACTORCONTAINER_INITIAL_SIZE)
|
||||||
@@ -960,7 +960,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun addParticle(particle: ParticleBase) {
|
fun addParticle(particle: ParticleBase) {
|
||||||
particlesContainer.add(particle)
|
particlesContainer.appendHead(particle)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addUI(ui: UICanvas) {
|
fun addUI(ui: UICanvas) {
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,69 +1,473 @@
|
|||||||
package net.torvald.terrarum.modulecomputers.virtualcomputer.computer
|
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.Globals
|
||||||
import org.luaj.vm2.LoadState
|
import org.luaj.vm2.LoadState
|
||||||
|
import org.luaj.vm2.LuaError
|
||||||
import org.luaj.vm2.LuaValue
|
import org.luaj.vm2.LuaValue
|
||||||
import org.luaj.vm2.compiler.LuaC
|
import org.luaj.vm2.compiler.LuaC
|
||||||
import org.luaj.vm2.lib.*
|
import org.luaj.vm2.lib.*
|
||||||
import org.luaj.vm2.lib.jse.JseBaseLib
|
import org.luaj.vm2.lib.jse.*
|
||||||
import org.luaj.vm2.lib.jse.JseMathLib
|
import org.lwjgl.BufferUtils
|
||||||
import org.luaj.vm2.lib.jse.JseStringLib
|
import org.lwjgl.openal.AL10
|
||||||
import java.io.InputStream
|
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) {
|
class LuaComputerVM(val display: MDA) {
|
||||||
|
|
||||||
val luaInstance: Globals// = JsePlatform.standardGlobals()
|
val DEBUG = true
|
||||||
|
|
||||||
val stdout = MDAPrintStream(display)
|
lateinit private var luaJ_globals: Globals
|
||||||
val stderr = MDAPrintStream(display)
|
|
||||||
val stdin = LuaComputerInputStream(this)
|
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 {
|
init {
|
||||||
// initialise the lua instance
|
initSandbox()
|
||||||
luaInstance = Globals()
|
}
|
||||||
luaInstance.load(JseBaseLib())
|
|
||||||
luaInstance.load(PackageLib())
|
|
||||||
luaInstance.load(Bit32Lib())
|
|
||||||
luaInstance.load(TableLib())
|
|
||||||
luaInstance.load(JseStringLib())
|
|
||||||
luaInstance.load(CoroutineLib())
|
|
||||||
luaInstance.load(JseMathLib())
|
|
||||||
//luaInstance.load(JseIoLib())
|
|
||||||
//luaInstance.load(JseOsLib())
|
|
||||||
//luaInstance.load(LuajavaLib())
|
|
||||||
|
|
||||||
LoadTerrarumTermLib(luaInstance, display)
|
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)
|
stdout = TerminalPrintStream(this)
|
||||||
LuaC.install(luaInstance)
|
stderr = TerminalPrintStream(this)
|
||||||
|
stdin = TerminalInputStream(this)
|
||||||
|
|
||||||
// bit-bit32 alias
|
luaJ_globals.STDOUT = stdout
|
||||||
luaInstance["bit"] = luaInstance["bit32"]
|
luaJ_globals.STDERR = stderr
|
||||||
|
luaJ_globals.STDIN = stdin
|
||||||
|
|
||||||
// set input/outputstreams
|
luaJ_globals["bit"] = luaJ_globals["bit32"]
|
||||||
luaInstance.STDOUT = stdout
|
|
||||||
luaInstance.STDERR = stderr
|
// load libraries
|
||||||
luaInstance.STDIN = stdin
|
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<Pair<Second, Double>>()
|
||||||
|
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 {
|
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.
|
* Install a function into the lua.
|
||||||
* @param identifier How you might call this lua function. E.g. "term.println"
|
* @param identifier How you might call this lua function. E.g. "term.println"
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ class MDA(val width: Int, val height: Int) {
|
|||||||
var blink = true
|
var blink = true
|
||||||
|
|
||||||
init {
|
init {
|
||||||
//glyphs.fillWith(0)
|
glyphs.fillWith(0)
|
||||||
//attributes.fillWith(1)
|
attributes.fillWith(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum.modulecomputers.virtualcomputer.standalone
|
|||||||
|
|
||||||
import com.badlogic.gdx.Game
|
import com.badlogic.gdx.Game
|
||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
|
import com.badlogic.gdx.InputProcessor
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplication
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplication
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
@@ -24,26 +25,19 @@ class StandaloneApp : Game() {
|
|||||||
|
|
||||||
lateinit var batch: SpriteBatch
|
lateinit var batch: SpriteBatch
|
||||||
|
|
||||||
lateinit var vmThread: Thread
|
val display = MDA(64, 40)
|
||||||
|
|
||||||
val display = MDA(80, 25)
|
|
||||||
val vm = LuaComputerVM(display)
|
val vm = LuaComputerVM(display)
|
||||||
|
|
||||||
override fun create() {
|
override fun create() {
|
||||||
font = TextureRegionPack(Gdx.files.internal("assets/mods/dwarventech/gui/lcd.tga"), 12, 16)
|
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"))
|
execLed = Texture(Gdx.files.internal("assets/mods/dwarventech/gui/led_green.tga"))
|
||||||
waitLed = Texture(Gdx.files.internal("assets/mods/dwarventech/gui/led_orange.tga"))
|
waitLed = Texture(Gdx.files.internal("assets/mods/dwarventech/gui/led_orange.tga"))
|
||||||
|
|
||||||
batch = SpriteBatch()
|
batch = SpriteBatch()
|
||||||
|
|
||||||
//Gdx.input.inputProcessor = TVMInputProcessor()
|
Gdx.input.inputProcessor = StandaloneAppInputProcessor(vm)
|
||||||
|
|
||||||
|
|
||||||
//vmThread = Thread(vm)
|
|
||||||
//vmThread.start()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val height: Int; get() = Gdx.graphics.height
|
private val height: Int; get() = Gdx.graphics.height
|
||||||
@@ -60,6 +54,26 @@ class StandaloneApp : Game() {
|
|||||||
|
|
||||||
private var textCursorDrawTimer = 0f // 0f..0.5f: not draw
|
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() {
|
override fun render() {
|
||||||
Gdx.graphics.setTitle("Terrarum Lua Computer Standalone — F: ${Gdx.graphics.framesPerSecond}")
|
Gdx.graphics.setTitle("Terrarum Lua Computer Standalone — F: ${Gdx.graphics.framesPerSecond}")
|
||||||
|
|
||||||
@@ -130,51 +144,48 @@ class StandaloneApp : Game() {
|
|||||||
this.end()
|
this.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class StandaloneAppInputProcessor(private val vm: LuaComputerVM) : InputProcessor {
|
||||||
/*class TVMInputProcessor(val vm: TerranVM) : InputProcessor {
|
override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||||
override fun touchUp(p0: Int, p1: Int, p2: Int, p3: Int): Boolean {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mouseMoved(p0: Int, p1: Int): Boolean {
|
override fun mouseMoved(screenX: Int, screenY: Int): Boolean {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun keyTyped(p0: Char): Boolean {
|
override fun keyTyped(character: Char): Boolean {
|
||||||
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun scrolled(p0: Int): Boolean {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun keyUp(p0: Int): Boolean {
|
override fun scrolled(amount: Int): Boolean {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun touchDragged(p0: Int, p1: Int, p2: Int): Boolean {
|
override fun keyUp(keycode: Int): Boolean {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun keyDown(p0: Int): Boolean {
|
override fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean {
|
||||||
return false
|
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
|
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)
|
private fun Byte.toUint() = java.lang.Byte.toUnsignedInt(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val config = LwjglApplicationConfiguration()
|
val config = LwjglApplicationConfiguration()
|
||||||
config.width = 1106
|
config.width = 914
|
||||||
config.height = 556
|
config.height = 796
|
||||||
config.foregroundFPS = 100
|
config.foregroundFPS = 100
|
||||||
config.vSyncEnabled = false
|
config.vSyncEnabled = false
|
||||||
config.resizable = false
|
config.resizable = false
|
||||||
|
|||||||
@@ -321,6 +321,7 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
|
|
||||||
private fun drawGamepadAxis(gamepad: TerrarumController, batch: SpriteBatch, axisX: Float, axisY: Float, uiX: Int, uiY: Int) {
|
private fun drawGamepadAxis(gamepad: TerrarumController, batch: SpriteBatch, axisX: Float, axisY: Float, uiX: Int, uiY: Int) {
|
||||||
val uiColour = ItemSlotImageFactory.CELLCOLOUR_BLACK
|
val uiColour = ItemSlotImageFactory.CELLCOLOUR_BLACK
|
||||||
|
val deadzoneColour = Color(0xaa0000aa.toInt())
|
||||||
val w = 128f
|
val w = 128f
|
||||||
val h = 128f
|
val h = 128f
|
||||||
val halfW = w / 2f
|
val halfW = w / 2f
|
||||||
@@ -329,6 +330,8 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
val pointDX = axisX * halfW
|
val pointDX = axisX * halfW
|
||||||
val pointDY = -axisY * halfH
|
val pointDY = -axisY * halfH
|
||||||
|
|
||||||
|
val deadzone = AppLoader.gamepadDeadzone
|
||||||
|
|
||||||
blendNormal(batch)
|
blendNormal(batch)
|
||||||
|
|
||||||
batch.end()
|
batch.end()
|
||||||
@@ -336,6 +339,8 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
Terrarum.inShapeRenderer {
|
Terrarum.inShapeRenderer {
|
||||||
it.color = uiColour
|
it.color = uiColour
|
||||||
it.rect(uiX.toFloat(), AppLoader.screenH - uiY.toFloat(), w, -h)
|
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.color = Color.WHITE
|
||||||
it.line(uiX + halfW, AppLoader.screenH - (uiY + halfH), uiX + halfW + pointDX, AppLoader.screenH - (uiY + halfH + pointDY))
|
it.line(uiX + halfW, AppLoader.screenH - (uiY + halfH), uiX + halfW + pointDX, AppLoader.screenH - (uiY + halfH + pointDY))
|
||||||
it.color = Color.GRAY
|
it.color = Color.GRAY
|
||||||
|
|||||||
BIN
work_files/UI/crt_560x650.psd
LFS
Normal file
BIN
work_files/UI/crt_560x650.psd
LFS
Normal file
Binary file not shown.
Reference in New Issue
Block a user