mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-14 12:34:05 +09:00
Keyboard strobing moved to a new thread so that fast typing is possible even if the game's update method is running slowly
This commit is contained in:
@@ -25,7 +25,9 @@ import net.torvald.terrarum.controller.TerrarumController;
|
|||||||
import net.torvald.terrarum.controller.XinputControllerAdapter;
|
import net.torvald.terrarum.controller.XinputControllerAdapter;
|
||||||
import net.torvald.terrarum.gameactors.BlockMarkerActor;
|
import net.torvald.terrarum.gameactors.BlockMarkerActor;
|
||||||
import net.torvald.terrarum.gamecontroller.IME;
|
import net.torvald.terrarum.gamecontroller.IME;
|
||||||
|
import net.torvald.terrarum.gamecontroller.InputStrober;
|
||||||
import net.torvald.terrarum.gamecontroller.KeyToggler;
|
import net.torvald.terrarum.gamecontroller.KeyToggler;
|
||||||
|
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent;
|
||||||
import net.torvald.terrarum.gameworld.GameWorld;
|
import net.torvald.terrarum.gameworld.GameWorld;
|
||||||
import net.torvald.terrarum.imagefont.TinyAlphNum;
|
import net.torvald.terrarum.imagefont.TinyAlphNum;
|
||||||
import net.torvald.terrarum.langpack.Lang;
|
import net.torvald.terrarum.langpack.Lang;
|
||||||
@@ -234,7 +236,7 @@ public class App implements ApplicationListener {
|
|||||||
private static com.badlogic.gdx.graphics.Color gradWhiteTop = new com.badlogic.gdx.graphics.Color(0xf8f8f8ff);
|
private static com.badlogic.gdx.graphics.Color gradWhiteTop = new com.badlogic.gdx.graphics.Color(0xf8f8f8ff);
|
||||||
private static com.badlogic.gdx.graphics.Color gradWhiteBottom = new com.badlogic.gdx.graphics.Color(0xd8d8d8ff);
|
private static com.badlogic.gdx.graphics.Color gradWhiteBottom = new com.badlogic.gdx.graphics.Color(0xd8d8d8ff);
|
||||||
|
|
||||||
private static Screen currentScreen;
|
private static TerrarumGamescreen currentScreen;
|
||||||
private static LoadScreenBase currentSetLoadScreen;
|
private static LoadScreenBase currentSetLoadScreen;
|
||||||
|
|
||||||
private void initViewPort(int width, int height) {
|
private void initViewPort(int width, int height) {
|
||||||
@@ -284,6 +286,8 @@ public class App implements ApplicationListener {
|
|||||||
"xinput", "xbox", "game", "joy", "pad"
|
"xinput", "xbox", "game", "joy", "pad"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static InputStrober inputStrober = InputStrober.INSTANCE; // kinda dummy field
|
||||||
|
|
||||||
public static Screen getCurrentScreen() {
|
public static Screen getCurrentScreen() {
|
||||||
return currentScreen;
|
return currentScreen;
|
||||||
}
|
}
|
||||||
@@ -709,6 +713,8 @@ public class App implements ApplicationListener {
|
|||||||
resizeReqSize = new Point2i(width, height);
|
resizeReqSize = new Point2i(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
System.out.println("Goodbye !");
|
System.out.println("Goodbye !");
|
||||||
@@ -762,6 +768,8 @@ public class App implements ApplicationListener {
|
|||||||
|
|
||||||
Terrarum.INSTANCE.dispose();
|
Terrarum.INSTANCE.dispose();
|
||||||
|
|
||||||
|
inputStrober.dispose();
|
||||||
|
|
||||||
deleteTempfiles();
|
deleteTempfiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,15 +793,19 @@ public class App implements ApplicationListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void setScreen(Screen screen) {
|
public static void setScreen(Screen screen) {
|
||||||
|
if (!(screen instanceof TerrarumGamescreen)) {
|
||||||
|
throw new IllegalArgumentException("Screen must be instance of TerrarumGameScreen: " + screen.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
|
|
||||||
if (screen instanceof LoadScreenBase) {
|
if (screen instanceof LoadScreenBase) {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
"Loadscreen '" + screen.getClass().getSimpleName() + "' must be set with 'setLoadScreen()' method");
|
"Loadscreen '" + screen.getClass().getSimpleName() + "' must be set with 'setLoadScreen()' method");
|
||||||
}
|
}
|
||||||
|
|
||||||
_setScr(screen);
|
_setScr((TerrarumGamescreen) screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void _setScr(Screen screen) {
|
private static void _setScr(TerrarumGamescreen screen) {
|
||||||
|
|
||||||
printdbg("AppLoader-Static", "Changing screen to " + screen.getClass().getCanonicalName());
|
printdbg("AppLoader-Static", "Changing screen to " + screen.getClass().getCanonicalName());
|
||||||
|
|
||||||
@@ -1305,4 +1317,12 @@ public class App implements ApplicationListener {
|
|||||||
public static long getTIME_T() {
|
public static long getTIME_T() {
|
||||||
return System.currentTimeMillis() / 1000L;
|
return System.currentTimeMillis() / 1000L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just an event handler I'm slipping in
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
public static void inputStrobed(TerrarumKeyboardEvent event) {
|
||||||
|
currentScreen.inputStrobed(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import net.torvald.terrarum.gameactors.Actor
|
|||||||
import net.torvald.terrarum.gameactors.ActorID
|
import net.torvald.terrarum.gameactors.ActorID
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
import net.torvald.terrarum.gameactors.BlockMarkerActor
|
import net.torvald.terrarum.gameactors.BlockMarkerActor
|
||||||
|
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
||||||
import net.torvald.terrarum.gameitem.ItemID
|
import net.torvald.terrarum.gameitem.ItemID
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
||||||
@@ -31,7 +32,7 @@ import java.util.concurrent.locks.Lock
|
|||||||
* Although the game (as product) can have infinitely many stages/planets/etc., those stages must be manually managed by YOU;
|
* Although the game (as product) can have infinitely many stages/planets/etc., those stages must be manually managed by YOU;
|
||||||
* this instance only stores the stage that is currently being used.
|
* this instance only stores the stage that is currently being used.
|
||||||
*/
|
*/
|
||||||
open class IngameInstance(val batch: SpriteBatch, val isMultiplayer: Boolean = false) : Screen {
|
open class IngameInstance(val batch: SpriteBatch, val isMultiplayer: Boolean = false) : TerrarumGamescreen {
|
||||||
|
|
||||||
open protected val actorMBRConverter = object : MBRConverter<ActorWithBody> {
|
open protected val actorMBRConverter = object : MBRConverter<ActorWithBody> {
|
||||||
override fun getDimensions(): Int = 2
|
override fun getDimensions(): Int = 2
|
||||||
@@ -134,6 +135,9 @@ open class IngameInstance(val batch: SpriteBatch, val isMultiplayer: Boolean = f
|
|||||||
override fun hide() {
|
override fun hide() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun inputStrobed(e: TerrarumKeyboardEvent) {
|
||||||
|
}
|
||||||
|
|
||||||
override fun show() {
|
override fun show() {
|
||||||
// the very basic show() implementation
|
// the very basic show() implementation
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ import com.badlogic.gdx.Gdx
|
|||||||
import com.badlogic.gdx.ScreenAdapter
|
import com.badlogic.gdx.ScreenAdapter
|
||||||
import com.badlogic.gdx.graphics.OrthographicCamera
|
import com.badlogic.gdx.graphics.OrthographicCamera
|
||||||
import com.badlogic.gdx.utils.Disposable
|
import com.badlogic.gdx.utils.Disposable
|
||||||
|
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
||||||
import net.torvald.terrarum.langpack.Lang
|
import net.torvald.terrarum.langpack.Lang
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
import net.torvald.util.CircularArray
|
import net.torvald.util.CircularArray
|
||||||
|
|
||||||
open class LoadScreenBase : ScreenAdapter(), Disposable {
|
open class LoadScreenBase : ScreenAdapter(), Disposable, TerrarumGamescreen {
|
||||||
|
|
||||||
open var preLoadJob: (LoadScreenBase) -> Unit = {}
|
open var preLoadJob: (LoadScreenBase) -> Unit = {}
|
||||||
open var screenToLoad: IngameInstance? = null
|
open var screenToLoad: IngameInstance? = null
|
||||||
@@ -82,4 +83,7 @@ open class LoadScreenBase : ScreenAdapter(), Disposable {
|
|||||||
override fun resize(width: Int, height: Int) {
|
override fun resize(width: Int, height: Int) {
|
||||||
initViewPort(App.scr.width, App.scr.height)
|
initViewPort(App.scr.width, App.scr.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun inputStrobed(e: TerrarumKeyboardEvent) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,6 @@ typealias RGBA8888 = Int
|
|||||||
object Terrarum : Disposable {
|
object Terrarum : Disposable {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
IngameController.KEYBOARD_DELAYS[1]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
11
src/net/torvald/terrarum/TerrarumGamescreen.kt
Normal file
11
src/net/torvald/terrarum/TerrarumGamescreen.kt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package net.torvald.terrarum
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Screen
|
||||||
|
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2021-11-06.
|
||||||
|
*/
|
||||||
|
interface TerrarumGamescreen : Screen {
|
||||||
|
fun inputStrobed(e: TerrarumKeyboardEvent)
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
|||||||
import net.torvald.terrarum.console.CommandDict
|
import net.torvald.terrarum.console.CommandDict
|
||||||
import net.torvald.terrarum.gameactors.*
|
import net.torvald.terrarum.gameactors.*
|
||||||
import net.torvald.terrarum.gameactors.ai.ActorAI
|
import net.torvald.terrarum.gameactors.ai.ActorAI
|
||||||
|
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.gameworld.WorldTime
|
import net.torvald.terrarum.gameworld.WorldTime
|
||||||
import net.torvald.terrarum.gameworld.fmod
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
@@ -389,6 +390,10 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
warning32bitJavaIcon.texture.dispose()
|
warning32bitJavaIcon.texture.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun inputStrobed(e: TerrarumKeyboardEvent) {
|
||||||
|
uiContainer.forEach { it?.inputStrobed(e) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun setCameraPosition(newX: Float, newY: Float) {
|
fun setCameraPosition(newX: Float, newY: Float) {
|
||||||
|
|||||||
@@ -277,112 +277,5 @@ class IngameController(val terrarumIngame: TerrarumIngame) : InputAdapter() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
data class TerrarumKeyboardEvent(
|
|
||||||
val type: Int,
|
|
||||||
val character: String?, // representative key symbol
|
|
||||||
val headkey: Int, // representative keycode
|
|
||||||
val repeatCount: Int,
|
|
||||||
val keycodes: IntArray
|
|
||||||
)
|
|
||||||
private const val KEY_DOWN = 0
|
|
||||||
private const val KEY_CHANGE = 1
|
|
||||||
const val N_KEY_ROLLOVER = 8
|
|
||||||
var KEYBOARD_DELAYS = longArrayOf(0L,250000000L,0L,25000000L,0L)
|
|
||||||
private var stroboTime = 0L
|
|
||||||
private var stroboStatus = 0
|
|
||||||
private var repeatCount = 0
|
|
||||||
private var oldKeys = IntArray(N_KEY_ROLLOVER) { 0 }
|
|
||||||
/** always Low Layer */
|
|
||||||
// private var keymap = IME.getLowLayerByName(App.getConfigString("basekeyboardlayout"))
|
|
||||||
|
|
||||||
fun resetKeyboardStrobo() {
|
|
||||||
stroboStatus = 0
|
|
||||||
repeatCount = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// code proudly stolen from tsvm's TVDOS.SYS
|
|
||||||
fun withKeyboardEvent(callback: (TerrarumKeyboardEvent) -> Unit) {
|
|
||||||
val keys = strobeKeys()
|
|
||||||
var keyChanged = !arrayEq(keys, oldKeys)
|
|
||||||
val keyDiff = arrayDiff(keys, oldKeys)
|
|
||||||
val keymap = IME.getLowLayerByName(App.getConfigString("basekeyboardlayout"))
|
|
||||||
|
|
||||||
if (stroboStatus % 2 == 0 && keys[0] != 0) {
|
|
||||||
stroboStatus += 1
|
|
||||||
stroboTime = System.nanoTime()
|
|
||||||
repeatCount += 1
|
|
||||||
|
|
||||||
val shiftin = keys.contains(Keys.SHIFT_LEFT) || keys.contains(Keys.SHIFT_RIGHT)
|
|
||||||
val keysym0 = keysToStr(keymap, keys)
|
|
||||||
val newKeysym0 = keysToStr(keymap, keyDiff)
|
|
||||||
val keysym = if (keysym0 == null) null
|
|
||||||
else if (shiftin && keysym0[1]?.isNotBlank() == true) keysym0[1]
|
|
||||||
else keysym0[0]
|
|
||||||
val newKeysym = if (newKeysym0 == null) null
|
|
||||||
else if (shiftin && newKeysym0[1]?.isNotBlank() == true) newKeysym0[1]
|
|
||||||
else newKeysym0[0]
|
|
||||||
|
|
||||||
val headKeyCode = if (keyDiff.size < 1) keys[0] else keyDiff[0]
|
|
||||||
|
|
||||||
if (!keyChanged) {
|
|
||||||
// println("KEY_DOWN '$keysym' ($headKeyCode) $repeatCount; ${keys.joinToString()}")
|
|
||||||
callback(TerrarumKeyboardEvent(KEY_DOWN, keysym, headKeyCode, repeatCount, keys))
|
|
||||||
}
|
|
||||||
else if (newKeysym != null) {
|
|
||||||
// println("KEY_DOWC '$newKeysym' ($headKeyCode) $repeatCount; ${keys.joinToString()}")
|
|
||||||
callback(TerrarumKeyboardEvent(KEY_DOWN, newKeysym, headKeyCode, repeatCount, keys))
|
|
||||||
}
|
|
||||||
|
|
||||||
oldKeys = keys // don't put this outside of if-cascade
|
|
||||||
}
|
|
||||||
else if (keyChanged || keys[0] == 0) {
|
|
||||||
stroboStatus = 0
|
|
||||||
repeatCount = 0
|
|
||||||
|
|
||||||
if (keys[0] == 0) keyChanged = false
|
|
||||||
}
|
|
||||||
else if (stroboStatus % 2 == 1 && System.nanoTime() - stroboTime < KEYBOARD_DELAYS[stroboStatus]) {
|
|
||||||
Thread.sleep(1L)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
stroboStatus += 1
|
|
||||||
if (stroboStatus >= 4)
|
|
||||||
stroboStatus = 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun keysToStr(keymap: TerrarumKeyLayout, keys: IntArray): Array<String?>? {
|
|
||||||
if (keys.size == 0) return null
|
|
||||||
val headkey = keys[0]
|
|
||||||
return keymap.symbols?.get(headkey)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun strobeKeys(): IntArray {
|
|
||||||
var keysPushed = 0
|
|
||||||
val keyEventBuffers = IntArray(N_KEY_ROLLOVER) { 0 }
|
|
||||||
for (k in 1..254) {
|
|
||||||
if (Gdx.input.isKeyPressed(k)) {
|
|
||||||
keyEventBuffers[keysPushed] = k
|
|
||||||
keysPushed += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keysPushed >= N_KEY_ROLLOVER) break
|
|
||||||
}
|
|
||||||
return keyEventBuffers
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun arrayEq(a: IntArray, b: IntArray): Boolean {
|
|
||||||
for (i in 0 until a.size) {
|
|
||||||
if (a[i] != b.getOrNull(i)) return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun arrayDiff(a: IntArray, b: IntArray): IntArray {
|
|
||||||
return a.filter { !b.contains(it) }.toIntArray()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inline fun BitSet.bitCount() = this.cardinality()
|
private inline fun BitSet.bitCount() = this.cardinality()
|
||||||
}
|
}
|
||||||
136
src/net/torvald/terrarum/gamecontroller/InputStrober.kt
Normal file
136
src/net/torvald/terrarum/gamecontroller/InputStrober.kt
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
package net.torvald.terrarum.gamecontroller
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx
|
||||||
|
import com.badlogic.gdx.Input
|
||||||
|
import net.torvald.terrarum.App
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2021-11-06.
|
||||||
|
*/
|
||||||
|
object InputStrober {
|
||||||
|
|
||||||
|
const val KEY_DOWN = 0
|
||||||
|
const val KEY_CHANGE = 1
|
||||||
|
const val N_KEY_ROLLOVER = 8
|
||||||
|
|
||||||
|
var KEYBOARD_DELAYS = longArrayOf(0L,250000000L,0L,25000000L,0L)
|
||||||
|
private var stroboTime = 0L
|
||||||
|
private var stroboStatus = 0
|
||||||
|
private var repeatCount = 0
|
||||||
|
private var oldKeys = IntArray(N_KEY_ROLLOVER) { 0 }
|
||||||
|
/** always Low Layer */
|
||||||
|
// private var keymap = IME.getLowLayerByName(App.getConfigString("basekeyboardlayout"))
|
||||||
|
|
||||||
|
private val thread = Thread { while (!Thread.interrupted()) {
|
||||||
|
if (Gdx.input != null) withKeyboardEvent()
|
||||||
|
} }
|
||||||
|
|
||||||
|
init {
|
||||||
|
println("InputStrobe start")
|
||||||
|
thread.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun dispose() {
|
||||||
|
thread.interrupt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resetKeyboardStrobo() {
|
||||||
|
stroboStatus = 0
|
||||||
|
repeatCount = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// code proudly stolen from tsvm's TVDOS.SYS
|
||||||
|
private fun withKeyboardEvent() {
|
||||||
|
val keys = strobeKeys()
|
||||||
|
var keyChanged = !arrayEq(keys, oldKeys)
|
||||||
|
val keyDiff = arrayDiff(keys, oldKeys)
|
||||||
|
val keymap = IME.getLowLayerByName(App.getConfigString("basekeyboardlayout"))
|
||||||
|
|
||||||
|
// println("Key strobed: ${keys.joinToString()}")
|
||||||
|
|
||||||
|
if (stroboStatus % 2 == 0 && keys[0] != 0) {
|
||||||
|
stroboStatus += 1
|
||||||
|
stroboTime = System.nanoTime()
|
||||||
|
repeatCount += 1
|
||||||
|
|
||||||
|
val shiftin = keys.contains(Input.Keys.SHIFT_LEFT) || keys.contains(Input.Keys.SHIFT_RIGHT)
|
||||||
|
val keysym0 = keysToStr(keymap, keys)
|
||||||
|
val newKeysym0 = keysToStr(keymap, keyDiff)
|
||||||
|
val keysym = if (keysym0 == null) null
|
||||||
|
else if (shiftin && keysym0[1]?.isNotBlank() == true) keysym0[1]
|
||||||
|
else keysym0[0]
|
||||||
|
val newKeysym = if (newKeysym0 == null) null
|
||||||
|
else if (shiftin && newKeysym0[1]?.isNotBlank() == true) newKeysym0[1]
|
||||||
|
else newKeysym0[0]
|
||||||
|
|
||||||
|
val headKeyCode = if (keyDiff.size < 1) keys[0] else keyDiff[0]
|
||||||
|
|
||||||
|
if (!keyChanged) {
|
||||||
|
// println("KEY_DOWN '$keysym' ($headKeyCode) $repeatCount; ${keys.joinToString()}")
|
||||||
|
App.inputStrobed(TerrarumKeyboardEvent(KEY_DOWN, keysym, headKeyCode, repeatCount, keys))
|
||||||
|
}
|
||||||
|
else if (newKeysym != null) {
|
||||||
|
// println("KEY_DOWC '$newKeysym' ($headKeyCode) $repeatCount; ${keys.joinToString()}")
|
||||||
|
App.inputStrobed(TerrarumKeyboardEvent(KEY_DOWN, newKeysym, headKeyCode, repeatCount, keys))
|
||||||
|
}
|
||||||
|
|
||||||
|
oldKeys = keys // don't put this outside of if-cascade
|
||||||
|
}
|
||||||
|
else if (keyChanged || keys[0] == 0) {
|
||||||
|
stroboStatus = 0
|
||||||
|
repeatCount = 0
|
||||||
|
|
||||||
|
if (keys[0] == 0) keyChanged = false
|
||||||
|
}
|
||||||
|
else if (stroboStatus % 2 == 1 && System.nanoTime() - stroboTime < KEYBOARD_DELAYS[stroboStatus]) {
|
||||||
|
Thread.sleep(1L)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
stroboStatus += 1
|
||||||
|
if (stroboStatus >= 4)
|
||||||
|
stroboStatus = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun keysToStr(keymap: TerrarumKeyLayout, keys: IntArray): Array<String?>? {
|
||||||
|
if (keys.isEmpty()) return null
|
||||||
|
val headkey = keys[0]
|
||||||
|
return keymap.symbols?.get(headkey)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun strobeKeys(): IntArray {
|
||||||
|
var keysPushed = 0
|
||||||
|
val keyEventBuffers = IntArray(N_KEY_ROLLOVER) { 0 }
|
||||||
|
for (k in 1..254) {
|
||||||
|
if (Gdx.input.isKeyPressed(k)) {
|
||||||
|
keyEventBuffers[keysPushed] = k
|
||||||
|
keysPushed += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keysPushed >= N_KEY_ROLLOVER) break
|
||||||
|
}
|
||||||
|
return keyEventBuffers
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun arrayEq(a: IntArray, b: IntArray): Boolean {
|
||||||
|
for (i in a.indices) {
|
||||||
|
if (a[i] != b.getOrNull(i)) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun arrayDiff(a: IntArray, b: IntArray): IntArray {
|
||||||
|
return a.filter { !b.contains(it) }.toIntArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
data class TerrarumKeyboardEvent(
|
||||||
|
val type: Int,
|
||||||
|
val character: String?, // representative key symbol
|
||||||
|
val headkey: Int, // representative keycode
|
||||||
|
val repeatCount: Int,
|
||||||
|
val keycodes: IntArray
|
||||||
|
)
|
||||||
@@ -11,6 +11,7 @@ import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
|||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
import net.torvald.terrarum.blockproperties.BlockPropUtil
|
import net.torvald.terrarum.blockproperties.BlockPropUtil
|
||||||
import net.torvald.terrarum.gameactors.*
|
import net.torvald.terrarum.gameactors.*
|
||||||
|
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
||||||
import net.torvald.terrarum.gameitem.ItemID
|
import net.torvald.terrarum.gameitem.ItemID
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
||||||
@@ -412,6 +413,9 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
uiPenMenu.dispose()
|
uiPenMenu.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun inputStrobed(e: TerrarumKeyboardEvent) {
|
||||||
|
}
|
||||||
|
|
||||||
private fun makePenWork(x: Int, y: Int) {
|
private fun makePenWork(x: Int, y: Int) {
|
||||||
val world = gameWorld
|
val world = gameWorld
|
||||||
val palSelection = uiPaletteSelector.fore
|
val palSelection = uiPaletteSelector.fore
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import net.torvald.terrarum.console.Authenticator
|
|||||||
import net.torvald.terrarum.gameactors.*
|
import net.torvald.terrarum.gameactors.*
|
||||||
import net.torvald.terrarum.gamecontroller.IngameController
|
import net.torvald.terrarum.gamecontroller.IngameController
|
||||||
import net.torvald.terrarum.gamecontroller.KeyToggler
|
import net.torvald.terrarum.gamecontroller.KeyToggler
|
||||||
|
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
||||||
import net.torvald.terrarum.gameitem.GameItem
|
import net.torvald.terrarum.gameitem.GameItem
|
||||||
import net.torvald.terrarum.gameitem.inInteractableRange
|
import net.torvald.terrarum.gameitem.inInteractableRange
|
||||||
import net.torvald.terrarum.gameparticles.ParticleBase
|
import net.torvald.terrarum.gameparticles.ParticleBase
|
||||||
@@ -1173,6 +1174,10 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun inputStrobed(e: TerrarumKeyboardEvent) {
|
||||||
|
uiContainer.forEach { it?.inputStrobed(e) }
|
||||||
|
}
|
||||||
|
|
||||||
fun activateDormantActor(actor: Actor) {
|
fun activateDormantActor(actor: Actor) {
|
||||||
if (App.IS_DEVELOPMENT_BUILD && !isInactive(actor.referenceID)) {
|
if (App.IS_DEVELOPMENT_BUILD && !isInactive(actor.referenceID)) {
|
||||||
/*if (isActive(actor.referenceID))
|
/*if (isActive(actor.referenceID))
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import net.torvald.terrarum.App
|
|||||||
import net.torvald.terrarum.CommonResourcePool
|
import net.torvald.terrarum.CommonResourcePool
|
||||||
import net.torvald.terrarum.DefaultConfig
|
import net.torvald.terrarum.DefaultConfig
|
||||||
import net.torvald.terrarum.gamecontroller.IME
|
import net.torvald.terrarum.gamecontroller.IME
|
||||||
|
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
||||||
import net.torvald.terrarum.langpack.Lang
|
import net.torvald.terrarum.langpack.Lang
|
||||||
import net.torvald.terrarum.linearSearch
|
import net.torvald.terrarum.linearSearch
|
||||||
import net.torvald.terrarum.ui.*
|
import net.torvald.terrarum.ui.*
|
||||||
@@ -176,6 +177,11 @@ class UIKeyboardControlPanel(remoCon: UIRemoCon?) : UICanvas() {
|
|||||||
// addUIitem(keyboardTestPanel)
|
// addUIitem(keyboardTestPanel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun inputStrobed(e: TerrarumKeyboardEvent) {
|
||||||
|
super.inputStrobed(e)
|
||||||
|
keyboardTestPanel.inputStrobed(e)
|
||||||
|
}
|
||||||
|
|
||||||
private fun resetKeyConfig() {
|
private fun resetKeyConfig() {
|
||||||
listOf("control_key_up",
|
listOf("control_key_up",
|
||||||
"control_key_left",
|
"control_key_left",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
|||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.App.printdbgerr
|
import net.torvald.terrarum.App.printdbgerr
|
||||||
|
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
||||||
import net.torvald.terrarum.serialise.WriteConfig
|
import net.torvald.terrarum.serialise.WriteConfig
|
||||||
import net.torvald.terrarum.ui.Toolkit
|
import net.torvald.terrarum.ui.Toolkit
|
||||||
import net.torvald.terrarum.ui.UICanvas
|
import net.torvald.terrarum.ui.UICanvas
|
||||||
@@ -266,7 +267,9 @@ open class UIRemoCon(val parent: TitleScreen, val treeRoot: QNDTreeNode<String>)
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun inputStrobed(e: TerrarumKeyboardEvent) {
|
||||||
|
openUI?.inputStrobed(e)
|
||||||
|
}
|
||||||
|
|
||||||
class UIRemoConElement(uiRemoCon: UIRemoCon, val labels: Array<String>, val tags: Array<Array<String>>) {
|
class UIRemoConElement(uiRemoCon: UIRemoCon, val labels: Array<String>, val tags: Array<Array<String>>) {
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.badlogic.gdx.utils.Disposable
|
|||||||
import net.torvald.terrarum.App
|
import net.torvald.terrarum.App
|
||||||
import net.torvald.terrarum.Second
|
import net.torvald.terrarum.Second
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
|
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
|
||||||
@@ -219,6 +220,12 @@ abstract class UICanvas(
|
|||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
open fun inputStrobed(e: TerrarumKeyboardEvent) {
|
||||||
|
if (this.isVisible) {
|
||||||
|
uiItems.forEach { it.inputStrobed(e) }
|
||||||
|
handler.subUIs.forEach { it.inputStrobed(e) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open fun resize(width: Int, height: Int) {
|
open fun resize(width: Int, height: Int) {
|
||||||
this.width = width
|
this.width = width
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Camera
|
|||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.utils.Disposable
|
import com.badlogic.gdx.utils.Disposable
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
|
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -238,6 +239,9 @@ abstract class UIItem(var parentUI: UICanvas, val initialX: Int, val initialY: I
|
|||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
open fun inputStrobed(e: TerrarumKeyboardEvent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
abstract override fun dispose()
|
abstract override fun dispose()
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,8 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
|||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.gamecontroller.IME
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.gamecontroller.IngameController
|
import net.torvald.terrarum.gamecontroller.*
|
||||||
import net.torvald.terrarum.gamecontroller.TerrarumInputMethod
|
|
||||||
import net.torvald.terrarum.utils.Clipboard
|
import net.torvald.terrarum.utils.Clipboard
|
||||||
import net.torvald.terrarumsansbitmap.gdx.CodepointSequence
|
import net.torvald.terrarumsansbitmap.gdx.CodepointSequence
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
@@ -45,6 +44,8 @@ data class InputLenCap(val count: Int, val unit: CharLenUnit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Make sure `inputStrobed()` of the parentUI is up and running.
|
||||||
|
*
|
||||||
* Protip: if there are multiple TextLineInputs on a same UI, draw bottom one first, otherwise the IME's
|
* Protip: if there are multiple TextLineInputs on a same UI, draw bottom one first, otherwise the IME's
|
||||||
* candidate window will be hidden by the bottom UIItem if they overlaps.
|
* candidate window will be hidden by the bottom UIItem if they overlaps.
|
||||||
*
|
*
|
||||||
@@ -156,20 +157,15 @@ class UIItemTextLineInput(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun update(delta: Float) {
|
override fun inputStrobed(e: TerrarumKeyboardEvent) {
|
||||||
super.update(delta)
|
|
||||||
val mouseDown = Terrarum.mouseDown
|
|
||||||
val oldActive = isActive
|
val oldActive = isActive
|
||||||
|
|
||||||
if (mouseDown) {
|
|
||||||
isActive = mouseUp
|
|
||||||
}
|
|
||||||
|
|
||||||
if (App.getConfigString("inputmethod") == "none") imeOn = false
|
|
||||||
|
|
||||||
// process keypresses
|
// process keypresses
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
IngameController.withKeyboardEvent { (_, char, headkey, repeatCount, keycodes) ->
|
|
||||||
|
val (eventType, char, headkey, repeatCount, keycodes) = e
|
||||||
|
|
||||||
|
if (eventType == InputStrober.KEY_DOWN || eventType == InputStrober.KEY_CHANGE) {
|
||||||
fboUpdateLatch = true
|
fboUpdateLatch = true
|
||||||
forceLitCursor()
|
forceLitCursor()
|
||||||
val ime = getIME()
|
val ime = getIME()
|
||||||
@@ -263,13 +259,28 @@ class UIItemTextLineInput(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// don't put innards of tryCursorBack/Forward here -- you absolutely don't want that behaviour
|
// don't put innards of tryCursorBack/Forward here -- you absolutely don't want that behaviour
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (textbuf.size == 0) {
|
if (textbuf.size == 0) {
|
||||||
currentPlaceholderText = CodepointSequence(placeholder().toCodePoints())
|
currentPlaceholderText = CodepointSequence(placeholder().toCodePoints())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (oldActive) { // just became deactivated
|
||||||
|
endComposing()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun update(delta: Float) {
|
||||||
|
super.update(delta)
|
||||||
|
val mouseDown = Terrarum.mouseDown
|
||||||
|
|
||||||
|
if (mouseDown) {
|
||||||
|
isActive = mouseUp
|
||||||
|
}
|
||||||
|
|
||||||
|
if (App.getConfigString("inputmethod") == "none") imeOn = false
|
||||||
|
|
||||||
|
if (isActive) {
|
||||||
cursorBlinkCounter += delta
|
cursorBlinkCounter += delta
|
||||||
|
|
||||||
while (cursorBlinkCounter >= CURSOR_BLINK_TIME) {
|
while (cursorBlinkCounter >= CURSOR_BLINK_TIME) {
|
||||||
@@ -277,9 +288,6 @@ class UIItemTextLineInput(
|
|||||||
cursorOn = !cursorOn
|
cursorOn = !cursorOn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (oldActive) { // just became deactivated
|
|
||||||
endComposing()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mouseDown && !mouseLatched && (enablePasteButton && enableIMEButton && mouseUpOnButton1 || enableIMEButton && !enablePasteButton && mouseUpOnButton2)) {
|
if (mouseDown && !mouseLatched && (enablePasteButton && enableIMEButton && mouseUpOnButton1 || enableIMEButton && !enablePasteButton && mouseUpOnButton2)) {
|
||||||
toggleIME()
|
toggleIME()
|
||||||
|
|||||||
Reference in New Issue
Block a user