commit
10006ebfc9
|
@ -49,6 +49,7 @@ if (APPLE)
|
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-gnu")
|
||||
endif(APPLE)
|
||||
|
||||
option(USE_LLD_LINKER "Use the LLVM lld linker instead of gcc's linker" OFF)
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
if (NOT IS_TRAVIS)
|
||||
add_compile_options(
|
||||
|
@ -63,6 +64,9 @@ if (CMAKE_COMPILER_IS_GNUCXX)
|
|||
-Wno-implicit-fallthrough
|
||||
)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive")
|
||||
if (USE_LLD_LINKER)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=lld")
|
||||
endif(USE_LLD_LINKER)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -Og")
|
||||
endif (CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "بقايا جسم كوكب بني قزم شبه ممتازة"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" زر \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "الكاميرا السفلية"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "مكان الوصول"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "البعد: %distance{f.2} سنة ضوئية"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Entirely Capitalist - no government welfare provision"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" قبعة\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Hold {target} anti-normal"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "اعادة"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "اعادة التوجية و التكبير"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "الي"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" لا يوجد غلاف جوي\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "انعراج"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "مستعمرة زراعة صغيرة"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "تقريب"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Кафяво джудже"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Бутон \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Долна камера"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Дестинация"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Пос \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Разстояние: %distance{f.2} сг"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Изцяло капиталистическа - без намеса от правителството"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Задръж {target} анти-нормално"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Нулиране"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Нулирай Ориентацията и Мащабирането"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Роботи"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" незначителна атмосфера\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Отклонение"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Млада фермерска колония."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Приближи"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Nan marró (objecte subestel·lar)"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" botó \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Càmera inferior"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Destinació"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Distància: %distance{f.2} al"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Capitalisme salvatge. Cap prestació social del govern."
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Bolet\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Orientació anti-normal respecte a {target}"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Reiniciar"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reiniciar orientació i zoom"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robots"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" sense atmosfera significativa\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Guinyada"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Colònia agrícola recent."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Apropar"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Hnědý trpaslík (podhvězda)"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" klávesa \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Pohled zdola"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Destinace"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" směr \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Vzdálenost: %distance{f.2} ly"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Naprostý kapitalismus - žádný státní sociální systém"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" klobouk\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Hold {target} anti-normal"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset orientace a zoomu"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Roboti"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" bez výrazné atmosféry\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Zatáčení"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Nová zemědělská kolonie."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Zvětšit"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Brun dværg sub-stjerneobjekt"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Knap \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Underkamera"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Destinatio"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Retning \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Afstand: %distance{f.2} ly"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Ren kapitalisme - ingen offentlige velfærdsydelser"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Hold {target} anti-normal"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Nulstil"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Nulstil Synspunkt og Zoom"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robotter"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" uden nogen betydningsfuld atmosfære\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Sideror"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Ung landbrugskoloni."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Zoom ind"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Brauner Zwerg (substellares Objekt)"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\"-Taste \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Untere Ansicht"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Reiseziel"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\"-Richtung \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Entfernung: %distance{f.2} Lj"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Rein kapitalistisch – kein staatliches Sozialsystem"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\"-Hat\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "{target} anti-normal halten"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Zurücksetzen"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Ansicht und Zoom zurücksetzen"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Roboter"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" ohne signifikante Atmosphäre\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Gieren"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Neu gegründete landwirtschaftliche Kolonie."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Vergrößern"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Brown dwarf sub-stellar object"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Button \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Bottom camera"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Destination"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Distance: %distance{f.2} ly"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Entirely Capitalist - no government welfare provision"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Hold {target} anti-normal"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset Orientation and Zoom"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Ρομπότ"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" with no significant atmosphere\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Yaw"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Young farming colony."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Zoom in"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Brown dwarf sub-stellar object"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Button \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Bottom camera"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Destination"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Distance: %distance{f.2} ly"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Entirely Capitalist - no government welfare provision"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Hold {target} anti-normal"
|
||||
|
@ -651,10 +639,6 @@
|
|||
"description": "",
|
||||
"message": "Joystick input"
|
||||
},
|
||||
"JOY_AXIS": {
|
||||
"description": "Regarding joystick",
|
||||
"message": "%{sign}%joyname %axis Axis"
|
||||
},
|
||||
"L4L5_DISPLAY_MODE_TOGGLE": {
|
||||
"description": "Either show L4/L5 points or don't",
|
||||
"message": "Switch between Lagrange L4/L5 point display modes."
|
||||
|
@ -751,70 +735,6 @@
|
|||
"description": "",
|
||||
"message": "Manual control mode"
|
||||
},
|
||||
"MAP_LOCK_HYPERSPACE_TARGET": {
|
||||
"description": "",
|
||||
"message": "Lock Hyperspace Target"
|
||||
},
|
||||
"MAP_TOGGLE_INFO_PANEL": {
|
||||
"description": "",
|
||||
"message": "Toggle Info Panel"
|
||||
},
|
||||
"MAP_TOGGLE_SELECTION_FOLLOW_VIEW": {
|
||||
"description": "",
|
||||
"message": "Toggle Selection Following View"
|
||||
},
|
||||
"MAP_VIEW_ROTATE_DOWN": {
|
||||
"description": "",
|
||||
"message": "Rotate View Down"
|
||||
},
|
||||
"MAP_VIEW_ROTATE_LEFT": {
|
||||
"description": "",
|
||||
"message": "Rotate View Left"
|
||||
},
|
||||
"MAP_VIEW_ROTATE_RIGHT": {
|
||||
"description": "",
|
||||
"message": "Rotate View Right"
|
||||
},
|
||||
"MAP_VIEW_ROTATE_UP": {
|
||||
"description": "",
|
||||
"message": "Rotate View Up"
|
||||
},
|
||||
"MAP_VIEW_SHIFT_BACKWARD": {
|
||||
"description": "",
|
||||
"message": "Shift View Backwards"
|
||||
},
|
||||
"MAP_VIEW_SHIFT_DOWN": {
|
||||
"description": "",
|
||||
"message": "Shift View Down"
|
||||
},
|
||||
"MAP_VIEW_SHIFT_FORWARD": {
|
||||
"description": "",
|
||||
"message": "Shift View Forwards"
|
||||
},
|
||||
"MAP_VIEW_SHIFT_LEFT": {
|
||||
"description": "",
|
||||
"message": "Shift View Left"
|
||||
},
|
||||
"MAP_VIEW_SHIFT_RIGHT": {
|
||||
"description": "",
|
||||
"message": "Shift View Right"
|
||||
},
|
||||
"MAP_VIEW_SHIFT_UP": {
|
||||
"description": "",
|
||||
"message": "Shift View Up"
|
||||
},
|
||||
"MAP_WARP_TO_CURRENT_SYSTEM": {
|
||||
"description": "",
|
||||
"message": "Warp to Current System"
|
||||
},
|
||||
"MAP_WARP_TO_HYPERSPACE_TARGET": {
|
||||
"description": "",
|
||||
"message": "Warp to Hyperspace Target"
|
||||
},
|
||||
"MAP_WARP_TO_SELECTED_SYSTEM": {
|
||||
"description": "",
|
||||
"message": "Warp to Selected System"
|
||||
},
|
||||
"MASS": {
|
||||
"description": "",
|
||||
"message": "Mass"
|
||||
|
@ -1231,10 +1151,6 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset Orientation and Zoom"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robots"
|
||||
|
@ -1707,10 +1623,6 @@
|
|||
"description": "",
|
||||
"message": "Toggle HUD mode"
|
||||
},
|
||||
"TOGGLE_LUA_CONSOLE": {
|
||||
"description": "",
|
||||
"message": "Toggle Lua console"
|
||||
},
|
||||
"TOGGLE_RADAR_MODE": {
|
||||
"description": "",
|
||||
"message": "Toggle radar mode"
|
||||
|
@ -1871,14 +1783,6 @@
|
|||
"description": "",
|
||||
"message": "\" with no significant atmosphere\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Yaw"
|
||||
|
@ -1895,10 +1799,6 @@
|
|||
"description": "",
|
||||
"message": "Young farming colony."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Zoom in"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Brown dwarf sub-stellar object"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Button \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Bottom camera"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Destination"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Distance: %distance{f.2} ly"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Entirely Capitalist - no government welfare provision"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Hold {target} anti-normal"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset Orientation and Zoom"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robots"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" with no significant atmosphere\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Yaw"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Young farming colony."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Zoom in"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Enana marrón (objeto subestelar)"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Botón \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Cámara inferior"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Destino"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Distancia: %distance{f.2} AL"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Capitalista puro - sin intervencion del estado"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Seta\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Fijar anti-normal con {target}"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Reiniciar"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reiniciar orientación y zoom"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robots"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" sin atmósfera significativa\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Guiñada"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Colonia agrícola joven."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Acercar"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Naine brune sous-stellaire."
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\"bouton\""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Vue Inférieure"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Destination"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Doc \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Distance: %distance{f.2} al"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Entièrement capitaliste - pas de gouvernement réel"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\"Couv\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Maintenir {target} en direction anti-normale"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Réinitialise l'orientation et le zoom"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robots"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" sans atmosphère significative\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Lacets"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Jeune colonie agricole."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Zoom avant"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Abhac donn (rinn fo-réaltach)"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Cnaipe \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Ceamara íochtarach"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Ceann scríbe"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Treo \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Fad: %distance{f.2} sbh"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Caipitlíoch amach is amach - gan aon chóras leasa shóisialaigh"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hata\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Hold {target} anti-normal"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Athshocraigh"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Athshocraigh an Treoshuíomh agus an Zúmáil"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Róbait"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" gan atmaisféar arbh fhiú trácht air\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Luascáil"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Coilíneacht óg feirmeoireachta."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Zúmáil isteach"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Troich dhonn - nì fo-reultach"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Putan \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Camara a' bhuinn"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Ceann-uidhe"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\"Comhair\""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Astar: %distance{f.2} bl-shol"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Calpach gu tur - gun riaghaltas no sochair"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Ad\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Cum {target} gu h-an àbhaisteach"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Ath-shuidhich"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Ath-shuidhich a' chomhair agus an sùm"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robotairean"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" gun àile ceart\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Claonadh"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Tuineachadh àiteachais òg."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Sùm a-steach"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Smeđi patuljak pod-zvijezdani objekt"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Tipka \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Bottom camera"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Cilj"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Smjer \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Udaljenost: %distance{f.2} sg"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Potpuni kapitalizam - bez vladinih socijalnih davanja"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Hold {target} anti-normal"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset Orientation and Zoom"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Roboti"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" sa beznačajnom atmosferom\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Skretanje"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Mlada poljoprivredna kolonija."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Povećaj"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Barna törpe objektum"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Gomb \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Alsó kamera"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Célállomás"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Irány \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Távolság: %distance{f.2} fényév"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Teljesen kapitalista - kormányintézkedések nélkül"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Antinormál irány tartása"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Alaphelyzet"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Nézet alaphelyzetbe"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robotok"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" számottevő atmoszféra nélkül\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Kitér"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Fiatal farmkolónia"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Közelítés"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Brown dwarf sub-stellar object"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Button \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Kamera bawah"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Tujuan"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Arah \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Distance: %distance{f.2} ly"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Entirely Capitalist - no government welfare provision"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Hold {target} anti-normal"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset Orientation and Zoom"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robot"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" tanpa atmosfer signifikan\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Yaw"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Koloni pertanian muda."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Zoom in"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Nana Bruna (oggetto substellare)"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Pulsante \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Camera inferiore"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Destinazione"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Distanza: %distance{f.2} AL"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Capitalismo perfetto - nessun intervento dello Stato in economia"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Mantieni {target} anti-normale"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Azzera Zoom"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reimposta Orientamento e Zoom"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robot"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" con atmosfera insignificante\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Imbardata"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Giovane colonia agricola."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Zoom avanti"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Rudasis nykštukas - subžvaigždinis objektas"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Mygtukas \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Kamera iš apačios"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Paskirties vieta"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Katalogas \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Atstumas: %distance{f.2} šviesm."
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Visiškai kapitalistinė - nėra valstybinės socialinės paramos"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Kepurė \""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Hold {target} anti-normal"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Perkrauti"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Atitaisyti kryptį ir priartinimą"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robotai"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" neturi reikšmingos atmosferos\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Nuokrypis"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Jauna žemės ūkio kolonija."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Priartinti"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Brown dwarf sub-stellar object"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Button \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Bottom camera"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Destinasjon"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Distance: %distance{f.2} ly"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Entirely Capitalist - no government welfare provision"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Hold {target} anti-normal"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset Orientation and Zoom"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Roboter"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" with no significant atmosphere\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Yaw"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Young farming colony."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Zoom in"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Bruine dwerg, sub-stellair object"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Knop \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Onderste camera"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Bestemming"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Richting \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Afstand: %distance{f.2} lj"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Volkomen kapitalistisch - geen overheids-gesubsidieerde welzijnsvoorzieningen"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hoed\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Behoud {target} anti-normaal"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Herinstellen Oriëntatie en Zoom"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robots"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" zonder significante atmosfeer\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Gier"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Jonge agrarische kolonie."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Zoom in"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Brązowy karzeł"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" przycisk \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Dolna kamera"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Punkt docelowy"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Dystans: %distance{f.2} lś"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Całkowity Kapitalizm - bez opieki społecznej"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Utrzymuj się wzdłuż antynormalnej do {target}"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset orientacji i zbliżenia"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Roboty"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" bez znaczącej atmosfery\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Odchylenie poziome"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Młoda kolonia rolnicza."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Zbliż"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Objeto sub-estelar anã castanha"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Botão \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Câmara inferior"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Destino"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Distância: %distance{f.2} ly"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Completamente Capitalista - não há segurança social do estado"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Hold {target} anti-normal"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Reiniciar"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset Orientation and Zoom"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robôs"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" sem atmosfera significativa\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Yaw"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Colónia agrícola jovem."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Zoom in"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Objeto sub-estelar anã marrom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Botão \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Câmera inferior"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Destino"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Distância: %distance{f.2} al"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Completamente Capitalista - governo não faz provisões para o bem-estar"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Chapéu\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Hold {target} anti-normal"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reiniciar Orientação e Zoom"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robôs"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" sem atmosfera significativa\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Guinada"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Jovem colônia agricultora."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Aproximar zoom"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Obiect sub-stelar pitică cenușie"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Buton \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Vedere de jos"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Destinație"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Distanța: %distance{f.2} al"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Complet Capitalist - nici o dispoziție pentru prosperitatea guvernului"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Buton vizualizare\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Menține {target} înclinația anti-normală"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Resetare"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Resetează Orientare și Focalizare"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Roboți"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" fără atmosferă semnificativă\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Girare"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Colonie proaspătă de agricultură."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Focalizează"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Коричневый карлик - субзвёздный объект"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Кнопка \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Нижний экран"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Пункт назначения"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Напр. \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Расстояние: %distance{f.2} СвЛ"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Ультракапитализм - отсутствие соцгарантий."
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Удерживать {target} против нормали"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Сброс"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Камера по умолчанию"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Роботы"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" с разрежённой атмосферой\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Управление рысканьем"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Молодая сельскохозяйственная колония."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Приблизить камеру"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Brunt dvärgstjärnobjekt"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Knapp \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Nedre kamera"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Destination"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Distans: %distance{f.2} ly"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Helt kapitalistiskt - ingen välfärd tillhandahållen från regeringen"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hatt\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Hold {target} anti-normal"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Återställ"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Återställ orientering och zoom"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robotar"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" utan någon nämnbar atmosfär\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Gira"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Ung jordbrukskoloni."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Zooma in"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "Kahverengi cüce alt-yıldız cismi"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Düğme \""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "Alt kamera"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "Hedef"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Yön \""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "Uzaklık: %distance{f.2} Iy"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "Tamamen Kapitalist - yönetim mal varlığını düzenlemiyor"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Üst düğme\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "Ters-dikey yönelimde {target} sabitle"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "Yeniden başlat"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Yönelim ve Yakınlaştırmayı Sıfırla"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "Robotlar"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\" belli bir atmosferi yok\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "Sapma"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "Genç tarım kolonisi."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "Yakınlaştır"
|
||||
|
|
|
@ -103,10 +103,6 @@
|
|||
"description": "",
|
||||
"message": "褐矮星亚恒星体"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\"按钮\""
|
||||
},
|
||||
"CAMERA_BOTTOM_VIEW": {
|
||||
"description": "",
|
||||
"message": "底部摄像机"
|
||||
|
@ -327,10 +323,6 @@
|
|||
"description": "",
|
||||
"message": "目的地"
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\"目录\""
|
||||
},
|
||||
"DISTANCE_LY": {
|
||||
"description": "",
|
||||
"message": "距离: %distance{f.2} 光年"
|
||||
|
@ -495,10 +487,6 @@
|
|||
"description": "",
|
||||
"message": "完全资本主义 - 政府不提供福利"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\"帽子\""
|
||||
},
|
||||
"HEADING_LOCK_ANTINORMAL": {
|
||||
"description": "Autopilot direction (perpendicular, down), relative to plane of orbit",
|
||||
"message": "保持{target}反法线"
|
||||
|
@ -1231,10 +1219,6 @@
|
|||
"description": "",
|
||||
"message": "重置"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "重置方向和缩放"
|
||||
},
|
||||
"ROBOTS": {
|
||||
"description": "",
|
||||
"message": "机器人"
|
||||
|
@ -1871,14 +1855,6 @@
|
|||
"description": "",
|
||||
"message": "\"没有明显大气\""
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"YAW": {
|
||||
"description": "",
|
||||
"message": "偏航"
|
||||
|
@ -1895,10 +1871,6 @@
|
|||
"description": "",
|
||||
"message": "新兴的农业殖民地."
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
},
|
||||
"ZOOM_IN": {
|
||||
"description": "",
|
||||
"message": "放大"
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" زر \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "تحكم الروئية الرئيسي"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "اسلحة"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" قبعة\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "Увеличение на Изглед"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Бутон \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Пос \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Общи Контроли за Изглед"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Оръжия"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "Общи Контроли"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Увеличение:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" botó \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Controls de vista general"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Armes"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Bolet\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" klávesa \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" směr \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Ovládací prvky celkového pohledu"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Zbraně"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" klobouk\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Knap \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Retning \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Generel synspunktsstyring"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Våben"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "Ansicht zoomen"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\"-Taste \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\"-Richtung \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Allgemeine Ansichtssteuerung"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Waffen"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\"-Hat\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "Allgemeine Steuerung"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positiv:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Button \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "General View Controls"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Weapons"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
{
|
||||
"AXIS": {
|
||||
"description": "Cardinal name used to compose Joystick <X> Button <Y>",
|
||||
"message": " Axis "
|
||||
},
|
||||
"BIND_AXIS_PITCH": {
|
||||
"description": "Descriptive name for the Pitch axis.",
|
||||
"message": "Pitch"
|
||||
|
@ -91,6 +95,18 @@
|
|||
"description": "Axis binding",
|
||||
"message": "Map Yaw"
|
||||
},
|
||||
"BIND_MAP_WARP_TO_CURRENT_SYSTEM": {
|
||||
"description": "Descriptive name for the MapWarpToCurrentSystem action.",
|
||||
"message": "Warp to Current System"
|
||||
},
|
||||
"BIND_MAP_WARP_TO_SELECTED_SYSTEM": {
|
||||
"description": "Descriptive name for the MapWarpToSelectedSystem action.",
|
||||
"message": "Warp to Selected System"
|
||||
},
|
||||
"BIND_MAP_TOGGLE_SELECTION_FOLLOW_VIEW": {
|
||||
"description": "Descriptive name for the MapToggleSelectionFollowView action.",
|
||||
"message": "Toggle Selection Following View"
|
||||
},
|
||||
"BIND_PRIMARY_FIRE": {
|
||||
"description": "Descriptive name for the PrimaryFire action.",
|
||||
"message": "Primary Fire"
|
||||
|
@ -103,6 +119,10 @@
|
|||
"description": "Descriptive name for the ResetCamera action.",
|
||||
"message": "Reset Camera View to Default"
|
||||
},
|
||||
"BIND_RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "Descriptive name for the ResetOrientationAndZoom action.",
|
||||
"message": "Reset Orientation and Zoom"
|
||||
},
|
||||
"BIND_RIGHT_CAMERA": {
|
||||
"description": "Descriptive name for the RightCamera action.",
|
||||
"message": "Switch to Right Camera"
|
||||
|
@ -127,6 +147,10 @@
|
|||
"description": "Descriptive name for the ToggleHudMode action.",
|
||||
"message": "Toggle HUD Mode"
|
||||
},
|
||||
"BIND_TOGGLE_LUA_CONSOLE": {
|
||||
"description": "Descriptive name for the ToggleLuaConsole action.",
|
||||
"message": "Toggle Lua console"
|
||||
},
|
||||
"BIND_TOGGLE_ROTATION_DAMPING": {
|
||||
"description": "Descriptive name for the ToggleRotationDamping action.",
|
||||
"message": "Toggle Rotation Damping"
|
||||
|
@ -143,6 +167,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Button \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "General View Controls"
|
||||
|
@ -170,6 +202,26 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Weapons"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"MOUSE": {
|
||||
"description": "A computer mouse, used to create the name for a mouse button binding",
|
||||
"message": "Mouse "
|
||||
},
|
||||
"MOUSE_LMB": {
|
||||
"description": "An acronym for the left mouse button",
|
||||
"message": "LMB"
|
||||
},
|
||||
"MOUSE_MMB": {
|
||||
"description": "An acronym for the middle mouse button",
|
||||
"message": "MMB"
|
||||
},
|
||||
"MOUSE_RMB": {
|
||||
"description": "An acronym for the right mouse button",
|
||||
"message": "RMB"
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +269,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Button \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "General View Controls"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Weapons"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Botón \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Vista General"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Armamento"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Seta\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "Controles Generales"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positivo:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "Zoom vue"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\"bouton\""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Doc \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Contrôles de vue généraux"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Armes"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\"Couv\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "Contrôles généraux"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positif:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Cnaipe \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Treo \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Rialtáin Ghinearálta Radhairc"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Airm"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hata\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Putan \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\"Comhair\""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Uidheaman-smachd coitcheann"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Airm"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Ad\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Tipka \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Smjer \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "General View Controls"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Oružja"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Gomb \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Irány \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Általános nézet vezérlők"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Fegyverek"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "Általános"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Pozitív:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Button \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Arah \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "General View Controls"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Senjata"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "Zoom Vista"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Pulsante \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Controlli Generali della Visuale"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Armamenti"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "Controlli Generici"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positivo:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Mygtukas \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Katalogas \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Bendras Vaizdo Valdymas"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Ginklai"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Kepurė \""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Button \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "General View Controls"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Weapons"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Knop \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Richting \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Algemeen zicht beheer"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Wapens"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hoed\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "Powiększ widok"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" przycisk \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Kontrolki widoku głównego"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Bronie"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "Kontrolki ogólne"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Botão \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "General View Controls"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Armas"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Botão \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Controles de vista geral"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Armas"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Chapéu\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Buton \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Controale Generale Vizionare"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Arme"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Buton vizualizare\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "View Zoom"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Кнопка \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Напр. \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Управление камерой"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Управление оружием:"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hat\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "General Controls"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positive:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "Zoom-vy"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Knapp \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Dir \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Generella vykontroller"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Vapen"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Hatt\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "Generella kontroller"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Positiv:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "Görüntü Yakınlaştırma"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\" Düğme \""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\" Yön \""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "Genel Görünüm Kontrolleri"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "Silahlar"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\" Üst düğme\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "Genel Kontroller"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "Pozitif:"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@
|
|||
"description": "Descriptive name for the View Zoom axis",
|
||||
"message": "视图缩放"
|
||||
},
|
||||
"BUTTON": {
|
||||
"description": "",
|
||||
"message": "\"按钮\""
|
||||
},
|
||||
"DIRECTION": {
|
||||
"description": "Direction",
|
||||
"message": "\"目录\""
|
||||
},
|
||||
"GROUP_GENERAL_VIEW_CONTROLS": {
|
||||
"description": "Header for the GeneralViewControls input group.",
|
||||
"message": "通用视角控制"
|
||||
|
@ -170,6 +178,10 @@
|
|||
"description": "Header for the Weapons input group.",
|
||||
"message": "武器"
|
||||
},
|
||||
"HAT": {
|
||||
"description": "Hat switch: Is the top button on a joystick",
|
||||
"message": "\"帽子\""
|
||||
},
|
||||
"PAGE_GENERAL": {
|
||||
"description": "Header for the General input page.",
|
||||
"message": "常规控制"
|
||||
|
@ -217,5 +229,17 @@
|
|||
"TEXT_KEY_POSITIVE": {
|
||||
"description": "Indicates the positive half of a key-binding pair.",
|
||||
"message": "正面"
|
||||
},
|
||||
"X": {
|
||||
"description": "keybinding: x axis",
|
||||
"message": "X"
|
||||
},
|
||||
"Y": {
|
||||
"description": "keybinding: y axis",
|
||||
"message": "Y"
|
||||
},
|
||||
"Z": {
|
||||
"description": "keybinding: z axis",
|
||||
"message": "Z"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "اعادة"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "اعادة التوجية و التكبير"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Return to game"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Нулиране"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Нулирай Ориентацията и Мащабирането"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Върни се в играта"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reiniciar orientació i zoom"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Return to game"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset orientace a zoomu"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Návrat do hry"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Nulstil"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Nulstil Synspunkt og Zoom"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Return to game"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Zurücksetzen"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Ansicht und Zoom zurücksetzen"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Zurück zum Spiel"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset Orientation and Zoom"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Return to game"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset Orientation and Zoom"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Return to game"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset Orientation and Zoom"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Return to game"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Reiniciar"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reiniciar orientación y zoom"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Volver al juego"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Réinitialise l'orientation et le zoom"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Reprendre la partie"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Athshocraigh"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Athshocraigh an Treoshuíomh agus an Zúmáil"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Fill ar an gcluiche"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Ath-shuidhich"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Ath-shuidhich a' chomhair agus an sùm"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Till dhan gheama"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset Orientation and Zoom"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Return to game"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Alaphelyzet"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Nézet alaphelyzetbe"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Vissza"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset Orientation and Zoom"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Return to game"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Azzera"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reimposta Orientamento e Zoom"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Torna al gioco"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Perkrauti"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Atitaisyti kryptį ir priartinimą"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Grįžti į žaidimą"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset Orientation and Zoom"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Return to game"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Herinstellen Oriëntatie en Zoom"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Terug naar spel"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset orientacji i zbliżenia"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Powrót do gry"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Reiniciar"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reset Orientation and Zoom"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Return to game"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Reset"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Reiniciar Orientação e Zoom"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Voltar ao jogo"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Resetare"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Resetează Orientare și Focalizare"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Întoarcere în joc"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Сброс"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Камера по умолчанию"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Вернуться к игре"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Återställ"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Återställ orientering och zoom"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Återgå till spelet"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "Yeniden başlat"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "Yönelim ve Yakınlaştırmayı Sıfırla"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "Oyuna dön"
|
||||
|
|
|
@ -1643,6 +1643,10 @@
|
|||
"description": "",
|
||||
"message": "重置"
|
||||
},
|
||||
"RESET_ORIENTATION_AND_ZOOM": {
|
||||
"description": "",
|
||||
"message": "重置方向和缩放"
|
||||
},
|
||||
"RETURN_TO_GAME": {
|
||||
"description": "",
|
||||
"message": "返回游戏"
|
||||
|
|
|
@ -276,7 +276,7 @@ end
|
|||
|
||||
function Windows.edgeButtons.Show()
|
||||
-- view control buttons
|
||||
if mainMenuButton(icons.reset_view, lc.RESET_ORIENTATION_AND_ZOOM) then
|
||||
if mainMenuButton(icons.reset_view, lui.RESET_ORIENTATION_AND_ZOOM) then
|
||||
sectorView:ResetView()
|
||||
end
|
||||
mainMenuButton(icons.rotate_view, lui.ROTATE_VIEW)
|
||||
|
|
|
@ -15,12 +15,45 @@ local linput = Lang.GetResource("input-core")
|
|||
local ui = require 'pigui'
|
||||
local ModalWindow = require 'pigui.libs.modal-win'
|
||||
|
||||
local function l18n_key_from_id(str)
|
||||
return str:gsub("([^A-Z0-9_])([A-Z0-9])", "%1_%2"):upper()
|
||||
end
|
||||
|
||||
-- convert an axis binding style ID to a translation resource identifier
|
||||
local function localize_binding_id(str)
|
||||
-- TODO: avoid reading lines from the "Core" resource (lc)
|
||||
-- it's here to reuse old strings (keyboard bindings for maps in KeyBindings.inc.h)
|
||||
local jsonIndex = str:gsub("([^A-Z0-9_])([A-Z0-9])", "%1_%2"):upper()
|
||||
return rawget(linput, jsonIndex) or rawget(lc, jsonIndex) or error("NO_JSON: " .. jsonIndex)
|
||||
return rawget(linput, jsonIndex) or '[NO_JSON] '..jsonIndex
|
||||
end
|
||||
|
||||
local function get_binding_desc(bind)
|
||||
if not bind then return end
|
||||
local axis_names = { linput.X, linput.Y, linput.Z }
|
||||
local mouse_names = { linput.MOUSE_LMB, linput.MOUSE_MMB, linput.MOUSE_RMB }
|
||||
if bind.key then
|
||||
return Input.GetKeyName(bind.key)
|
||||
elseif bind.joystick and bind.hat then
|
||||
return Input.GetJoystickName(bind.joystick) .. linput.HAT .. bind.hat .. linput.DIRECTION .. bind.dir
|
||||
elseif bind.joystick and bind.button then
|
||||
return Input.GetJoystickName(bind.joystick) .. linput.BUTTON .. bind.button
|
||||
elseif bind.joystick and bind.axis then
|
||||
return (bind.direction < 0 and "-" or "") .. Input.GetJoystickName(bind.joystick) .. linput.AXIS .. (axis_names[bind.axis + 1] or tostring(bind.axis))
|
||||
elseif bind.mouse then
|
||||
return linput.MOUSE .. (mouse_names[bind.mouse + 1] or tostring(bind.mouse))
|
||||
end
|
||||
end
|
||||
|
||||
-- Get a localized name for a key chord to display on a binding
|
||||
local function get_chord_desc(chord)
|
||||
if not chord.enabled then return "" end
|
||||
|
||||
local str = get_binding_desc(chord.activator)
|
||||
local mod1 = chord.modifier1
|
||||
local mod2 = chord.modifier2
|
||||
|
||||
if mod1 then str = str .. " + " .. get_binding_desc(mod1) end
|
||||
if mod2 then str = str .. " + " .. get_binding_desc(mod2) end
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
local player = nil
|
||||
|
@ -41,7 +74,7 @@ local optionsWinSize = Vector2(ui.screenWidth * 0.4, ui.screenHeight * 0.6)
|
|||
local showTab = 'video'
|
||||
|
||||
local binding_pages
|
||||
local keyCaptureId
|
||||
local keyCaptureBind
|
||||
local keyCaptureNum
|
||||
|
||||
local function combo(label, selected, items, tooltip)
|
||||
|
@ -278,66 +311,46 @@ end
|
|||
|
||||
local captureBindingWindow
|
||||
captureBindingWindow = ModalWindow.New("CaptureBinding", function()
|
||||
local info
|
||||
|
||||
for _,page in pairs(binding_pages) do
|
||||
for _,group in pairs(page) do
|
||||
if group.id then
|
||||
for _,i in pairs(group) do
|
||||
if i.id == keyCaptureId then
|
||||
info = i
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local info = keyCaptureBind
|
||||
|
||||
ui.text(localize_binding_id(info.id))
|
||||
ui.text(lui.PRESS_A_KEY_OR_CONTROLLER_BUTTON)
|
||||
|
||||
if info.type == 'action' then
|
||||
local desc
|
||||
if keyCaptureNum == 1 then desc = info.bindingDescription1
|
||||
else desc = info.bindingDescription2 end
|
||||
desc = desc or '<None>'
|
||||
ui.text(desc)
|
||||
if info.type == 'Action' then
|
||||
local desc = keyCaptureNum == 1 and info.binding or info.binding2
|
||||
ui.text(desc.enabled and get_chord_desc(desc) or '<None>')
|
||||
|
||||
local bindingKey = Engine.pigui.GetKeyBinding()
|
||||
local setBinding = false
|
||||
if(bindingKey and keyCaptureNum==1 and bindingKey~=info.binding1) or (bindingKey and keyCaptureNum==2 and bindingKey~=info.binding2) then setBinding = true end
|
||||
|
||||
if setBinding and keyCaptureNum == 1 then Input.SetActionBinding(info.id, bindingKey, info.binding2)
|
||||
elseif setBinding and keyCaptureNum==2 then Input.SetActionBinding(info.id, info.binding1, bindingKey)
|
||||
local set, bindingKey = Engine.pigui.GetKeyBinding()
|
||||
if set then
|
||||
if keyCaptureNum == 1 then info.binding = bindingKey
|
||||
else info.binding2 = bindingKey end
|
||||
end
|
||||
elseif info.type == 'axis' then
|
||||
elseif info.type == 'Axis' then
|
||||
local desc
|
||||
if keyCaptureNum == 1 then desc = info.axisDescription
|
||||
elseif keyCaptureNum == 2 then desc = info.positiveDescription
|
||||
else desc = info.negativeDescription end
|
||||
desc = desc or '<None>'
|
||||
if keyCaptureNum == 1 then
|
||||
desc = get_binding_desc(info.axis) or '<None>'
|
||||
else
|
||||
desc = keyCaptureNum == 2 and info.positive or info.negative
|
||||
desc = desc.enabled and get_chord_desc(desc) or '<None>'
|
||||
end
|
||||
ui.text(desc)
|
||||
|
||||
if keyCaptureNum == 1 then
|
||||
local bindingAxis = Engine.pigui.GetAxisBinding()
|
||||
|
||||
if bindingAxis and bindingAxis~=info.axis then
|
||||
Input.SetAxisBinding(info.id, bindingAxis, info.positive, info.negative)
|
||||
end
|
||||
local set, bindingAxis = Engine.pigui.GetAxisBinding()
|
||||
if set then info.axis = bindingAxis end
|
||||
elseif keyCaptureNum == 2 then
|
||||
local bindingKey = Engine.pigui.GetKeyBinding()
|
||||
|
||||
if bindingKey and bindingKey ~= info.positive then
|
||||
Input.SetAxisBinding(info.id, info.axis, bindingKey, info.negative)
|
||||
end
|
||||
local set, bindingKey = Engine.pigui.GetKeyBinding()
|
||||
if set then info.positive = bindingKey end
|
||||
else
|
||||
local bindingKey = Engine.pigui.GetKeyBinding()
|
||||
if bindingKey and bindingKey ~= info.negative then
|
||||
Input.SetAxisBinding(info.id, info.axis, info.positive, bindingKey)
|
||||
end
|
||||
local set, bindingKey = Engine.pigui.GetKeyBinding()
|
||||
if set then info.negative = bindingKey end
|
||||
end
|
||||
end
|
||||
|
||||
optionTextButton(lui.OK, nil, true, function() captureBindingWindow:close() end)
|
||||
optionTextButton(lui.OK, nil, true, function()
|
||||
Input.SaveBinding(info)
|
||||
captureBindingWindow:close()
|
||||
end)
|
||||
end, function (self, drawPopupFn)
|
||||
ui.setNextWindowPosCenter('Always')
|
||||
ui.withStyleColorsAndVars({["PopupBg"] = Color(20, 20, 80, 230)}, {WindowBorderSize = 1}, drawPopupFn)
|
||||
|
@ -394,22 +407,24 @@ local function showLanguageOptions()
|
|||
end
|
||||
|
||||
local function actionBinding(info)
|
||||
local bindings = { info.binding1, info.binding2 }
|
||||
local descs = { info.bindingDescription1, info.bindingDescription2 }
|
||||
local descs = {
|
||||
get_chord_desc(info.binding),
|
||||
get_chord_desc(info.binding2)
|
||||
}
|
||||
|
||||
if (ui.collapsingHeader(localize_binding_id(info.id), {})) then
|
||||
ui.columns(3,"##bindings",false)
|
||||
ui.nextColumn()
|
||||
ui.text(linput.TEXT_BINDING)
|
||||
bindingTextButton((descs[1] or '')..'##'..info.id..'1', (descs[1] or ''), true, function()
|
||||
keyCaptureId = info.id
|
||||
keyCaptureBind = info
|
||||
keyCaptureNum = 1
|
||||
captureBindingWindow:open()
|
||||
end)
|
||||
ui.nextColumn()
|
||||
ui.text(linput.TEXT_ALT_BINDING)
|
||||
bindingTextButton((descs[2] or '')..'##'..info.id..'2', (descs[2] or ''), true, function()
|
||||
keyCaptureId = info.id
|
||||
keyCaptureBind = info
|
||||
keyCaptureNum = 2
|
||||
captureBindingWindow:open()
|
||||
end)
|
||||
|
@ -418,51 +433,38 @@ local function actionBinding(info)
|
|||
end
|
||||
|
||||
local function axisBinding(info)
|
||||
local bindings = { info.axis, info.positive, info.negative }
|
||||
local descs = { info.axisDescription, info.positiveDescription, info.negativeDescription }
|
||||
local axis, positive, negative = info.axis, info.positive, info.negative
|
||||
local descs = { get_binding_desc(axis), get_chord_desc(positive), get_chord_desc(negative) }
|
||||
|
||||
if (ui.collapsingHeader(localize_binding_id(info.id), {})) then
|
||||
ui.columns(3,"##axisjoybindings",false)
|
||||
ui.text("Axis:")
|
||||
ui.nextColumn()
|
||||
bindingTextButton((descs[1] or '')..'##'..info.id..'axis', (descs[1] or ''), true, function()
|
||||
keyCaptureId = info.id
|
||||
keyCaptureBind = info
|
||||
keyCaptureNum = 1
|
||||
captureBindingWindow:open()
|
||||
end)
|
||||
ui.nextColumn()
|
||||
if info.axis then
|
||||
local c, inverted, deadzone, sensitivity = nil, info.axis:sub(1,1) == "-",
|
||||
tonumber(info.axis:match"/DZ(%d+%.%d*)" or 0) * 100,
|
||||
tonumber(info.axis:match"/E(%d+%.%d*)" or 1) * 100
|
||||
local axis = info.axis:match("Joy[0-9a-f]+/Axis%d+")
|
||||
local function set_axis()
|
||||
local _ax = (inverted and "-" or "") .. axis .. "/DZ" .. deadzone / 100.0 .. "/E" .. sensitivity / 100.0
|
||||
Input.SetAxisBinding(info.id, _ax, info.positive, info.negative)
|
||||
end
|
||||
if axis then
|
||||
local c, inverted = nil, axis.direction < 0
|
||||
c,inverted = ui.checkbox("Inverted##"..info.id, inverted, linput.TEXT_INVERT_AXIS)
|
||||
set_axis()
|
||||
ui.nextColumn()
|
||||
ui.nextColumn()
|
||||
c, deadzone = slider("Deadzone##"..info.id, deadzone, 0, 100, linput.TEXT_AXIS_DEADZONE)
|
||||
set_axis()
|
||||
ui.nextColumn()
|
||||
c, sensitivity = slider("Sensitivity##"..info.id, sensitivity, 0, 100, linput.TEXT_AXIS_SENSITIVITY)
|
||||
set_axis()
|
||||
if c then axis.direction = inverted and -1 or 1; info.axis = axis end
|
||||
end
|
||||
-- new row
|
||||
ui.nextColumn()
|
||||
ui.columns(3,"##axiskeybindings",false)
|
||||
ui.text(linput.TEXT_KEY_BINDINGS)
|
||||
ui.nextColumn()
|
||||
ui.text(linput.TEXT_KEY_POSITIVE)
|
||||
bindingTextButton((descs[2] or '')..'##'..info.id..'positive', (descs[2] or ''), true, function()
|
||||
keyCaptureId = info.id
|
||||
keyCaptureBind = info
|
||||
keyCaptureNum = 2
|
||||
captureBindingWindow:open()
|
||||
end)
|
||||
ui.nextColumn()
|
||||
ui.text(linput.TEXT_KEY_NEGATIVE)
|
||||
bindingTextButton((descs[3] or '')..'##'..info.id..'negative', (descs[3] or ''), true, function()
|
||||
keyCaptureId = info.id
|
||||
keyCaptureBind = info
|
||||
keyCaptureNum = 3
|
||||
captureBindingWindow:open()
|
||||
end)
|
||||
|
@ -475,7 +477,7 @@ local function showControlsOptions()
|
|||
|
||||
local mouseYInvert = Input.GetMouseYInverted()
|
||||
local joystickEnabled = Input.GetJoystickEnabled()
|
||||
binding_pages = Input.GetBindings()
|
||||
binding_pages = Input.GetBindingPages()
|
||||
local c
|
||||
|
||||
c,mouseYInvert = checkbox(lui.INVERT_MOUSE_Y, mouseYInvert)
|
||||
|
@ -490,22 +492,26 @@ local function showControlsOptions()
|
|||
ui.text(localize_binding_id("Page" .. page.id))
|
||||
end)
|
||||
ui.separator()
|
||||
Engine.pigui.PushID(page.id)
|
||||
for _,group in ipairs(page) do
|
||||
if group.id then
|
||||
Engine.pigui.PushID(group.id)
|
||||
if _ > 1 then ui.text '' end
|
||||
ui.withFont(pionillium.medium.name, bindingGroupFontSize, function()
|
||||
ui.text(localize_binding_id("Group" .. group.id))
|
||||
end)
|
||||
ui.separator()
|
||||
for _,info in ipairs(group) do
|
||||
if info.type == 'action' then
|
||||
actionBinding(info)
|
||||
elseif info.type == 'axis' then
|
||||
axisBinding(info)
|
||||
for _,binding in ipairs(group) do
|
||||
if binding.type == 'Action' then
|
||||
actionBinding(binding)
|
||||
elseif binding.type == 'Axis' then
|
||||
axisBinding(binding)
|
||||
end
|
||||
end
|
||||
Engine.pigui.PopID()
|
||||
end
|
||||
end
|
||||
Engine.pigui.PopID()
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ local Windows = {
|
|||
|
||||
function Windows.edgeButtons.Show()
|
||||
-- view control buttons
|
||||
if ui.coloredSelectedIconButton(icons.reset_view, mainButtonSize, false, mainButtonFramePadding, svColor.BUTTON_ACTIVE, svColor.BUTTON_INK, lc.RESET_ORIENTATION_AND_ZOOM) then
|
||||
if ui.coloredSelectedIconButton(icons.reset_view, mainButtonSize, false, mainButtonFramePadding, svColor.BUTTON_ACTIVE, svColor.BUTTON_INK, luc.RESET_ORIENTATION_AND_ZOOM) then
|
||||
systemView:SetVisibility("RESET_VIEW")
|
||||
end
|
||||
ui.coloredSelectedIconButton(icons.rotate_view, mainButtonSize, false, mainButtonFramePadding, svColor.BUTTON_ACTIVE, svColor.BUTTON_INK, luc.ROTATE_VIEW)
|
||||
|
|
|
@ -298,7 +298,7 @@ ui.registerHandler('game', function(delta_t)
|
|||
if not ui.optionsWindow.isOpen then
|
||||
Game.SetTimeAcceleration("paused")
|
||||
ui.optionsWindow:open()
|
||||
Input.DisableBindings()
|
||||
Input.EnableBindings(false)
|
||||
else
|
||||
ui.optionsWindow:close()
|
||||
if not ui.optionsWindow.isOpen then
|
||||
|
|
|
@ -15,8 +15,8 @@ def write_translation_file(path, data):
|
|||
with open(path, 'w', encoding='utf-8') as fl:
|
||||
json.dump(data, fl,
|
||||
ensure_ascii=False,
|
||||
indent=3,
|
||||
separators=(',',' : '),
|
||||
indent=2,
|
||||
separators=(',',': '),
|
||||
sort_keys=True)
|
||||
fl.write('\n')
|
||||
|
||||
|
|
|
@ -58,6 +58,33 @@ namespace AnimationCurves {
|
|||
return 0.5 * (1.0 - std::cos(p * M_PI));
|
||||
}
|
||||
|
||||
// Based on http://blog.moagrius.com/actionscript/jsas-understanding-easing/
|
||||
// and observations from Godot Engine and Star Citizen
|
||||
// This supports four different easing functions encoded in a single float:
|
||||
// e == 1.0|-1.0: linear easing, returns p
|
||||
// e > 1.0: in-quadratic, in-cubic etc. for e = 2.0, e = 3.0 ...
|
||||
// e < 1.0: out-quadratic, out-cubic etc. for e = 0.5, e = 0.33_ ...
|
||||
// e == 0.0: returns zero
|
||||
// e > -1.0: reverse inout-quadratic, inout-cubic for e = -0.5, e = -0.33_ ...
|
||||
// e < -1.0: inout-quadratic, inout-cubic etc. for e = -2.0, e = -3.0 ...
|
||||
inline float SmoothEasing(double p, double e)
|
||||
{
|
||||
// e > 0.0 = ease in or out / e < 0.0 = ease in-out
|
||||
if (e > 0.0) {
|
||||
// e < 1.0 = ease out / e > 1.0 = ease in
|
||||
return e < 1.0 ? (1.0 - pow(1.0 - p, 1.0 / e)) : (pow(p, e));
|
||||
} else if (e < 0) {
|
||||
// Ease in-out at arbirary exponents (the e term is negated to get positive exponent)
|
||||
float m = (p - 0.5) * 2.0;
|
||||
float t = p * 2.0;
|
||||
if (t < 1)
|
||||
return pow(t, -e) * 0.5;
|
||||
else
|
||||
return (1.0 - pow(1.0 - m, -e)) * 0.5 + 0.5;
|
||||
} else // completely flat at 0.0
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
} // namespace AnimationCurves
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "GameConfig.h"
|
||||
#include "FileSystem.h"
|
||||
#include "KeyBindings.h"
|
||||
|
||||
GameConfig::GameConfig(const map_string &override_)
|
||||
{
|
||||
|
@ -13,8 +12,8 @@ GameConfig::GameConfig(const map_string &override_)
|
|||
map["AMD_MESA_HACKS"] = "0";
|
||||
map["DisableSound"] = "0";
|
||||
map["StartFullscreen"] = "0";
|
||||
map["ScrWidth"] = "800";
|
||||
map["ScrHeight"] = "600";
|
||||
map["ScrWidth"] = "1280";
|
||||
map["ScrHeight"] = "720";
|
||||
map["UIScaleFactor"] = "1";
|
||||
map["DetailCities"] = "1";
|
||||
map["DetailPlanets"] = "1";
|
||||
|
@ -51,7 +50,7 @@ GameConfig::GameConfig(const map_string &override_)
|
|||
map["EnableGPUJobs"] = "1";
|
||||
map["GL3ForwardCompatible"] = "1";
|
||||
|
||||
Load();
|
||||
Read(FileSystem::userFiles, "config.ini");
|
||||
|
||||
for (auto i = override_.begin(); i != override_.end(); ++i) {
|
||||
const std::string &key = (*i).first;
|
||||
|
@ -59,13 +58,3 @@ GameConfig::GameConfig(const map_string &override_)
|
|||
map[key] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void GameConfig::Load()
|
||||
{
|
||||
Read(FileSystem::userFiles, "config.ini");
|
||||
}
|
||||
|
||||
bool GameConfig::Save()
|
||||
{
|
||||
return Write(FileSystem::userFiles, "config.ini");
|
||||
}
|
||||
|
|
|
@ -10,9 +10,6 @@ class GameConfig : public IniConfig {
|
|||
public:
|
||||
typedef std::map<std::string, std::string> map_string;
|
||||
GameConfig(const map_string &override_ = map_string());
|
||||
|
||||
void Load();
|
||||
bool Save();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
770
src/Input.cpp
770
src/Input.cpp
|
@ -2,44 +2,442 @@
|
|||
// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
|
||||
|
||||
#include "Input.h"
|
||||
#include "AnimationCurves.h"
|
||||
#include "GameConfig.h"
|
||||
#include "InputBindings.h"
|
||||
#include "Pi.h"
|
||||
#include "SDL.h"
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_joystick.h"
|
||||
#include "ui/Context.h"
|
||||
|
||||
#include <array>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
Input::Input(IniConfig *config) :
|
||||
using namespace Input;
|
||||
|
||||
namespace Input {
|
||||
std::vector<sigc::slot<void(Input::Manager *)>> *m_registrations;
|
||||
|
||||
std::vector<sigc::slot<void(Input::Manager *)>> &GetBindingRegistration()
|
||||
{
|
||||
return *m_registrations;
|
||||
}
|
||||
|
||||
bool AddBindingRegistrar(sigc::slot<void(Input::Manager *)> &&fn)
|
||||
{
|
||||
static std::vector<sigc::slot<void(Input::Manager *)>> registrations;
|
||||
m_registrations = ®istrations;
|
||||
|
||||
registrations.push_back(fn);
|
||||
return true;
|
||||
}
|
||||
} // namespace Input
|
||||
|
||||
/*
|
||||
|
||||
STATIC JOYSTICK HANDLING
|
||||
|
||||
*/
|
||||
|
||||
namespace Input {
|
||||
std::map<SDL_JoystickID, JoystickInfo> m_joysticks;
|
||||
|
||||
InputBindings::Action nullAction;
|
||||
InputBindings::Axis nullAxis;
|
||||
} // namespace Input
|
||||
|
||||
std::string Input::JoystickName(int joystick)
|
||||
{
|
||||
return m_joysticks[joystick].name;
|
||||
}
|
||||
|
||||
std::string Input::JoystickGUIDString(int joystick)
|
||||
{
|
||||
const int guidBufferLen = 33; // as documented by SDL
|
||||
char guidBuffer[guidBufferLen];
|
||||
|
||||
SDL_JoystickGetGUIDString(m_joysticks[joystick].guid, guidBuffer, guidBufferLen);
|
||||
return std::string(guidBuffer);
|
||||
}
|
||||
|
||||
// conveniance version of JoystickFromGUID below that handles the string mangling.
|
||||
int Input::JoystickFromGUIDString(const std::string &guid)
|
||||
{
|
||||
return JoystickFromGUIDString(guid.c_str());
|
||||
}
|
||||
|
||||
// conveniance version of JoystickFromGUID below that handles the string mangling.
|
||||
int Input::JoystickFromGUIDString(const char *guid)
|
||||
{
|
||||
return JoystickFromGUID(SDL_JoystickGetGUIDFromString(guid));
|
||||
}
|
||||
|
||||
// return the internal ID of the stated joystick guid.
|
||||
// returns -1 if we couldn't find the joystick in question.
|
||||
int Input::JoystickFromGUID(SDL_JoystickGUID guid)
|
||||
{
|
||||
const int guidLength = 16; // as defined
|
||||
for (auto pair : m_joysticks) {
|
||||
JoystickInfo &state = pair.second;
|
||||
if (0 == memcmp(state.guid.data, guid.data, guidLength)) {
|
||||
return static_cast<int>(pair.first);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_JoystickGUID Input::JoystickGUID(int joystick)
|
||||
{
|
||||
return m_joysticks[joystick].guid;
|
||||
}
|
||||
|
||||
static std::string saveAxisConfig(const Input::JoystickInfo::Axis &axis)
|
||||
{
|
||||
return fmt::format("DZ{:.1f} CV{:.1f}{}", axis.deadzone, axis.curve, (axis.zeroToOne ? " Half" : ""));
|
||||
}
|
||||
|
||||
static void loadAxisConfig(const std::string &str, Input::JoystickInfo::Axis &outAxis)
|
||||
{
|
||||
std::regex matcher("DZ([\\d\\.]+)\\s*(?:CV(-?[\\d\\.]+))?\\s*(Half)?", std::regex::icase);
|
||||
std::smatch match_results;
|
||||
if (std::regex_search(str, match_results, matcher)) {
|
||||
outAxis.deadzone = std::stof(match_results[1].str());
|
||||
outAxis.curve = match_results[2].matched ? std::stof(match_results[2].str()) : 1.0;
|
||||
outAxis.zeroToOne = match_results[3].matched;
|
||||
}
|
||||
outAxis.value = 0;
|
||||
}
|
||||
|
||||
void Input::InitJoysticks(IniConfig *config)
|
||||
{
|
||||
SDL_Init(SDL_INIT_JOYSTICK);
|
||||
|
||||
int joy_count = SDL_NumJoysticks();
|
||||
Output("Initializing joystick subsystem.\n");
|
||||
|
||||
for (int n = 0; n < joy_count; n++) {
|
||||
JoystickInfo state;
|
||||
|
||||
state.joystick = SDL_JoystickOpen(n);
|
||||
if (!state.joystick) {
|
||||
Warning("SDL_JoystickOpen(%i): %s\n", n, SDL_GetError());
|
||||
continue;
|
||||
}
|
||||
|
||||
state.name = SDL_JoystickName(state.joystick);
|
||||
state.guid = SDL_JoystickGetGUID(state.joystick);
|
||||
state.axes.resize(SDL_JoystickNumAxes(state.joystick));
|
||||
state.buttons.resize(SDL_JoystickNumButtons(state.joystick));
|
||||
state.hats.resize(SDL_JoystickNumHats(state.joystick));
|
||||
|
||||
std::array<char, 33> joystickGUIDName;
|
||||
SDL_JoystickGetGUIDString(state.guid, joystickGUIDName.data(), joystickGUIDName.size());
|
||||
Output("Found joystick '%s' (GUID: %s)\n", SDL_JoystickName(state.joystick), joystickGUIDName.data());
|
||||
Output(" - %ld axes, %ld buttons, %ld hats\n", state.axes.size(), state.buttons.size(), state.hats.size());
|
||||
|
||||
std::string joystickName = "Joystick." + std::string(joystickGUIDName.data());
|
||||
config->SetString(joystickName, "Name", state.name);
|
||||
|
||||
for (size_t i = 0; i < state.axes.size(); i++) {
|
||||
std::string axisName = "Axis" + std::to_string(i);
|
||||
if (!config->HasEntry(joystickName, axisName)) {
|
||||
config->SetString(joystickName, axisName, saveAxisConfig(state.axes[i]));
|
||||
continue;
|
||||
}
|
||||
|
||||
loadAxisConfig(config->String(joystickName, axisName, ""), state.axes[i]);
|
||||
Output(" - axis %ld: deadzone %.2f, curve: %.2f, half-axis mode: %b\n",
|
||||
i, state.axes[i].deadzone, state.axes[i].curve, state.axes[i].zeroToOne);
|
||||
}
|
||||
|
||||
SDL_JoystickID joyID = SDL_JoystickInstanceID(state.joystick);
|
||||
m_joysticks[joyID] = state;
|
||||
}
|
||||
|
||||
config->Save();
|
||||
}
|
||||
|
||||
std::map<SDL_JoystickID, JoystickInfo> &Input::GetJoysticks()
|
||||
{
|
||||
return m_joysticks;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
INPUT MANAGER INITIALIZATION
|
||||
|
||||
*/
|
||||
|
||||
Manager::Manager(IniConfig *config) :
|
||||
m_config(config),
|
||||
keyModState(0),
|
||||
mouseButton(),
|
||||
mouseMotion(),
|
||||
m_capturingMouse(false),
|
||||
joystickEnabled(true),
|
||||
mouseYInvert(false)
|
||||
mouseYInvert(false),
|
||||
m_enableBindings(true)
|
||||
{
|
||||
joystickEnabled = (m_config->Int("EnableJoystick")) ? true : false;
|
||||
mouseYInvert = (m_config->Int("InvertMouseY")) ? true : false;
|
||||
|
||||
InitJoysticks();
|
||||
Input::InitJoysticks(m_config);
|
||||
}
|
||||
|
||||
void Input::InitGame()
|
||||
void Manager::InitGame()
|
||||
{
|
||||
//reset input states
|
||||
keyState.clear();
|
||||
keyModState = 0;
|
||||
mouseButton.fill(0);
|
||||
mouseMotion.fill(0);
|
||||
for (std::map<SDL_JoystickID, JoystickState>::iterator stick = joysticks.begin(); stick != joysticks.end(); ++stick) {
|
||||
JoystickState &state = stick->second;
|
||||
|
||||
// Force a rebuild of key chords and modifier state
|
||||
m_frameListChanged = true;
|
||||
|
||||
for (auto &pair : Input::GetJoysticks()) {
|
||||
JoystickInfo &state = pair.second;
|
||||
std::fill(state.buttons.begin(), state.buttons.end(), false);
|
||||
std::fill(state.hats.begin(), state.hats.end(), 0);
|
||||
std::fill(state.axes.begin(), state.axes.end(), 0.f);
|
||||
for (auto &ax : state.axes) {
|
||||
ax.value = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Input::NewFrame()
|
||||
/*
|
||||
|
||||
BINDING AND INPUT FRAME HANDLING
|
||||
|
||||
*/
|
||||
|
||||
InputBindings::Action *InputFrame::AddAction(std::string id)
|
||||
{
|
||||
auto *action = manager->GetActionBinding(id);
|
||||
if (!action)
|
||||
throw std::runtime_error("Adding unknown action binding to InputFrame, id: " + id);
|
||||
|
||||
actions.push_back(action);
|
||||
return action;
|
||||
}
|
||||
|
||||
InputBindings::Axis *InputFrame::AddAxis(std::string id)
|
||||
{
|
||||
auto *axis = manager->GetAxisBinding(id);
|
||||
if (!axis)
|
||||
throw std::runtime_error("Adding unknown axis binding to an InputFrame, id: " + id);
|
||||
|
||||
axes.push_back(axis);
|
||||
return axis;
|
||||
}
|
||||
|
||||
bool Manager::PushInputFrame(InputFrame *frame)
|
||||
{
|
||||
if (HasInputFrame(frame)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_inputFrames.push_back(frame);
|
||||
frame->active = true;
|
||||
frame->onFrameAdded.emit(frame);
|
||||
m_frameListChanged = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
InputFrame *Manager::PopInputFrame()
|
||||
{
|
||||
if (m_inputFrames.size() > 0) {
|
||||
auto frame = m_inputFrames.back();
|
||||
m_inputFrames.pop_back();
|
||||
frame->active = false;
|
||||
frame->onFrameRemoved.emit(frame);
|
||||
m_frameListChanged = true;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Manager::RemoveInputFrame(InputFrame *frame)
|
||||
{
|
||||
auto it = std::find(m_inputFrames.begin(), m_inputFrames.end(), frame);
|
||||
if (it != m_inputFrames.end()) {
|
||||
m_inputFrames.erase(it);
|
||||
|
||||
// When an input frame is removed, its actions and axes are no longer active.
|
||||
for (auto *action : frame->actions) {
|
||||
if (action->m_active) {
|
||||
action->m_active = false;
|
||||
action->onReleased.emit();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto *axis : frame->axes) {
|
||||
if (axis->m_value != 0.0) {
|
||||
axis->m_value = 0.0;
|
||||
axis->onAxisValue.emit(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
frame->active = false;
|
||||
frame->onFrameRemoved.emit(frame);
|
||||
m_frameListChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
InputBindings::Action *Manager::AddActionBinding(std::string id, BindingGroup *group, InputBindings::Action &&binding)
|
||||
{
|
||||
// throw an error if we attempt to bind an action onto an already-bound axis in the same group.
|
||||
if (group->bindings.count(id) && group->bindings[id] != BindingGroup::ENTRY_ACTION)
|
||||
Error("Attempt to bind already-registered axis %s as an action.\n", id.c_str());
|
||||
|
||||
group->bindings[id] = BindingGroup::ENTRY_ACTION;
|
||||
|
||||
// Load from the config
|
||||
std::string config_str = m_config->String(id.c_str());
|
||||
if (!config_str.empty()) {
|
||||
nonstd::string_view str(config_str);
|
||||
str >> binding;
|
||||
}
|
||||
|
||||
return &(actionBindings[id] = binding);
|
||||
}
|
||||
|
||||
InputBindings::Axis *Manager::AddAxisBinding(std::string id, BindingGroup *group, InputBindings::Axis &&binding)
|
||||
{
|
||||
// throw an error if we attempt to bind an axis onto an already-bound action in the same group.
|
||||
if (group->bindings.count(id) && group->bindings[id] != BindingGroup::ENTRY_AXIS)
|
||||
Error("Attempt to bind already-registered action %s as an axis.\n", id.c_str());
|
||||
|
||||
group->bindings[id] = BindingGroup::ENTRY_AXIS;
|
||||
|
||||
// Load from the config
|
||||
std::string config_str = m_config->String(id.c_str());
|
||||
if (!config_str.empty()) {
|
||||
nonstd::string_view str(config_str);
|
||||
str >> binding;
|
||||
}
|
||||
|
||||
return &(axisBindings[id] = binding);
|
||||
}
|
||||
|
||||
InputBindings::Action *Manager::GetActionBinding(std::string id)
|
||||
{
|
||||
return actionBindings.count(id) ? &actionBindings[id] : &Input::nullAction;
|
||||
}
|
||||
|
||||
InputBindings::Axis *Manager::GetAxisBinding(std::string id)
|
||||
{
|
||||
return axisBindings.count(id) ? &axisBindings[id] : &Input::nullAxis;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
STATE MANAGEMENT
|
||||
|
||||
*/
|
||||
|
||||
bool Manager::GetBindingState(InputBindings::KeyBinding &key)
|
||||
{
|
||||
using Type = InputBindings::KeyBinding::Type;
|
||||
|
||||
switch (key.type) {
|
||||
case Type::Disabled:
|
||||
return false;
|
||||
case Type::KeyboardKey:
|
||||
return KeyState(key.keycode);
|
||||
case Type::JoystickButton:
|
||||
return JoystickButtonState(key.joystick.id, key.joystick.button);
|
||||
case Type::JoystickHat:
|
||||
return (JoystickHatState(key.joystick.id, key.joystick.hat) & key.joystick.button) == key.joystick.button;
|
||||
case Type::MouseButton:
|
||||
return MouseButtonState(key.mouse.button);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
float Manager::GetAxisState(InputBindings::JoyAxis &axis)
|
||||
{
|
||||
if (axis.direction == 0)
|
||||
return 0.0; // disabled
|
||||
|
||||
return JoystickAxisState(axis.joystickId, axis.axis) * float(axis.direction);
|
||||
}
|
||||
|
||||
bool Manager::GetModifierState(InputBindings::KeyChord *chord)
|
||||
{
|
||||
bool mod1 = chord->modifier1.Enabled() ? m_modifiers[chord->modifier1] : true;
|
||||
bool mod2 = chord->modifier2.Enabled() ? m_modifiers[chord->modifier2] : true;
|
||||
return mod1 && mod2;
|
||||
}
|
||||
|
||||
int Manager::JoystickButtonState(int joystick, int button)
|
||||
{
|
||||
if (!joystickEnabled) return 0;
|
||||
if (joystick < 0 || joystick >= int(GetJoysticks().size()))
|
||||
return 0;
|
||||
|
||||
if (button < 0 || button >= int(GetJoysticks()[joystick].buttons.size()))
|
||||
return 0;
|
||||
|
||||
return GetJoysticks()[joystick].buttons[button];
|
||||
}
|
||||
|
||||
int Manager::JoystickHatState(int joystick, int hat)
|
||||
{
|
||||
if (!joystickEnabled) return 0;
|
||||
if (joystick < 0 || joystick >= int(GetJoysticks().size()))
|
||||
return 0;
|
||||
|
||||
if (hat < 0 || hat >= int(GetJoysticks()[joystick].hats.size()))
|
||||
return 0;
|
||||
|
||||
return GetJoysticks()[joystick].hats[hat];
|
||||
}
|
||||
|
||||
float Manager::JoystickAxisState(int joystick, int axis)
|
||||
{
|
||||
if (!joystickEnabled) return 0;
|
||||
if (joystick < 0 || joystick >= int(GetJoysticks().size()))
|
||||
return 0;
|
||||
|
||||
if (axis < 0 || axis >= int(GetJoysticks()[joystick].axes.size()))
|
||||
return 0;
|
||||
|
||||
return GetJoysticks()[joystick].axes[axis].value;
|
||||
}
|
||||
|
||||
void Manager::SetJoystickEnabled(bool state)
|
||||
{
|
||||
joystickEnabled = state;
|
||||
if (m_enableConfigSaving) {
|
||||
m_config->SetInt("EnableJoystick", joystickEnabled);
|
||||
m_config->Save();
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::SetMouseYInvert(bool state)
|
||||
{
|
||||
mouseYInvert = state;
|
||||
if (m_enableConfigSaving) {
|
||||
m_config->SetInt("InvertMouseY", mouseYInvert);
|
||||
m_config->Save();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
FRAME AND EVENT HANDLING
|
||||
|
||||
*/
|
||||
|
||||
void Manager::NewFrame()
|
||||
{
|
||||
mouseMotion.fill(0);
|
||||
mouseWheel = 0;
|
||||
|
@ -56,94 +454,83 @@ void Input::NewFrame()
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InputResponse Input::InputFrame::ProcessSDLEvent(SDL_Event &event)
|
||||
{
|
||||
bool matched = false;
|
||||
|
||||
for (KeyBindings::ActionBinding *action : actions) {
|
||||
auto resp = action->CheckSDLEventAndDispatch(&event);
|
||||
if (resp == RESPONSE_MATCHED) return resp;
|
||||
matched = matched || resp > RESPONSE_NOMATCH;
|
||||
}
|
||||
|
||||
for (KeyBindings::AxisBinding *axis : axes) {
|
||||
auto resp = axis->CheckSDLEventAndDispatch(&event);
|
||||
if (resp == RESPONSE_MATCHED) return resp;
|
||||
matched = matched || resp > RESPONSE_NOMATCH;
|
||||
}
|
||||
|
||||
return matched ? RESPONSE_PASSTHROUGH : RESPONSE_NOMATCH;
|
||||
}
|
||||
|
||||
bool Input::PushInputFrame(Input::InputFrame *frame)
|
||||
{
|
||||
if (HasInputFrame(frame)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inputFrames.push_back(frame);
|
||||
frame->active = true;
|
||||
frame->onFrameAdded();
|
||||
return true;
|
||||
}
|
||||
|
||||
Input::InputFrame *Input::PopInputFrame()
|
||||
{
|
||||
if (inputFrames.size() > 0) {
|
||||
auto frame = inputFrames.back();
|
||||
inputFrames.pop_back();
|
||||
frame->active = false;
|
||||
frame->onFrameRemoved();
|
||||
return frame;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Input::RemoveInputFrame(Input::InputFrame *frame)
|
||||
{
|
||||
auto it = std::find(inputFrames.begin(), inputFrames.end(), frame);
|
||||
if (it != inputFrames.end()) {
|
||||
inputFrames.erase(it);
|
||||
frame->active = false;
|
||||
frame->onFrameRemoved();
|
||||
if (m_frameListChanged) {
|
||||
RebuildInputFrames();
|
||||
}
|
||||
}
|
||||
|
||||
KeyBindings::ActionBinding *Input::AddActionBinding(std::string id, BindingGroup *group, KeyBindings::ActionBinding binding)
|
||||
void Manager::RebuildInputFrames()
|
||||
{
|
||||
// throw an error if we attempt to bind an action onto an already-bound axis in the same group.
|
||||
if (group->bindings.count(id) && group->bindings[id] != BindingGroup::ENTRY_ACTION)
|
||||
Error("Attempt to bind already-registered axis %s as an action.\n", id.c_str());
|
||||
// Reset the list of active chords.
|
||||
m_chords.clear();
|
||||
m_activeActions.clear();
|
||||
m_activeAxes.clear();
|
||||
|
||||
group->bindings[id] = BindingGroup::ENTRY_ACTION;
|
||||
for (const auto *frame : reverse_container(m_inputFrames)) {
|
||||
|
||||
// Load from the config
|
||||
std::string config_str = m_config->String(id.c_str());
|
||||
if (config_str.length() > 0) binding.SetFromString(config_str);
|
||||
// Push all enabled key chords onto the key chord stack.
|
||||
for (auto *action : frame->actions) {
|
||||
if (!action->Enabled())
|
||||
continue;
|
||||
|
||||
return &(actionBindings[id] = binding);
|
||||
m_activeActions.push_back(action);
|
||||
assert(m_activeActions.back() == action);
|
||||
if (action->binding.Enabled())
|
||||
m_chords.push_back(&action->binding);
|
||||
|
||||
if (action->binding2.Enabled())
|
||||
m_chords.push_back(&action->binding2);
|
||||
}
|
||||
|
||||
for (auto *axis : frame->axes) {
|
||||
if (!axis->Enabled())
|
||||
continue;
|
||||
|
||||
m_activeAxes.push_back(axis);
|
||||
if (axis->positive.Enabled())
|
||||
m_chords.push_back(&axis->positive);
|
||||
|
||||
if (axis->negative.Enabled())
|
||||
m_chords.push_back(&axis->negative);
|
||||
}
|
||||
|
||||
// If we have a modal frame, it prevents input from passing through it to frames below
|
||||
if (frame->modal) { // modal frame blocks all inputs below it
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Group all chords with the same number of modifiers together, in descending order.
|
||||
std::sort(m_chords.begin(), m_chords.end(), [](const InputBindings::KeyChord *a, const InputBindings::KeyChord *b) { return *a < *b; });
|
||||
|
||||
// Reinitialize the modifier list, preserving key state.
|
||||
m_modifiers.clear();
|
||||
for (auto *chord : m_chords) {
|
||||
m_modifiers.emplace(chord->modifier1, GetBindingState(chord->modifier1));
|
||||
m_modifiers.emplace(chord->modifier2, GetBindingState(chord->modifier2));
|
||||
}
|
||||
}
|
||||
|
||||
KeyBindings::AxisBinding *Input::AddAxisBinding(std::string id, BindingGroup *group, KeyBindings::AxisBinding binding)
|
||||
static int8_t keys_in_chord(InputBindings::KeyChord *chord)
|
||||
{
|
||||
// throw an error if we attempt to bind an axis onto an already-bound action in the same group.
|
||||
if (group->bindings.count(id) && group->bindings[id] != BindingGroup::ENTRY_AXIS)
|
||||
Error("Attempt to bind already-registered action %s as an axis.\n", id.c_str());
|
||||
|
||||
group->bindings[id] = BindingGroup::ENTRY_AXIS;
|
||||
|
||||
// Load from the config
|
||||
std::string config_str = m_config->String(id.c_str());
|
||||
if (config_str.length() > 0) binding.SetFromString(config_str);
|
||||
|
||||
return &(axisBindings[id] = binding);
|
||||
return chord->activator.Enabled() + chord->modifier1.Enabled() + chord->modifier2.Enabled();
|
||||
}
|
||||
|
||||
void Input::HandleSDLEvent(SDL_Event &event)
|
||||
static float applyDeadzoneAndCurve(const JoystickInfo::Axis &axis, float value)
|
||||
{
|
||||
float absVal = std::fabs(value);
|
||||
float sign = value < 0.0 ? 1.0 : -1.0;
|
||||
if (absVal < axis.deadzone) return 0.0f;
|
||||
// renormalize value to 0..1 after deadzone
|
||||
absVal = (absVal - axis.deadzone) * (1.0 / (1.0 - axis.deadzone));
|
||||
return AnimationCurves::SmoothEasing(absVal, axis.curve) * sign;
|
||||
}
|
||||
|
||||
void Manager::HandleSDLEvent(SDL_Event &event)
|
||||
{
|
||||
using namespace InputBindings;
|
||||
|
||||
switch (event.type) {
|
||||
case SDL_KEYDOWN:
|
||||
// Set key state to "just pressed"
|
||||
|
@ -179,146 +566,139 @@ void Input::HandleSDLEvent(SDL_Event &event)
|
|||
mouseMotion[0] += event.motion.xrel;
|
||||
mouseMotion[1] += event.motion.yrel;
|
||||
break;
|
||||
case SDL_JOYAXISMOTION:
|
||||
if (!joysticks[event.jaxis.which].joystick)
|
||||
case SDL_JOYAXISMOTION: {
|
||||
if (!GetJoysticks()[event.jaxis.which].joystick)
|
||||
break;
|
||||
if (event.jaxis.value == -32768)
|
||||
joysticks[event.jaxis.which].axes[event.jaxis.axis] = 1.f;
|
||||
auto &axis = GetJoysticks()[event.jaxis.which].axes[event.jaxis.axis];
|
||||
if (axis.zeroToOne)
|
||||
// assume -32768 == 0.0 in half-axis mode (this is true for most controllers)
|
||||
axis.value = applyDeadzoneAndCurve(axis, (event.jaxis.value + 32768) / 65535.f);
|
||||
else
|
||||
joysticks[event.jaxis.which].axes[event.jaxis.axis] = -event.jaxis.value / 32767.f;
|
||||
break;
|
||||
axis.value = applyDeadzoneAndCurve(axis, (event.jaxis.value == -32768 ? -1.f : event.jaxis.value / 32767.f));
|
||||
} break;
|
||||
case SDL_JOYBUTTONUP:
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
if (!joysticks[event.jaxis.which].joystick)
|
||||
if (!GetJoysticks()[event.jaxis.which].joystick)
|
||||
break;
|
||||
joysticks[event.jbutton.which].buttons[event.jbutton.button] = event.jbutton.state != 0;
|
||||
GetJoysticks()[event.jbutton.which].buttons[event.jbutton.button] = event.jbutton.state != 0;
|
||||
break;
|
||||
case SDL_JOYHATMOTION:
|
||||
if (!joysticks[event.jaxis.which].joystick)
|
||||
if (!GetJoysticks()[event.jaxis.which].joystick)
|
||||
break;
|
||||
joysticks[event.jhat.which].hats[event.jhat.hat] = event.jhat.value;
|
||||
GetJoysticks()[event.jhat.which].hats[event.jhat.hat] = event.jhat.value;
|
||||
break;
|
||||
default:
|
||||
// Don't process non-input events any further.
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it = inputFrames.rbegin(); it != inputFrames.rend(); it++) {
|
||||
auto *inputFrame = *it;
|
||||
auto resp = inputFrame->ProcessSDLEvent(event);
|
||||
if (resp == RESPONSE_MATCHED) break;
|
||||
// if bindings are disabled, don't process the event any further
|
||||
if (!m_enableBindings)
|
||||
return;
|
||||
|
||||
// Update the modifier status from this event
|
||||
for (auto &pair : m_modifiers) {
|
||||
auto r = pair.first.Matches(event);
|
||||
if (r != Response::Ignored) {
|
||||
pair.second = r == Response::Pressed ? true : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Input::InitJoysticks()
|
||||
{
|
||||
SDL_Init(SDL_INIT_JOYSTICK);
|
||||
|
||||
int joy_count = SDL_NumJoysticks();
|
||||
Output("Initializing joystick subsystem.\n");
|
||||
for (int n = 0; n < joy_count; n++) {
|
||||
JoystickState state;
|
||||
|
||||
state.joystick = SDL_JoystickOpen(n);
|
||||
if (!state.joystick) {
|
||||
Warning("SDL_JoystickOpen(%i): %s\n", n, SDL_GetError());
|
||||
// If the event matches one of the key chords we care about, update that chord
|
||||
int num_keys_in_chord = 0;
|
||||
for (auto *chord : m_chords) {
|
||||
Response activator = chord->activator.Matches(event);
|
||||
if (activator == Response::Ignored)
|
||||
continue;
|
||||
}
|
||||
|
||||
state.guid = SDL_JoystickGetGUID(state.joystick);
|
||||
state.axes.resize(SDL_JoystickNumAxes(state.joystick));
|
||||
state.buttons.resize(SDL_JoystickNumButtons(state.joystick));
|
||||
state.hats.resize(SDL_JoystickNumHats(state.joystick));
|
||||
if (chord->IsActive()) {
|
||||
// Another press event came in for a key that's currently pressed right now.
|
||||
// This should be sufficiently rare that it won't be happening.
|
||||
if (activator == Response::Pressed)
|
||||
break;
|
||||
else { // clear the active state, continue processing the release event
|
||||
chord->m_active = false;
|
||||
// in case of a press-release sequence in the same frame, make sure to properly send updates.
|
||||
chord->m_queuedEvents |= 2;
|
||||
}
|
||||
} else {
|
||||
// Key-release event for a non-active chord. Don't handle it, but pass it on so
|
||||
// another key chord (with fewer / different modifiers) can handle it.
|
||||
if (activator == Response::Released)
|
||||
continue;
|
||||
|
||||
std::array<char, 33> joystickGUIDName;
|
||||
SDL_JoystickGetGUIDString(state.guid, joystickGUIDName.data(), joystickGUIDName.size());
|
||||
Output("Found joystick '%s' (GUID: %s)\n", SDL_JoystickName(state.joystick), joystickGUIDName.data());
|
||||
Output(" - %ld axes, %ld buttons, %ld hats\n", state.axes.size(), state.buttons.size(), state.hats.size());
|
||||
// Break here to prevent CTRL+ALT+X from activating <CTRL>+X / <ALT>+X / <NONE>+X
|
||||
// when there's a CTRL+ALT+X binding
|
||||
if (keys_in_chord(chord) < num_keys_in_chord)
|
||||
break;
|
||||
|
||||
SDL_JoystickID joyID = SDL_JoystickInstanceID(state.joystick);
|
||||
joysticks[joyID] = state;
|
||||
}
|
||||
}
|
||||
|
||||
std::string Input::JoystickName(int joystick)
|
||||
{
|
||||
return std::string(SDL_JoystickName(joysticks[joystick].joystick));
|
||||
}
|
||||
|
||||
std::string Input::JoystickGUIDString(int joystick)
|
||||
{
|
||||
const int guidBufferLen = 33; // as documented by SDL
|
||||
char guidBuffer[guidBufferLen];
|
||||
|
||||
SDL_JoystickGetGUIDString(joysticks[joystick].guid, guidBuffer, guidBufferLen);
|
||||
return std::string(guidBuffer);
|
||||
}
|
||||
|
||||
// conveniance version of JoystickFromGUID below that handles the string mangling.
|
||||
int Input::JoystickFromGUIDString(const std::string &guid)
|
||||
{
|
||||
return JoystickFromGUIDString(guid.c_str());
|
||||
}
|
||||
|
||||
// conveniance version of JoystickFromGUID below that handles the string mangling.
|
||||
int Input::JoystickFromGUIDString(const char *guid)
|
||||
{
|
||||
return JoystickFromGUID(SDL_JoystickGetGUIDFromString(guid));
|
||||
}
|
||||
|
||||
// return the internal ID of the stated joystick guid.
|
||||
// returns -1 if we couldn't find the joystick in question.
|
||||
int Input::JoystickFromGUID(SDL_JoystickGUID guid)
|
||||
{
|
||||
const int guidLength = 16; // as defined
|
||||
for (std::map<SDL_JoystickID, JoystickState>::iterator stick = joysticks.begin(); stick != joysticks.end(); ++stick) {
|
||||
JoystickState &state = stick->second;
|
||||
if (0 == memcmp(state.guid.data, guid.data, guidLength)) {
|
||||
return static_cast<int>(stick->first);
|
||||
bool mod1 = chord->modifier1.Enabled() ? m_modifiers[chord->modifier1] : true;
|
||||
bool mod2 = chord->modifier2.Enabled() ? m_modifiers[chord->modifier2] : true;
|
||||
if (mod1 && mod2) {
|
||||
// Modifiers are pressed, we can activate the chord.
|
||||
chord->m_active = true;
|
||||
// in the case of a press-release in the same frame, make sure to properly send updates
|
||||
chord->m_queuedEvents |= 1;
|
||||
// all copies of this chord should be notified, but don't propagate to chords with fewer modifiers
|
||||
num_keys_in_chord = keys_in_chord(chord);
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_JoystickGUID Input::JoystickGUID(int joystick)
|
||||
void Manager::DispatchEvents()
|
||||
{
|
||||
return joysticks[joystick].guid;
|
||||
// Chords which have had their modifier keys released this frame get updated all at once
|
||||
for (auto *chord : m_chords) {
|
||||
if (chord->IsActive() && !GetModifierState(chord)) {
|
||||
chord->m_active = false;
|
||||
chord->m_queuedEvents |= 2;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto *action : m_activeActions) {
|
||||
// if we have queued events for this binding, make sure to
|
||||
uint8_t queued = action->binding.m_queuedEvents | action->binding2.m_queuedEvents;
|
||||
if (queued) {
|
||||
bool wasActive = action->m_active;
|
||||
action->m_active = action->binding.IsActive() || action->binding2.IsActive();
|
||||
|
||||
// if at least one of the bindings was pressed this frame and the action was not
|
||||
// previously active, call the pressed event
|
||||
if (queued & 1 && !wasActive)
|
||||
action->onPressed.emit();
|
||||
|
||||
// if at least one of the bindings was released this frame but are not pressed currently,
|
||||
// call the released event
|
||||
if (queued & 2 && !action->m_active)
|
||||
action->onReleased.emit();
|
||||
|
||||
// clear queued events
|
||||
action->binding.m_queuedEvents = action->binding2.m_queuedEvents = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto *axis : m_activeAxes) {
|
||||
float value = GetAxisState(axis->axis);
|
||||
|
||||
value += axis->positive.IsActive();
|
||||
value -= axis->negative.IsActive();
|
||||
|
||||
value = Clamp(value, -1.0f, 1.0f);
|
||||
if (value != 0.0 || axis->m_value != 0.0) {
|
||||
axis->m_value = value;
|
||||
axis->onAxisValue.emit(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Input::JoystickButtonState(int joystick, int button)
|
||||
{
|
||||
if (!joystickEnabled) return 0;
|
||||
if (joystick < 0 || joystick >= int(joysticks.size()))
|
||||
return 0;
|
||||
/*
|
||||
|
||||
if (button < 0 || button >= int(joysticks[joystick].buttons.size()))
|
||||
return 0;
|
||||
INPUT DEVICE MANAGEMENT ROUTINES
|
||||
|
||||
return joysticks[joystick].buttons[button];
|
||||
}
|
||||
*/
|
||||
|
||||
int Input::JoystickHatState(int joystick, int hat)
|
||||
{
|
||||
if (!joystickEnabled) return 0;
|
||||
if (joystick < 0 || joystick >= int(joysticks.size()))
|
||||
return 0;
|
||||
|
||||
if (hat < 0 || hat >= int(joysticks[joystick].hats.size()))
|
||||
return 0;
|
||||
|
||||
return joysticks[joystick].hats[hat];
|
||||
}
|
||||
|
||||
float Input::JoystickAxisState(int joystick, int axis)
|
||||
{
|
||||
if (!joystickEnabled) return 0;
|
||||
if (joystick < 0 || joystick >= int(joysticks.size()))
|
||||
return 0;
|
||||
|
||||
if (axis < 0 || axis >= int(joysticks[joystick].axes.size()))
|
||||
return 0;
|
||||
|
||||
return joysticks[joystick].axes[axis];
|
||||
}
|
||||
|
||||
void Input::SetCapturingMouse(bool grabbed)
|
||||
void Manager::SetCapturingMouse(bool grabbed)
|
||||
{
|
||||
// early-out to avoid changing (possibly) expensive WM state
|
||||
if (grabbed == m_capturingMouse)
|
||||
|
|
183
src/Input.h
183
src/Input.h
|
@ -4,7 +4,7 @@
|
|||
#ifndef INPUT_H
|
||||
#define INPUT_H
|
||||
|
||||
#include "KeyBindings.h"
|
||||
#include "InputBindings.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -12,17 +12,23 @@
|
|||
|
||||
class IniConfig;
|
||||
|
||||
class Input {
|
||||
public:
|
||||
Input(IniConfig *config);
|
||||
void InitGame();
|
||||
void HandleSDLEvent(SDL_Event &ev);
|
||||
void NewFrame();
|
||||
// Macro to simplify registering input bindings in the codebase
|
||||
// TODO: evaluate if registering key bindings via lua / json file works better
|
||||
#define REGISTER_INPUT_BINDING(name) \
|
||||
namespace name##Input \
|
||||
{ \
|
||||
void Register(Input::Manager *input); \
|
||||
bool name##Registered = Input::AddBindingRegistrar(&Register); \
|
||||
} \
|
||||
void name##Input::Register(Input::Manager *input)
|
||||
|
||||
namespace Input {
|
||||
class Manager;
|
||||
|
||||
// The Page->Group->Binding system serves as a thin veneer for the UI to make
|
||||
// sane reasonings about how to structure the Options dialog.
|
||||
struct BindingGroup {
|
||||
enum EntryType {
|
||||
enum EntryType : uint8_t {
|
||||
ENTRY_ACTION,
|
||||
ENTRY_AXIS
|
||||
};
|
||||
|
@ -36,28 +42,99 @@ public:
|
|||
std::map<std::string, BindingGroup> groups;
|
||||
};
|
||||
|
||||
BindingPage *GetBindingPage(std::string id) { return &bindingPages[id]; }
|
||||
std::map<std::string, BindingPage> GetBindingPages() { return bindingPages; }
|
||||
|
||||
struct InputFrame {
|
||||
std::vector<KeyBindings::ActionBinding *> actions;
|
||||
std::vector<KeyBindings::AxisBinding *> axes;
|
||||
using Axis = InputBindings::Axis;
|
||||
using Action = InputBindings::Action;
|
||||
|
||||
bool active;
|
||||
InputFrame(Input::Manager *man, bool modal = false) :
|
||||
manager(man),
|
||||
modal(modal)
|
||||
{}
|
||||
|
||||
std::vector<Action *> actions;
|
||||
std::vector<Axis *> axes;
|
||||
|
||||
// Must set this to a valid Input::Manager instance before using AddAction / AddAxis
|
||||
Manager *manager = nullptr;
|
||||
bool active = false;
|
||||
bool modal = false;
|
||||
|
||||
// Call this at startup to register all the bindings associated with the frame.
|
||||
virtual void RegisterBindings(){};
|
||||
|
||||
// Called when the frame is added to the stack.
|
||||
virtual void onFrameAdded(){};
|
||||
sigc::signal<void(InputFrame *)> onFrameAdded;
|
||||
|
||||
// Called when the frame is removed from the stack.
|
||||
virtual void onFrameRemoved(){};
|
||||
sigc::signal<void(InputFrame *)> onFrameRemoved;
|
||||
|
||||
// Check the event against all the inputs in this frame.
|
||||
InputResponse ProcessSDLEvent(SDL_Event &event);
|
||||
Action *AddAction(std::string id);
|
||||
Axis *AddAxis(std::string id);
|
||||
};
|
||||
|
||||
struct JoystickInfo {
|
||||
struct Axis {
|
||||
float value = 0.0;
|
||||
float deadzone = 0.0;
|
||||
float curve = 1.0;
|
||||
bool zeroToOne = false;
|
||||
};
|
||||
|
||||
SDL_Joystick *joystick;
|
||||
SDL_JoystickGUID guid;
|
||||
std::string name;
|
||||
|
||||
std::vector<bool> buttons;
|
||||
std::vector<int> hats;
|
||||
|
||||
std::vector<Axis> axes;
|
||||
};
|
||||
|
||||
void InitJoysticks(IniConfig *config);
|
||||
std::map<SDL_JoystickID, JoystickInfo> &GetJoysticks();
|
||||
|
||||
// User display name for the joystick from the API/OS.
|
||||
std::string JoystickName(int joystick);
|
||||
// fetch the GUID for the named joystick
|
||||
SDL_JoystickGUID JoystickGUID(int joystick);
|
||||
std::string JoystickGUIDString(int joystick);
|
||||
|
||||
// reverse map a JoystickGUID to the actual internal ID.
|
||||
int JoystickFromGUIDString(const std::string &guid);
|
||||
int JoystickFromGUIDString(const char *guid);
|
||||
int JoystickFromGUID(SDL_JoystickGUID guid);
|
||||
|
||||
// We use SDL's joystick IDs because they're stable enough for the job.
|
||||
inline int JoystickFromID(SDL_JoystickID id) { return id; }
|
||||
|
||||
// An adapter to decouple input frame creation from input binding registration.
|
||||
// The functions registered via AddBindingRegistrar should be thread-safe and
|
||||
// should not depend on anything but the manager object being passed in.
|
||||
// The registrars are guaranteed to be called after static initialization has finished.
|
||||
std::vector<sigc::slot<void(Input::Manager *)>> &GetBindingRegistration();
|
||||
bool AddBindingRegistrar(sigc::slot<void(Input::Manager *)> &&fn);
|
||||
} // namespace Input
|
||||
|
||||
class Input::Manager {
|
||||
public:
|
||||
Manager(IniConfig *config);
|
||||
void InitGame();
|
||||
|
||||
// Call this at the start of a frame, before passing SDL events in
|
||||
void NewFrame();
|
||||
|
||||
// Call once per SDL event, handles updating all internal state
|
||||
void HandleSDLEvent(SDL_Event &ev);
|
||||
|
||||
// Call immediately after processing events, dispatches events to Action / Axis bindings.
|
||||
void DispatchEvents();
|
||||
|
||||
// When enable is false, this prevents the input system from writing to the config file.
|
||||
void EnableConfigSaving(bool enable) { m_enableConfigSaving = enable; }
|
||||
|
||||
BindingPage *GetBindingPage(std::string id) { return &bindingPages[id]; }
|
||||
std::map<std::string, BindingPage> GetBindingPages() { return bindingPages; }
|
||||
|
||||
// Pushes an InputFrame onto the input stack.
|
||||
bool PushInputFrame(InputFrame *frame);
|
||||
|
||||
|
@ -65,32 +142,33 @@ public:
|
|||
InputFrame *PopInputFrame();
|
||||
|
||||
// Get a read-only list of input frames.
|
||||
const std::vector<InputFrame *> &GetInputFrames() { return inputFrames; }
|
||||
const std::vector<InputFrame *> &GetInputFrames() { return m_inputFrames; }
|
||||
|
||||
// Check if a specific input frame is currently on the stack.
|
||||
bool HasInputFrame(InputFrame *frame)
|
||||
{
|
||||
return std::count(inputFrames.begin(), inputFrames.end(), frame) > 0;
|
||||
return std::count(m_inputFrames.begin(), m_inputFrames.end(), frame) > 0;
|
||||
}
|
||||
|
||||
// Remove an arbitrary input frame from the input stack.
|
||||
void RemoveInputFrame(InputFrame *frame);
|
||||
|
||||
// Inform the input system that a binding or frame was changed this frame.
|
||||
void MarkBindingsDirty() { m_frameListChanged = true; }
|
||||
|
||||
// Creates a new action binding, copying the provided binding.
|
||||
// The returned binding pointer points to the actual binding.
|
||||
KeyBindings::ActionBinding *AddActionBinding(std::string id, BindingGroup *group, KeyBindings::ActionBinding binding);
|
||||
KeyBindings::ActionBinding *GetActionBinding(std::string id)
|
||||
{
|
||||
return actionBindings.count(id) ? &actionBindings[id] : nullptr;
|
||||
}
|
||||
InputBindings::Action *AddActionBinding(std::string id, BindingGroup *group, InputBindings::Action &&binding);
|
||||
InputBindings::Action *GetActionBinding(std::string id);
|
||||
|
||||
// Creates a new axis binding, copying the provided binding.
|
||||
// The returned binding pointer points to the actual binding.
|
||||
KeyBindings::AxisBinding *AddAxisBinding(std::string id, BindingGroup *group, KeyBindings::AxisBinding binding);
|
||||
KeyBindings::AxisBinding *GetAxisBinding(std::string id)
|
||||
{
|
||||
return axisBindings.count(id) ? &axisBindings[id] : nullptr;
|
||||
}
|
||||
InputBindings::Axis *AddAxisBinding(std::string id, BindingGroup *group, InputBindings::Axis &&binding);
|
||||
InputBindings::Axis *GetAxisBinding(std::string id);
|
||||
|
||||
// Call EnableBindings() to temporarily disable handling input bindings while
|
||||
// you're recording a new input binding or are in a modal window.
|
||||
void EnableBindings(bool enabled) { m_enableBindings = enabled; }
|
||||
|
||||
bool KeyState(SDL_Keycode k) { return IsKeyDown(k); }
|
||||
|
||||
|
@ -110,30 +188,10 @@ public:
|
|||
float JoystickAxisState(int joystick, int axis);
|
||||
|
||||
bool IsJoystickEnabled() { return joystickEnabled; }
|
||||
void SetJoystickEnabled(bool state) { joystickEnabled = state; }
|
||||
void SetJoystickEnabled(bool state);
|
||||
|
||||
struct JoystickState {
|
||||
SDL_Joystick *joystick;
|
||||
SDL_JoystickGUID guid;
|
||||
std::vector<bool> buttons;
|
||||
std::vector<int> hats;
|
||||
std::vector<float> axes;
|
||||
};
|
||||
std::map<SDL_JoystickID, JoystickState> GetJoysticksState() { return joysticks; }
|
||||
|
||||
// User display name for the joystick from the API/OS.
|
||||
std::string JoystickName(int joystick);
|
||||
// fetch the GUID for the named joystick
|
||||
SDL_JoystickGUID JoystickGUID(int joystick);
|
||||
std::string JoystickGUIDString(int joystick);
|
||||
|
||||
// reverse map a JoystickGUID to the actual internal ID.
|
||||
int JoystickFromGUIDString(const std::string &guid);
|
||||
int JoystickFromGUIDString(const char *guid);
|
||||
int JoystickFromGUID(SDL_JoystickGUID guid);
|
||||
|
||||
void SetMouseYInvert(bool state) { mouseYInvert = state; }
|
||||
bool IsMouseYInvert() { return mouseYInvert; }
|
||||
void SetMouseYInvert(bool state);
|
||||
|
||||
int MouseButtonState(int button) { return mouseButton[button]; }
|
||||
void SetMouseButtonState(int button, bool state) { mouseButton[button] = state; }
|
||||
|
@ -162,9 +220,13 @@ public:
|
|||
sigc::signal<void, bool> onMouseWheel;
|
||||
|
||||
private:
|
||||
void InitJoysticks();
|
||||
void RebuildInputFrames();
|
||||
bool GetModifierState(InputBindings::KeyChord *key);
|
||||
bool GetBindingState(InputBindings::KeyBinding &key);
|
||||
float GetAxisState(InputBindings::JoyAxis &axis);
|
||||
|
||||
IniConfig *m_config;
|
||||
bool m_enableConfigSaving;
|
||||
|
||||
std::map<SDL_Keycode, uint8_t> keyState;
|
||||
int keyModState;
|
||||
|
@ -175,13 +237,20 @@ private:
|
|||
|
||||
bool joystickEnabled;
|
||||
bool mouseYInvert;
|
||||
std::map<SDL_JoystickID, JoystickState> joysticks;
|
||||
|
||||
std::map<std::string, BindingPage> bindingPages;
|
||||
std::map<std::string, KeyBindings::ActionBinding> actionBindings;
|
||||
std::map<std::string, KeyBindings::AxisBinding> axisBindings;
|
||||
std::map<std::string, InputBindings::Action> actionBindings;
|
||||
std::map<std::string, InputBindings::Axis> axisBindings;
|
||||
bool m_enableBindings;
|
||||
|
||||
std::vector<InputFrame *> inputFrames;
|
||||
std::vector<InputFrame *> m_inputFrames;
|
||||
bool m_frameListChanged;
|
||||
|
||||
std::vector<InputBindings::Action *> m_activeActions;
|
||||
std::vector<InputBindings::Axis *> m_activeAxes;
|
||||
|
||||
std::map<InputBindings::KeyBinding, bool> m_modifiers;
|
||||
std::vector<InputBindings::KeyChord *> m_chords;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,380 @@
|
|||
// Copyright © 2008-2020 Pioneer Developers. See AUTHORS.txt for details
|
||||
// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
|
||||
|
||||
#include "InputBindings.h"
|
||||
#include "Input.h"
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_joystick.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <regex>
|
||||
|
||||
using namespace InputBindings;
|
||||
|
||||
namespace Input {
|
||||
int JoystickFromGUIDString(const std::string &guid);
|
||||
std::string JoystickGUIDString(int joystickID);
|
||||
} // namespace Input
|
||||
|
||||
// Helper function to early-out in Matches()
|
||||
Response MatchType(const KeyBinding &k, const SDL_Event &ev)
|
||||
{
|
||||
using Type = KeyBinding::Type;
|
||||
|
||||
bool p = false;
|
||||
bool r = false;
|
||||
|
||||
switch (k.type) {
|
||||
case Type::Disabled:
|
||||
return Response::Ignored;
|
||||
case Type::KeyboardKey:
|
||||
p = ev.type == SDL_KEYDOWN;
|
||||
r = ev.type == SDL_KEYUP;
|
||||
break;
|
||||
case Type::JoystickButton:
|
||||
p = ev.type == SDL_JOYBUTTONDOWN;
|
||||
r = ev.type == SDL_JOYBUTTONUP;
|
||||
break;
|
||||
case Type::JoystickHat:
|
||||
if (ev.type == SDL_JOYHATMOTION) {
|
||||
p = (ev.jhat.value & k.joystick.button) == k.joystick.button;
|
||||
r = !p;
|
||||
}
|
||||
break;
|
||||
case Type::MouseButton:
|
||||
p = ev.type == SDL_MOUSEBUTTONDOWN;
|
||||
r = ev.type == SDL_MOUSEBUTTONUP;
|
||||
break;
|
||||
}
|
||||
|
||||
return p ? Response::Pressed : r ? Response::Released : Response::Ignored;
|
||||
}
|
||||
|
||||
Response KeyBinding::Matches(const SDL_Event &ev) const
|
||||
{
|
||||
Response r = MatchType(*this, ev);
|
||||
if (r == Response::Ignored)
|
||||
return r;
|
||||
|
||||
if (type == Type::KeyboardKey) {
|
||||
return (ev.key.keysym.sym == keycode) ? r : Response::Ignored;
|
||||
} else if (type == Type::JoystickButton) {
|
||||
bool cond = (joystick.id == ev.jbutton.which && joystick.button == ev.jbutton.button);
|
||||
return cond ? r : Response::Ignored;
|
||||
} else if (type == Type::JoystickHat) {
|
||||
bool cond = (joystick.id == ev.jhat.which && joystick.hat == ev.jhat.hat);
|
||||
return cond ? r : Response::Ignored;
|
||||
} else if (type == Type::MouseButton) {
|
||||
return (mouse.button == ev.button.button) ? r : Response::Ignored;
|
||||
}
|
||||
|
||||
return Response::Ignored;
|
||||
}
|
||||
|
||||
bool KeyBinding::operator==(const KeyBinding &rhs) const
|
||||
{
|
||||
if (type != rhs.type)
|
||||
return false;
|
||||
|
||||
if (type == Type::KeyboardKey)
|
||||
return keycode == rhs.keycode;
|
||||
else if (type == Type::JoystickButton)
|
||||
return joystick.id == rhs.joystick.id && joystick.button == rhs.joystick.button;
|
||||
else if (type == Type::JoystickHat)
|
||||
return joystick.id == rhs.joystick.id && joystick.hat == rhs.joystick.hat && joystick.button == rhs.joystick.button;
|
||||
else if (type == Type::MouseButton)
|
||||
return mouse.button == rhs.mouse.button;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
#define ret_if_different(val) \
|
||||
if (val != rhs.val) return val < rhs.val
|
||||
bool KeyBinding::operator<(const KeyBinding &rhs) const
|
||||
{
|
||||
ret_if_different(type);
|
||||
|
||||
switch (type) {
|
||||
case Type::KeyboardKey:
|
||||
ret_if_different(keycode);
|
||||
break;
|
||||
case Type::JoystickButton:
|
||||
ret_if_different(joystick.id);
|
||||
ret_if_different(joystick.button);
|
||||
break;
|
||||
case Type::JoystickHat:
|
||||
ret_if_different(joystick.id);
|
||||
ret_if_different(joystick.hat);
|
||||
ret_if_different(joystick.button);
|
||||
break;
|
||||
case Type::MouseButton:
|
||||
ret_if_different(mouse.button);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return this < &rhs;
|
||||
}
|
||||
#undef ret_if_different
|
||||
|
||||
Action &Action::operator=(const Action &rhs)
|
||||
{
|
||||
binding = rhs.binding;
|
||||
binding2 = rhs.binding2;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Axis &Axis::operator=(const Axis &rhs)
|
||||
{
|
||||
axis = rhs.axis;
|
||||
positive = rhs.positive;
|
||||
negative = rhs.negative;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// Config Loading
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
using smatch = std::match_results<nonstd::string_view::const_iterator>;
|
||||
static std::regex disabled_matcher("^disabled", std::regex::icase);
|
||||
|
||||
// Handle the fiddly bits of matching a regex and advancing the beginning of a string
|
||||
bool consumeMatch(nonstd::string_view &str, smatch &match_results, std::regex ®)
|
||||
{
|
||||
if (!std::regex_search(str.cbegin(), str.cend(), match_results, reg))
|
||||
return false;
|
||||
|
||||
str.remove_prefix(std::distance(str.cbegin(), match_results[0].second));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Key54 | JoyGUID/B3 JoyGUID/H4/2 | Mouse5
|
||||
// Less awful than iostreams, but still not elegant. That's C++ for you.
|
||||
// TODO: save joystick id->GUID mapping separately in the config file and
|
||||
// don't write them here to save space
|
||||
nonstd::string_view &InputBindings::operator>>(nonstd::string_view &str, KeyBinding &out)
|
||||
{
|
||||
static std::regex key_matcher("^Key(\\d+)");
|
||||
static std::regex joystick_matcher("^Joy([^/]{32})");
|
||||
static std::regex joystick_button("^/B(\\d+)");
|
||||
static std::regex joystick_hat("^/H(\\d+)/(\\d+)");
|
||||
static std::regex mouse_matcher("^Mouse(\\d+)");
|
||||
|
||||
const auto begin = str.cbegin();
|
||||
const auto end = str.cend();
|
||||
|
||||
// match_results[0].second should always point to the character after the
|
||||
// parsed key binding unless the value present could not be parsed.
|
||||
smatch match_results;
|
||||
if (std::regex_search(begin, end, match_results, key_matcher)) {
|
||||
out.type = KeyBinding::Type::KeyboardKey;
|
||||
out.keycode = std::stoi(match_results[1]);
|
||||
} else if (std::regex_search(begin, end, match_results, joystick_matcher)) {
|
||||
out.joystick.id = Input::JoystickFromGUIDString(match_results[1]);
|
||||
const auto start = match_results[0].second;
|
||||
if (std::regex_search(start, end, match_results, joystick_button)) {
|
||||
out.type = KeyBinding::Type::JoystickButton;
|
||||
out.joystick.button = std::stoi(match_results[1]);
|
||||
out.joystick.hat = 0;
|
||||
} else if (std::regex_search(start, end, match_results, joystick_hat)) {
|
||||
out.type = KeyBinding::Type::JoystickHat;
|
||||
out.joystick.hat = std::stoi(match_results[1]);
|
||||
out.joystick.button = std::stoi(match_results[2]);
|
||||
}
|
||||
} else if (std::regex_search(begin, end, match_results, mouse_matcher)) {
|
||||
out.type = KeyBinding::Type::MouseButton;
|
||||
out.mouse.button = std::stoi(match_results[1]);
|
||||
} else {
|
||||
out.type = KeyBinding::Type::Disabled;
|
||||
// consume the disabled text if present.
|
||||
std::regex_search(begin, end, match_results, disabled_matcher);
|
||||
}
|
||||
|
||||
// return a string view containing the rest of the string
|
||||
if (!match_results.empty())
|
||||
str.remove_prefix(std::distance(begin, match_results[0].second));
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
// Serialize a KeyBinding into the output stream.
|
||||
// Writes nothing if the binding is disabled
|
||||
std::ostream &InputBindings::operator<<(std::ostream &str, KeyBinding &in)
|
||||
{
|
||||
switch (in.type) {
|
||||
case KeyBinding::Type::KeyboardKey:
|
||||
return str << "Key" << in.keycode;
|
||||
case KeyBinding::Type::JoystickButton:
|
||||
return str << "Joy" << Input::JoystickGUIDString(in.joystick.id)
|
||||
<< "/B" << int(in.joystick.button);
|
||||
case KeyBinding::Type::JoystickHat:
|
||||
return str << "Joy" << Input::JoystickGUIDString(in.joystick.id)
|
||||
<< "/H" << int(in.joystick.hat) << "/" << int(in.joystick.button);
|
||||
case KeyBinding::Type::MouseButton:
|
||||
return str << "Mouse" << int(in.mouse.button);
|
||||
default:
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
// Match [-]JoyGUID/A4
|
||||
nonstd::string_view &InputBindings::operator>>(nonstd::string_view &str, JoyAxis &out)
|
||||
{
|
||||
static std::regex joy_matcher("^Joy([^/]{32})/A(\\d+)");
|
||||
auto begin = str.cbegin();
|
||||
|
||||
bool reverse = !str.empty() && str[0] == '-';
|
||||
if (reverse)
|
||||
++begin;
|
||||
|
||||
smatch match_results;
|
||||
if (std::regex_search(begin, str.cend(), match_results, joy_matcher)) {
|
||||
out.joystickId = Input::JoystickFromGUIDString(match_results[1]);
|
||||
out.axis = std::stoi(match_results[2]);
|
||||
out.direction = reverse ? -1 : 1;
|
||||
} else {
|
||||
std::regex_search(str.cbegin(), str.cend(), match_results, std::regex("^disabled"));
|
||||
out.direction = 0;
|
||||
}
|
||||
|
||||
if (!match_results.empty())
|
||||
str.remove_prefix(std::distance(str.cbegin(), match_results[0].second));
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
// [-]JoyGUID/A4
|
||||
std::ostream &InputBindings::operator<<(std::ostream &str, JoyAxis &in)
|
||||
{
|
||||
if (!in.Enabled())
|
||||
return str << "disabled";
|
||||
|
||||
return str << (in.direction < 0.0 ? "-Joy" : "Joy")
|
||||
<< Input::JoystickGUIDString(in.joystickId)
|
||||
<< "/A" << int(in.axis);
|
||||
}
|
||||
|
||||
// find a close paren, copy str into ret str, and return retstr
|
||||
// (for one-line failure case returns)
|
||||
nonstd::string_view &findCloseParen(nonstd::string_view &str, nonstd::string_view &retstr, smatch &match_results)
|
||||
{
|
||||
if (std::regex_search(str.cbegin(), str.cend(), match_results, std::regex("\\)")))
|
||||
str.remove_prefix(std::distance(str.cbegin(), match_results[0].second));
|
||||
|
||||
retstr = str;
|
||||
return retstr;
|
||||
}
|
||||
|
||||
// Parse KeyChord(Key53 + JoyGUID/B3 + Mouse1) | KeyChord(Mouse5)
|
||||
nonstd::string_view &InputBindings::operator>>(nonstd::string_view &str, KeyChord &out)
|
||||
{
|
||||
static std::regex key_chord("^KeyChord\\(\\s*");
|
||||
static std::regex plus_sign("^\\s*\\+\\s*");
|
||||
smatch match_results;
|
||||
|
||||
// Early-out for disabled key chord
|
||||
if (consumeMatch(str, match_results, disabled_matcher))
|
||||
return str;
|
||||
|
||||
// make a copy of the string view so we can nondestructively consume matches.
|
||||
nonstd::string_view iterstr = str;
|
||||
|
||||
// ensure we read the KeyChord( opening
|
||||
if (!consumeMatch(iterstr, match_results, key_chord))
|
||||
return str;
|
||||
|
||||
// read the activator KeyBinding
|
||||
iterstr >> out.activator;
|
||||
|
||||
// if the activator is disabled, early-out here.
|
||||
// if we don't have a following plus sign, discard everything to the next close-paren
|
||||
if (!out.activator.Enabled() || !consumeMatch(iterstr, match_results, plus_sign))
|
||||
return findCloseParen(iterstr, str, match_results);
|
||||
|
||||
// read the first modifier
|
||||
iterstr >> out.modifier1;
|
||||
|
||||
// ditto for the second modifier
|
||||
if (!out.modifier1.Enabled() || !consumeMatch(iterstr, match_results, plus_sign))
|
||||
return findCloseParen(iterstr, str, match_results);
|
||||
|
||||
iterstr >> out.modifier2;
|
||||
|
||||
return findCloseParen(iterstr, str, match_results);
|
||||
}
|
||||
|
||||
// KeyChord(Key54 + JoyGUID/B4 + JoyGUID/H1/3)
|
||||
std::ostream &InputBindings::operator<<(std::ostream &str, KeyChord &in)
|
||||
{
|
||||
if (!in.Enabled())
|
||||
return str << "disabled";
|
||||
|
||||
str << "KeyChord(" << in.activator;
|
||||
if (in.modifier1.Enabled()) {
|
||||
str << " + " << in.modifier1;
|
||||
if (in.modifier2.Enabled())
|
||||
str << " + " << in.modifier2;
|
||||
}
|
||||
str << ")";
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
nonstd::string_view &InputBindings::operator>>(nonstd::string_view &str, Axis &out)
|
||||
{
|
||||
static std::regex input_axis("^InputAxis\\(\\s*");
|
||||
static std::regex comma_sep("^\\s*,\\s*");
|
||||
smatch match_results;
|
||||
|
||||
auto iterstr = str;
|
||||
if (!consumeMatch(iterstr, match_results, input_axis))
|
||||
return str;
|
||||
iterstr >> out.axis;
|
||||
|
||||
if (!consumeMatch(iterstr, match_results, comma_sep))
|
||||
return findCloseParen(iterstr, str, match_results);
|
||||
|
||||
iterstr >> out.negative;
|
||||
|
||||
if (!consumeMatch(iterstr, match_results, comma_sep))
|
||||
return findCloseParen(iterstr, str, match_results);
|
||||
iterstr >> out.positive;
|
||||
|
||||
return findCloseParen(iterstr, str, match_results);
|
||||
}
|
||||
|
||||
// InputAxis(-JoyGUID/A3, KeyChord(Key32), KeyChord(Mouse5 + JoyGUID/H1/1))
|
||||
// InputAxis(disabled, disabled, disabled)
|
||||
std::ostream &InputBindings::operator<<(std::ostream &str, Axis &in)
|
||||
{
|
||||
return str << "InputAxis(" << in.axis << ", " << in.negative << ", " << in.positive << ")";
|
||||
}
|
||||
|
||||
nonstd::string_view &InputBindings::operator>>(nonstd::string_view &str, Action &out)
|
||||
{
|
||||
static std::regex input_action("^InputAction\\(\\s*");
|
||||
static std::regex comma_sep("^\\s*,\\s*");
|
||||
smatch match_results;
|
||||
|
||||
auto iterstr = str;
|
||||
if (!consumeMatch(iterstr, match_results, input_action))
|
||||
return str;
|
||||
iterstr >> out.binding;
|
||||
|
||||
if (!consumeMatch(iterstr, match_results, comma_sep))
|
||||
return findCloseParen(iterstr, str, match_results);
|
||||
iterstr >> out.binding2;
|
||||
|
||||
return findCloseParen(iterstr, str, match_results);
|
||||
}
|
||||
|
||||
// InputAction(KeyChord(Key53 + Mouse4), KeyChord(Mouse5 + JoyGUID/H1/1))
|
||||
// InputAction(disabled, disabled)
|
||||
std::ostream &InputBindings::operator<<(std::ostream &str, Action &in)
|
||||
{
|
||||
return str << "InputAction(" << in.binding << ", " << in.binding2 << ")";
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
// Copyright © 2008-2020 Pioneer Developers. See AUTHORS.txt for details
|
||||
// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DeleteEmitter.h"
|
||||
#include "nonstd/string_view.hpp"
|
||||
#include <SDL_events.h>
|
||||
#include <SDL_keycode.h>
|
||||
#include <sigc++/sigc++.h>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
namespace InputBindings {
|
||||
enum class Response {
|
||||
Ignored = 0,
|
||||
Pressed,
|
||||
Released
|
||||
};
|
||||
|
||||
struct KeyBinding {
|
||||
enum class Type : uint8_t {
|
||||
Disabled,
|
||||
KeyboardKey,
|
||||
JoystickButton,
|
||||
JoystickHat,
|
||||
MouseButton
|
||||
};
|
||||
|
||||
Type type = Type::Disabled;
|
||||
union {
|
||||
SDL_Keycode keycode = 0;
|
||||
struct {
|
||||
// 65536 possible IDs should be more than plenty, even with lots of hot-plug noise.
|
||||
uint16_t id;
|
||||
// if type = JoystickHat, this is the hat direction; otherwise it's the button index
|
||||
uint8_t button;
|
||||
uint8_t hat;
|
||||
} joystick;
|
||||
struct {
|
||||
uint8_t button;
|
||||
} mouse;
|
||||
};
|
||||
|
||||
KeyBinding() = default;
|
||||
|
||||
KeyBinding(SDL_Keycode k) :
|
||||
type(Type::KeyboardKey), keycode(k) {}
|
||||
|
||||
static KeyBinding JoystickButton(uint8_t joystickID, uint8_t button)
|
||||
{
|
||||
KeyBinding t;
|
||||
t.type = Type::JoystickButton;
|
||||
t.joystick = { joystickID, button, 0 };
|
||||
return t;
|
||||
}
|
||||
|
||||
static KeyBinding JoystickHat(uint8_t joystickID, uint8_t hat, uint8_t direction)
|
||||
{
|
||||
KeyBinding t;
|
||||
t.type = Type::JoystickHat;
|
||||
t.joystick = { joystickID, direction, hat };
|
||||
return t;
|
||||
}
|
||||
|
||||
static KeyBinding MouseButton(uint8_t mouseButton)
|
||||
{
|
||||
KeyBinding t;
|
||||
t.type = Type::MouseButton;
|
||||
t.mouse.button = mouseButton;
|
||||
return t;
|
||||
}
|
||||
|
||||
static KeyBinding FromEvent(SDL_Event &event);
|
||||
|
||||
bool Enabled() const { return type != Type::Disabled; }
|
||||
Response Matches(const SDL_Event &ev) const;
|
||||
|
||||
bool operator==(const KeyBinding &rhs) const;
|
||||
bool operator<(const KeyBinding &rhs) const;
|
||||
|
||||
// serialization
|
||||
friend nonstd::string_view &operator>>(nonstd::string_view &, KeyBinding &);
|
||||
friend std::ostream &operator<<(std::ostream &, KeyBinding &);
|
||||
};
|
||||
|
||||
struct JoyAxis {
|
||||
uint8_t joystickId;
|
||||
uint8_t axis;
|
||||
int8_t direction; // if 0, the axis is disabled
|
||||
|
||||
bool Enabled() const { return direction != 0; }
|
||||
|
||||
bool operator==(const JoyAxis &rhs) const
|
||||
{
|
||||
if (!direction && !rhs.direction)
|
||||
return true;
|
||||
|
||||
return joystickId == rhs.joystickId && axis == rhs.axis && direction == rhs.direction;
|
||||
}
|
||||
|
||||
// serialization
|
||||
friend nonstd::string_view &operator>>(nonstd::string_view &, JoyAxis &);
|
||||
friend std::ostream &operator<<(std::ostream &, JoyAxis &);
|
||||
};
|
||||
|
||||
struct KeyChord {
|
||||
KeyBinding activator;
|
||||
KeyBinding modifier1;
|
||||
KeyBinding modifier2;
|
||||
|
||||
KeyChord() = default;
|
||||
KeyChord(KeyBinding a, KeyBinding m1 = {}, KeyBinding m2 = {}) :
|
||||
activator(a),
|
||||
modifier1(m1),
|
||||
modifier2(m2)
|
||||
{}
|
||||
|
||||
bool IsActive() const { return Enabled() && m_active; }
|
||||
bool Enabled() const { return activator.Enabled(); }
|
||||
|
||||
bool operator==(const KeyChord &rhs) const
|
||||
{
|
||||
return activator == rhs.activator && modifier1 == rhs.modifier1 && modifier2 == rhs.modifier2;
|
||||
}
|
||||
bool operator!=(const KeyChord &rhs) const { return !(*this == rhs); }
|
||||
|
||||
// Groups chords by number of modifiers in descending order
|
||||
bool operator<(const KeyChord &rhs) const
|
||||
{
|
||||
return (modifier2.Enabled() && !rhs.modifier2.Enabled()) || (modifier1.Enabled() && !rhs.modifier2.Enabled());
|
||||
}
|
||||
|
||||
bool m_active = false;
|
||||
uint8_t m_queuedEvents = 0;
|
||||
|
||||
// serialization
|
||||
friend nonstd::string_view &operator>>(nonstd::string_view &, KeyChord &);
|
||||
friend std::ostream &operator<<(std::ostream &, KeyChord &);
|
||||
};
|
||||
|
||||
struct Action : public DeleteEmitter {
|
||||
KeyChord binding;
|
||||
KeyChord binding2;
|
||||
|
||||
Action() = default;
|
||||
Action(KeyChord b1, KeyChord b2 = {}) :
|
||||
binding(b1),
|
||||
binding2(b2)
|
||||
{}
|
||||
|
||||
// NOTE: sigc::signals cannot be copied, this function is for convenience to copy bindings only
|
||||
Action &operator=(const Action &rhs);
|
||||
|
||||
bool IsActive() { return m_active; }
|
||||
bool Enabled() { return binding.Enabled() || binding2.Enabled(); }
|
||||
|
||||
bool m_active = false;
|
||||
|
||||
sigc::signal<void> onPressed;
|
||||
sigc::signal<void> onReleased;
|
||||
|
||||
// serialization
|
||||
friend nonstd::string_view &operator>>(nonstd::string_view &, Action &);
|
||||
friend std::ostream &operator<<(std::ostream &, Action &);
|
||||
};
|
||||
|
||||
struct Axis : public DeleteEmitter {
|
||||
JoyAxis axis;
|
||||
KeyChord positive;
|
||||
KeyChord negative;
|
||||
|
||||
Axis() = default;
|
||||
Axis(JoyAxis a, KeyChord p = {}, KeyChord n = {}) :
|
||||
axis(a),
|
||||
positive(p),
|
||||
negative(n)
|
||||
{}
|
||||
|
||||
Axis(KeyChord p, KeyChord n = {}) :
|
||||
axis{},
|
||||
positive(p),
|
||||
negative(n)
|
||||
{}
|
||||
|
||||
// NOTE: sigc::signals cannot be copied, this function is for convenience to copy bindings only
|
||||
Axis &operator=(const Axis &rhs);
|
||||
|
||||
bool IsActive() { return m_value != 0.0 || positive.IsActive() || negative.IsActive(); }
|
||||
float GetValue() { return m_value; }
|
||||
bool Enabled() { return axis.Enabled() || positive.Enabled() || negative.Enabled(); }
|
||||
|
||||
float m_value;
|
||||
|
||||
sigc::signal<void(float)> onAxisValue;
|
||||
|
||||
// serialization
|
||||
friend nonstd::string_view &operator>>(nonstd::string_view &, Axis &);
|
||||
friend std::ostream &operator<<(std::ostream &, Axis &);
|
||||
};
|
||||
|
||||
nonstd::string_view &operator>>(nonstd::string_view &, KeyBinding &);
|
||||
std::ostream &operator<<(std::ostream &, KeyBinding &);
|
||||
|
||||
nonstd::string_view &operator>>(nonstd::string_view &, JoyAxis &);
|
||||
std::ostream &operator<<(std::ostream &, JoyAxis &);
|
||||
|
||||
nonstd::string_view &operator>>(nonstd::string_view &, KeyChord &);
|
||||
std::ostream &operator<<(std::ostream &, KeyChord &);
|
||||
|
||||
nonstd::string_view &operator>>(nonstd::string_view &, Action &);
|
||||
std::ostream &operator<<(std::ostream &, Action &);
|
||||
|
||||
nonstd::string_view &operator>>(nonstd::string_view &, Axis &);
|
||||
std::ostream &operator<<(std::ostream &, Axis &);
|
||||
}; // namespace InputBindings
|
|
@ -1,712 +0,0 @@
|
|||
// Copyright © 2008-2020 Pioneer Developers. See AUTHORS.txt for details
|
||||
// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
|
||||
|
||||
#include "KeyBindings.h"
|
||||
#include "GameConfig.h"
|
||||
#include "Input.h"
|
||||
#include "Lang.h"
|
||||
#include "Pi.h"
|
||||
#include "StringF.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
static bool m_disableBindings = 0;
|
||||
|
||||
namespace KeyBindings {
|
||||
|
||||
#define KEY_BINDING(name, a, b, c, d) ActionBinding name;
|
||||
#define AXIS_BINDING(name, a, b, c) JoyAxisBinding name;
|
||||
#include "KeyBindings.inc.h"
|
||||
|
||||
// create the BindingPrototype sets for use by the UI
|
||||
#define BINDING_PAGE(name) const BindingPrototype BINDING_PROTOS_##name[] = {
|
||||
#define BINDING_PAGE_END() \
|
||||
{ \
|
||||
0, 0, 0, 0 \
|
||||
} \
|
||||
} \
|
||||
;
|
||||
#define BINDING_GROUP(ui_name) \
|
||||
{ ui_name, 0, 0, 0 },
|
||||
#define KEY_BINDING(name, config_name, ui_name, def1, def2) \
|
||||
{ ui_name, config_name, &KeyBindings::name, 0 },
|
||||
#define AXIS_BINDING(name, config_name, ui_name, default_value) \
|
||||
{ ui_name, config_name, 0, &KeyBindings::name },
|
||||
#include "KeyBindings.inc.h"
|
||||
|
||||
// static binding object lists for use by the dispatch function
|
||||
static ActionBinding *const s_KeyBindings[] = {
|
||||
#define KEY_BINDING(name, a, b, c, d) &KeyBindings::name,
|
||||
#include "KeyBindings.inc.h"
|
||||
0
|
||||
};
|
||||
|
||||
bool KeyBinding::IsActive() const
|
||||
{
|
||||
if (type == BINDING_DISABLED) {
|
||||
return false;
|
||||
} else if (type == KEYBOARD_KEY) {
|
||||
if (!Pi::input->KeyState(u.keyboard.key))
|
||||
return false;
|
||||
if (u.keyboard.mod == KMOD_NONE)
|
||||
return true;
|
||||
else {
|
||||
int mod = Pi::input->KeyModState();
|
||||
if (mod & KMOD_CTRL) {
|
||||
mod |= KMOD_CTRL;
|
||||
}
|
||||
if (mod & KMOD_SHIFT) {
|
||||
mod |= KMOD_SHIFT;
|
||||
}
|
||||
if (mod & KMOD_ALT) {
|
||||
mod |= KMOD_ALT;
|
||||
}
|
||||
if (mod & KMOD_GUI) {
|
||||
mod |= KMOD_GUI;
|
||||
}
|
||||
return ((mod & u.keyboard.mod) == u.keyboard.mod);
|
||||
}
|
||||
} else if (type == JOYSTICK_BUTTON) {
|
||||
return Pi::input->JoystickButtonState(u.joystickButton.joystick, u.joystickButton.button) != 0;
|
||||
} else if (type == JOYSTICK_HAT) {
|
||||
// SDL_HAT generates diagonal directions by ORing two cardinal directions.
|
||||
int hatState = Pi::input->JoystickHatState(u.joystickHat.joystick, u.joystickHat.hat);
|
||||
return (hatState & u.joystickHat.direction) == u.joystickHat.direction;
|
||||
} else
|
||||
abort();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KeyBinding::Matches(const SDL_Keysym *sym) const
|
||||
{
|
||||
int mod = sym->mod;
|
||||
if (mod & KMOD_CTRL) {
|
||||
mod |= KMOD_CTRL;
|
||||
}
|
||||
if (mod & KMOD_SHIFT) {
|
||||
mod |= KMOD_SHIFT;
|
||||
}
|
||||
if (mod & KMOD_ALT) {
|
||||
mod |= KMOD_ALT;
|
||||
}
|
||||
if (mod & KMOD_GUI) {
|
||||
mod |= KMOD_GUI;
|
||||
}
|
||||
return (type == KEYBOARD_KEY) &&
|
||||
(sym->sym == u.keyboard.key) &&
|
||||
((mod & u.keyboard.mod) == u.keyboard.mod);
|
||||
}
|
||||
|
||||
bool KeyBinding::Matches(const SDL_JoyButtonEvent *joy) const
|
||||
{
|
||||
return (type == JOYSTICK_BUTTON) &&
|
||||
(joy->which == u.joystickButton.joystick) &&
|
||||
(joy->button == u.joystickButton.button);
|
||||
}
|
||||
|
||||
bool KeyBinding::Matches(const SDL_JoyHatEvent *joy) const
|
||||
{
|
||||
return (type == JOYSTICK_HAT) &&
|
||||
(joy->which == u.joystickHat.joystick) &&
|
||||
(joy->hat == u.joystickHat.hat) &&
|
||||
(joy->value == u.joystickHat.direction);
|
||||
}
|
||||
|
||||
std::string KeyBinding::Description() const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
||||
if (type == BINDING_DISABLED) {
|
||||
// blank
|
||||
} else if (type == KEYBOARD_KEY) {
|
||||
if (u.keyboard.mod & KMOD_SHIFT) oss << Lang::SHIFT << " + ";
|
||||
if (u.keyboard.mod & KMOD_CTRL) oss << Lang::CTRL << " + ";
|
||||
if (u.keyboard.mod & KMOD_ALT) oss << Lang::ALT << " + ";
|
||||
if (u.keyboard.mod & KMOD_GUI) oss << Lang::META << " + ";
|
||||
oss << SDL_GetKeyName(u.keyboard.key);
|
||||
} else if (type == JOYSTICK_BUTTON) {
|
||||
oss << Pi::input->JoystickName(u.joystickButton.joystick);
|
||||
oss << Lang::BUTTON << int(u.joystickButton.button);
|
||||
} else if (type == JOYSTICK_HAT) {
|
||||
oss << Pi::input->JoystickName(u.joystickHat.joystick);
|
||||
oss << Lang::HAT << int(u.joystickHat.hat);
|
||||
oss << Lang::DIRECTION << int(u.joystickHat.direction);
|
||||
} else
|
||||
assert(0 && "invalid key binding type");
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* In a C string pointed to by the string pointer pointed to by p, scan for
|
||||
* the character token tok, copying the bytes on the way to bufOut which is at most buflen long.
|
||||
*
|
||||
* returns true on success, returns false if the end of the input string was reached,
|
||||
* or the buffer would be overfilled without encountering the token.
|
||||
*
|
||||
* upon return, the pointer pointed to by p will refer to the character AFTER the tok.
|
||||
*/
|
||||
static bool ReadToTok(char tok, const char **p, char *bufOut, size_t buflen)
|
||||
{
|
||||
unsigned int idx;
|
||||
for (idx = 0; idx < buflen; idx++) {
|
||||
if (**p == '\0' || **p == tok) {
|
||||
break;
|
||||
}
|
||||
bufOut[idx] = *((*p)++);
|
||||
}
|
||||
// if, after that, we're not pointing at the tok, we must have hit
|
||||
// the terminal or run out of buffer.
|
||||
if (**p != tok) {
|
||||
return false;
|
||||
}
|
||||
// otherwise, skip over the tok.
|
||||
(*p)++;
|
||||
// if there is sufficient space in the buffer, NUL terminate.
|
||||
if (idx < buflen) {
|
||||
bufOut[idx] = '\0';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Example strings:
|
||||
* Key55
|
||||
* Joy{uuid}/Button2
|
||||
* Joy{uuid}/Hat0Dir3
|
||||
*/
|
||||
bool KeyBinding::FromString(const char *str, KeyBinding &kb)
|
||||
{
|
||||
const char *digits = "1234567890";
|
||||
const char *p = str;
|
||||
|
||||
if (strcmp(p, "disabled") == 0) {
|
||||
kb.Clear();
|
||||
} else if (strncmp(p, "Key", 3) == 0) {
|
||||
kb.type = KEYBOARD_KEY;
|
||||
p += 3;
|
||||
|
||||
kb.u.keyboard.key = SDL_Keycode(atoi(p));
|
||||
p += strspn(p, digits);
|
||||
|
||||
if (strncmp(p, "Mod", 3) == 0) {
|
||||
p += 3;
|
||||
kb.u.keyboard.mod = SDL_Keymod(atoi(p));
|
||||
} else {
|
||||
kb.u.keyboard.mod = KMOD_NONE;
|
||||
}
|
||||
} else if (strncmp(p, "Joy", 3) == 0) {
|
||||
p += 3;
|
||||
|
||||
const int JoyUUIDLength = 33;
|
||||
char joyUUIDBuf[JoyUUIDLength];
|
||||
|
||||
// read the UUID
|
||||
if (!ReadToTok('/', &p, joyUUIDBuf, JoyUUIDLength)) {
|
||||
return false;
|
||||
}
|
||||
// force terminate
|
||||
joyUUIDBuf[JoyUUIDLength - 1] = '\0';
|
||||
// now, locate the internal ID.
|
||||
int joy = Pi::input->JoystickFromGUIDString(joyUUIDBuf);
|
||||
if (joy == -1) {
|
||||
return false;
|
||||
}
|
||||
if (strncmp(p, "Button", 6) == 0) {
|
||||
p += 6;
|
||||
kb.type = JOYSTICK_BUTTON;
|
||||
kb.u.joystickButton.joystick = joy;
|
||||
kb.u.joystickButton.button = atoi(p);
|
||||
} else if (strncmp(p, "Hat", 3) == 0) {
|
||||
p += 3;
|
||||
kb.type = JOYSTICK_HAT;
|
||||
kb.u.joystickHat.joystick = joy;
|
||||
kb.u.joystickHat.hat = atoi(p);
|
||||
p += strspn(p, digits);
|
||||
|
||||
if (strncmp(p, "Dir", 3) != 0)
|
||||
return false;
|
||||
|
||||
p += 3;
|
||||
kb.u.joystickHat.direction = atoi(p);
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
KeyBinding KeyBinding::FromString(const char *str)
|
||||
{
|
||||
KeyBinding kb;
|
||||
if (!KeyBinding::FromString(str, kb))
|
||||
kb.Clear();
|
||||
return kb;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &oss, const KeyBinding &kb)
|
||||
{
|
||||
if (kb.type == BINDING_DISABLED) {
|
||||
oss << "disabled";
|
||||
} else if (kb.type == KEYBOARD_KEY) {
|
||||
oss << "Key" << int(kb.u.keyboard.key);
|
||||
if (kb.u.keyboard.mod != 0) {
|
||||
oss << "Mod" << int(kb.u.keyboard.mod);
|
||||
}
|
||||
} else if (kb.type == JOYSTICK_BUTTON) {
|
||||
oss << "Joy" << Pi::input->JoystickGUIDString(kb.u.joystickButton.joystick);
|
||||
oss << "/Button" << int(kb.u.joystickButton.button);
|
||||
} else if (kb.type == JOYSTICK_HAT) {
|
||||
oss << "Joy" << Pi::input->JoystickGUIDString(kb.u.joystickButton.joystick);
|
||||
oss << "/Hat" << int(kb.u.joystickHat.hat);
|
||||
oss << "Dir" << int(kb.u.joystickHat.direction);
|
||||
} else {
|
||||
assert(0 && "KeyBinding type field is invalid");
|
||||
}
|
||||
return oss;
|
||||
}
|
||||
|
||||
std::string KeyBinding::ToString() const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << *this;
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
KeyBinding KeyBinding::FromKeyMod(SDL_Keycode key, SDL_Keymod mod)
|
||||
{
|
||||
KeyBinding kb;
|
||||
kb.type = KEYBOARD_KEY;
|
||||
kb.u.keyboard.key = key;
|
||||
// expand the modifier to cover both left & right variants
|
||||
int imod = mod;
|
||||
if (imod & KMOD_CTRL) {
|
||||
imod |= KMOD_CTRL;
|
||||
}
|
||||
if (imod & KMOD_SHIFT) {
|
||||
imod |= KMOD_SHIFT;
|
||||
}
|
||||
if (imod & KMOD_ALT) {
|
||||
imod |= KMOD_ALT;
|
||||
}
|
||||
if (imod & KMOD_GUI) {
|
||||
imod |= KMOD_GUI;
|
||||
}
|
||||
kb.u.keyboard.mod = static_cast<SDL_Keymod>(imod);
|
||||
return kb;
|
||||
}
|
||||
|
||||
KeyBinding KeyBinding::FromJoystickButton(Uint8 joystick, Uint8 button)
|
||||
{
|
||||
KeyBinding kb;
|
||||
kb.type = JOYSTICK_BUTTON;
|
||||
kb.u.joystickButton.joystick = joystick;
|
||||
kb.u.joystickButton.button = button;
|
||||
return kb;
|
||||
}
|
||||
|
||||
KeyBinding KeyBinding::FromJoystickHat(Uint8 joystick, Uint8 hat, Uint8 direction)
|
||||
{
|
||||
KeyBinding kb;
|
||||
kb.type = JOYSTICK_HAT;
|
||||
kb.u.joystickHat.joystick = joystick;
|
||||
kb.u.joystickHat.hat = hat;
|
||||
kb.u.joystickHat.direction = direction;
|
||||
return kb;
|
||||
}
|
||||
|
||||
void ActionBinding::SetFromString(const char *str)
|
||||
{
|
||||
const size_t BUF_SIZE = 64;
|
||||
const size_t len = strlen(str);
|
||||
if (len >= BUF_SIZE) {
|
||||
Output("invalid ActionBinding string\n");
|
||||
binding1 = KeyBinding::FromString(str);
|
||||
binding2.Clear();
|
||||
} else {
|
||||
const char *sep = strchr(str, ',');
|
||||
if (sep) {
|
||||
char buf[BUF_SIZE];
|
||||
const size_t len1 = sep - str;
|
||||
const size_t len2 = len - len1 - 1;
|
||||
memcpy(buf, str, len1);
|
||||
buf[len1] = '\0';
|
||||
binding1 = KeyBinding::FromString(buf);
|
||||
memcpy(buf, sep + 1, len2);
|
||||
buf[len2] = '\0';
|
||||
binding2 = KeyBinding::FromString(buf);
|
||||
} else {
|
||||
binding1 = KeyBinding::FromString(str);
|
||||
binding2.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string ActionBinding::ToString() const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
if (binding1.Enabled() && binding2.Enabled()) {
|
||||
oss << binding1 << "," << binding2;
|
||||
} else if (binding1.Enabled()) {
|
||||
oss << binding1;
|
||||
} else if (binding2.Enabled()) {
|
||||
oss << binding2;
|
||||
} else {
|
||||
oss << "disabled";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
bool ActionBinding::IsActive() const
|
||||
{
|
||||
return binding1.IsActive() || binding2.IsActive();
|
||||
}
|
||||
|
||||
bool ActionBinding::Matches(const SDL_Keysym *sym) const
|
||||
{
|
||||
return binding1.Matches(sym) || binding2.Matches(sym);
|
||||
}
|
||||
|
||||
InputResponse ActionBinding::CheckSDLEventAndDispatch(const SDL_Event *event)
|
||||
{
|
||||
if (m_disableBindings) return RESPONSE_NOMATCH;
|
||||
switch (event->type) {
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP: {
|
||||
if (Matches(&event->key.keysym)) {
|
||||
if (event->key.state == SDL_PRESSED)
|
||||
onPress.emit();
|
||||
else if (event->key.state == SDL_RELEASED)
|
||||
onRelease.emit();
|
||||
return RESPONSE_MATCHED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_JOYBUTTONUP: {
|
||||
if (binding1.Matches(&event->jbutton) || binding2.Matches(&event->jbutton)) {
|
||||
if (event->jbutton.state == SDL_PRESSED)
|
||||
onPress.emit();
|
||||
else if (event->jbutton.state == SDL_RELEASED)
|
||||
onRelease.emit();
|
||||
return RESPONSE_MATCHED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_JOYHATMOTION: {
|
||||
if (binding1.Matches(&event->jhat) || binding2.Matches(&event->jhat)) {
|
||||
onPress.emit();
|
||||
// XXX to emit onRelease, we need to have access to the state of the joystick hat prior to this event,
|
||||
// so that we can detect the case of switching from a direction that matches the binding to some other direction
|
||||
return RESPONSE_MATCHED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
return RESPONSE_NOMATCH;
|
||||
}
|
||||
|
||||
bool JoyAxisBinding::IsActive() const
|
||||
{
|
||||
// If the stick is within the deadzone, it's not active.
|
||||
return fabs(Pi::input->JoystickAxisState(joystick, axis)) > deadzone;
|
||||
}
|
||||
|
||||
float JoyAxisBinding::GetValue() const
|
||||
{
|
||||
if (!Enabled()) return 0.0f;
|
||||
|
||||
const float o_val = Pi::input->JoystickAxisState(joystick, axis);
|
||||
|
||||
// Deadzone with normalisation
|
||||
float value = fabs(o_val);
|
||||
if (value < deadzone) {
|
||||
return 0.0f;
|
||||
} else {
|
||||
// subtract deadzone and re-normalise to full range
|
||||
value = (value - deadzone) / (1.0f - deadzone);
|
||||
}
|
||||
|
||||
// Apply sensitivity scaling and clamp.
|
||||
value = fmax(fmin(value * sensitivity, 1.0f), 0.0f);
|
||||
|
||||
value = copysign(value, o_val);
|
||||
|
||||
// Invert as necessary.
|
||||
return direction == POSITIVE ? value : 0.0f - value;
|
||||
}
|
||||
|
||||
bool JoyAxisBinding::Matches(const SDL_Event *event) const
|
||||
{
|
||||
if (event->type != SDL_JOYAXISMOTION) return false;
|
||||
return event->jaxis.which == joystick && event->jaxis.axis == axis;
|
||||
}
|
||||
|
||||
std::string JoyAxisBinding::Description() const
|
||||
{
|
||||
if (!Enabled()) return std::string();
|
||||
|
||||
const char *axis_names[] = { Lang::X, Lang::Y, Lang::Z };
|
||||
std::ostringstream ossaxisnum;
|
||||
ossaxisnum << int(axis);
|
||||
|
||||
return stringf(Lang::JOY_AXIS,
|
||||
formatarg("sign", direction == KeyBindings::NEGATIVE ? "-" : ""), // no + sign if positive
|
||||
formatarg("signp", direction == KeyBindings::NEGATIVE ? "-" : "+"), // optional with + sign
|
||||
formatarg("joynum", joystick),
|
||||
formatarg("joyname", Pi::input->JoystickName(joystick)),
|
||||
formatarg("axis", axis < 3 ? axis_names[axis] : ossaxisnum.str()));
|
||||
}
|
||||
|
||||
bool JoyAxisBinding::FromString(const char *str, JoyAxisBinding &ab)
|
||||
{
|
||||
if (strcmp(str, "disabled") == 0) {
|
||||
ab.Clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *p = str;
|
||||
|
||||
if (p[0] == '-') {
|
||||
ab.direction = NEGATIVE;
|
||||
p++;
|
||||
} else
|
||||
ab.direction = POSITIVE;
|
||||
|
||||
if (strncmp(p, "Joy", 3) != 0)
|
||||
return false;
|
||||
p += 3;
|
||||
|
||||
const int JoyUUIDLength = 33;
|
||||
char joyUUIDBuf[JoyUUIDLength];
|
||||
|
||||
// read the UUID
|
||||
if (!ReadToTok('/', &p, joyUUIDBuf, JoyUUIDLength)) {
|
||||
return false;
|
||||
}
|
||||
// force terminate
|
||||
joyUUIDBuf[JoyUUIDLength - 1] = '\0';
|
||||
// now, map the GUID to a joystick number
|
||||
const int joystick = Pi::input->JoystickFromGUIDString(joyUUIDBuf);
|
||||
if (joystick == -1) {
|
||||
return false;
|
||||
}
|
||||
// found a joystick
|
||||
assert(joystick < 256);
|
||||
ab.joystick = Uint8(joystick);
|
||||
|
||||
if (strncmp(p, "Axis", 4) != 0)
|
||||
return false;
|
||||
|
||||
p += 4;
|
||||
ab.axis = atoi(p);
|
||||
|
||||
// Skip past the axis integer
|
||||
if (!(p = strstr(p, "/DZ")))
|
||||
return true; // deadzone is optional
|
||||
|
||||
p += 3;
|
||||
ab.deadzone = atof(p);
|
||||
|
||||
// Skip past the deadzone float
|
||||
if (!(p = strstr(p, "/E")))
|
||||
return true; // sensitivity is optional
|
||||
|
||||
p += 2;
|
||||
ab.sensitivity = atof(p);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
JoyAxisBinding JoyAxisBinding::FromString(const char *str)
|
||||
{
|
||||
JoyAxisBinding ab;
|
||||
if (!JoyAxisBinding::FromString(str, ab))
|
||||
ab.Clear();
|
||||
return ab;
|
||||
}
|
||||
|
||||
std::string JoyAxisBinding::ToString() const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
if (Enabled()) {
|
||||
if (direction == NEGATIVE)
|
||||
oss << '-';
|
||||
|
||||
oss << "Joy";
|
||||
oss << Pi::input->JoystickGUIDString(joystick);
|
||||
oss << "/Axis";
|
||||
oss << int(axis);
|
||||
oss << "/DZ" << deadzone;
|
||||
oss << "/E" << sensitivity;
|
||||
} else {
|
||||
oss << "disabled";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void AxisBinding::SetFromString(const std::string str)
|
||||
{
|
||||
size_t ofs = 0;
|
||||
size_t nextpos = str.find(',');
|
||||
if (nextpos == std::string::npos) return;
|
||||
|
||||
if (str.substr(ofs, 8) != "disabled")
|
||||
axis = JoyAxisBinding::FromString(str.substr(0, nextpos).c_str());
|
||||
|
||||
ofs = nextpos + 1;
|
||||
nextpos = str.find(',', ofs);
|
||||
if (str.substr(ofs, 8) != "disabled")
|
||||
positive = KeyBinding::FromString(str.substr(ofs, nextpos - ofs).c_str());
|
||||
|
||||
ofs = nextpos + 1;
|
||||
if (str.substr(ofs, 8) != "disabled")
|
||||
negative = KeyBinding::FromString(str.substr(ofs).c_str());
|
||||
}
|
||||
|
||||
std::string AxisBinding::ToString() const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << axis.ToString() << ',';
|
||||
oss << positive.ToString() << ',';
|
||||
oss << negative.ToString();
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
bool AxisBinding::IsActive() const
|
||||
{
|
||||
return axis.IsActive() || positive.IsActive() || negative.IsActive();
|
||||
}
|
||||
|
||||
float AxisBinding::GetValue() const
|
||||
{
|
||||
// Holding the positive and negative keys cancel each other out,
|
||||
float value = 0.0f;
|
||||
value += positive.IsActive() ? 1.0 : 0.0;
|
||||
value -= negative.IsActive() ? 1.0 : 0.0;
|
||||
|
||||
// And input on the axis device supercedes both of them.
|
||||
return axis.IsActive() ? axis.GetValue() : value;
|
||||
}
|
||||
|
||||
InputResponse AxisBinding::CheckSDLEventAndDispatch(const SDL_Event *event)
|
||||
{
|
||||
if (m_disableBindings) return RESPONSE_NOMATCH;
|
||||
float value = GetValue();
|
||||
switch (event->type) {
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP: {
|
||||
if (positive.Matches(&event->key.keysym) && negative.Matches(&event->key.keysym)) {
|
||||
onAxis.emit(value);
|
||||
return RESPONSE_MATCHED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_JOYBUTTONUP: {
|
||||
if (positive.Matches(&event->jbutton) || negative.Matches(&event->jbutton)) {
|
||||
onAxis.emit(value);
|
||||
return RESPONSE_MATCHED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_JOYHATMOTION: {
|
||||
if (positive.Matches(&event->jhat) || positive.Matches(&event->jhat)) {
|
||||
onAxis.emit(value);
|
||||
// XXX to emit onRelease, we need to have access to the state of the joystick hat prior to this event,
|
||||
// so that we can detect the case of switching from a direction that matches the binding to some other direction
|
||||
return RESPONSE_MATCHED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_JOYAXISMOTION: {
|
||||
if (axis.Matches(event)) {
|
||||
onAxis.emit(value);
|
||||
return RESPONSE_MATCHED;
|
||||
}
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
return RESPONSE_NOMATCH;
|
||||
}
|
||||
|
||||
void DispatchSDLEvent(const SDL_Event *event)
|
||||
{
|
||||
switch (event->type) {
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_JOYBUTTONUP:
|
||||
case SDL_JOYHATMOTION:
|
||||
break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
// simplest possible approach here: just check each binding and dispatch if it matches
|
||||
for (ActionBinding *const *binding = s_KeyBindings; *binding; ++binding) {
|
||||
(*binding)->CheckSDLEventAndDispatch(event);
|
||||
}
|
||||
}
|
||||
|
||||
void InitKeyBinding(ActionBinding &kb, const std::string &bindName, Uint32 defaultKey1, Uint32 defaultKey2)
|
||||
{
|
||||
std::string keyName = Pi::config->String(bindName.c_str());
|
||||
if (keyName.length() == 0) {
|
||||
if (defaultKey1 && defaultKey2) {
|
||||
keyName = stringf("Key%0{u},Key%1{u}", defaultKey1, defaultKey2);
|
||||
} else if (defaultKey1 || defaultKey2) {
|
||||
Uint32 k = (defaultKey1 | defaultKey2); // only one of them is non-zero, so this gets the non-zero value
|
||||
keyName = stringf("Key%0{u}", k);
|
||||
}
|
||||
Pi::config->SetString(bindName.c_str(), keyName.c_str());
|
||||
}
|
||||
|
||||
// set the binding from the configured or default value
|
||||
kb.SetFromString(keyName.c_str());
|
||||
}
|
||||
|
||||
void InitAxisBinding(JoyAxisBinding &ab, const std::string &bindName, const std::string &defaultAxis)
|
||||
{
|
||||
std::string axisName = Pi::config->String(bindName.c_str());
|
||||
if (axisName.length() == 0) {
|
||||
axisName = defaultAxis;
|
||||
Pi::config->SetString(bindName.c_str(), axisName.c_str());
|
||||
}
|
||||
|
||||
// set the binding from the configured or default value
|
||||
if (!JoyAxisBinding::FromString(axisName.c_str(), ab)) {
|
||||
Output("invalid axis binding '%s' in config file for %s\n", axisName.c_str(), bindName.c_str());
|
||||
ab.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateBindings()
|
||||
{
|
||||
#define KEY_BINDING(name, config_name, b, default_value_1, default_value_2) \
|
||||
InitKeyBinding(KeyBindings::name, config_name, default_value_1, default_value_2);
|
||||
#define AXIS_BINDING(name, config_name, b, default_value) \
|
||||
InitAxisBinding(KeyBindings::name, config_name, default_value);
|
||||
#include "KeyBindings.inc.h"
|
||||
}
|
||||
|
||||
void InitBindings()
|
||||
{
|
||||
UpdateBindings();
|
||||
Pi::config->Save();
|
||||
}
|
||||
|
||||
void EnableBindings()
|
||||
{
|
||||
m_disableBindings = 0;
|
||||
}
|
||||
|
||||
void DisableBindings()
|
||||
{
|
||||
m_disableBindings = 1;
|
||||
}
|
||||
|
||||
} // namespace KeyBindings
|
|
@ -1,229 +0,0 @@
|
|||
// Copyright © 2008-2020 Pioneer Developers. See AUTHORS.txt for details
|
||||
// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
|
||||
|
||||
#ifndef KEYBINDINGS_H
|
||||
#define KEYBINDINGS_H
|
||||
|
||||
#include "libs.h"
|
||||
#include <iosfwd>
|
||||
|
||||
enum InputResponse {
|
||||
// None of the inputs match the event.
|
||||
RESPONSE_NOMATCH = 0,
|
||||
// An input matched, but won't consume the event.
|
||||
RESPONSE_PASSTHROUGH,
|
||||
// An input matched and consumed the event.
|
||||
RESPONSE_MATCHED
|
||||
};
|
||||
|
||||
namespace KeyBindings {
|
||||
enum Type {
|
||||
BINDING_DISABLED,
|
||||
KEYBOARD_KEY,
|
||||
JOYSTICK_BUTTON,
|
||||
JOYSTICK_HAT,
|
||||
MOUSE_BUTTON // TODO: implementme!
|
||||
};
|
||||
|
||||
struct KeyBinding {
|
||||
public:
|
||||
// constructors
|
||||
static bool FromString(const char *str, KeyBinding &binding);
|
||||
static KeyBinding FromString(const char *str);
|
||||
static KeyBinding FromKeyMod(SDL_Keycode key, SDL_Keymod mod);
|
||||
static KeyBinding FromJoystickButton(Uint8 joystick, Uint8 button);
|
||||
static KeyBinding FromJoystickHat(Uint8 joystick, Uint8 hat, Uint8 direction);
|
||||
|
||||
KeyBinding() :
|
||||
type(BINDING_DISABLED)
|
||||
{
|
||||
u.keyboard.key = SDLK_UNKNOWN;
|
||||
u.keyboard.mod = KMOD_NONE;
|
||||
}
|
||||
KeyBinding(SDL_Keycode key, SDL_Keymod mod = KMOD_NONE) :
|
||||
type(KEYBOARD_KEY)
|
||||
{
|
||||
u.keyboard.key = key;
|
||||
u.keyboard.mod = mod;
|
||||
}
|
||||
|
||||
std::string ToString() const; // for serialisation
|
||||
std::string Description() const; // for display to the user
|
||||
|
||||
bool IsActive() const;
|
||||
bool Matches(const SDL_Keysym *sym) const;
|
||||
bool Matches(const SDL_JoyButtonEvent *joy) const;
|
||||
bool Matches(const SDL_JoyHatEvent *joy) const;
|
||||
|
||||
void Clear() { memset(this, 0, sizeof(*this)); }
|
||||
|
||||
bool Enabled() const { return (type != BINDING_DISABLED); }
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &oss, const KeyBinding &kb);
|
||||
|
||||
private:
|
||||
Type type;
|
||||
union {
|
||||
struct {
|
||||
SDL_Keycode key;
|
||||
SDL_Keymod mod;
|
||||
} keyboard;
|
||||
|
||||
struct {
|
||||
Uint8 joystick;
|
||||
Uint8 button;
|
||||
} joystickButton;
|
||||
|
||||
struct {
|
||||
Uint8 joystick;
|
||||
Uint8 hat;
|
||||
Uint8 direction;
|
||||
} joystickHat;
|
||||
|
||||
/* TODO: implement binding mouse buttons.
|
||||
struct {
|
||||
Uint8 button;
|
||||
// TODO: implement binding multiple clicks as their own action.
|
||||
Uint8 clicks;
|
||||
} mouseButton;
|
||||
*/
|
||||
} u;
|
||||
};
|
||||
|
||||
struct ActionBinding {
|
||||
KeyBinding binding1;
|
||||
KeyBinding binding2;
|
||||
|
||||
sigc::signal<void> onPress;
|
||||
sigc::signal<void> onRelease;
|
||||
|
||||
ActionBinding() {}
|
||||
ActionBinding(KeyBinding b1, KeyBinding b2 = KeyBinding()) :
|
||||
binding1(b1),
|
||||
binding2(b2) {}
|
||||
// This constructor is just a programmer shortcut.
|
||||
ActionBinding(SDL_Keycode k1, SDL_Keycode k2 = SDLK_UNKNOWN)
|
||||
{
|
||||
binding1 = KeyBinding(k1);
|
||||
if (k2 != SDLK_UNKNOWN) binding2 = KeyBinding(k2);
|
||||
}
|
||||
|
||||
void SetFromString(const char *str);
|
||||
void SetFromString(const std::string str) { return SetFromString(str.c_str()); }
|
||||
std::string ToString() const;
|
||||
|
||||
bool IsActive() const;
|
||||
InputResponse CheckSDLEventAndDispatch(const SDL_Event *event);
|
||||
|
||||
bool Matches(const SDL_Keysym *sym) const;
|
||||
};
|
||||
|
||||
enum AxisDirection {
|
||||
POSITIVE,
|
||||
NEGATIVE
|
||||
};
|
||||
|
||||
struct JoyAxisBinding {
|
||||
public:
|
||||
JoyAxisBinding() :
|
||||
joystick(JOYSTICK_DISABLED),
|
||||
axis(0),
|
||||
direction(POSITIVE),
|
||||
deadzone(0.0f),
|
||||
sensitivity(1.0f) {}
|
||||
JoyAxisBinding(Uint8 joystick_, Uint8 axis_, AxisDirection direction_, float deadzone_ = 0.0f, float sensitivity_ = 1.0f) :
|
||||
joystick(joystick_),
|
||||
axis(axis_),
|
||||
direction(direction_),
|
||||
deadzone(deadzone_),
|
||||
sensitivity(sensitivity_) {}
|
||||
|
||||
float GetValue() const;
|
||||
std::string Description() const;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
joystick = JOYSTICK_DISABLED;
|
||||
axis = 0;
|
||||
direction = POSITIVE;
|
||||
deadzone = 0.0f;
|
||||
sensitivity = 1.0f;
|
||||
}
|
||||
|
||||
bool Enabled() const { return (joystick != JOYSTICK_DISABLED); }
|
||||
|
||||
static bool FromString(const char *str, JoyAxisBinding &binding);
|
||||
static JoyAxisBinding FromString(const char *str);
|
||||
std::string ToString() const;
|
||||
|
||||
bool Matches(const SDL_Event *event) const;
|
||||
bool IsActive() const;
|
||||
|
||||
bool IsInverted() { return direction == NEGATIVE; }
|
||||
AxisDirection GetDirection() { return direction; }
|
||||
void SetDirection(AxisDirection dir) { direction = dir; }
|
||||
|
||||
float GetDeadzone() { return deadzone; }
|
||||
void SetDeadzone(float dz) { deadzone = dz; }
|
||||
|
||||
float GetSensitivity() { return sensitivity; }
|
||||
void SetSensitivity(float sens) { sensitivity = sens; }
|
||||
|
||||
private:
|
||||
enum { JOYSTICK_DISABLED = Uint8(-1) };
|
||||
Uint8 joystick;
|
||||
Uint8 axis;
|
||||
AxisDirection direction;
|
||||
float deadzone;
|
||||
float sensitivity;
|
||||
};
|
||||
|
||||
struct AxisBinding {
|
||||
JoyAxisBinding axis;
|
||||
KeyBinding positive;
|
||||
KeyBinding negative;
|
||||
|
||||
AxisBinding() {}
|
||||
AxisBinding(JoyAxisBinding ax, KeyBinding pos = KeyBinding(), KeyBinding neg = KeyBinding()) :
|
||||
axis(ax),
|
||||
positive(pos),
|
||||
negative(neg) {}
|
||||
// This constructor is just a programmer shortcut.
|
||||
AxisBinding(SDL_Keycode k1, SDL_Keycode k2) :
|
||||
positive(KeyBinding(k1)),
|
||||
negative(KeyBinding(k2)) {}
|
||||
|
||||
sigc::signal<void, float> onAxis;
|
||||
|
||||
void SetFromString(const char *str) { return SetFromString(std::string(str)); }
|
||||
void SetFromString(const std::string str);
|
||||
std::string ToString() const;
|
||||
|
||||
bool IsActive() const;
|
||||
float GetValue() const;
|
||||
InputResponse CheckSDLEventAndDispatch(const SDL_Event *event);
|
||||
};
|
||||
|
||||
struct BindingPrototype {
|
||||
const char *label, *function;
|
||||
ActionBinding *kb;
|
||||
JoyAxisBinding *ab;
|
||||
};
|
||||
|
||||
void InitBindings();
|
||||
void UpdateBindings();
|
||||
void EnableBindings();
|
||||
void DisableBindings();
|
||||
|
||||
void DispatchSDLEvent(const SDL_Event *event);
|
||||
|
||||
#define KEY_BINDING(name, a, b, c, d) extern ActionBinding name;
|
||||
#define AXIS_BINDING(name, a, b, c) extern JoyAxisBinding name;
|
||||
#include "KeyBindings.inc.h"
|
||||
|
||||
#define BINDING_PAGE(name) extern const BindingPrototype BINDING_PROTOS_##name[];
|
||||
#include "KeyBindings.inc.h"
|
||||
|
||||
} // namespace KeyBindings
|
||||
|
||||
#endif /* KEYBINDINGS_H */
|
|
@ -1,56 +0,0 @@
|
|||
// Copyright © 2008-2020 Pioneer Developers. See AUTHORS.txt for details
|
||||
// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
|
||||
|
||||
#ifndef KEY_BINDING
|
||||
#define KEY_BINDING(name, config_name, ui_name, default_value_1, default_value_2)
|
||||
#endif
|
||||
#ifndef AXIS_BINDING
|
||||
#define AXIS_BINDING(name, config_name, ui_name, default_value)
|
||||
#endif
|
||||
#ifndef BINDING_GROUP
|
||||
#define BINDING_GROUP(ui_name)
|
||||
#endif
|
||||
#ifndef BINDING_PAGE
|
||||
#define BINDING_PAGE(ui_name)
|
||||
#endif
|
||||
#ifndef BINDING_PAGE_END
|
||||
#define BINDING_PAGE_END()
|
||||
#endif
|
||||
|
||||
BINDING_PAGE(CONTROLS)
|
||||
BINDING_GROUP(Lang::MISCELLANEOUS)
|
||||
KEY_BINDING(toggleLuaConsole, "BindToggleLuaConsole", Lang::TOGGLE_LUA_CONSOLE, SDLK_BACKQUOTE, 0)
|
||||
|
||||
BINDING_GROUP(Lang::RADAR_CONTROL)
|
||||
KEY_BINDING(toggleScanMode, "BindToggleScanMode", Lang::TOGGLE_RADAR_MODE, SDLK_BACKSLASH, 0)
|
||||
KEY_BINDING(increaseScanRange, "BindIncreaseScanRange", Lang::INCREASE_RADAR_RANGE, SDLK_RIGHTBRACKET, 0)
|
||||
KEY_BINDING(decreaseScanRange, "BindDecreaseScanRange", Lang::DECREASE_RADAR_RANGE, SDLK_LEFTBRACKET, 0)
|
||||
|
||||
BINDING_PAGE_END()
|
||||
|
||||
BINDING_PAGE(VIEW)
|
||||
|
||||
BINDING_GROUP(Lang::INTERNAL_VIEW)
|
||||
KEY_BINDING(frontCamera, "BindFrontCamera", Lang::CAMERA_FRONT_VIEW, SDLK_KP_8, SDLK_UP)
|
||||
KEY_BINDING(rearCamera, "BindRearCamera", Lang::CAMERA_REAR_VIEW, SDLK_KP_2, SDLK_DOWN)
|
||||
KEY_BINDING(leftCamera, "BindLeftCamera", Lang::CAMERA_LEFT_VIEW, SDLK_KP_4, SDLK_LEFT)
|
||||
KEY_BINDING(rightCamera, "BindRightCamera", Lang::CAMERA_RIGHT_VIEW, SDLK_KP_6, SDLK_RIGHT)
|
||||
KEY_BINDING(topCamera, "BindTopCamera", Lang::CAMERA_TOP_VIEW, SDLK_KP_9, 0)
|
||||
KEY_BINDING(bottomCamera, "BindBottomCamera", Lang::CAMERA_BOTTOM_VIEW, SDLK_KP_3, 0)
|
||||
|
||||
BINDING_GROUP(Lang::EXTERNAL_VIEW)
|
||||
KEY_BINDING(cameraRollLeft, "BindCameraRollLeft", Lang::ROLL_LEFT, SDLK_KP_1, 0)
|
||||
KEY_BINDING(cameraRollRight, "BindCameraRollRight", Lang::ROLL_RIGHT, SDLK_KP_3, 0)
|
||||
KEY_BINDING(cameraRotateDown, "BindCameraRotateDown", Lang::ROTATE_DOWN, SDLK_KP_2, SDLK_DOWN)
|
||||
KEY_BINDING(cameraRotateUp, "BindCameraRotateUp", Lang::ROTATE_UP, SDLK_KP_8, SDLK_UP)
|
||||
KEY_BINDING(cameraRotateLeft, "BindCameraRotateLeft", Lang::ROTATE_LEFT, SDLK_KP_4, SDLK_LEFT)
|
||||
KEY_BINDING(cameraRotateRight, "BindCameraRotateRight", Lang::ROTATE_RIGHT, SDLK_KP_6, SDLK_RIGHT)
|
||||
KEY_BINDING(resetCamera, "BindResetCamera", Lang::RESET, SDLK_HOME, 0)
|
||||
|
||||
BINDING_PAGE_END()
|
||||
|
||||
#undef KEY_BINDING
|
||||
#undef AXIS_BINDING
|
||||
#undef BINDING_GROUP
|
||||
#undef BINDING_PAGE
|
||||
#undef BINDING_PAGE_END
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue