initial commit: gd-controls plugin scaffolding

- promptfont font assets and license
- key_mapping CSVs for Godot input bindings and prompt-font glyphs
  across keyboard/mouse, PC/Xbox/Sony/Nintendo controllers, and touch
- gen.py generates prompt_font_mapping.gd from key_mapping/promptfont.csv,
  splicing between STARTGEN/ENDGEN markers
- device, manager, file_manager scaffolding (work in progress)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Daniel Samson 2026-04-28 23:07:46 +01:00
commit ab63851a74
No known key found for this signature in database
GPG Key ID: A9EB2589C60F7268
38 changed files with 36469 additions and 0 deletions

16
.gitignore vendored Normal file
View File

@ -0,0 +1,16 @@
# macOS
.DS_Store
# Godot 4+
.godot/
.import/
export.cfg
export_presets.cfg
# Imported translations (autogenerated from CSVs)
*.translation
# Mono
.mono/
data_*/
mono_crash.*.json

9
LICENSE Normal file
View File

@ -0,0 +1,9 @@
MIT License
Copyright (c) 2026 funfirerabbit
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.

10
README.md Normal file
View File

@ -0,0 +1,10 @@
# gd-controls
Standardize game controls framework
- Input detection for keyboard/mouse, PC/XBox/Playstation/Nintendo controller
- Custom GameControlLabel that changes the symbols based on the input detection
## Default Mapping
gd-controls comes with [default mapping](key_mapping/names.csv) and mapping to the [promptfont icon font set](key_mapping/promptfont.csv).

View File

@ -0,0 +1,91 @@
This Font Software is licensed under the SIL Open Font License,
Version 1.1. This license is copied below, and is also available
with a FAQ at <http://scripts.sil.org/OFL>
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View File

@ -0,0 +1,66 @@
## About PromptFont
This is a font designed for user interfaces and button prompts in games. It includes the base alphabet, icons for keys, gamepad buttons, devices, and a wide variety of general user interface icons like stats, actions, items, attributes, and more. All the icons included in the font are custom made and available under the same [SIL Open Font Licence](LICENSE.txt). Included trademarks however of course still belong to their respective owners.
PromptFont is based on the Xolonium font by Severin Meyer.
## Attribution
If you use this font in your project please leave an attribution notice in your credits like this:
> PromptFont by Yukari "Shinmera" Hafner, available at https://shinmera.com/promptfont
## Release Files
The [PromptFont release](https://codeberg.org/shinmera/promptfont/releases/download/latest/promptfont.zip) includes a couple of files. Here's what they're for:
- ``LICENSE.txt``
A copy of the SIL Open Font license
- ``README.md``
A copy of this readme
- ``index.html``
A copy of the [website](https://shinmera.com/docs/promptfont) so you can use it offline as well
- ``glyphs.json``
This is a JSON file with an array of the glyphs the font provides. Each glyph is an object with the following attributes:
- ``character`` The actual character as a one-character string
- ``code`` The unicode codepoint name (``U+XXXX``)
- ``codepoint`` The actual codepoint as an integer
- ``category`` The category the glyph belongs to
- ``name`` The unique human-readable name of the glyph
- ``code-name`` The unique code-readable name of the glyph. It only contains lowercase characters a-z, numbers 0-9, and dashes. This should make it easy to turn into a code symbol
- ``tags`` A list of tags that apply to the glyph. There are a number of tags for glyph variants and so on, but the most important categories are probably:
- ``analog`` Analog stick movements and `l`, `r`, `s` for the sticks
- ``button`` Button presses and `x`, `y`, `a`, `b`, `l1`, `r1`, `l3`, `r3`, etc for the buttons
- ``dpad`` Dpad movements
- ``key`` Keyboard keys
- ``touch``, ``press``, ``hold``, ``release``, ``move-l``, ``move-r``, ``move-u``, ``move-d``, etc for movements
- ``device`` Device icons
- ``xbox`` Applies to Xbox style gamepads
- ``nintendo`` Applies to Nintendo style gamepads
- ``sony`` Applies to Sony Playstation style gamepads
- ``generic`` Applies to any gamepad
- ``ui`` User interface icons
- ``wide-alternate`` The glyph has a wider alternate variant to its standard unit square representation. You can get the variant by shifting the codepoint up by 2560 (`0xA00`). If you use a text system that supports ligatures, you can instead use a zero-width space (`U+200B`) after a glyph to select its wide variant, if available. Since the zero-width space is invisible, if no wide alternate is available, it won't be visible that you tried to select for one, making the process completely transparent.
- ``backfill`` This is a backfill glyph, intended for use together with another appropriate glyph. By using a different colour for the backfill glyph than for the following glyph, you can provide additional contrast and styling control for your prompt displays. If you use a text system that supports ligatures, you can instead use a zero-width joining space (`U+200A`) after a glyph to select its appropriate backfill glyph. So to create, for instance, a backfilled left click, you would write ``\\u278A\\u200A\\u278A`` and change the text colour for the first two and third characters.
- ``tags.txt``
A plaintext CSV file that maps all of the tags to the ``code-name`` of each glyph that was tagged as such. Each line is simply the tag name followed by the code names separated by a space.
- ``promptfont.txt``
A plaintext UTF-8 file that contains all the characters that the font provides.
- ``promptfont.ttf`` ``promptfont.otf`` ``promptfont.woff`` ``promptfont.woff2``
Compiled versions of the font, which you should be able to use directly in-engine or other programs.
- ``promptfont.css``
A CSS file that includes CSS classes for every special glyph, so you can easily embed it in HTML pages and JS games.
- ``promptfont.h`` ``promptfont.cs`` ``promptfont.py`` ``promptfont.lua`` ``promptfont.lisp`` ``promptfont.rs`` ``promptfont.gd`` ``promptfont.gml``
Source files that define constants for the special glyphs to allow easier embedding in C, C++, C#, Python, Lua, Lisp, Rust, GDScript and GML.
- ``promptfont.exe`` ``promptfont.run`` ``promptfont.o``
Binaries of the promptfont utilities. You can use this to search for glyphs or to compile the data files from the json representation.
- ``atlas-*.png``
Texture atlases of the various glyphs. Each glyph is 64x64 pixels and has a 1 pixel margin around itself. They are ordered left to right top to bottom according to their filename in the ``glyphs/`` directory of this repository. Since these rasterised versions don't scale well we heavily recommend you to use the fonts directly.
## Engine Specifics
Since there's far too many engines out there and their methods vary a lot, we can't include guides in this repository. For specifics on how to use this font in your engine of choice, please consult the [user-contributed Wiki](https://shinmera.com/project/promptfont/wiki/).
## Contributing Glyphs
For a brief guide on what to watch out for if you'd like to contribute to this font, please see the [CONTRIBUTING.md](CONTRIBUTING.md) file. If you'd like to request new glyphs to be added, please comment on the [issue ticket]().
## Support
If you'd like to support the continued development of PromptFont, please consider becoming a backer on Patreon:
[![Patreon](https://filebox.tymoon.eu//file/TWpjeU9RPT0=)](https://patreon.com/shinmera)

16628
fonts/promptfont/editor.js Normal file

File diff suppressed because it is too large Load Diff

11135
fonts/promptfont/glyphs.json Normal file

File diff suppressed because it is too large Load Diff

325
fonts/promptfont/index.css Normal file
View File

@ -0,0 +1,325 @@
@font-face {
font-family: 'integratedpromptfont';
src: url('promptfont.ttf');
}
@keyframes fadeOut {
0% { opacity: 1;}
50% { opacity: 1;}
100% { opacity: 0;}
}
@keyframes rainbow{
100%,0%{color: rgb(255,0,0)}
8%{color: rgb(255,127,0)}
16%{color: rgb(255,255,0)}
25%{color: rgb(127,255,0)}
33%{color: rgb(0,255,0)}
41%{color: rgb(0,255,127)}
50%{color: rgb(0,255,255)}
58%{color: rgb(0,127,255)}
66%{color: rgb(0,0,255)}
75%{color: rgb(127,0,255)}
83%{color: rgb(255,0,255)}
91%{color: rgb(255,0,127)}
}
body {
font-family: sans-serif;
font-size: 14pt;
margin: 0 auto;
max-width: 1280px;
overflow-y: scroll;
}
header {
padding: 1em;
border-bottom: 3px solid #CCCCCC;
}
footer {
padding: 1em;
border-top: 3px solid #CCCCCC;
text-align: center;
}
footer img {
max-width: 800px;
margin: 0 auto 2em auto;
}
a.button {
font-size: 18pt;
font-weight: normal;
color: black;
background: #EEEEEE;
border: 2px solid #CCCCCC;
border-radius: .2em;
padding: .2em .4em;
margin: .2em;
text-decoration: none;
cursor: pointer;
}
a.button:hover {
background: #CCCCCC;
}
main {
background: #EEEEEE;
padding: 2em 0 2em 0;
}
input {
color: inherit;
}
input.search {
box-sizing: border-box;
width: 20em;
display: block;
margin: 0 auto;
padding: 0.2em 0.5em;
border-radius: 0.2em;
}
.search {
font-size: 1.5em;
border: 1px solid #CCCCCC;
}
.composer {
text-align: center;
font-size: 1.5em;
background: #CCCCCC;
font-family: integratedpromptfont;
position: fixed;
left: 0; right: 0; bottom: 0;
}
.composer .ProseMirror {
padding: 0.2em 0.5em;
}
.composer .ProseMirror-menubar {
border-width: 3px;
}
.composer .ProseMirror-menuitem {
position: relative;
display: inline-flex;
}
.composer .ProseMirror-menuitem .panel {
position: absolute;
top: 1em;
display: flex;
background: #303030;
align-items: center;
padding: 0.2em 0.5em;
}
input.composer {
box-sizing: border-box;
font-family: inherit;
width: 100%;
display: block;
padding: 0.2em 0.5em;
border: none;
}
input.composer:focus {
outline: none;
}
.glyphsection {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.glyphsection h2 {
width: 100%;
text-align: center;
}
.glyph {
text-align: center;
margin: 1em;
width: 8em;
cursor: pointer;
}
.glyph span {
display: block;
}
.glyph code {
display: block;
}
.glyph i {
display: block;
font-family: integratedpromptfont;
font-size: 32pt;
font-style: normal;
transition: font-size .5s;
}
.glyph:hover i{
font-size: 8em;
}
.notice{
position: fixed;
top: 0;
left: 0;
right: 0;
text-align: center;
padding: 0.5em 1em;
font-size: 1.5em;
background: white;
color: black;
border-bottom: 2px solid #CCCCCC;
opacity: 1;
animation: fadeOut 2s;
animation-fill-mode: forwards;
}
.notice i{
font-family: integratedpromptfont;
font-style: normal;
display: inline-block;
min-width: 1em;
}
img{
max-width: 100%;
}
.hidden{
display: none !important;
}
#popup{
background: rgba(0,0,0,0.5);
position: fixed;
left: 0; right: 0; top: 0; bottom: 0;
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
}
#popup .box{
flex-grow: 0;
background: white;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 3em 1fr 1fr;
column-gap: 0.5em;
row-gap: 0.5em;
font-size: 1.5em;
box-shadow: 0 0 5em rgba(0,0,0,0.2);
}
#popup .box i{
font-family: integratedpromptfont;
font-style: normal;
}
#popup .box nav{
grid-column: 1 / 3;
grid-row: 1 / 2;
font-size: 1.2em;
display: flex;
align-items: center;
background: #303030;
color: #EFEFEF;
}
#popup .copy:hover, #popup .compose:hover{
color: orange;
cursor: pointer;
}
#popup .box nav *{
margin: 0.5em;
}
#popup .box nav i{
width: 1em;
text-align: center;
}
#popup .box nav h2{
flex-grow: 1;
font-size: 1.5em;
font-weight: bold;
}
#popup .box .preview{
grid-column: 1 / 2;
display: flex;
align-items: center;
justify-content: center;
font-size: 72pt;
padding: 0.5em 2em;
cursor: default;
}
#popup .box .preview.black{
grid-row: 2/3;
background: #202020;
color: #E0E0E0;
}
#popup .box .preview.white{
grid-row: 3/4;
background: #E0E0E0;
color: #202020;
}
#popup .box .preview i:hover{
animation: rainbow 10s linear;
animation-iteration-count: infinite;
}
#popup .box .info{
grid-column: 2 / 3;
grid-row: 2 / 4;
padding: 1em;
}
#popup .box .info .row{
display: flex;
}
#popup .box .info .row *{
flex-grow: 1;
}
#popup .box .info .row label{
flex-grow: 0;
min-width: 6em;
display: inline-block;
}
.glyphsection#all .glyph {
width: 3em;
}
.glyphsection#all code {
display: none;
}
.glyphsection#all span {
display: none;
}
@media (prefers-color-scheme: dark){
body {
background: #202020;
color: #E0E0E0;
}
header {
border-color: #303030;
}
a {
color: orange;
}
a.button {
color: white;
background: #303030;
border-color: #555555;
}
a.button:hover {
background: #555555;
}
main {
background: #151515;
color: #D0D0D0;
}
.search {
background: #101010;
border-color: #555555;
}
.composer {
background: #252525;
}
.composer .ProseMirror-menubar {
background: #303030;
border-color: #555555;
}
.composer .ProseMirror-menuitem .ProseMirror-menu-active {
background: #151515;
}
.composer .ProseMirror-menuseparator {
border-color: #505050;
}
.notice {
background: black;
color: white;
border-color: #555555;
}
#popup {
background: rgba(0,0,0,0.5);
}
#popup .box {
background: #202020;
box-shadow: 0 0 5em rgba(0,0,0,1.0);
}
#popup .box nav {
background: #303030;
}
}

4992
fonts/promptfont/index.html Normal file

File diff suppressed because it is too large Load Diff

132
fonts/promptfont/index.js Normal file
View File

@ -0,0 +1,132 @@
let notice = null;
let clearNotice = ()=>{
if(notice){
clearTimeout(notice.timeout);
document.body.removeChild(notice.element);
notice = null;
}
}
let showNotice = (html)=>{
clearNotice();
notice = {};
notice.element = document.createElement("div");
notice.element.setAttribute("class", "notice");
notice.element.innerHTML = html;
document.body.appendChild(notice.element);
notice.timeout = setTimeout(clearNotice, 2000);
};
let copyToClipboard = (string)=>{
navigator.clipboard.writeText(string).then(
()=>showNotice("<i>"+string+"</i> copied to clipboard!"),
()=>showNotice("Failed to copy to clipboard."));
};
let match = (query, el)=>{
query = query.trim().toLowerCase();
if(query === "") return true;
let inner = el.innerText.toLowerCase();
for(let k in el.dataset){
inner += " "+k+":"+el.dataset[k].toLowerCase();
}
for(let part of query.split(/ +/)){
if(!inner.includes(part))
return false;
}
return true;
};
let find = (query)=>{
for(let glyph of document.querySelectorAll(".glyph")){
if(match(query, glyph)) return glyph;
};
return null;
};
let composer = document.querySelector(".composer");
composer.compose = (glyph)=>{
composer.value += glyph.dataset["character"];
};
let popup = document.querySelector("#popup");
popup.glyph = null;
popup.addEventListener("click", ()=>popup.classList.add("hidden"));
popup.querySelector(".box").addEventListener("click", (ev)=>ev.stopPropagation());
let hidePopup = ()=>popup.classList.add("hidden");
let showPopup = (glyph)=>{
popup.glyph = glyph;
for(let el of popup.querySelectorAll("[data-text]"))
el.innerText = glyph.dataset[el.dataset.text];
popup.classList.remove("hidden");
};
for(let el of popup.querySelectorAll(".copy")){
el.addEventListener("click", ()=>{
copyToClipboard(el.innerText);
});
}
for(let el of popup.querySelectorAll(".compose")){
el.addEventListener("click", ()=>{
composer.compose(popup.glyph);
hidePopup();
});
}
for(let el of document.querySelectorAll(".glyph")){
el.addEventListener("click", (ev)=>{
if(ev.ctrlKey) composer.compose(el);
else showPopup(el)
});
}
let search = document.querySelector("input[type=search]");
search.addEventListener("input", (ev)=>{
let query = search.value;
for(let glyph of document.querySelectorAll(".glyph")){
if(match(query, glyph))
glyph.classList.remove("hidden");
else
glyph.classList.add("hidden");
}
for(let section of document.querySelectorAll(".glyphsection")){
if(section.querySelector(".glyph:not(.hidden)") !== null)
section.classList.remove("hidden");
else
section.classList.add("hidden");
}
});
// Try the editor
editor(composer);
// Query parameter wrangling
search.value = new URLSearchParams(document.location.search).get("q");
if(search.value) search.dispatchEvent(new Event('input', {bubbles: true}));
let pre = new URLSearchParams(document.location.search).get("c");
if(pre){
for(let query of pre.split(' ')){
let found = find(query);
if(found) composer.compose(found);
}
}
let updateQuery = ()=>{
const url = new URL(window.location.href);
if(search.value)
url.searchParams.set("q", search.value);
else
url.searchParams.delete("q");
if(composer.value){
let parts = [];
for(const codepoint of composer.value){
let hex = codepoint.codePointAt(0).toString(16);
parts.push("0000".substring(0, 4-hex.length)+hex);
}
url.searchParams.set("c", parts.join(" "));
}else
url.searchParams.delete("c");
window.history.replaceState(null, '', url);
}
search.addEventListener("change", updateQuery);
composer.addEventListener("change", updateQuery);

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dketekofafye3"
path="res://.godot/imported/preview.png-77f4630472c09587c75dd6977ce13622.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/gd-controls/fonts/promptfont/preview.png"
dest_files=["res://.godot/imported/preview.png-77f4630472c09587c75dd6977ce13622.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
uid://etgn2q4yux0u

Binary file not shown.

View File

@ -0,0 +1,36 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://cghf1fy60knvy"
path="res://.godot/imported/promptfont.otf-b6ba09760ea41d2b073d643b500ef004.fontdata"
[deps]
source_file="res://addons/gd-controls/fonts/promptfont/promptfont.otf"
dest_files=["res://.godot/imported/promptfont.otf-b6ba09760ea41d2b073d643b500ef004.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
modulate_color_glyphs=false
hinting=1
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

Binary file not shown.

View File

@ -0,0 +1,36 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://c3om505vtdpp0"
path="res://.godot/imported/promptfont.ttf-8779440645ca7068936c9cabdf3fceb2.fontdata"
[deps]
source_file="res://addons/gd-controls/fonts/promptfont/promptfont.ttf"
dest_files=["res://.godot/imported/promptfont.ttf-8779440645ca7068936c9cabdf3fceb2.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
modulate_color_glyphs=false
hinting=1
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

Binary file not shown.

View File

@ -0,0 +1,36 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://wgxc825f3m34"
path="res://.godot/imported/promptfont.woff-ca88eefa4915f5fb3e36fc7b94510676.fontdata"
[deps]
source_file="res://addons/gd-controls/fonts/promptfont/promptfont.woff"
dest_files=["res://.godot/imported/promptfont.woff-ca88eefa4915f5fb3e36fc7b94510676.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
modulate_color_glyphs=false
hinting=1
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

Binary file not shown.

View File

@ -0,0 +1,36 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://b4e4tohgnvhpp"
path="res://.godot/imported/promptfont.woff2-0ff9573f54305acbf524118b660508f6.fontdata"
[deps]
source_file="res://addons/gd-controls/fonts/promptfont/promptfont.woff2"
dest_files=["res://.godot/imported/promptfont.woff2-0ff9573f54305acbf524118b660508f6.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
modulate_color_glyphs=false
hinting=1
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

435
fonts/promptfont/tags.txt Normal file

File diff suppressed because one or more lines are too long

0
key_mapping/.gdignore Normal file
View File

25
key_mapping/names.csv Normal file
View File

@ -0,0 +1,25 @@
KEY,GODOT,KEYBOARD_1,KEYBOARD_2,MOUSE,PC_CONTROLLER,XBOX_CONTROLLER,SONY_CONTROLLER,NINTENDO_CONTROLLER,TOUCH
DPAD_UP,Joypad Button 11,1,1,Mouse Wheel Up,D-PAD Up,D-PAD Up,D-PAD Up,,
DPAD_RIGHT,Joypad Button 13,2,2,Mouse Thumb Button 1,D-PAD Right,D-PAD Right,D-PAD Right,,
DPAD_DOWN,Joypad Button 12,3,3,Mouse Wheel Down,D-PAD Down,D-PAD Down,D-PAD Down,,
DPAD_LEFT,Joypad Button 14,4,4,Mouse Thumb Button 2,D-PAD Up,D-PAD Up,D-PAD Up,,
AXIS_LS_UP,Joypad Axis 1 -,UP,W,,Joystick 0 Up,Left Stick Up,Left Stick Up,Left Stick Up,
AXIS_LS_RIGHT,Joypad Axis 0 +,RIGHT,D,,Joystick 0 Right,Left Stick Right,Left Stick Right,Left Stick Right,
AXIS_LS_DOWN,Joypad Axis 1 +,DOWN,S,,Joystick 0 Down,Left Stick Down,Left Stick Down,Left Stick Down,
AXIS_LS_LEFT,Joypad Axis 0 -,LEFT,A,,Joystick 0 Left,Left Stick Left,Left Stick Left,Left Stick Left,
AXIS_RS_UP,Joypad Axis 3 -,,,MOUSE -Y,Joystick 1 Up,Right Stick Up,Right Stick Up,Right Stick Up,
AXIS_RS_RIGHT,Joypad Axis 2 +,,,MOUSE +X,Joystick 1 Right,Right Stick Right,Right Stick Right,Right Stick Right,
AXIS_RS_DOWN,Joypad Axis 3 +,,,MOUSE +Y,Joystick 1Down,Right Stick Down,Right Stick Down,Right Stick Down,
AXIS_RS_LEFT,Joypad Axis 2 -,,,MOUSE -X,Joystick 1 Left,Right Stick Left,Right Stick Left,Right Stick Left,
ACTION_LS,Joypad Button 7,Z,Z,,Left Stick,LS,L3,,
ACTION_RS,Joypad Button 8,X,X,,Right Stick,RS,R3,,
ACTION_START,Joypad Button 6,Enter,Enter,,Start,Menu,Start,+,
ACTION_BACK,Joypad Button 4,Backspace,Backspace,,Back,Back,Select,-,
ACTION_TOP,Joypad Button 3,R,R,,Top Action,Y,Triangle,X,
ACTION_BOTTOM,Joypad Button 0,E,E,Mouse Button Left,Bottom Action,A,Cross,B,
ACTION_LEFT,Joypad Button 2,F,F,,Left Action,X,Square,Y,
ACTION_RIGHT,Joypad Button 1,C,C,Mouse Button Right,Right Action,B,Circle,A,
ACTION_LB,Joypad Button 9,Q,Q,,Left Shoulder,LB,L1,,
ACTION_RB,Joypad Button 10,T,T,,Right Shoulder,RB,R1,,
AXIS_LT,Joypad Axis 4 +,CTRL,CTRL,,Left Trigger,LT,L2,,
AXIS_RT,Joypad Axis 5 +,SPACE,SPACE,,Right Trigger,RT,R2,,
1 KEY GODOT KEYBOARD_1 KEYBOARD_2 MOUSE PC_CONTROLLER XBOX_CONTROLLER SONY_CONTROLLER NINTENDO_CONTROLLER TOUCH
2 DPAD_UP Joypad Button 11 1 1 Mouse Wheel Up D-PAD Up D-PAD Up D-PAD Up
3 DPAD_RIGHT Joypad Button 13 2 2 Mouse Thumb Button 1 D-PAD Right D-PAD Right D-PAD Right
4 DPAD_DOWN Joypad Button 12 3 3 Mouse Wheel Down D-PAD Down D-PAD Down D-PAD Down
5 DPAD_LEFT Joypad Button 14 4 4 Mouse Thumb Button 2 D-PAD Up D-PAD Up D-PAD Up
6 AXIS_LS_UP Joypad Axis 1 - UP W Joystick 0 Up Left Stick Up Left Stick Up Left Stick Up
7 AXIS_LS_RIGHT Joypad Axis 0 + RIGHT D Joystick 0 Right Left Stick Right Left Stick Right Left Stick Right
8 AXIS_LS_DOWN Joypad Axis 1 + DOWN S Joystick 0 Down Left Stick Down Left Stick Down Left Stick Down
9 AXIS_LS_LEFT Joypad Axis 0 - LEFT A Joystick 0 Left Left Stick Left Left Stick Left Left Stick Left
10 AXIS_RS_UP Joypad Axis 3 - MOUSE -Y Joystick 1 Up Right Stick Up Right Stick Up Right Stick Up
11 AXIS_RS_RIGHT Joypad Axis 2 + MOUSE +X Joystick 1 Right Right Stick Right Right Stick Right Right Stick Right
12 AXIS_RS_DOWN Joypad Axis 3 + MOUSE +Y Joystick 1Down Right Stick Down Right Stick Down Right Stick Down
13 AXIS_RS_LEFT Joypad Axis 2 - MOUSE -X Joystick 1 Left Right Stick Left Right Stick Left Right Stick Left
14 ACTION_LS Joypad Button 7 Z Z Left Stick LS L3
15 ACTION_RS Joypad Button 8 X X Right Stick RS R3
16 ACTION_START Joypad Button 6 Enter Enter Start Menu Start +
17 ACTION_BACK Joypad Button 4 Backspace Backspace Back Back Select -
18 ACTION_TOP Joypad Button 3 R R Top Action Y Triangle X
19 ACTION_BOTTOM Joypad Button 0 E E Mouse Button Left Bottom Action A Cross B
20 ACTION_LEFT Joypad Button 2 F F Left Action X Square Y
21 ACTION_RIGHT Joypad Button 1 C C Mouse Button Right Right Action B Circle A
22 ACTION_LB Joypad Button 9 Q Q Left Shoulder LB L1
23 ACTION_RB Joypad Button 10 T T Right Shoulder RB R1
24 AXIS_LT Joypad Axis 4 + CTRL CTRL Left Trigger LT L2
25 AXIS_RT Joypad Axis 5 + SPACE SPACE Right Trigger RT R2

View File

@ -0,0 +1,25 @@
KEY,GODOT,KEYBOARD_1,KEYBOARD_2,MOUSE,PC_CONTROLLER,XBOX_CONTROLLER,SONY_CONTROLLER,NINTENDO_CONTROLLER,TOUCH
DPAD_UP,Joypad Button 11,U+FF11,,U+27F0,U+2200,U+227B,U+219F,,
DPAD_RIGHT,Joypad Button 13,U+FF12,,U+278D,U+2201,U+227C,U+21A0,,
DPAD_DOWN,Joypad Button 12,U+FF13,,U+27F1,U+2202,U+227D,U+21A1,,
DPAD_LEFT,Joypad Button 14,U+FF14,,U+278E,U+21FF,U+227A,U+219E,,
AXIS_LS_UP,Joypad Axis 1 -,U+23F6,U+FF37,,,U+21BE,U+21BE,U+21BE,
AXIS_LS_RIGHT,Joypad Axis 0 +,U+23F5,U+FF24,,,U+21C0,U+21C0,U+21C0,
AXIS_LS_DOWN,Joypad Axis 1 +,U+23F7,U+FF33,,,U+21C2,U+21C2,U+21C2,
AXIS_LS_LEFT,Joypad Axis 0 -,U+23F4,U+FF21,,,U+21BC,U+21BC,U+21BC,
AXIS_RS_UP,Joypad Axis 3 -,,,U+27F9,,U+21BF,U+21BF,U+21BF,
AXIS_RS_RIGHT,Joypad Axis 2 +,,,U+27FD,,U+21C1,U+21C1,U+21C1,
AXIS_RS_DOWN,Joypad Axis 3 +,,,U+27FE,,U+21C3,U+21C3,U+21C3,
AXIS_RS_LEFT,Joypad Axis 2 -,,,U+27F8,,U+21BD,U+21BD,U+21BD,
ACTION_LS,Joypad Button 7,U+FF3A,,,,U+21BA,U+21EF,,
ACTION_RS,Joypad Button 8,U+FF38,,,,U+21BB,U+21F0,,
ACTION_START,Joypad Button 6,U+242E,,,U+21F8,U+21FA,U+21F8,U+21FE,
ACTION_BACK,Joypad Button 4,U+242D,,,U+21F7,U+21FB,U+21F7,U+21FD,
ACTION_TOP,Joypad Button 3,U+FF32,,,,U+21D1,U+21E1,U+21D0,
ACTION_BOTTOM,Joypad Button 0,U+FF25,,U+278A,,U+21D3,U+21E3,U+21D2,
ACTION_LEFT,Joypad Button 2,U+FF26,,,,U+21D0,U+21E0,U+21D1,
ACTION_RIGHT,Joypad Button1,U+FF23,,U+278B,,U+21D2,U+21E2,U+21D3,
ACTION_LB,Joypad Button 9,U+FF31,,,U+2198,U+2198,U+21B0,,
ACTION_RB,Joypad Button 10,U+FF34,,,U+2199,U+2199,U+21B1,,
AXIS_LT,Joypad Axis 4 +,U+2427,,,U+2196,U+2196,U+21B2,,
AXIS_RT,Joypad Axis 5 +,U+243A,,,U+2197,U+2197,U+21B3,,
1 KEY GODOT KEYBOARD_1 KEYBOARD_2 MOUSE PC_CONTROLLER XBOX_CONTROLLER SONY_CONTROLLER NINTENDO_CONTROLLER TOUCH
2 DPAD_UP Joypad Button 11 U+FF11 U+27F0 U+2200 U+227B U+219F
3 DPAD_RIGHT Joypad Button 13 U+FF12 U+278D U+2201 U+227C U+21A0
4 DPAD_DOWN Joypad Button 12 U+FF13 U+27F1 U+2202 U+227D U+21A1
5 DPAD_LEFT Joypad Button 14 U+FF14 U+278E U+21FF U+227A U+219E
6 AXIS_LS_UP Joypad Axis 1 - U+23F6 U+FF37 U+21BE U+21BE U+21BE
7 AXIS_LS_RIGHT Joypad Axis 0 + U+23F5 U+FF24 U+21C0 U+21C0 U+21C0
8 AXIS_LS_DOWN Joypad Axis 1 + U+23F7 U+FF33 U+21C2 U+21C2 U+21C2
9 AXIS_LS_LEFT Joypad Axis 0 - U+23F4 U+FF21 U+21BC U+21BC U+21BC
10 AXIS_RS_UP Joypad Axis 3 - U+27F9 U+21BF U+21BF U+21BF
11 AXIS_RS_RIGHT Joypad Axis 2 + U+27FD U+21C1 U+21C1 U+21C1
12 AXIS_RS_DOWN Joypad Axis 3 + U+27FE U+21C3 U+21C3 U+21C3
13 AXIS_RS_LEFT Joypad Axis 2 - U+27F8 U+21BD U+21BD U+21BD
14 ACTION_LS Joypad Button 7 U+FF3A U+21BA U+21EF
15 ACTION_RS Joypad Button 8 U+FF38 U+21BB U+21F0
16 ACTION_START Joypad Button 6 U+242E U+21F8 U+21FA U+21F8 U+21FE
17 ACTION_BACK Joypad Button 4 U+242D U+21F7 U+21FB U+21F7 U+21FD
18 ACTION_TOP Joypad Button 3 U+FF32 U+21D1 U+21E1 U+21D0
19 ACTION_BOTTOM Joypad Button 0 U+FF25 U+278A U+21D3 U+21E3 U+21D2
20 ACTION_LEFT Joypad Button 2 U+FF26 U+21D0 U+21E0 U+21D1
21 ACTION_RIGHT Joypad Button1 U+FF23 U+278B U+21D2 U+21E2 U+21D3
22 ACTION_LB Joypad Button 9 U+FF31 U+2198 U+2198 U+21B0
23 ACTION_RB Joypad Button 10 U+FF34 U+2199 U+2199 U+21B1
24 AXIS_LT Joypad Axis 4 + U+2427 U+2196 U+2196 U+21B2
25 AXIS_RT Joypad Axis 5 + U+243A U+2197 U+2197 U+21B3

7
plugin.cfg Normal file
View File

@ -0,0 +1,7 @@
[plugin]
name="gd-controls"
description="Game Controls Framework"
author="Daniel Samson"
version="0.1.0"
script="plugin.gd"

9
plugin.gd Normal file
View File

@ -0,0 +1,9 @@
@tool
extends EditorPlugin
func _enter_tree() -> void:
add_autoload_singleton("GdControlsManager", "res://addons/gd-controls/src/manager.gd")
func _exit_tree() -> void:
pass

1
plugin.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://dn8h7dfs18qp0

38
src/device.gd Normal file
View File

@ -0,0 +1,38 @@
extends Node
class_name GdControlsDevice
enum MODE {
KEYBOARD_1_AND_MOUSE,
KEYBOARD_2_AND_MOUSE,
PC_CONTROLLER,
XBOX_CONTROLLER,
SONY_CONTROLLER,
NINTENDO_CONTROLLER,
TOUCH,
}
const KEY_DPAD_UP = "DPAD_UP"
const KEY_DPAD_RIGHT = "DPAD_RIGHT"
const KEY_DPAD_DOWN = "DPAD_DOWN"
const KEY_DPAD_LEFT = "DPAD_LEFT"
const KEY_AXIS_LS_UP = "AXIS_LS_UP"
const KEY_AXIS_LS_RIGHT = "AXIS_LS_RIGHT"
const KEY_AXIS_LS_DOWN = "AXIS_LS_DOWN"
const KEY_AXIS_LS_LEFT = "AXIS_LS_LEFT"
const KEY_AXIS_RS_UP = "AXIS_RS_UP"
const KEY_AXIS_RS_RIGHT = "AXIS_RS_RIGHT"
const KEY_AXIS_RS_DOWN = "AXIS_RS_DOWN"
const KEY_AXIS_RS_LEFT = "AXIS_RS_LEFT"
const KEY_ACTION_LS = "ACTION_LS"
const KEY_ACTION_RS = "ACTION_RS"
const KEY_ACTION_START = "ACTION_START"
const KEY_ACTION_BACK = "ACTION_BACK"
const KEY_ACTION_TOP = "ACTION_TOP"
const KEY_ACTION_BOTTOM = "ACTION_BOTTOM"
const KEY_ACTION_LEFT = "ACTION_LEFT"
const KEY_ACTION_RIGHT = "ACTION_RIGHT"
const KEY_ACTION_LB = "ACTION_LB"
const KEY_ACTION_RB = "ACTION_RB"
const KEY_AXIS_LT = "AXIS_LT"
const KEY_AXIS_RT = "AXIS_RT"

1
src/device.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://qbwgdgojsxbq

20
src/file_manager.gd Normal file
View File

@ -0,0 +1,20 @@
extends Node
class_name GdControlsFileManager
static func load_file(path: String, initial_data: Dictionary = {}) -> Dictionary:
if not FileAccess.file_exists(path):
save_file(path, initial_data)
var save_game = FileAccess.get_file_as_string(path)
var parse_result = JSON.parse_string(save_game)
if parse_result == null:
printerr("JSON Parse Error: " + path)
return parse_result
static func save_file(path: String, data: Dictionary) -> void:
var save_game = FileAccess.open(path, FileAccess.WRITE)
var json_string = JSON.stringify(data)
save_game.store_line(json_string)
save_game.close()

1
src/file_manager.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://csvyd7w86gf1i

87
src/gen.py Normal file
View File

@ -0,0 +1,87 @@
#!/usr/bin/env python3
"""Regenerate prompt_font_mapping.gd from key_mapping/promptfont.csv.
Splices the generated dictionary between the STARTGEN/ENDGEN markers in
the .gd file, leaving the surrounding scaffolding (extends, class_name,
and the warning header) intact.
"""
from pathlib import Path
import csv
import sys
ADDON = Path(__file__).resolve().parent.parent
CSV_PATH = ADDON / "key_mapping" / "promptfont.csv"
OUT_PATH = ADDON / "src" / "prompt_font_mapping.gd"
# Each output MODE pulls its character from the first non-empty cell in
# the listed CSV columns, in order. This lets keyboard modes fall back
# to mouse for right-stick rows that only have a mouse glyph.
MODE_TO_COLUMNS = {
"KEYBOARD_1_AND_MOUSE": ["KEYBOARD_1", "MOUSE"],
"KEYBOARD_2_AND_MOUSE": ["KEYBOARD_2", "MOUSE"],
"PC_CONTROLLER": ["PC_CONTROLLER"],
"XBOX_CONTROLLER": ["XBOX_CONTROLLER"],
"SONY_CONTROLLER": ["SONY_CONTROLLER"],
"NINTENDO_CONTROLLER": ["NINTENDO_CONTROLLER"],
"TOUCH": ["TOUCH"],
}
START_MARKER = "# === STARTGEN ==="
END_MARKER = "# === ENDGEN ==="
def codepoint_to_char(value: str) -> str:
value = value.strip()
if not value:
return ""
if not value.startswith("U+"):
raise ValueError(f"unexpected codepoint format: {value!r}")
return chr(int(value[2:], 16))
def gd_escape(s: str) -> str:
return s.replace("\\", "\\\\").replace('"', '\\"')
def render(rows: list[dict]) -> str:
lines = ["", "const prompt_font_mapping: Dictionary = {"]
for mode, columns in MODE_TO_COLUMNS.items():
lines.append(f"\tGdControlsDevice.MODE.{mode}: {{")
for row in rows:
chosen = ""
for col in columns:
cell = row.get(col, "")
if cell and cell.strip():
chosen = cell
break
char = codepoint_to_char(chosen)
lines.append(
f'\t\tGdControlsDevice.KEY_{row["KEY"]}: "{gd_escape(char)}",'
)
lines.append("\t},")
lines.append("}")
lines.append("")
return "\n".join(lines)
def splice(existing: str, generated: str) -> str:
if START_MARKER not in existing or END_MARKER not in existing:
raise SystemExit(
f"{OUT_PATH} is missing {START_MARKER!r} / {END_MARKER!r} markers"
)
before, _, rest = existing.partition(START_MARKER)
_, _, after = rest.partition(END_MARKER)
return before + START_MARKER + generated + END_MARKER + after
def main() -> None:
with CSV_PATH.open(newline="", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
output = splice(OUT_PATH.read_text(encoding="utf-8"), render(rows))
OUT_PATH.write_text(output, encoding="utf-8")
print(f"wrote {OUT_PATH}", file=sys.stderr)
if __name__ == "__main__":
main()

221
src/manager.gd Normal file
View File

@ -0,0 +1,221 @@
extends Node
class_name GdControlsManager
signal device_changed(device_category: DeviceCategory, device_type: DeviceType, device_id: int, device_name: String)
const SETTINGS_PATH = "user://game.controls.json"
enum DeviceCategory {
UNKOWN,
KEYBOARD,
POINTER,
CONTROLLER,
TOUCH,
}
enum DeviceType {
UNKOWN,
KEYBOARD,
MOUSE,
PC_CONTROLLER,
XBOX_CONTROLLER,
SONY_CONTROLLER,
NINTENDO_CONTROLLER,
TOUCH,
}
# inital or fallback mode
@export var default_device_mode: GdControlsDevice.MODE = GdControlsDevice.MODE.KEYBOARD_1_AND_MOUSE
# data keys
const _KEY_DEVICE_CATEGORY = "device_category"
const _KEY_DEVICE_TYPE = "device_type"
const _KEY_DEVICE_ID = "device_id"
const _KEY_DEVICE_NAME = "device_name"
const _KEY_DEVICE_MODE = "device_mode"
var _data_defaults: Dictionary = {
_KEY_DEVICE_CATEGORY: DeviceCategory.UNKOWN,
_KEY_DEVICE_TYPE: DeviceType.UNKOWN,
_KEY_DEVICE_ID: -2,
_KEY_DEVICE_NAME: "",
_KEY_DEVICE_MODE: GdControlsDevice.MODE.KEYBOARD_1_AND_MOUSE
}
var _data: Dictionary = _data_defaults
func _init():
_data = GdControlsFileManager.load_file(SETTINGS_PATH, _data_defaults)
func _ready():
_notifify_device_change()
func get_device_category() -> DeviceCategory:
return _data[_KEY_DEVICE_CATEGORY]
func set_device_category(category: DeviceCategory):
_data[_KEY_DEVICE_CATEGORY] = category
func get_device_type() -> DeviceType:
return _data[_KEY_DEVICE_TYPE]
func set_device_type(type: DeviceType):
_data[_KEY_DEVICE_TYPE] = type
func get_device_id() -> int:
return _data[_KEY_DEVICE_ID]
func set_device_id(id: int):
_data[_KEY_DEVICE_ID] = id
func get_device_name() -> String:
return _data[_KEY_DEVICE_NAME]
func set_device_name(name: String):
_data[_KEY_DEVICE_NAME] = name
func get_device_mode() -> GdControlsDevice.MODE:
return _data[_KEY_DEVICE_MODE]
func set_device_mode(mode: GdControlsDevice.MODE):
_data[_KEY_DEVICE_MODE] = mode
func _input(event: InputEvent):
# to help info, on we need to detect the input type
var last_device_category = get_device_category()
var device_category = _detect_input_category(event)
# let ignore the mouse
if device_category == DeviceCategory.POINTER:
return
# Controller is a special case
if device_category == DeviceCategory.CONTROLLER:
_on_controller_input(event)
return
if device_category == last_device_category:
return
if device_category == DeviceCategory.KEYBOARD:
_on_keyboard_input(event)
elif device_category == DeviceCategory.POINTER:
_on_pointer_input(event)
elif device_category == DeviceCategory.TOUCH:
_on_touch_input(event)
func _detect_input_category(event: InputEvent) -> DeviceCategory:
if event is InputEventKey:
return DeviceCategory.KEYBOARD
elif (event is InputEventMouse or event is InputEventMouseButton or event is InputEventMouseMotion):
return DeviceCategory.POINTER
elif (event is InputEventScreenTouch or event is InputEventScreenDrag):
return DeviceCategory.TOUCH
elif event is InputEventJoypadButton:
return DeviceCategory.CONTROLLER
else:
return DeviceCategory.UNKOWN
func _on_controller_input(event: InputEvent):
var last_device_id = get_device_id()
var device_id = event.get_device()
var type = _detect_controller(event)
var _last_type = get_device_type()
if (last_device_id == device_id and _last_type == type):
return
# Device has changed
set_device_id(device_id)
set_device_category(DeviceCategory.CONTROLLER)
var joy_name = Input.get_joy_name(device_id)
set_device_name(joy_name)
if type == DeviceType.XBOX_CONTROLLER:
set_device_type(DeviceType.XBOX_CONTROLLER)
set_device_mode(GdControlsDevice.MODE.XBOX_CONTROLLER)
elif type == DeviceType.SONY_CONTROLLER:
set_device_type(DeviceType.SONY_CONTROLLER)
set_device_mode(GdControlsDevice.MODE.SONY_CONTROLLER)
elif type == DeviceType.NINTENDO_CONTROLLER:
set_device_type(DeviceType.NINTENDO_CONTROLLER)
set_device_mode(GdControlsDevice.MODE.NINTENDO_CONTROLLER)
elif type == DeviceType.PC_CONTROLLER:
set_device_type(DeviceType.PC_CONTROLLER)
set_device_mode(GdControlsDevice.MODE.PC_CONTROLLER)
GdControlsFileManager.save_file(SETTINGS_PATH, _data)
_notifify_device_change()
func _detect_controller(event: InputEvent) -> DeviceType:
var device_id = event.get_device()
var joy_name = Input.get_joy_name(device_id)
if joy_name.to_lower().contains("xbox"):
return DeviceType.XBOX_CONTROLLER
elif joy_name.to_lower().contains("sony") or joy_name.to_lower().contains("ps"):
return DeviceType.SONY_CONTROLLER
elif joy_name.to_lower().contains("nintendo"):
return DeviceType.NINTENDO_CONTROLLER
else:
return DeviceType.PC_CONTROLLER
func _on_keyboard_input(event: InputEvent):
if(get_device_category() == DeviceCategory.KEYBOARD):
return
set_device_id(event.get_device())
set_device_category(DeviceCategory.KEYBOARD)
set_device_name("Keyboard")
set_device_type(DeviceType.KEYBOARD)
if default_device_mode == GdControlsDevice.MODE.KEYBOARD_2_AND_MOUSE:
set_device_mode(GdControlsDevice.MODE.KEYBOARD_2_AND_MOUSE)
else:
set_device_mode(GdControlsDevice.MODE.KEYBOARD_1_AND_MOUSE)
GdControlsFileManager.save_file(SETTINGS_PATH, _data)
_notifify_device_change()
func _on_pointer_input(event: InputEvent):
if(get_device_category() == DeviceCategory.POINTER):
return
set_device_id(event.get_device())
set_device_category(DeviceCategory.POINTER)
set_device_name("Mouse")
set_device_type(DeviceType.MOUSE)
if default_device_mode == GdControlsDevice.MODE.KEYBOARD_2_AND_MOUSE:
set_device_mode(GdControlsDevice.MODE.KEYBOARD_2_AND_MOUSE)
else:
set_device_mode(GdControlsDevice.MODE.KEYBOARD_1_AND_MOUSE)
GdControlsFileManager.save_file(SETTINGS_PATH, _data)
_notifify_device_change()
func _on_touch_input(event: InputEvent):
if(get_device_category() == DeviceCategory.TOUCH):
return
set_device_id(event.get_device())
set_device_category(DeviceCategory.TOUCH)
set_device_name("Touch")
set_device_type(DeviceType.TOUCH)
if default_device_mode == GdControlsDevice.MODE.KEYBOARD_2_AND_MOUSE:
set_device_mode(GdControlsDevice.MODE.KEYBOARD_2_AND_MOUSE)
else:
set_device_mode(GdControlsDevice.MODE.KEYBOARD_1_AND_MOUSE)
GdControlsFileManager.save_file(SETTINGS_PATH, _data)
_notifify_device_change()
func _notifify_device_change():
device_changed.emit(get_device_category(), get_device_type(), get_device_id(), get_device_name())

1
src/manager.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://llabbbxoahp0

194
src/prompt_font_mapping.gd Normal file
View File

@ -0,0 +1,194 @@
# === IMPORTANT! ===
# This file is autogenerated and MUST not be modifed
# To update please update the key_mapping files and use game_controls_mapping_gen.py script
#
extends Node
class_name GdControlsPromptFontMapping
# === STARTGEN ===
const prompt_font_mapping: Dictionary = {
GdControlsDevice.MODE.KEYBOARD_1_AND_MOUSE: {
GdControlsDevice.KEY_DPAD_UP: "",
GdControlsDevice.KEY_DPAD_RIGHT: "",
GdControlsDevice.KEY_DPAD_DOWN: "",
GdControlsDevice.KEY_DPAD_LEFT: "",
GdControlsDevice.KEY_AXIS_LS_UP: "",
GdControlsDevice.KEY_AXIS_LS_RIGHT: "",
GdControlsDevice.KEY_AXIS_LS_DOWN: "",
GdControlsDevice.KEY_AXIS_LS_LEFT: "",
GdControlsDevice.KEY_AXIS_RS_UP: "",
GdControlsDevice.KEY_AXIS_RS_RIGHT: "",
GdControlsDevice.KEY_AXIS_RS_DOWN: "",
GdControlsDevice.KEY_AXIS_RS_LEFT: "",
GdControlsDevice.KEY_ACTION_LS: "",
GdControlsDevice.KEY_ACTION_RS: "",
GdControlsDevice.KEY_ACTION_START: "",
GdControlsDevice.KEY_ACTION_BACK: "",
GdControlsDevice.KEY_ACTION_TOP: "",
GdControlsDevice.KEY_ACTION_BOTTOM: "",
GdControlsDevice.KEY_ACTION_LEFT: "",
GdControlsDevice.KEY_ACTION_RIGHT: "",
GdControlsDevice.KEY_ACTION_LB: "",
GdControlsDevice.KEY_ACTION_RB: "",
GdControlsDevice.KEY_AXIS_LT: "",
GdControlsDevice.KEY_AXIS_RT: "",
},
GdControlsDevice.MODE.KEYBOARD_2_AND_MOUSE: {
GdControlsDevice.KEY_DPAD_UP: "",
GdControlsDevice.KEY_DPAD_RIGHT: "",
GdControlsDevice.KEY_DPAD_DOWN: "",
GdControlsDevice.KEY_DPAD_LEFT: "",
GdControlsDevice.KEY_AXIS_LS_UP: "",
GdControlsDevice.KEY_AXIS_LS_RIGHT: "",
GdControlsDevice.KEY_AXIS_LS_DOWN: "",
GdControlsDevice.KEY_AXIS_LS_LEFT: "",
GdControlsDevice.KEY_AXIS_RS_UP: "",
GdControlsDevice.KEY_AXIS_RS_RIGHT: "",
GdControlsDevice.KEY_AXIS_RS_DOWN: "",
GdControlsDevice.KEY_AXIS_RS_LEFT: "",
GdControlsDevice.KEY_ACTION_LS: "",
GdControlsDevice.KEY_ACTION_RS: "",
GdControlsDevice.KEY_ACTION_START: "",
GdControlsDevice.KEY_ACTION_BACK: "",
GdControlsDevice.KEY_ACTION_TOP: "",
GdControlsDevice.KEY_ACTION_BOTTOM: "",
GdControlsDevice.KEY_ACTION_LEFT: "",
GdControlsDevice.KEY_ACTION_RIGHT: "",
GdControlsDevice.KEY_ACTION_LB: "",
GdControlsDevice.KEY_ACTION_RB: "",
GdControlsDevice.KEY_AXIS_LT: "",
GdControlsDevice.KEY_AXIS_RT: "",
},
GdControlsDevice.MODE.PC_CONTROLLER: {
GdControlsDevice.KEY_DPAD_UP: "",
GdControlsDevice.KEY_DPAD_RIGHT: "",
GdControlsDevice.KEY_DPAD_DOWN: "",
GdControlsDevice.KEY_DPAD_LEFT: "",
GdControlsDevice.KEY_AXIS_LS_UP: "",
GdControlsDevice.KEY_AXIS_LS_RIGHT: "",
GdControlsDevice.KEY_AXIS_LS_DOWN: "",
GdControlsDevice.KEY_AXIS_LS_LEFT: "",
GdControlsDevice.KEY_AXIS_RS_UP: "",
GdControlsDevice.KEY_AXIS_RS_RIGHT: "",
GdControlsDevice.KEY_AXIS_RS_DOWN: "",
GdControlsDevice.KEY_AXIS_RS_LEFT: "",
GdControlsDevice.KEY_ACTION_LS: "",
GdControlsDevice.KEY_ACTION_RS: "",
GdControlsDevice.KEY_ACTION_START: "",
GdControlsDevice.KEY_ACTION_BACK: "",
GdControlsDevice.KEY_ACTION_TOP: "",
GdControlsDevice.KEY_ACTION_BOTTOM: "",
GdControlsDevice.KEY_ACTION_LEFT: "",
GdControlsDevice.KEY_ACTION_RIGHT: "",
GdControlsDevice.KEY_ACTION_LB: "",
GdControlsDevice.KEY_ACTION_RB: "",
GdControlsDevice.KEY_AXIS_LT: "",
GdControlsDevice.KEY_AXIS_RT: "",
},
GdControlsDevice.MODE.XBOX_CONTROLLER: {
GdControlsDevice.KEY_DPAD_UP: "",
GdControlsDevice.KEY_DPAD_RIGHT: "",
GdControlsDevice.KEY_DPAD_DOWN: "",
GdControlsDevice.KEY_DPAD_LEFT: "",
GdControlsDevice.KEY_AXIS_LS_UP: "",
GdControlsDevice.KEY_AXIS_LS_RIGHT: "",
GdControlsDevice.KEY_AXIS_LS_DOWN: "",
GdControlsDevice.KEY_AXIS_LS_LEFT: "",
GdControlsDevice.KEY_AXIS_RS_UP: "",
GdControlsDevice.KEY_AXIS_RS_RIGHT: "",
GdControlsDevice.KEY_AXIS_RS_DOWN: "",
GdControlsDevice.KEY_AXIS_RS_LEFT: "",
GdControlsDevice.KEY_ACTION_LS: "",
GdControlsDevice.KEY_ACTION_RS: "",
GdControlsDevice.KEY_ACTION_START: "",
GdControlsDevice.KEY_ACTION_BACK: "",
GdControlsDevice.KEY_ACTION_TOP: "",
GdControlsDevice.KEY_ACTION_BOTTOM: "",
GdControlsDevice.KEY_ACTION_LEFT: "",
GdControlsDevice.KEY_ACTION_RIGHT: "",
GdControlsDevice.KEY_ACTION_LB: "",
GdControlsDevice.KEY_ACTION_RB: "",
GdControlsDevice.KEY_AXIS_LT: "",
GdControlsDevice.KEY_AXIS_RT: "",
},
GdControlsDevice.MODE.SONY_CONTROLLER: {
GdControlsDevice.KEY_DPAD_UP: "",
GdControlsDevice.KEY_DPAD_RIGHT: "",
GdControlsDevice.KEY_DPAD_DOWN: "",
GdControlsDevice.KEY_DPAD_LEFT: "",
GdControlsDevice.KEY_AXIS_LS_UP: "",
GdControlsDevice.KEY_AXIS_LS_RIGHT: "",
GdControlsDevice.KEY_AXIS_LS_DOWN: "",
GdControlsDevice.KEY_AXIS_LS_LEFT: "",
GdControlsDevice.KEY_AXIS_RS_UP: "",
GdControlsDevice.KEY_AXIS_RS_RIGHT: "",
GdControlsDevice.KEY_AXIS_RS_DOWN: "",
GdControlsDevice.KEY_AXIS_RS_LEFT: "",
GdControlsDevice.KEY_ACTION_LS: "",
GdControlsDevice.KEY_ACTION_RS: "",
GdControlsDevice.KEY_ACTION_START: "",
GdControlsDevice.KEY_ACTION_BACK: "",
GdControlsDevice.KEY_ACTION_TOP: "",
GdControlsDevice.KEY_ACTION_BOTTOM: "",
GdControlsDevice.KEY_ACTION_LEFT: "",
GdControlsDevice.KEY_ACTION_RIGHT: "",
GdControlsDevice.KEY_ACTION_LB: "",
GdControlsDevice.KEY_ACTION_RB: "",
GdControlsDevice.KEY_AXIS_LT: "",
GdControlsDevice.KEY_AXIS_RT: "",
},
GdControlsDevice.MODE.NINTENDO_CONTROLLER: {
GdControlsDevice.KEY_DPAD_UP: "",
GdControlsDevice.KEY_DPAD_RIGHT: "",
GdControlsDevice.KEY_DPAD_DOWN: "",
GdControlsDevice.KEY_DPAD_LEFT: "",
GdControlsDevice.KEY_AXIS_LS_UP: "",
GdControlsDevice.KEY_AXIS_LS_RIGHT: "",
GdControlsDevice.KEY_AXIS_LS_DOWN: "",
GdControlsDevice.KEY_AXIS_LS_LEFT: "",
GdControlsDevice.KEY_AXIS_RS_UP: "",
GdControlsDevice.KEY_AXIS_RS_RIGHT: "",
GdControlsDevice.KEY_AXIS_RS_DOWN: "",
GdControlsDevice.KEY_AXIS_RS_LEFT: "",
GdControlsDevice.KEY_ACTION_LS: "",
GdControlsDevice.KEY_ACTION_RS: "",
GdControlsDevice.KEY_ACTION_START: "",
GdControlsDevice.KEY_ACTION_BACK: "",
GdControlsDevice.KEY_ACTION_TOP: "",
GdControlsDevice.KEY_ACTION_BOTTOM: "",
GdControlsDevice.KEY_ACTION_LEFT: "",
GdControlsDevice.KEY_ACTION_RIGHT: "",
GdControlsDevice.KEY_ACTION_LB: "",
GdControlsDevice.KEY_ACTION_RB: "",
GdControlsDevice.KEY_AXIS_LT: "",
GdControlsDevice.KEY_AXIS_RT: "",
},
GdControlsDevice.MODE.TOUCH: {
GdControlsDevice.KEY_DPAD_UP: "",
GdControlsDevice.KEY_DPAD_RIGHT: "",
GdControlsDevice.KEY_DPAD_DOWN: "",
GdControlsDevice.KEY_DPAD_LEFT: "",
GdControlsDevice.KEY_AXIS_LS_UP: "",
GdControlsDevice.KEY_AXIS_LS_RIGHT: "",
GdControlsDevice.KEY_AXIS_LS_DOWN: "",
GdControlsDevice.KEY_AXIS_LS_LEFT: "",
GdControlsDevice.KEY_AXIS_RS_UP: "",
GdControlsDevice.KEY_AXIS_RS_RIGHT: "",
GdControlsDevice.KEY_AXIS_RS_DOWN: "",
GdControlsDevice.KEY_AXIS_RS_LEFT: "",
GdControlsDevice.KEY_ACTION_LS: "",
GdControlsDevice.KEY_ACTION_RS: "",
GdControlsDevice.KEY_ACTION_START: "",
GdControlsDevice.KEY_ACTION_BACK: "",
GdControlsDevice.KEY_ACTION_TOP: "",
GdControlsDevice.KEY_ACTION_BOTTOM: "",
GdControlsDevice.KEY_ACTION_LEFT: "",
GdControlsDevice.KEY_ACTION_RIGHT: "",
GdControlsDevice.KEY_ACTION_LB: "",
GdControlsDevice.KEY_ACTION_RB: "",
GdControlsDevice.KEY_AXIS_LT: "",
GdControlsDevice.KEY_AXIS_RT: "",
},
}
# === ENDGEN ===

View File

@ -0,0 +1 @@
uid://bjs3370eluj6b