addon for remapping inputs
-rw-r--r--.github/FUNDING.yml1
-rw-r--r--.github/workflows/export.yml68
-rw-r--r--.gitignore8
-rw-r--r--LICENSE21
-rw-r--r--README.md51
-rw-r--r--Test.tscn24
-rw-r--r--addons/remap/ActionIcons.gd26
-rw-r--r--addons/remap/ActionLabel.gd22
-rw-r--r--addons/remap/IconMap.gd120
-rw-r--r--addons/remap/InteractiveActionLabel.gd35
-rw-r--r--addons/remap/KeyPromptLabel.gd27
-rw-r--r--addons/remap/KeySelector.gd18
-rw-r--r--addons/remap/KeySelector.tscn60
-rw-r--r--addons/remap/PromptFont.tres7
-rw-r--r--addons/remap/PromptFont.ttfbin0 -> 58372 bytes
-rw-r--r--addons/remap/RemapUtilities.gd10
-rw-r--r--addons/remap/circle.styleboxbin0 -> 400 bytes
-rw-r--r--addons/remap/main.themebin0 -> 766 bytes
-rw-r--r--export_presets.cfg24
-rw-r--r--icon.pngbin0 -> 11691 bytes
-rw-r--r--icon.png.import35
-rw-r--r--project.godot95
22 files changed, 652 insertions, 0 deletions
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..1bfbcab
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+ko_fi: bendn
diff --git a/.github/workflows/export.yml b/.github/workflows/export.yml
new file mode 100644
index 0000000..0d33f16
--- /dev/null
+++ b/.github/workflows/export.yml
@@ -0,0 +1,68 @@
+name: "export"
+on:
+ workflow_dispatch:
+ push:
+ paths:
+ - "**.gd"
+ - "**.tscn"
+ - "**.import"
+ - "**.tres"
+ - "**.ttf"
+ - "**.yml"
+ branches:
+ - main
+
+env:
+ GODOT_VERSION: 3.5
+ NAME: ${{ github.event.repository.name }}
+
+jobs:
+ export:
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/bend-n/godot-2d:3.5
+ name: ${{ matrix.name }}
+ strategy:
+ matrix:
+ include:
+ - name: Linux export
+ platform: linux
+
+ steps:
+ - name: Build (Windows)
+ if: matrix.platform == 'windows'
+ uses: bend-n/godot-actions/.github/actions/export-windows@main
+
+ - name: Build (Linux)
+ if: matrix.platform == 'linux'
+ uses: bend-n/godot-actions/.github/actions/export-linux@main
+
+ - name: Build (Mac)
+ if: matrix.platform == 'mac'
+ uses: bend-n/godot-actions/.github/actions/export-mac@main
+
+ - name: Build (Web)
+ if: matrix.platform == 'web'
+ uses: bend-n/godot-actions/.github/actions/export-web@main
+
+ - name: Build (Android)
+ if: matrix.platform == 'android'
+ uses: bend-n/godot-actions/.github/actions/export-android@main
+ with:
+ android-keystore-base64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
+ android-password: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
+
+ push-itch:
+ needs: [export]
+ name: Push to itch.io
+ runs-on: ubuntu-20.04
+ steps:
+ - name: Check for api key
+ id: secret
+ run: echo '::set-output name=secret::${{ secrets.BUTLER_CREDENTIALS }}'
+
+ - name: Push
+ if: steps.secret.outputs.secret
+ uses: bend-n/godot-actions/.github/actions/itch-push@main
+ with:
+ api-key: ${{ secrets.BUTLER_CREDENTIALS }}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5bbe921
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+.import/
+logs/
+*.sh
+*.py
+*.pgn
+.vscode/
+exports/
+*.x86_64
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..9a9763e
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 bendn
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c6dbb07
--- /dev/null
+++ b/README.md
@@ -0,0 +1,51 @@
+# godot-template
+
+[![version](https://img.shields.io/badge/3.x-blue?logo=godot-engine&logoColor=white&label=godot&style=for-the-badge)](https://godotengine.org "Made with godot")
+<a href='https://ko-fi.com/bendn' title='Buy me a coffee' target='_blank'><img height='28' src='https://storage.ko-fi.com/cdn/brandasset/kofi_button_red.png' alt='Buy me a coffee'> </a>
+
+Godot template repository for my programs
+
+---
+
+## How to use
+
+> **Note** This template uses the [gpm](https://github.com/you-win/godot-package-manager).
+
+- Click use this template button
+- Clone your new repository
+- Run install_addons.sh
+- Add your files & change `FUNDING.yml`
+- Commit & push
+
+<details>
+<summary>For itch.io depoloyment</summary>
+<br>
+
+Add a secret called `BUTLER_CREDENTIALS` with your [butler api key](https://itch.io/user/settings/api-keys).
+
+</details>
+
+<details>
+<summary>For android builds</summary>
+<br>
+
+> **Note**
+>
+> The keystore user/alias is found automatically.
+
+Add two secrets:
+
+- `ANDROID_KEYSTORE_BASE64`
+- `ANDROID_KEYSTORE_PASSWORD`
+
+</details>
+
+---
+
+### CI Availability
+
+| windows | ios | linux | android | mac | html | |
+| :----------------: | :-: | :----------------: | :----------------: | :----------------: | :----------------: | :-----------: |
+| :x: | :x: | :x: | :x: | :x: | :heavy_check_mark: | github pages |
+| :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | itch.io |
+| :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | godot exports |
diff --git a/Test.tscn b/Test.tscn
new file mode 100644
index 0000000..c2ecd59
--- /dev/null
+++ b/Test.tscn
@@ -0,0 +1,24 @@
+[gd_scene load_steps=3 format=2]
+
+[ext_resource path="res://addons/remap/ActionLabel.gd" type="Script" id=1]
+[ext_resource path="res://addons/remap/InteractiveActionLabel.gd" type="Script" id=2]
+
+[node name="Test" type="Control"]
+anchor_right = 1.0
+anchor_bottom = 1.0
+
+[node name="ActionLabel" type="HBoxContainer" parent="."]
+anchor_right = 1.0
+script = ExtResource( 1 )
+_name = "lef"
+action = "ui_left"
+
+[node name="InteractiveActionLabel" type="HBoxContainer" parent="."]
+anchor_top = 0.5
+anchor_right = 1.0
+anchor_bottom = 0.5
+margin_left = 4.0
+margin_bottom = 15.0
+script = ExtResource( 2 )
+_name = "right"
+action = "ui_right"
diff --git a/addons/remap/ActionIcons.gd b/addons/remap/ActionIcons.gd
new file mode 100644
index 0000000..a338b58
--- /dev/null
+++ b/addons/remap/ActionIcons.gd
@@ -0,0 +1,26 @@
+extends HBoxContainer
+class_name ActionIcons
+
+var action: String
+
+
+func _ready():
+ theme = preload("./main.theme")
+ add_constant_override("separation", 4)
+
+
+func _update():
+ for i in get_children():
+ i.queue_free()
+ var act_list := InputMap.get_action_list(action)
+ for e in act_list:
+ var icon = IconMap.get_icon(e)
+ if icon:
+ var p: PanelContainer = PanelContainer.new()
+ var i: Label = Label.new()
+ i.text = icon
+ i.align = Label.ALIGN_CENTER
+ i.valign = Label.VALIGN_CENTER
+ p.add_child(i)
+ add_child(p)
+ i.rect_min_size = Vector2(30, 30)
diff --git a/addons/remap/ActionLabel.gd b/addons/remap/ActionLabel.gd
new file mode 100644
index 0000000..0de8bb9
--- /dev/null
+++ b/addons/remap/ActionLabel.gd
@@ -0,0 +1,22 @@
+tool
+extends HBoxContainer
+class_name ActionLabel
+
+export(String) var _name: String
+export(String) var action: String
+
+var icons := ActionIcons.new()
+var name_label := Label.new()
+
+
+func _ready() -> void:
+ name_label.text = _name
+ name_label.valign = Label.VALIGN_CENTER
+ name_label.align = Label.ALIGN_CENTER
+ add_child(name_label)
+ var spacer := Control.new()
+ spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ add_child(spacer)
+ add_child(icons)
+ icons.action = action
+ icons._update()
diff --git a/addons/remap/IconMap.gd b/addons/remap/IconMap.gd
new file mode 100644
index 0000000..e8b8923
--- /dev/null
+++ b/addons/remap/IconMap.gd
@@ -0,0 +1,120 @@
+extends Reference
+class_name IconMap
+
+const key_map := {
+ KEY_LEFT: "←",
+ KEY_RIGHT: "→",
+ KEY_UP: "↑",
+ KEY_DOWN: "↓",
+ KEY_ENTER: "␮",
+ KEY_KP_ENTER: "␮",
+ KEY_HOME: "␵",
+ KEY_CONTROL: "␧",
+ KEY_ALT: "␨",
+ KEY_SHIFT: "␩",
+ KEY_SUPER_L: "␪",
+ KEY_SUPER_R: "␫",
+ KEY_TAB: "␫",
+ KEY_CAPSLOCK: "␬",
+ KEY_BACKSPACE: "␭",
+ KEY_ESCAPE: "␯",
+ KEY_PRINT: "␰",
+ KEY_SCROLLLOCK: "␱",
+ KEY_PAUSE: "␲",
+ KEY_NUMLOCK: "␳",
+ KEY_DELETE: "␷",
+ KEY_INSERT: "␴",
+ KEY_PAGEUP: "␶",
+ KEY_PAGEDOWN: "␹",
+ KEY_SPACE: "␺",
+ KEY_F1: "①",
+ KEY_F2: "②",
+ KEY_F3: "③",
+ KEY_F4: "④",
+ KEY_F5: "⑤",
+ KEY_F6: "⑥",
+ KEY_F7: "⑦",
+ KEY_F8: "⑧",
+ KEY_F9: "⑨",
+ KEY_F10: "⑩",
+ KEY_F11: "⑪",
+ KEY_F12: "⑫",
+ KEY_SEMICOLON: ";",
+ KEY_QUOTELEFT: "`",
+ KEY_COMMA: ",",
+ KEY_PERIOD: ".",
+ KEY_SLASH: "/",
+ KEY_BACKSLASH: "\\",
+ KEY_MINUS: "-",
+ KEY_EQUAL: "=",
+ KEY_BRACKETLEFT: "[",
+ KEY_BRACKETRIGHT: "]",
+ KEY_BRACELEFT: "{",
+ KEY_BRACERIGHT: "}",
+ KEY_APOSTROPHE: "'",
+ KEY_MENU: "⇻",
+ KEY_END: "␸"
+}
+
+# JOY_SONY_CIRCLE and JOY_XBOX_B are the same as JOY_DS_A
+# TODO: use a different map for each controller after finding out what kind it is
+const gamepad_button_map := {
+ JOY_XBOX_X: "↤",
+ JOY_XBOX_A: "↧",
+ JOY_XBOX_B: "↦",
+ JOY_XBOX_Y: "↥",
+ JOY_L: "↘",
+ JOY_R: "↙",
+ JOY_L2: "↖",
+ JOY_R2: "↗",
+ JOY_DPAD_LEFT: "↞",
+ JOY_DPAD_RIGHT: "↠",
+ JOY_DPAD_UP: "↟",
+ JOY_DPAD_DOWN: "↡",
+}
+
+const joystick_map := {
+ -1:
+ {
+ JOY_ANALOG_LX: "↼",
+ JOY_ANALOG_LY: "⇈",
+ JOY_ANALOG_RX: "↽",
+ JOY_ANALOG_RY: "↿",
+ },
+ 1:
+ {
+ JOY_ANALOG_LX: "⇀",
+ JOY_ANALOG_LY: "⇂",
+ JOY_ANALOG_RX: "⇁",
+ JOY_ANALOG_RY: "⇃",
+ }
+}
+
+const mouse_button_map := {
+ BUTTON_LEFT: "⟵", BUTTON_RIGHT: "⟶", BUTTON_MIDDLE: "⟷", BUTTON_WHEEL_DOWN: "⟱", BUTTON_WHEEL_UP: "⟰"
+}
+
+
+static func get_icon(e: InputEvent) -> String:
+ if e is InputEventKey:
+ if key_map.has(e.scancode):
+ return key_map[e.scancode]
+ elif OS.get_scancode_string(e.scancode):
+ return OS.get_scancode_string(e.scancode)
+ elif OS.keyboard_get_scancode_from_physical(e.physical_scancode):
+ var scancode = OS.keyboard_get_scancode_from_physical(e.physical_scancode)
+ if key_map.has(scancode):
+ return key_map[scancode]
+ elif OS.get_scancode_string(scancode):
+ return OS.get_scancode_string(scancode)
+
+ elif e is InputEventJoypadButton:
+ if gamepad_button_map.has(e.button_index):
+ return gamepad_button_map[e.button_index]
+ elif e is InputEventJoypadMotion:
+ if joystick_map[int(e.axis_value)].has(e.axis):
+ return joystick_map[int(e.axis_value)][e.axis]
+ elif e is InputEventMouseButton:
+ if mouse_button_map.has(e.button_index):
+ return mouse_button_map[e.button_index]
+ return "❓"
diff --git a/addons/remap/InteractiveActionLabel.gd b/addons/remap/InteractiveActionLabel.gd
new file mode 100644
index 0000000..064fdbb
--- /dev/null
+++ b/addons/remap/InteractiveActionLabel.gd
@@ -0,0 +1,35 @@
+extends ActionLabel
+class_name InteractiveActionLabel
+
+
+# if this is overriden, the new scene must
+# - have a confirmed(action: InputEvent) signal
+# - have a cancelled() signal
+# - free itself when one of them is emitted
+export(PackedScene) var popup = preload("./KeySelector.tscn")
+
+func _ready():
+ var clear := Button.new()
+ clear.theme = preload("./main.theme")
+ clear.text = "✗"
+ clear.connect("pressed", self, "clear")
+ clear.size_flags_vertical = SIZE_EXPAND_FILL
+ clear.rect_min_size.x = 30
+ add_child(clear)
+ move_child(clear, 0)
+
+
+func _gui_input(event: InputEvent):
+ if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed:
+ var selector = popup.instance()
+ add_child(selector)
+ selector.connect("confirmed",self,"_on_key_selected")
+
+
+func _on_key_selected(event: InputEvent):
+ RemapUtilities.add_action(action,event)
+ icons._update()
+
+func clear():
+ RemapUtilities.clear_mappings(action)
+ icons._update()
diff --git a/addons/remap/KeyPromptLabel.gd b/addons/remap/KeyPromptLabel.gd
new file mode 100644
index 0000000..9844a49
--- /dev/null
+++ b/addons/remap/KeyPromptLabel.gd
@@ -0,0 +1,27 @@
+extends Label
+
+const motions = [
+ InputEventMouseMotion,
+ InputEventJoypadMotion,
+ InputEventScreenDrag,
+ InputEventScreenTouch,
+ InputEventMIDI,
+ InputEventMouseButton
+]
+
+var selected: InputEvent
+
+
+func _input(event: InputEvent) -> void:
+ if check_is(event, motions):
+ return
+ $"%ok".disabled = false
+ selected = event
+ text = IconMap.get_icon(event)
+
+
+func check_is(it, is_it_a: Array) -> bool:
+ for i in is_it_a:
+ if it is i:
+ return true
+ return false
diff --git a/addons/remap/KeySelector.gd b/addons/remap/KeySelector.gd
new file mode 100644
index 0000000..edf27f4
--- /dev/null
+++ b/addons/remap/KeySelector.gd
@@ -0,0 +1,18 @@
+extends Node
+class_name KeySelector
+
+signal confirmed(event)
+signal cancelled
+
+
+func _ready():
+ $"%ok".connect("pressed", self, "confirmed")
+ $"%cancel".connect("pressed", self, "cancelled")
+
+func confirmed():
+ emit_signal("confirmed", $"%KeyPrompter".selected)
+ queue_free()
+
+func cancelled():
+ emit_signal("cancelled")
+ queue_free()
diff --git a/addons/remap/KeySelector.tscn b/addons/remap/KeySelector.tscn
new file mode 100644
index 0000000..801bd1a
--- /dev/null
+++ b/addons/remap/KeySelector.tscn
@@ -0,0 +1,60 @@
+[gd_scene load_steps=6 format=2]
+
+[ext_resource path="res://addons/remap/main.theme" type="Theme" id=1]
+[ext_resource path="res://addons/remap/KeyPromptLabel.gd" type="Script" id=2]
+[ext_resource path="res://addons/remap/PromptFont.ttf" type="DynamicFontData" id=3]
+[ext_resource path="res://addons/remap/KeySelector.gd" type="Script" id=4]
+
+[sub_resource type="DynamicFont" id=1]
+size = 40
+font_data = ExtResource( 3 )
+
+[node name="KeySelector" type="CanvasLayer"]
+script = ExtResource( 4 )
+
+[node name="ColorRect" type="ColorRect" parent="."]
+anchor_right = 1.0
+anchor_bottom = 1.0
+theme = ExtResource( 1 )
+color = Color( 0.160156, 0.160156, 0.160156, 0.705882 )
+
+[node name="Center" type="CenterContainer" parent="ColorRect"]
+anchor_right = 1.0
+anchor_bottom = 1.0
+
+[node name="V" type="VBoxContainer" parent="ColorRect/Center"]
+margin_left = 35.0
+margin_top = 51.0
+margin_right = 285.0
+margin_bottom = 129.0
+
+[node name="KeyPrompter" type="Label" parent="ColorRect/Center/V"]
+unique_name_in_owner = true
+margin_right = 250.0
+margin_bottom = 49.0
+rect_min_size = Vector2( 125, 0 )
+custom_fonts/font = SubResource( 1 )
+text = "press a key"
+align = 1
+script = ExtResource( 2 )
+
+[node name="H" type="HBoxContainer" parent="ColorRect/Center/V"]
+margin_top = 53.0
+margin_right = 250.0
+margin_bottom = 78.0
+
+[node name="ok" type="Button" parent="ColorRect/Center/V/H"]
+unique_name_in_owner = true
+margin_right = 119.0
+margin_bottom = 25.0
+size_flags_horizontal = 3
+disabled = true
+text = "ok"
+
+[node name="cancel" type="Button" parent="ColorRect/Center/V/H"]
+unique_name_in_owner = true
+margin_left = 130.0
+margin_right = 250.0
+margin_bottom = 25.0
+size_flags_horizontal = 3
+text = "cancel"
diff --git a/addons/remap/PromptFont.tres b/addons/remap/PromptFont.tres
new file mode 100644
index 0000000..ca3640f
--- /dev/null
+++ b/addons/remap/PromptFont.tres
@@ -0,0 +1,7 @@
+[gd_resource type="DynamicFont" load_steps=2 format=2]
+
+[ext_resource path="res://addons/remap/PromptFont.ttf" type="DynamicFontData" id=1]
+
+[resource]
+size = 20
+font_data = ExtResource( 1 )
diff --git a/addons/remap/PromptFont.ttf b/addons/remap/PromptFont.ttf
new file mode 100644
index 0000000..353caed
--- /dev/null
+++ b/addons/remap/PromptFont.ttf
Binary files differ
diff --git a/addons/remap/RemapUtilities.gd b/addons/remap/RemapUtilities.gd
new file mode 100644
index 0000000..74e237f
--- /dev/null
+++ b/addons/remap/RemapUtilities.gd
@@ -0,0 +1,10 @@
+extends Reference
+class_name RemapUtilities
+
+
+static func clear_mappings(action: String):
+ InputMap.action_erase_events(action)
+
+
+static func add_action(action: String, event: InputEvent):
+ InputMap.action_add_event(action, event)
diff --git a/addons/remap/circle.stylebox b/addons/remap/circle.stylebox
new file mode 100644
index 0000000..259f2ce
--- /dev/null
+++ b/addons/remap/circle.stylebox
Binary files differ
diff --git a/addons/remap/main.theme b/addons/remap/main.theme
new file mode 100644
index 0000000..361a271
--- /dev/null
+++ b/addons/remap/main.theme
Binary files differ
diff --git a/export_presets.cfg b/export_presets.cfg
new file mode 100644
index 0000000..fb88f7e
--- /dev/null
+++ b/export_presets.cfg
@@ -0,0 +1,24 @@
+[preset.0]
+
+name="Linux"
+platform="Linux/X11"
+runnable=true
+custom_features=""
+export_filter="all_resources"
+include_filter=""
+exclude_filter=""
+export_path=""
+script_export_mode=1
+script_encryption_key=""
+
+[preset.0.options]
+
+custom_template/debug=""
+custom_template/release=""
+binary_format/64_bits=true
+binary_format/embed_pck=true
+texture_format/bptc=false
+texture_format/s3tc=true
+texture_format/etc=false
+texture_format/etc2=false
+texture_format/no_bptc_fallbacks=true
diff --git a/icon.png b/icon.png
new file mode 100644
index 0000000..8a4e86b
--- /dev/null
+++ b/icon.png
Binary files differ
diff --git a/icon.png.import b/icon.png.import
new file mode 100644
index 0000000..a4c02e6
--- /dev/null
+++ b/icon.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://icon.png"
+dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+process/normal_map_invert_y=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/project.godot b/project.godot
new file mode 100644
index 0000000..97d96f9
--- /dev/null
+++ b/project.godot
@@ -0,0 +1,95 @@
+; Engine configuration file.
+; It's best edited using the editor UI and not directly,
+; since the parameters that go here are not all obvious.
+;
+; Format:
+; [section] ; section goes between []
+; param=value ; assign values to parameters
+
+config_version=4
+
+_global_script_classes=[ {
+"base": "HBoxContainer",
+"class": "ActionIcons",
+"language": "GDScript",
+"path": "res://addons/remap/ActionIcons.gd"
+}, {
+"base": "HBoxContainer",
+"class": "ActionLabel",
+"language": "GDScript",
+"path": "res://addons/remap/ActionLabel.gd"
+}, {
+"base": "Reference",
+"class": "IconMap",
+"language": "GDScript",
+"path": "res://addons/remap/IconMap.gd"
+}, {
+"base": "ActionLabel",
+"class": "InteractiveActionLabel",
+"language": "GDScript",
+"path": "res://addons/remap/InteractiveActionLabel.gd"
+}, {
+"base": "Node",
+"class": "KeySelector",
+"language": "GDScript",
+"path": "res://addons/remap/KeySelector.gd"
+}, {
+"base": "Reference",
+"class": "RemapUtilities",
+"language": "GDScript",
+"path": "res://addons/remap/RemapUtilities.gd"
+} ]
+_global_script_class_icons={
+"ActionIcons": "",
+"ActionLabel": "",
+"IconMap": "",
+"InteractiveActionLabel": "",
+"KeySelector": "",
+"RemapUtilities": ""
+}
+
+[application]
+
+config/name="Godot Template"
+run/main_scene="res://Test.tscn"
+config/use_custom_user_dir=true
+config/custom_user_dir_name="GodotTemplate"
+
+[debug]
+
+gdscript/warnings/return_value_discarded=false
+
+[display]
+
+window/size/width=320
+window/size/height=180
+window/size/test_width=1280
+window/size/test_height=720
+window/dpi/allow_hidpi=true
+window/stretch/mode="2d"
+window/stretch/aspect="expand"
+
+[input]
+
+ui_left={
+"deadzone": 0.5,
+"events": [ Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":16777229,"unicode":0,"echo":false,"script":null)
+, Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null)
+ ]
+}
+
+[logging]
+
+file_logging/enable_file_logging=true
+
+[rendering]
+
+quality/driver/driver_name="GLES2"
+2d/options/use_nvidia_rect_flicker_workaround=true
+quality/intended_usage/framebuffer_allocation=0
+quality/intended_usage/framebuffer_allocation.mobile=0
+2d/snapping/use_gpu_pixel_snap=true
+vram_compression/import_etc=true