custom keyboard handling wip

This commit is contained in:
minjaesong
2021-10-20 12:57:56 +09:00
parent d5eef2a687
commit 8a8e97d4b2
26 changed files with 765 additions and 214 deletions

View File

@@ -62,6 +62,12 @@
<element id="extracted-dir" path="$PROJECT_DIR$/lib/TerranVirtualDisk.jar" path-in-jar="/" /> <element id="extracted-dir" path="$PROJECT_DIR$/lib/TerranVirtualDisk.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/Terrarum_Joise.jar" path-in-jar="/" /> <element id="extracted-dir" path="$PROJECT_DIR$/lib/Terrarum_Joise.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/TerrarumSansBitmap.jar" path-in-jar="/" /> <element id="extracted-dir" path="$PROJECT_DIR$/lib/TerrarumSansBitmap.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/graal-sdk-21.1.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/icu4j-68.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/js-21.1.0-edit.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/js-scriptengine-21.1.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/truffle-api-21.1.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/regex-21.1.0-edit.jar" path-in-jar="/" />
</root> </root>
</artifact> </artifact>
</component> </component>

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,256 @@
[[""],[undefined],
[undefined],
["<HOME>"],
[undefined],
["<CALL>"],
["<ENDCALL>"],
["0",")"],
["1","!"],
["2","@"],
["3","#"],
["4","$"],
["5","%"],
["6","^"],
["7","&"],
["8","*"],
["9","("],
["*"],
["#"],
["<UP>"],
["<DOWN>"],
["<LEFT>"],
["<RIGHT>"],
["<CENTER>"],
["<VOL_UP>"],
["<VOL_DOWN>"],
["<POWER>"],
["<CAMERA>"],
["<CLEAR>"],
["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"],
[",","<"],
[".",">"],
["<ALT_L>"],
["<ALT_R>"],
["<SHIFT_L>"],
["<SHIFT_R>"],
["<TAB>"],
[" "],
["<SYM>"],
["<EXPLORER>"],
["<ENVELOPE>"],
["\n"],
["\x08"],
["`","~"],
["-","_"],
["=","+"],
["[","{"],
["]","}"],
["\\","|"],
["o","O"],
["'",'"'],
["/","?"],
["<AT>"],
["<NUM_LOCK>"],
["<HEADSETHOOK>"],
["<FOCUS>"],
["+"],
["<MENU>"],
["<NOTIFICATION>"],
["<SEARCH>"],
["<PLAY_PAUSE>"],
["<STOP>"],
["<NEXT>"],
["<PREV>"],
["<REW>"],
["<FFWD>"],
["<MUTE>"],
["<PAGE_UP>"],
["<PAGE_DOWN>"],
["<PICTSYMBOLS>"],
["<SW:>TCH_CHARSET>"],
["<:A:>"],
["<:B:>"],
["<:C:>"],
["<:X:>"],
["<:Y:>"],
["<:Z:>"],
["<:L1:>"],
["<:R1:>"],
["<:L2:>"],
["<:R2:>"],
["<:TL:>"],
["<:TR:>"],
["<:START:>"],
["<:SELECT:>"],
["<:MODE:>"],
["<ESC>"],
["<DEL>"],
[undefined],
[undefined],
["<CAPS_LOCK>"],
["<SCROLL_LOCK>"],
[undefined],
[undefined],
[undefined],
["<PRINT_SCREEN_SYS_RQ>"],
["<PAUSE_BREAK>"],
[undefined],
["<END>"],
["<INSERT>"],
[undefined],
[undefined],
[undefined],
[undefined],
["<CTRL_L>"],
["<CTRL_R>"],
["<F1>"],
["<F2>"],
["<F3>"],
["<F4>"],
["<F5>"],
["<F6>"],
["<F7>"],
["<F8>"],
["<F9>"],
["<F10>"],
["<F11>"],
["<F12>"],
["<NUM_LOCK>"],
["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:>"]
]

View File

@@ -0,0 +1,256 @@
[[""],[undefined],
[undefined],
["<HOME>"],
[undefined],
["<CALL>"],
["<ENDCALL>"],
["0",")"],
["1","!"],
["2","@"],
["3","#"],
["4","$"],
["5","%"],
["6","^"],
["7","&"],
["8","*"],
["9","("],
["*"],
["#"],
["<UP>"],
["<DOWN>"],
["<LEFT>"],
["<RIGHT>"],
["<CENTER>"],
["<VOL_UP>"],
["<VOL_DOWN>"],
["<POWER>"],
["<CAMERA>"],
["<CLEAR>"],
["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"],
[",","<"],
[".",">"],
["<ALT_L>"],
["<ALT_R>"],
["<SHIFT_L>"],
["<SHIFT_R>"],
["<TAB>"],
[" "],
["<SYM>"],
["<EXPLORER>"],
["<ENVELOPE>"],
["\n"],
["\x08"],
["`","~"],
["-","_"],
["=","+"],
["[","{"],
["]","}"],
["\\","|"],
[";",":"],
["'",'"'],
["/","?"],
["<AT>"],
["<NUM_LOCK>"],
["<HEADSETHOOK>"],
["<FOCUS>"],
["+"],
["<MENU>"],
["<NOTIFICATION>"],
["<SEARCH>"],
["<PLAY_PAUSE>"],
["<STOP>"],
["<NEXT>"],
["<PREV>"],
["<REW>"],
["<FFWD>"],
["<MUTE>"],
["<PAGE_UP>"],
["<PAGE_DOWN>"],
["<PICTSYMBOLS>"],
["<SW:>TCH_CHARSET>"],
["<:A:>"],
["<:B:>"],
["<:C:>"],
["<:X:>"],
["<:Y:>"],
["<:Z:>"],
["<:L1:>"],
["<:R1:>"],
["<:L2:>"],
["<:R2:>"],
["<:TL:>"],
["<:TR:>"],
["<:START:>"],
["<:SELECT:>"],
["<:MODE:>"],
["<ESC>"],
["<DEL>"],
[undefined],
[undefined],
["<CAPS_LOCK>"],
["<SCROLL_LOCK>"],
[undefined],
[undefined],
[undefined],
["<PRINT_SCREEN_SYS_RQ>"],
["<PAUSE_BREAK>"],
[undefined],
["<END>"],
["<INSERT>"],
[undefined],
[undefined],
[undefined],
[undefined],
["<CTRL_L>"],
["<CTRL_R>"],
["<F1>"],
["<F2>"],
["<F3>"],
["<F4>"],
["<F5>"],
["<F6>"],
["<F7>"],
["<F8>"],
["<F9>"],
["<F10>"],
["<F11>"],
["<F12>"],
["<NUM_LOCK>"],
["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:>"]
]

View File

@@ -25,5 +25,6 @@
<orderEntry type="library" name="TerranVirtualDisk" level="project" /> <orderEntry type="library" name="TerranVirtualDisk" level="project" />
<orderEntry type="library" name="graal-sdk-21.1.0-javadoc" level="project" /> <orderEntry type="library" name="graal-sdk-21.1.0-javadoc" level="project" />
<orderEntry type="library" name="gdx-platform-1.10.0-natives-desktop" level="project" /> <orderEntry type="library" name="gdx-platform-1.10.0-natives-desktop" level="project" />
<orderEntry type="library" name="graalvm-js-21.1.0 and graalvm-js-scriptengine-21.1.0" level="project" />
</component> </component>
</module> </module>

View File

@@ -3,7 +3,6 @@ package net.torvald.spriteassembler
import com.badlogic.gdx.Gdx import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Pixmap import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.utils.GdxRuntimeException import com.badlogic.gdx.utils.GdxRuntimeException
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.linearSearch import net.torvald.terrarum.linearSearch
import net.torvald.terrarum.serialise.Common import net.torvald.terrarum.serialise.Common
import net.torvald.terrarum.savegame.ByteArray64InputStream import net.torvald.terrarum.savegame.ByteArray64InputStream

View File

@@ -100,6 +100,8 @@ object DefaultConfig {
"fx_differential" to false, "fx_differential" to false,
//"fx_3dlut" to false, //"fx_3dlut" to false,
"basekeyboardlayout" to "us_qwerty"
// settings regarding debugger // settings regarding debugger
/*"buildingmakerfavs" to arrayOf( /*"buildingmakerfavs" to arrayOf(

View File

@@ -22,6 +22,7 @@ import net.torvald.terrarum.blockproperties.WireCodex
import net.torvald.terrarum.gameactors.Actor import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameactors.ActorID import net.torvald.terrarum.gameactors.ActorID
import net.torvald.terrarum.gameactors.faction.FactionCodex import net.torvald.terrarum.gameactors.faction.FactionCodex
import net.torvald.terrarum.gamecontroller.IngameController
import net.torvald.terrarum.gameworld.fmod import net.torvald.terrarum.gameworld.fmod
import net.torvald.terrarum.itemproperties.ItemCodex import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.itemproperties.MaterialCodex import net.torvald.terrarum.itemproperties.MaterialCodex
@@ -51,6 +52,10 @@ typealias RGBA8888 = Int
*/ */
object Terrarum : Disposable { object Terrarum : Disposable {
init {
IngameController.KEYBOARD_DELAYS[1]
}
/** /**
* All singleplayer "Player" must have this exact reference ID. * All singleplayer "Player" must have this exact reference ID.
*/ */
@@ -286,6 +291,8 @@ object Terrarum : Disposable {
/** Delta converted as it it was a FPS */ /** Delta converted as it it was a FPS */
inline val updateRate: Double inline val updateRate: Double
get() = 1.0 / Gdx.graphics.deltaTime get() = 1.0 / Gdx.graphics.deltaTime
val mouseDown: Boolean
get() = Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary"))
/** /**
* Usage: * Usage:

View File

@@ -1,15 +1,9 @@
package net.torvald.terrarum.gameactors package net.torvald.terrarum.gameactors
import net.torvald.random.HQRNG 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.ReferencingRanges
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed 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.savegame.toBigEndian
import net.torvald.terrarum.utils.PasswordBase32 import net.torvald.terrarum.utils.PasswordBase32

View File

@@ -0,0 +1,60 @@
package net.torvald.terrarum.gamecontroller
import com.badlogic.gdx.Gdx
import net.torvald.terrarum.App.printdbg
typealias TerrarumKeyLayout = Array<Array<String?>>
/**
* 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<String, TerrarumKeyLayout>()
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<String?>(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
}
}

View File

@@ -10,6 +10,7 @@ import net.torvald.terrarum.App
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.ItemCodex import net.torvald.terrarum.ItemCodex
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.controller.TerrarumController import net.torvald.terrarum.controller.TerrarumController
import net.torvald.terrarum.floorInt 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 // also, some UIs should NOT affect item usage (e.g. quickslot) and ingame's uiOpened property is doing
// the very job. // 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) terrarumIngame.worldPrimaryClickStart(terrarumIngame.actorNowPlaying!!, App.UPDATE_RATE)
worldPrimaryClickLatched = true worldPrimaryClickLatched = true
} }
@@ -141,7 +142,7 @@ class IngameController(val terrarumIngame: TerrarumIngame) : InputAdapter() {
// unlatch when: // unlatch when:
// - not clicking anymore // - not clicking anymore
// - using any item that is not fixture (blocks, picks) // - 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) { GameItem.Category.MISC != ItemCodex.get(terrarumIngame.actorNowPlaying?.inventory?.itemEquipped?.get(GameItem.EquipPosition.HAND_GRIP))?.inventoryCategory) {
worldPrimaryClickLatched = false worldPrimaryClickLatched = false
} }
@@ -273,162 +274,98 @@ class IngameController(val terrarumIngame: TerrarumIngame) : InputAdapter() {
} }
companion object { companion object {
const val KEY_DELAY = 0.2f data class TerrarumKeyboardEvent(
const val KEY_REPEAT = 1f / 40f val type: Int,
val KEYCODE_TO_CHAR = hashMapOf<Int, Char>( val character: String?,
Keys.NUM_1 to '1', val repeatCount: Int,
Keys.NUM_2 to '2', val keycodes: IntArray
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()
) )
val KEYCODE_TO_CHAR_SHIFT = hashMapOf<Int, Char>( private const val KEY_DOWN = 0
Keys.NUM_1 to '!', private const val KEY_CHANGE = 1
Keys.NUM_2 to '@', const val N_KEY_ROLLOVER = 8
Keys.NUM_3 to '#', var KEYBOARD_DELAYS = floatArrayOf(0.25f, 0.025f)
Keys.NUM_4 to '$', private var stroboTime = 0L
Keys.NUM_5 to '%', private var stroboStatus = 0
Keys.NUM_6 to '^', private var repeatCount = 0
Keys.NUM_7 to '&', private var oldKeys = IntArray(N_KEY_ROLLOVER) { 0 }
Keys.NUM_8 to '*', private var keymap = IME.getLowLayerByName(App.getConfigString("basekeyboardlayout"))
Keys.NUM_9 to '(',
Keys.NUM_0 to ')',
Keys.A to 'A', // code proudly stolen from tsvm's TVDOS.SYS
Keys.B to 'B', fun withKeyboardEvent(callback: (TerrarumKeyboardEvent) -> Unit) {
Keys.C to 'C', val keys = strobeKeys()
Keys.D to 'D', var keyChanged = !arrayEq(keys, oldKeys)
Keys.E to 'E', val keyDiff = arrayDiff(keys, oldKeys)
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 '~', if (stroboStatus % 2 == 0 && keys[0] != 0) {
Keys.MINUS to '_', stroboStatus += 1
Keys.EQUALS to '+', stroboTime = System.nanoTime()
Keys.BACKSPACE to 8.toChar(), repeatCount += 1
Keys.LEFT_BRACKET to '{', val shiftin = keys.contains(Keys.SHIFT_LEFT) || keys.contains(Keys.SHIFT_RIGHT)
Keys.RIGHT_BRACKET to '}', val keysym0 = keysToStr(keys)
Keys.BACKSLASH to '|', 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 ':', if (!keyChanged) {
Keys.APOSTROPHE to '"', callback(TerrarumKeyboardEvent(KEY_DOWN, keysym, repeatCount, keys))
Keys.ENTER to 10.toChar(), }
else if (newKeysym != null) {
callback(TerrarumKeyboardEvent(KEY_DOWN, newKeysym, repeatCount, keys))
}
Keys.COMMA to '<', oldKeys = keys // don't put this outside of if-cascade
Keys.PERIOD to '>', }
Keys.SLASH to '?', 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', private fun keysToStr(keys: IntArray): Array<String?>? {
Keys.NUMPAD_1 to '1', val headkey = keys[0]
Keys.NUMPAD_2 to '2', return if (keymap[headkey] == null) null else keymap[headkey]
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 '/', private fun strobeKeys(): IntArray {
Keys.NUMPAD_MULTIPLY to '*', var keysPushed = 0
Keys.NUMPAD_SUBTRACT to '-', val keyEventBuffers = IntArray(N_KEY_ROLLOVER) { 0 }
Keys.NUMPAD_ADD to '+', for (k in 1..254) {
Keys.NUMPAD_DOT to '.', if (Gdx.input.isKeyPressed(k)) {
Keys.NUMPAD_ENTER to 10.toChar() 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() private inline fun BitSet.bitCount() = this.cardinality()
} }

View File

@@ -363,7 +363,7 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
// make pen work HERE // make pen work HERE
// when LEFT mouse is down // 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) makePenWork(Terrarum.mouseTileX, Terrarum.mouseTileY)
// TODO drag support using bresenham's algo // TODO drag support using bresenham's algo

View File

@@ -6,7 +6,6 @@ import net.torvald.terrarum.console.ConsoleCommand
import net.torvald.terrarum.console.Echo import net.torvald.terrarum.console.Echo
import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.serialise.Common import net.torvald.terrarum.serialise.Common
import net.torvald.terrarum.serialise.WriteSavegame
import net.torvald.terrarum.savegame.VDUtil import net.torvald.terrarum.savegame.VDUtil
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException

View File

@@ -86,7 +86,7 @@ class UIBuildingMakerBlockChooser(val parent: BuildingMaker): UICanvas() {
} }
// respond to click // respond to click
if (Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary"))) { if (Terrarum.mouseDown) {
// scroll bar // scroll bar
if (relativeMouseX in width - SCROLLBAR_SIZE until width && relativeMouseY in 0 until height) { if (relativeMouseX in width - SCROLLBAR_SIZE until width && relativeMouseY in 0 until height) {
mouseOnScroll = true mouseOnScroll = true

View File

@@ -133,7 +133,7 @@ class UIBuildingMakerPenMenu(val parent: BuildingMaker): UICanvas() {
} }
// primary click // primary click
if (Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary"))) { if (Terrarum.mouseDown) {
// close by clicking close button or out-of-boud // close by clicking close button or out-of-boud
if (mouseVec.distanceSquared(RADIUS, RADIUS) !in CLOSE_BUTTON_RADIUS.sqr()..RADIUSF.sqr()) { if (mouseVec.distanceSquared(RADIUS, RADIUS) !in CLOSE_BUTTON_RADIUS.sqr()..RADIUSF.sqr()) {
closeGracefully() closeGracefully()
@@ -175,7 +175,7 @@ class UIBuildingMakerPenMenu(val parent: BuildingMaker): UICanvas() {
batch.draw(ItemCodex.getItemImage(slotConfig[i]), x - 16, y - 16, 32f, 32f) batch.draw(ItemCodex.getItemImage(slotConfig[i]), x - 16, y - 16, 32f, 32f)
// update as well while looping // update as well while looping
if (i == mouseOnBlocksSlot && Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary"))) { if (i == mouseOnBlocksSlot && Terrarum.mouseDown) {
parent.setPencilColour(slotConfig[i]) parent.setPencilColour(slotConfig[i])
closeGracefully() closeGracefully()
} }

View File

@@ -47,7 +47,7 @@ class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() {
// update map panning // update map panning
// if left click is down and cursor is in the map area // 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) { Terrarum.mouseScreenY in cellOffY..cellOffY + INVENTORY_CELLS_UI_HEIGHT) {
minimapPanX += Terrarum.mouseDeltaX * 2f / minimapZoom minimapPanX += Terrarum.mouseDeltaX * 2f / minimapZoom
minimapPanY += Terrarum.mouseDeltaY * 2f / minimapZoom minimapPanY += Terrarum.mouseDeltaY * 2f / minimapZoom

View File

@@ -4,11 +4,8 @@ import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch 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.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.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
@@ -77,7 +74,7 @@ open class UIRemoCon(val parent: TitleScreen, treeRepresentation: QNDTreeNode<St
private var openUI: UICanvas? = null private var openUI: UICanvas? = null
override fun updateUI(delta: Float) { override fun updateUI(delta: Float) {
if (mouseActionAvailable && Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary"))) { if (mouseActionAvailable && Terrarum.mouseDown) {
mouseActionAvailable = false mouseActionAvailable = false
remoConTray.update(delta) remoConTray.update(delta)
@@ -149,7 +146,7 @@ open class UIRemoCon(val parent: TitleScreen, treeRepresentation: QNDTreeNode<St
openUI?.update(delta) openUI?.update(delta)
if (!Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary"))) { if (!Terrarum.mouseDown) {
mouseActionAvailable = true mouseActionAvailable = true
} }
} }

View File

@@ -3,13 +3,10 @@ package net.torvald.terrarum.serialise
import net.torvald.spriteanimation.HasAssembledSprite import net.torvald.spriteanimation.HasAssembledSprite
import net.torvald.spriteanimation.SpriteAnimation import net.torvald.spriteanimation.SpriteAnimation
import net.torvald.spriteassembler.ADProperties import net.torvald.spriteassembler.ADProperties
import net.torvald.terrarum.NoSuchActorWithIDException
import net.torvald.terrarum.gameactors.Actor import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.gameactors.ActorWithBody
import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
import net.torvald.terrarum.savegame.* import net.torvald.terrarum.savegame.*
import java.io.Reader import java.io.Reader

View File

@@ -86,7 +86,7 @@ abstract class UICanvas(
get() = _mouseUpThis || handler.mouseUp get() = _mouseUpThis || handler.mouseUp
/** If mouse is hovering over it and mouse is down */ /** If mouse is hovering over it and mouse is down */
val mousePushed: Boolean val mousePushed: Boolean
get() = mouseUp && Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary")) get() = mouseUp && Terrarum.mouseDown
private val _mouseUpThis: Boolean private val _mouseUpThis: Boolean
get() = relativeMouseX in 0..width - 1 && relativeMouseY in 0..height - 1 get() = relativeMouseX in 0..width - 1 && relativeMouseY in 0..height - 1

View File

@@ -59,8 +59,6 @@ abstract class UIItem(var parentUI: UICanvas, val initialX: Int, val initialY: I
abstract val width: Int abstract val width: Int
abstract val height: Int abstract val height: Int
protected val mouseButton = App.getConfigInt("config_mouseprimary")
/** This variable is NOT updated on its own. /** This variable is NOT updated on its own.
* ``` * ```
* val posXDelta = posX - oldPosX * val posXDelta = posX - oldPosX
@@ -92,10 +90,10 @@ abstract class UIItem(var parentUI: UICanvas, val initialX: Int, val initialY: I
get() = relativeMouseX in 0..width - 1 && relativeMouseY in 0..height - 1 get() = relativeMouseX in 0..width - 1 && relativeMouseY in 0..height - 1
/** If mouse is hovering over it and mouse is down */ /** If mouse is hovering over it and mouse is down */
open val mousePushed: Boolean open val mousePushed: Boolean
get() = mouseUp && Gdx.input.isButtonPressed(mouseButton) get() = mouseUp && Terrarum.mouseDown
protected var mouseLatched = Gdx.input.isButtonPressed(mouseButton) protected var mouseLatched = Terrarum.mouseDown
/** UI to call (show up) while mouse is up */ /** UI to call (show up) while mouse is up */
open val mouseOverCall: UICanvas? = null open val mouseOverCall: UICanvas? = null
@@ -103,12 +101,13 @@ abstract class UIItem(var parentUI: UICanvas, val initialX: Int, val initialY: I
// kind of listener implementation // kind of listener implementation
/** Fired once for every update /** Fired once for every update
* Parametre: delta */ * Parameter: delta */
open var updateListener: ((Float) -> Unit)? = null open var updateListener: ((Float) -> Unit)? = null
/** Parametre: keycode */ /** Parameter: keycode */
open var keyDownListener: ((Int) -> Unit)? = null open var keyDownListener: ((Int) -> Unit)? = null
/** Parametre: keycode */ /** Parameter: keycode */
open var keyUpListener: ((Int) -> Unit)? = null open var keyUpListener: ((Int) -> Unit)? = null
open var keyTypedListener: ((Char) -> Unit)? = null
open var touchDraggedListener: ((Int, Int, Int) -> Unit)? = null open var touchDraggedListener: ((Int, Int, Int) -> Unit)? = null
/** Parameters: screenX, screenY, pointer, button */ /** Parameters: screenX, screenY, pointer, button */
open var touchDownListener: ((Int, Int, Int, Int) -> Unit)? = null 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 return false
} }
open fun keyTyped(character: Char): Boolean {
if (parentUI.isVisible && keyTypedListener != null) {
keyTypedListener!!.invoke(character)
return true
}
return false
}
// mouse controlled // mouse controlled
open fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean { open fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean {

View File

@@ -4,11 +4,8 @@ import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.*
import net.torvald.terrarum.App.printdbg 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 import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/** /**
@@ -223,7 +220,7 @@ class UIItemTextButtonList(
} }
if (!Gdx.input.isButtonPressed(mouseButton)) { if (!Terrarum.mouseDown) {
clickLatched = false clickLatched = false
} }

View File

@@ -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()
}
}

View File

@@ -27,5 +27,6 @@
<orderEntry type="library" name="TerranVirtualDisk" level="project" /> <orderEntry type="library" name="TerranVirtualDisk" level="project" />
<orderEntry type="library" name="graal-sdk-21.1.0-javadoc" level="project" /> <orderEntry type="library" name="graal-sdk-21.1.0-javadoc" level="project" />
<orderEntry type="library" name="gdx-platform-1.10.0-natives-desktop" level="project" /> <orderEntry type="library" name="gdx-platform-1.10.0-natives-desktop" level="project" />
<orderEntry type="library" name="graalvm-js-21.1.0 and graalvm-js-scriptengine-21.1.0" level="project" />
</component> </component>
</module> </module>