From 8a8e97d4b2b3864709c9484b5f84a22b5b65b090 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Wed, 20 Oct 2021 12:57:56 +0900 Subject: [PATCH] custom keyboard handling wip --- .idea/artifacts/TerrarumBuild.xml | 6 + assets/keylayout/colemak.properties | 6 - assets/keylayout/dvorak.properties | 6 - assets/keylayout/malt89.properties | 6 - assets/keylayout/qwerty.properties | 13 - assets/keylayout/us_colemak.key | 256 ++++++++++++++++++ assets/keylayout/us_qwerty.key | 256 ++++++++++++++++++ .../ingamemodule_basegame.iml | 1 + .../spriteassembler/AssembleSheetPixmap.kt | 1 - src/net/torvald/terrarum/DefaultConfig.kt | 2 + src/net/torvald/terrarum/Terrarum.kt | 7 + src/net/torvald/terrarum/gameactors/Actor.kt | 6 - .../torvald/terrarum/gamecontroller/IME.kt | 60 ++++ .../gamecontroller/IngameController.kt | 233 ++++++---------- .../terrarum/modulebasegame/BuildingMaker.kt | 2 +- .../terrarum/modulebasegame/console/Save.kt | 1 - .../ui/UIBuildingMakerBlockChooser.kt | 2 +- .../ui/UIBuildingMakerPenMenu.kt | 4 +- .../modulebasegame/ui/UIInventoryMinimap.kt | 2 +- .../terrarum/modulebasegame/ui/UIRemoCon.kt | 9 +- .../torvald/terrarum/serialise/WriteActor.kt | 3 - src/net/torvald/terrarum/ui/UICanvas.kt | 2 +- src/net/torvald/terrarum/ui/UIItem.kt | 21 +- .../terrarum/ui/UIItemTextButtonList.kt | 7 +- .../terrarum/ui/UIItemTextLineInput.kt | 66 +++++ terrarum.terrarum.iml | 1 + 26 files changed, 765 insertions(+), 214 deletions(-) delete mode 100644 assets/keylayout/colemak.properties delete mode 100644 assets/keylayout/dvorak.properties delete mode 100644 assets/keylayout/malt89.properties delete mode 100644 assets/keylayout/qwerty.properties create mode 100644 assets/keylayout/us_colemak.key create mode 100644 assets/keylayout/us_qwerty.key create mode 100644 src/net/torvald/terrarum/gamecontroller/IME.kt create mode 100644 src/net/torvald/terrarum/ui/UIItemTextLineInput.kt diff --git a/.idea/artifacts/TerrarumBuild.xml b/.idea/artifacts/TerrarumBuild.xml index 92f057a0f..7bbf5d5e6 100644 --- a/.idea/artifacts/TerrarumBuild.xml +++ b/.idea/artifacts/TerrarumBuild.xml @@ -62,6 +62,12 @@ + + + + + + \ No newline at end of file diff --git a/assets/keylayout/colemak.properties b/assets/keylayout/colemak.properties deleted file mode 100644 index 8391244c7..000000000 --- a/assets/keylayout/colemak.properties +++ /dev/null @@ -1,6 +0,0 @@ -layout_name=Colemak -ROW1=4s;4qNUM_1;4qNUM_2;4qNUM_3;4qNUM_4;4qNUM_5;4qNUM_6;4qNUM_7;4qNUM_8;4qNUM_9;4qNUM_0;4qMINUS;4qEQUALS;6qBACKSPACE -ROW2=6qTAB;4qQ;4qW;4qF;4qP;4qG;4qJ;4qL;4qU;4qY;4qSEMICOLON;4qLEFT_BRACKET;4qRIGHT_BRACKET;4qBACKSLASH -ROW3=7qCAPS_LOCK;4qA;4qR;4qS;4qT;4qD;4qH;4qN;4qE;4qI;4qO;4qAPOSTROPHE;7qENTER -ROW4=9qSHIFT_LEFT;4qZ;4qX;4qC;4qV;4qB;4qK;4qM;4qCOMMA;4qPERIOD;4qSLASH;9qSHIFT_RIGHT -ROW5=15s;28qSPACE diff --git a/assets/keylayout/dvorak.properties b/assets/keylayout/dvorak.properties deleted file mode 100644 index be6375087..000000000 --- a/assets/keylayout/dvorak.properties +++ /dev/null @@ -1,6 +0,0 @@ -layout_name=Dvorak Simplified -ROW1=4s;4qNUM_1;4qNUM_2;4qNUM_3;4qNUM_4;4qNUM_5;4qNUM_6;4qNUM_7;4qNUM_8;4qNUM_9;4qNUM_0;4qLEFT_BRACKET;4qRIGHT_BRACKET;6qBACKSPACE -ROW2=6qTAB;4qAPOSTROPHE;4qCOMMA;4qPERIOD;4qP;4qY;4qF;4qG;4qC;4qR;4qL;4qSLASH;4qEQUALS;4qBACKSLASH -ROW3=7qCAPS_LOCK;4qA;4qO;4qE;4qU;4qI;4qD;4qH;4qT;4qN;4qS;4qMINUS;7qENTER -ROW4=9qSHIFT_LEFT;4qSEMICOLON;4qQ;4qJ;4qK;4qX;4qB;4qM;4qW;4qV;4qZ;9qSHIFT_RIGHT -ROW5=15s;28qSPACE diff --git a/assets/keylayout/malt89.properties b/assets/keylayout/malt89.properties deleted file mode 100644 index c3aa94f25..000000000 --- a/assets/keylayout/malt89.properties +++ /dev/null @@ -1,6 +0,0 @@ -layout_name=Maltron 89 -ROW1=4qNUM_1;4qNUM_2;4qNUM_3;4qNUM_4;4qNUM_5;10s;4qNUM_6;4qNUM_7;4qNUM_8;4qNUM_9;4qNUM_0 -ROW2=4qQ;4qP;4qY;4qC;4qB;10s;4qV;4qM;4qU;4qZ;4qL -ROW3=4qA;4qN;4qI;4qS;4qF;10s;4qD;4qT;4qH;4qO;4qR -ROW4=4qCOMMA;4qPERIOD;4qJ;4qG;4qSEMICOLON;10s;4qAPOSTROPHE;4qW;4qK;4qX;4qNULL -ROW5=4qSHIFT_LEFT;4qBACKSLASH;4qLEFT_BRACKET;4qMINUS;3s;4qE;4s;4qENTER;3s;4qEQUALS;4qRIGHT_BACKET;4qSLASH;4qSHIFT_RIGHT diff --git a/assets/keylayout/qwerty.properties b/assets/keylayout/qwerty.properties deleted file mode 100644 index 705eba4ec..000000000 --- a/assets/keylayout/qwerty.properties +++ /dev/null @@ -1,13 +0,0 @@ -! generic QWERTY keyboard - -! row format: (n)q(keyname) -! n: width of a key, 4 for regular key (1.0u). Value smaller than 4 will break the UI, so DON'T -! keyname: name of the key that is recognised by the UI parser. -! each key in the row is separated by one semicolon. - -layout_name=QWERTY -ROW1=4s;4qNUM_1;4qNUM_2;4qNUM_3;4qNUM_4;4qNUM_5;4qNUM_6;4qNUM_7;4qNUM_8;4qNUM_9;4qNUM_0;4qMINUS;4qEQUALS;6qBACKSPACE -ROW2=6qTAB;4qQ;4qW;4qE;4qR;4qT;4qY;4qU;4qI;4qO;4qP;4qLEFT_BRACKET;4qRIGHT_BRACKET;4qBACKSLASH -ROW3=7qCAPS_LOCK;4qA;4qS;4qD;4qF;4qG;4qH;4qJ;4qK;4qL;4qSEMICOLON;4qAPOSTROPHE;7qENTER -ROW4=9qSHIFT_LEFT;4qZ;4qX;4qC;4qV;4qB;4qN;4qM;4qCOMMA;4qPERIOD;4qSLASH;9qSHIFT_RIGHT -ROW5=15s;28qSPACE diff --git a/assets/keylayout/us_colemak.key b/assets/keylayout/us_colemak.key new file mode 100644 index 000000000..0c6c98a82 --- /dev/null +++ b/assets/keylayout/us_colemak.key @@ -0,0 +1,256 @@ +[[""],[undefined], +[undefined], +[""], +[undefined], +[""], +[""], +["0",")"], +["1","!"], +["2","@"], +["3","#"], +["4","$"], +["5","%"], +["6","^"], +["7","&"], +["8","*"], +["9","("], +["*"], +["#"], +[""], +[""], +[""], +[""], +["
"], +[""], +[""], +[""], +[""], +[""], +["a","A"], +["b","B"], +["c","C"], +["s","S"], +["f","F"], +["t","T"], +["d","D"], +["h","H"], +["u","U"], +["n","N"], +["e","E"], +["i","I"], +["m","M"], +["k","K"], +["y","Y"], +[";",":"], +["q","Q"], +["p","P"], +["r","R"], +["g","G"], +["l","L"], +["v","V"], +["w","W"], +["x","X"], +["j","J"], +["z","Z"], +[",","<"], +[".",">"], +[""], +[""], +[""], +[""], +[""], +[" "], +[""], +[""], +[""], +["\n"], +["\x08"], +["`","~"], +["-","_"], +["=","+"], +["[","{"], +["]","}"], +["\\","|"], +["o","O"], +["'",'"'], +["/","?"], +[""], +[""], +[""], +[""], +["+"], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +["TCH_CHARSET>"], +["<:A:>"], +["<:B:>"], +["<:C:>"], +["<:X:>"], +["<:Y:>"], +["<:Z:>"], +["<:L1:>"], +["<:R1:>"], +["<:L2:>"], +["<:R2:>"], +["<:TL:>"], +["<:TR:>"], +["<:START:>"], +["<:SELECT:>"], +["<:MODE:>"], +[""], +[""], +[undefined], +[undefined], +[""], +[""], +[undefined], +[undefined], +[undefined], +[""], +[""], +[undefined], +[""], +[""], +[undefined], +[undefined], +[undefined], +[undefined], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +["0"], +["1"], +["2"], +["3"], +["4"], +["5"], +["6"], +["7"], +["8"], +["9"], +["/"], +["*"], +["-"], +["+"], +["."], +["."], +["\n"], +["="], +["("], +[")"], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +["<:CIRCLE:>"] +] diff --git a/assets/keylayout/us_qwerty.key b/assets/keylayout/us_qwerty.key new file mode 100644 index 000000000..5b0f3f3de --- /dev/null +++ b/assets/keylayout/us_qwerty.key @@ -0,0 +1,256 @@ +[[""],[undefined], +[undefined], +[""], +[undefined], +[""], +[""], +["0",")"], +["1","!"], +["2","@"], +["3","#"], +["4","$"], +["5","%"], +["6","^"], +["7","&"], +["8","*"], +["9","("], +["*"], +["#"], +[""], +[""], +[""], +[""], +["
"], +[""], +[""], +[""], +[""], +[""], +["a","A"], +["b","B"], +["c","C"], +["d","D"], +["e","E"], +["f","F"], +["g","G"], +["h","H"], +["i","I"], +["j","J"], +["k","K"], +["l","L"], +["m","M"], +["n","N"], +["o","O"], +["p","P"], +["q","Q"], +["r","R"], +["s","S"], +["t","T"], +["u","U"], +["v","V"], +["w","W"], +["x","X"], +["y","Y"], +["z","Z"], +[",","<"], +[".",">"], +[""], +[""], +[""], +[""], +[""], +[" "], +[""], +[""], +[""], +["\n"], +["\x08"], +["`","~"], +["-","_"], +["=","+"], +["[","{"], +["]","}"], +["\\","|"], +[";",":"], +["'",'"'], +["/","?"], +[""], +[""], +[""], +[""], +["+"], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +["TCH_CHARSET>"], +["<:A:>"], +["<:B:>"], +["<:C:>"], +["<:X:>"], +["<:Y:>"], +["<:Z:>"], +["<:L1:>"], +["<:R1:>"], +["<:L2:>"], +["<:R2:>"], +["<:TL:>"], +["<:TR:>"], +["<:START:>"], +["<:SELECT:>"], +["<:MODE:>"], +[""], +[""], +[undefined], +[undefined], +[""], +[""], +[undefined], +[undefined], +[undefined], +[""], +[""], +[undefined], +[""], +[""], +[undefined], +[undefined], +[undefined], +[undefined], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +[""], +["0"], +["1"], +["2"], +["3"], +["4"], +["5"], +["6"], +["7"], +["8"], +["9"], +["/"], +["*"], +["-"], +["+"], +["."], +["."], +["\n"], +["="], +["("], +[")"], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +[undefined], +["<:CIRCLE:>"] +] diff --git a/ingamemodule_basegame/ingamemodule_basegame.iml b/ingamemodule_basegame/ingamemodule_basegame.iml index 4c0d19460..d3971979f 100644 --- a/ingamemodule_basegame/ingamemodule_basegame.iml +++ b/ingamemodule_basegame/ingamemodule_basegame.iml @@ -25,5 +25,6 @@ + \ No newline at end of file diff --git a/src/net/torvald/spriteassembler/AssembleSheetPixmap.kt b/src/net/torvald/spriteassembler/AssembleSheetPixmap.kt index 73a2ea1d1..d4c197eea 100644 --- a/src/net/torvald/spriteassembler/AssembleSheetPixmap.kt +++ b/src/net/torvald/spriteassembler/AssembleSheetPixmap.kt @@ -3,7 +3,6 @@ package net.torvald.spriteassembler import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.Pixmap import com.badlogic.gdx.utils.GdxRuntimeException -import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.linearSearch import net.torvald.terrarum.serialise.Common import net.torvald.terrarum.savegame.ByteArray64InputStream diff --git a/src/net/torvald/terrarum/DefaultConfig.kt b/src/net/torvald/terrarum/DefaultConfig.kt index 67859b03d..93764ef55 100644 --- a/src/net/torvald/terrarum/DefaultConfig.kt +++ b/src/net/torvald/terrarum/DefaultConfig.kt @@ -100,6 +100,8 @@ object DefaultConfig { "fx_differential" to false, //"fx_3dlut" to false, + "basekeyboardlayout" to "us_qwerty" + // settings regarding debugger /*"buildingmakerfavs" to arrayOf( diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 0b78ad125..0e054f63d 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -22,6 +22,7 @@ import net.torvald.terrarum.blockproperties.WireCodex import net.torvald.terrarum.gameactors.Actor import net.torvald.terrarum.gameactors.ActorID import net.torvald.terrarum.gameactors.faction.FactionCodex +import net.torvald.terrarum.gamecontroller.IngameController import net.torvald.terrarum.gameworld.fmod import net.torvald.terrarum.itemproperties.ItemCodex import net.torvald.terrarum.itemproperties.MaterialCodex @@ -51,6 +52,10 @@ typealias RGBA8888 = Int */ object Terrarum : Disposable { + init { + IngameController.KEYBOARD_DELAYS[1] + } + /** * All singleplayer "Player" must have this exact reference ID. */ @@ -286,6 +291,8 @@ object Terrarum : Disposable { /** Delta converted as it it was a FPS */ inline val updateRate: Double get() = 1.0 / Gdx.graphics.deltaTime + val mouseDown: Boolean + get() = Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary")) /** * Usage: diff --git a/src/net/torvald/terrarum/gameactors/Actor.kt b/src/net/torvald/terrarum/gameactors/Actor.kt index ea4c0340a..a91f9df98 100644 --- a/src/net/torvald/terrarum/gameactors/Actor.kt +++ b/src/net/torvald/terrarum/gameactors/Actor.kt @@ -1,15 +1,9 @@ package net.torvald.terrarum.gameactors import net.torvald.random.HQRNG -import net.torvald.spriteanimation.HasAssembledSprite -import net.torvald.spriteanimation.SpriteAnimation -import net.torvald.spriteassembler.ADProperties import net.torvald.terrarum.ReferencingRanges import net.torvald.terrarum.Terrarum -import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer import net.torvald.terrarum.modulebasegame.gameactors.Pocketed -import net.torvald.terrarum.serialise.Common -import net.torvald.terrarum.savegame.ByteArray64Reader import net.torvald.terrarum.savegame.toBigEndian import net.torvald.terrarum.utils.PasswordBase32 diff --git a/src/net/torvald/terrarum/gamecontroller/IME.kt b/src/net/torvald/terrarum/gamecontroller/IME.kt new file mode 100644 index 000000000..9f9adfc5e --- /dev/null +++ b/src/net/torvald/terrarum/gamecontroller/IME.kt @@ -0,0 +1,60 @@ +package net.torvald.terrarum.gamecontroller + +import com.badlogic.gdx.Gdx +import net.torvald.terrarum.App.printdbg + +typealias TerrarumKeyLayout = Array> + +/** + * IME consists of two keyboard layers: + * - Low layer: "english" keyboard (qwerty, colemak, etc), stateless + * - High layer: chinese/japanese/korean/etc. keyboard, stateful + * + * Input to the IME Keyboard layout is always GDX/LWJGL3 keycode (only LWJGL3 offers OS-Keylayout-independent keycodes) + * + * Created by minjaesong on 2021-10-20. + */ +object IME { + + const val KEYLAYOUT_DIR = "assets/keylayout/" + const val KEYLAYOUT_EXTENSION = ".key" + + private val cached = HashMap() + + private val context = org.graalvm.polyglot.Context.newBuilder("js") + .allowHostAccess(org.graalvm.polyglot.HostAccess.NONE) + .allowHostClassLookup { false } + .allowIO(false) + .build() + + fun getLowLayerByName(name: String): TerrarumKeyLayout { + return cached.getOrPut(name) { parseKeylayoutFile("$KEYLAYOUT_DIR$name$KEYLAYOUT_EXTENSION") } + } + + + + private fun parseKeylayoutFile(path: String): TerrarumKeyLayout { + val file = Gdx.files.internal(path) + val src = file.readString("UTF-8") + val jsval = context.eval("js", src) + val out = Array(256) { Array(4) { null } } + for (keycode in 0L until 256L) { + val a = jsval.getArrayElement(keycode) + if (!a.isNull) { + for (layer in 0L until 4L) { + if (a.arraySize > layer) { + val b = a.getArrayElement(layer) + if (!b.isNull) { + out[keycode.toInt()][layer.toInt()] = b.asString() + } + } + } + } + } + + //println("[IME] Test Keymap print:"); for (keycode in 0 until 256) { print("$keycode:\t"); println(out[keycode].joinToString("\t")) } + + return out + } + +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/gamecontroller/IngameController.kt b/src/net/torvald/terrarum/gamecontroller/IngameController.kt index 2dbd8fa5e..32a27e7c7 100644 --- a/src/net/torvald/terrarum/gamecontroller/IngameController.kt +++ b/src/net/torvald/terrarum/gamecontroller/IngameController.kt @@ -10,6 +10,7 @@ import net.torvald.terrarum.App import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.App.printdbgerr import net.torvald.terrarum.ItemCodex +import net.torvald.terrarum.Terrarum import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.controller.TerrarumController import net.torvald.terrarum.floorInt @@ -130,7 +131,7 @@ class IngameController(val terrarumIngame: TerrarumIngame) : InputAdapter() { // also, some UIs should NOT affect item usage (e.g. quickslot) and ingame's uiOpened property is doing // the very job. - if (terrarumIngame.actorNowPlaying != null && Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary")) && !worldPrimaryClickLatched) { + if (terrarumIngame.actorNowPlaying != null && Terrarum.mouseDown && !worldPrimaryClickLatched) { terrarumIngame.worldPrimaryClickStart(terrarumIngame.actorNowPlaying!!, App.UPDATE_RATE) worldPrimaryClickLatched = true } @@ -141,7 +142,7 @@ class IngameController(val terrarumIngame: TerrarumIngame) : InputAdapter() { // unlatch when: // - not clicking anymore // - using any item that is not fixture (blocks, picks) - if (!Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary")) || + if (!Terrarum.mouseDown || GameItem.Category.MISC != ItemCodex.get(terrarumIngame.actorNowPlaying?.inventory?.itemEquipped?.get(GameItem.EquipPosition.HAND_GRIP))?.inventoryCategory) { worldPrimaryClickLatched = false } @@ -273,162 +274,98 @@ class IngameController(val terrarumIngame: TerrarumIngame) : InputAdapter() { } companion object { - const val KEY_DELAY = 0.2f - const val KEY_REPEAT = 1f / 40f - val KEYCODE_TO_CHAR = hashMapOf( - Keys.NUM_1 to '1', - Keys.NUM_2 to '2', - Keys.NUM_3 to '3', - Keys.NUM_4 to '4', - Keys.NUM_5 to '5', - Keys.NUM_6 to '6', - Keys.NUM_7 to '7', - Keys.NUM_8 to '8', - Keys.NUM_9 to '9', - Keys.NUM_0 to '0', - - Keys.A to 'a', - Keys.B to 'b', - Keys.C to 'c', - Keys.D to 'd', - Keys.E to 'e', - Keys.F to 'f', - Keys.G to 'g', - Keys.H to 'h', - Keys.I to 'i', - Keys.J to 'j', - Keys.K to 'k', - Keys.L to 'l', - Keys.M to 'm', - Keys.N to 'n', - Keys.O to 'o', - Keys.P to 'p', - Keys.Q to 'q', - Keys.R to 'r', - Keys.S to 's', - Keys.T to 't', - Keys.U to 'u', - Keys.V to 'v', - Keys.W to 'w', - Keys.X to 'x', - Keys.Y to 'y', - Keys.Z to 'z', - - Keys.GRAVE to '`', - Keys.MINUS to '-', - Keys.EQUALS to '=', - Keys.BACKSPACE to 8.toChar(), - - Keys.LEFT_BRACKET to '[', - Keys.RIGHT_BRACKET to ']', - Keys.BACKSLASH to '\\', - - Keys.SEMICOLON to ';', - Keys.APOSTROPHE to '\'', - Keys.ENTER to 10.toChar(), - - Keys.COMMA to ',', - Keys.PERIOD to '.', - Keys.SLASH to '/', - - Keys.SPACE to ' ', - - Keys.NUMPAD_0 to '0', - Keys.NUMPAD_1 to '1', - Keys.NUMPAD_2 to '2', - Keys.NUMPAD_3 to '3', - Keys.NUMPAD_4 to '4', - Keys.NUMPAD_5 to '5', - Keys.NUMPAD_6 to '6', - Keys.NUMPAD_7 to '7', - Keys.NUMPAD_8 to '8', - Keys.NUMPAD_9 to '9', - - Keys.NUMPAD_DIVIDE to '/', - Keys.NUMPAD_MULTIPLY to '*', - Keys.NUMPAD_SUBTRACT to '-', - Keys.NUMPAD_ADD to '+', - Keys.NUMPAD_DOT to '.', - Keys.NUMPAD_ENTER to 10.toChar() + data class TerrarumKeyboardEvent( + val type: Int, + val character: String?, + val repeatCount: Int, + val keycodes: IntArray ) - val KEYCODE_TO_CHAR_SHIFT = hashMapOf( - Keys.NUM_1 to '!', - Keys.NUM_2 to '@', - Keys.NUM_3 to '#', - Keys.NUM_4 to '$', - Keys.NUM_5 to '%', - Keys.NUM_6 to '^', - Keys.NUM_7 to '&', - Keys.NUM_8 to '*', - Keys.NUM_9 to '(', - Keys.NUM_0 to ')', + private const val KEY_DOWN = 0 + private const val KEY_CHANGE = 1 + const val N_KEY_ROLLOVER = 8 + var KEYBOARD_DELAYS = floatArrayOf(0.25f, 0.025f) + private var stroboTime = 0L + private var stroboStatus = 0 + private var repeatCount = 0 + private var oldKeys = IntArray(N_KEY_ROLLOVER) { 0 } + private var keymap = IME.getLowLayerByName(App.getConfigString("basekeyboardlayout")) - Keys.A to 'A', - Keys.B to 'B', - Keys.C to 'C', - Keys.D to 'D', - Keys.E to 'E', - Keys.F to 'F', - Keys.G to 'G', - Keys.H to 'H', - Keys.I to 'I', - Keys.J to 'J', - Keys.K to 'K', - Keys.L to 'L', - Keys.M to 'M', - Keys.N to 'N', - Keys.O to 'O', - Keys.P to 'P', - Keys.Q to 'Q', - Keys.R to 'R', - Keys.S to 'S', - Keys.T to 'T', - Keys.U to 'U', - Keys.V to 'V', - Keys.W to 'W', - Keys.X to 'X', - Keys.Y to 'Y', - Keys.Z to 'Z', + // 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) - Keys.GRAVE to '~', - Keys.MINUS to '_', - Keys.EQUALS to '+', - Keys.BACKSPACE to 8.toChar(), + if (stroboStatus % 2 == 0 && keys[0] != 0) { + stroboStatus += 1 + stroboTime = System.nanoTime() + repeatCount += 1 - Keys.LEFT_BRACKET to '{', - Keys.RIGHT_BRACKET to '}', - Keys.BACKSLASH to '|', + val shiftin = keys.contains(Keys.SHIFT_LEFT) || keys.contains(Keys.SHIFT_RIGHT) + val keysym0 = keysToStr(keys) + val newKeysym0 = keysToStr(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] - Keys.SEMICOLON to ':', - Keys.APOSTROPHE to '"', - Keys.ENTER to 10.toChar(), + if (!keyChanged) { + callback(TerrarumKeyboardEvent(KEY_DOWN, keysym, repeatCount, keys)) + } + else if (newKeysym != null) { + callback(TerrarumKeyboardEvent(KEY_DOWN, newKeysym, repeatCount, keys)) + } - Keys.COMMA to '<', - Keys.PERIOD to '>', - Keys.SLASH to '?', + oldKeys = keys // don't put this outside of if-cascade + } + else if (keyChanged || keys[0] == 0) { + stroboStatus = 0 + repeatCount = 0 - Keys.SPACE to ' ', + 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 + } + } - Keys.NUMPAD_0 to '0', - Keys.NUMPAD_1 to '1', - Keys.NUMPAD_2 to '2', - Keys.NUMPAD_3 to '3', - Keys.NUMPAD_4 to '4', - Keys.NUMPAD_5 to '5', - Keys.NUMPAD_6 to '6', - Keys.NUMPAD_7 to '7', - Keys.NUMPAD_8 to '8', - Keys.NUMPAD_9 to '9', + private fun keysToStr(keys: IntArray): Array? { + val headkey = keys[0] + return if (keymap[headkey] == null) null else keymap[headkey] + } - Keys.NUMPAD_DIVIDE to '/', - Keys.NUMPAD_MULTIPLY to '*', - Keys.NUMPAD_SUBTRACT to '-', - Keys.NUMPAD_ADD to '+', - Keys.NUMPAD_DOT to '.', - Keys.NUMPAD_ENTER to 10.toChar() - ) + 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..a.size) { + if (a[i] != b[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() - } \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt index 9d1b4f3e6..11613fc6a 100644 --- a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt +++ b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt @@ -363,7 +363,7 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) { // make pen work HERE // when LEFT mouse is down - if (!tappedOnUI && Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary")) && !mouseOnUI) { + if (!tappedOnUI && Terrarum.mouseDown && !mouseOnUI) { makePenWork(Terrarum.mouseTileX, Terrarum.mouseTileY) // TODO drag support using bresenham's algo diff --git a/src/net/torvald/terrarum/modulebasegame/console/Save.kt b/src/net/torvald/terrarum/modulebasegame/console/Save.kt index 20e06ffd0..e80e31eab 100644 --- a/src/net/torvald/terrarum/modulebasegame/console/Save.kt +++ b/src/net/torvald/terrarum/modulebasegame/console/Save.kt @@ -6,7 +6,6 @@ import net.torvald.terrarum.console.ConsoleCommand import net.torvald.terrarum.console.Echo import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.serialise.Common -import net.torvald.terrarum.serialise.WriteSavegame import net.torvald.terrarum.savegame.VDUtil import java.io.File import java.io.IOException diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIBuildingMakerBlockChooser.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIBuildingMakerBlockChooser.kt index 2db9e5a5a..9e7f57e4e 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIBuildingMakerBlockChooser.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIBuildingMakerBlockChooser.kt @@ -86,7 +86,7 @@ class UIBuildingMakerBlockChooser(val parent: BuildingMaker): UICanvas() { } // respond to click - if (Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary"))) { + if (Terrarum.mouseDown) { // scroll bar if (relativeMouseX in width - SCROLLBAR_SIZE until width && relativeMouseY in 0 until height) { mouseOnScroll = true diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIBuildingMakerPenMenu.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIBuildingMakerPenMenu.kt index 04ca0cfe0..b51436577 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIBuildingMakerPenMenu.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIBuildingMakerPenMenu.kt @@ -133,7 +133,7 @@ class UIBuildingMakerPenMenu(val parent: BuildingMaker): UICanvas() { } // primary click - if (Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary"))) { + if (Terrarum.mouseDown) { // close by clicking close button or out-of-boud if (mouseVec.distanceSquared(RADIUS, RADIUS) !in CLOSE_BUTTON_RADIUS.sqr()..RADIUSF.sqr()) { closeGracefully() @@ -175,7 +175,7 @@ class UIBuildingMakerPenMenu(val parent: BuildingMaker): UICanvas() { batch.draw(ItemCodex.getItemImage(slotConfig[i]), x - 16, y - 16, 32f, 32f) // update as well while looping - if (i == mouseOnBlocksSlot && Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary"))) { + if (i == mouseOnBlocksSlot && Terrarum.mouseDown) { parent.setPencilColour(slotConfig[i]) closeGracefully() } diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryMinimap.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryMinimap.kt index ddd773bef..dcd7f6a5b 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryMinimap.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryMinimap.kt @@ -47,7 +47,7 @@ class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() { // update map panning // if left click is down and cursor is in the map area - if (Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary")) && + if (Terrarum.mouseDown && Terrarum.mouseScreenY in cellOffY..cellOffY + INVENTORY_CELLS_UI_HEIGHT) { minimapPanX += Terrarum.mouseDeltaX * 2f / minimapZoom minimapPanY += Terrarum.mouseDeltaY * 2f / minimapZoom diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIRemoCon.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIRemoCon.kt index ca7f2dff4..f38038587 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIRemoCon.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIRemoCon.kt @@ -4,11 +4,8 @@ import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch -import net.torvald.terrarum.App +import net.torvald.terrarum.* import net.torvald.terrarum.App.printdbgerr -import net.torvald.terrarum.QNDTreeNode -import net.torvald.terrarum.TitleScreen -import net.torvald.terrarum.Yaml import net.torvald.terrarum.serialise.WriteConfig import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.ui.UICanvas @@ -77,7 +74,7 @@ open class UIRemoCon(val parent: TitleScreen, treeRepresentation: QNDTreeNode Unit)? = null - /** Parametre: keycode */ + /** Parameter: keycode */ open var keyDownListener: ((Int) -> Unit)? = null - /** Parametre: keycode */ + /** Parameter: keycode */ open var keyUpListener: ((Int) -> Unit)? = null + open var keyTypedListener: ((Char) -> Unit)? = null open var touchDraggedListener: ((Int, Int, Int) -> Unit)? = null /** Parameters: screenX, screenY, pointer, button */ open var touchDownListener: ((Int, Int, Int, Int) -> Unit)? = null @@ -188,6 +187,14 @@ abstract class UIItem(var parentUI: UICanvas, val initialX: Int, val initialY: I return false } + open fun keyTyped(character: Char): Boolean { + if (parentUI.isVisible && keyTypedListener != null) { + keyTypedListener!!.invoke(character) + return true + } + + return false + } // mouse controlled open fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean { diff --git a/src/net/torvald/terrarum/ui/UIItemTextButtonList.kt b/src/net/torvald/terrarum/ui/UIItemTextButtonList.kt index 921e87bdc..ad05675cb 100644 --- a/src/net/torvald/terrarum/ui/UIItemTextButtonList.kt +++ b/src/net/torvald/terrarum/ui/UIItemTextButtonList.kt @@ -4,11 +4,8 @@ import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch +import net.torvald.terrarum.* import net.torvald.terrarum.App.printdbg -import net.torvald.terrarum.BlendMode -import net.torvald.terrarum.Second -import net.torvald.terrarum.fillRect -import net.torvald.terrarum.toInt import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack /** @@ -223,7 +220,7 @@ class UIItemTextButtonList( } - if (!Gdx.input.isButtonPressed(mouseButton)) { + if (!Terrarum.mouseDown) { clickLatched = false } diff --git a/src/net/torvald/terrarum/ui/UIItemTextLineInput.kt b/src/net/torvald/terrarum/ui/UIItemTextLineInput.kt new file mode 100644 index 000000000..8edf45ade --- /dev/null +++ b/src/net/torvald/terrarum/ui/UIItemTextLineInput.kt @@ -0,0 +1,66 @@ +package net.torvald.terrarum.ui + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.graphics.Camera +import com.badlogic.gdx.graphics.Pixmap +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import com.badlogic.gdx.graphics.glutils.FrameBuffer +import net.torvald.terrarum.App +import net.torvald.terrarum.Terrarum +import java.awt.Color + +/** + * @param width width of the text input where the text gets drawn, not the entire item + * @param height height of the text input where the text gets drawn, not the entire item + * + * Created by minjaesong on 2021-10-20. + */ +class UIItemTextLineInput( + parentUI: UICanvas, + initialX: Int, initialY: Int, + override val width: Int, + override val height: Int, + var placeholder: String? = null, + val enablePasteButton: Boolean = true, + val enableLanguageButton: Boolean = false +) : UIItem(parentUI, initialX, initialY) { + + companion object { + val TEXTINPUT_COL_TEXT = Color.WHITE + val TEXTINPUT_COL_GREY = Color.GRAY + + } + + private val fbo = FrameBuffer(Pixmap.Format.RGBA8888, width, height, true) + + var isActive = true + var isGreyedOut = false + + val cursorX = 0 + val keybuf = StringBuilder() + + + override fun update(delta: Float) { + super.update(delta) + + if (Terrarum.mouseDown) { + isActive = mouseUp + } + + // process keypresses + if (isActive) { + + } + } + + + override fun render(batch: SpriteBatch, camera: Camera) { + super.render(batch, camera) + } + + override fun dispose() { + fbo.dispose() + } + + +} \ No newline at end of file diff --git a/terrarum.terrarum.iml b/terrarum.terrarum.iml index 1b2112522..4badc2ccd 100644 --- a/terrarum.terrarum.iml +++ b/terrarum.terrarum.iml @@ -27,5 +27,6 @@ + \ No newline at end of file