add reusable options menu plugin with localized UI
- Settings autoloads (Game/Input/Graphics/Audio) backed by FileManager, persisted to user:// JSON files - OptionsMenu scene with tabs wired to each autoload: Game (locale), Input (invert vertical axis), Graphics (window mode, borderless, screen), Audio (master/music/fx volume) - GraphicsSettings reads DisplayServer state when running in editor to avoid clobbering the editor's window mode; exported builds load from disk and apply via set_screen_and_apply with a _loading guard to suppress redundant writes - Built-in translations for en/es/fr/de/ja/zh_CN registered at runtime from translations/gd_options.csv - Control-prompt icon assets for keyboard, PlayStation, Xbox, Nintendo - Flesh out README with scope and audio bus layout requirement Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
30
README.md
|
|
@ -1,3 +1,31 @@
|
|||
# gd-options
|
||||
|
||||
re-usable settings plugin for godot (gd scripts), to configure game, graphics and sound settings.
|
||||
Re-usable settings/options menu for godot (gd scripts) to configure game, input, graphics and sound settings.
|
||||
|
||||
- GameSettings global
|
||||
- InputSettings global
|
||||
- GraphicsSettings global
|
||||
- AudioSettings global
|
||||
- Saves and loads states from [user://](https://docs.godotengine.org/en/latest/tutorials/io/data_paths.html) application directory
|
||||
|
||||
|
||||
## Pre-Requisites
|
||||
|
||||
Game:
|
||||
|
||||
- TBD
|
||||
|
||||
Input:
|
||||
|
||||
- TBD
|
||||
|
||||
Graphics:
|
||||
|
||||
- TBD
|
||||
|
||||
Audio:
|
||||
|
||||
- Use the default_audio_bus_layout
|
||||
- "Master" bus
|
||||
- "Music" bus
|
||||
- "FX" bus
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 4.0 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dt8o6v4myvb2q"
|
||||
path="res://.godot/imported/KEY_DOWN.png-db5c00d84239901c2bfbf05ce148575a.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/KEY_DOWN.png"
|
||||
dest_files=["res://.godot/imported/KEY_DOWN.png-db5c00d84239901c2bfbf05ce148575a.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
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c1lj53bll3mp"
|
||||
path="res://.godot/imported/KEY_ESCAPE.png-4112c7e5ae0541889735aba5dc6da45c.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/KEY_ESCAPE.png"
|
||||
dest_files=["res://.godot/imported/KEY_ESCAPE.png-4112c7e5ae0541889735aba5dc6da45c.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
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://df08tkh74g0dm"
|
||||
path="res://.godot/imported/KEY_LEFT.png-fcb4e867ccf668351738d285d9565478.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/KEY_LEFT.png"
|
||||
dest_files=["res://.godot/imported/KEY_LEFT.png-fcb4e867ccf668351738d285d9565478.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
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://6od4ov64yq33"
|
||||
path="res://.godot/imported/KEY_RIGHT.png-5cd1e2bc2a73d99e8a694485b76bd7e8.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/KEY_RIGHT.png"
|
||||
dest_files=["res://.godot/imported/KEY_RIGHT.png-5cd1e2bc2a73d99e8a694485b76bd7e8.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
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://p5yncir26dqu"
|
||||
path="res://.godot/imported/KEY_Space.png-6ebe9469c176686eee2ce4f13cdf43ad.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/KEY_Space.png"
|
||||
dest_files=["res://.godot/imported/KEY_Space.png-6ebe9469c176686eee2ce4f13cdf43ad.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
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://p0idtl3l4xpg"
|
||||
path="res://.godot/imported/KEY_UP.png-a465606ae8ff2e0094872f1fcd95f662.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/KEY_UP.png"
|
||||
dest_files=["res://.godot/imported/KEY_UP.png-a465606ae8ff2e0094872f1fcd95f662.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
|
||||
|
After Width: | Height: | Size: 4.6 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://5rlsvoigepav"
|
||||
path="res://.godot/imported/NINTENDO_A.png-1133963d3d95bb7911eaea48a6493953.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/NINTENDO_A.png"
|
||||
dest_files=["res://.godot/imported/NINTENDO_A.png-1133963d3d95bb7911eaea48a6493953.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
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://v8e53j5fae7s"
|
||||
path="res://.godot/imported/NINTENDO_B.png-71079ec7d91adfd964db31c69d270d55.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/NINTENDO_B.png"
|
||||
dest_files=["res://.godot/imported/NINTENDO_B.png-71079ec7d91adfd964db31c69d270d55.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
|
||||
|
After Width: | Height: | Size: 7.0 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://4xnpke0wyy2k"
|
||||
path="res://.godot/imported/NINTENDO_L_STICK.png-6bf0c64f885d12f3d83a6fcfeab8b5ad.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/NINTENDO_L_STICK.png"
|
||||
dest_files=["res://.godot/imported/NINTENDO_L_STICK.png-6bf0c64f885d12f3d83a6fcfeab8b5ad.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
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://2vdkcgguxkl3"
|
||||
path="res://.godot/imported/PC_3.png-e43ec084787993051cd4117e1a2fbf54.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/PC_3.png"
|
||||
dest_files=["res://.godot/imported/PC_3.png-e43ec084787993051cd4117e1a2fbf54.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
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://mq256cphr7u0"
|
||||
path="res://.godot/imported/PC_4.png-4e355b02957e6797c28dd6053ab283f8.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/PC_4.png"
|
||||
dest_files=["res://.godot/imported/PC_4.png-4e355b02957e6797c28dd6053ab283f8.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
|
||||
|
After Width: | Height: | Size: 7.0 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dncihvca65x2k"
|
||||
path="res://.godot/imported/PC_L_STICK.png-e16867830a0da2f8d934db342770d5d5.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/PC_L_STICK.png"
|
||||
dest_files=["res://.godot/imported/PC_L_STICK.png-e16867830a0da2f8d934db342770d5d5.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
|
||||
|
After Width: | Height: | Size: 5.6 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dkt8euh0x2swy"
|
||||
path="res://.godot/imported/SONY_CIRCLE.png-e64c9555ca52ceeebf5b5bc8cb8223b9.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/SONY_CIRCLE.png"
|
||||
dest_files=["res://.godot/imported/SONY_CIRCLE.png-e64c9555ca52ceeebf5b5bc8cb8223b9.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
|
||||
|
After Width: | Height: | Size: 6.0 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b7ikqvnmxeamg"
|
||||
path="res://.godot/imported/SONY_L_STICK.png-edbe50457f559751ea0d398cb1c12ab7.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/SONY_L_STICK.png"
|
||||
dest_files=["res://.godot/imported/SONY_L_STICK.png-edbe50457f559751ea0d398cb1c12ab7.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
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://d0evrplde0q3o"
|
||||
path="res://.godot/imported/SONY_TRIANGLE.png-bee76e54090e568cc259f3ef0b2b0562.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/SONY_TRIANGLE.png"
|
||||
dest_files=["res://.godot/imported/SONY_TRIANGLE.png-bee76e54090e568cc259f3ef0b2b0562.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
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://brpfx4lnncoi8"
|
||||
path="res://.godot/imported/SONY_X.png-1aa62cf73935425c61d7fd08b92ec8d8.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/SONY_X.png"
|
||||
dest_files=["res://.godot/imported/SONY_X.png-1aa62cf73935425c61d7fd08b92ec8d8.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
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ch42wo4dfxoht"
|
||||
path="res://.godot/imported/SONY_X_2.png-a39382ba8ac25a3a8c0c6076b4f4af7e.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/SONY_X_2.png"
|
||||
dest_files=["res://.godot/imported/SONY_X_2.png-a39382ba8ac25a3a8c0c6076b4f4af7e.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
|
||||
|
After Width: | Height: | Size: 4.6 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c8adjt2dxqus1"
|
||||
path="res://.godot/imported/XBOX_A.png-5d27fee059048526f6cdc8c932465e67.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/XBOX_A.png"
|
||||
dest_files=["res://.godot/imported/XBOX_A.png-5d27fee059048526f6cdc8c932465e67.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
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://tkv02aehmxtx"
|
||||
path="res://.godot/imported/XBOX_B.png-125144c582ca2244930a6bbd891fc7f3.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/XBOX_B.png"
|
||||
dest_files=["res://.godot/imported/XBOX_B.png-125144c582ca2244930a6bbd891fc7f3.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
|
||||
|
After Width: | Height: | Size: 6.9 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cxl3tg6i16gwx"
|
||||
path="res://.godot/imported/XBOX_L_STICK.png-d149b7fc8397efa8962f68901404f7bd.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/gd-options/assets/control_icons/XBOX_L_STICK.png"
|
||||
dest_files=["res://.godot/imported/XBOX_L_STICK.png-d149b7fc8397efa8962f68901404f7bd.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
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
[plugin]
|
||||
|
||||
name="gd-options"
|
||||
description="Re-usable settings menu for godot (gd scripts) to configure game, input, graphics and sound settings."
|
||||
author="Daniel Samson"
|
||||
version="0.1.0"
|
||||
script="plugin.gd"
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
add_autoload_singleton("GameSettings", "res://addons/gd-options/src/common/game_settings.gd")
|
||||
add_autoload_singleton("InputSettings", "res://addons/gd-options/src/common/input_settings.gd")
|
||||
add_autoload_singleton("GraphicsSettings", "res://addons/gd-options/src/common/graphics_settings.gd")
|
||||
add_autoload_singleton("AudioSettings", "res://addons/gd-options/src/common/audio_settings.gd")
|
||||
|
||||
func _exit_tree() -> void:
|
||||
pass
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://c3d6j5klvqktf
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
extends Node
|
||||
|
||||
# CLAMP Settings in decebels
|
||||
const MIN_DB = -80
|
||||
const MAX_DB = 20
|
||||
# file path
|
||||
const _SETTINGS_PATH = "user://audio.settings.json"
|
||||
# audio server buses:
|
||||
const _MASTER_BUS = "Master"
|
||||
const _MUSIC_BUS = "Music"
|
||||
const _FX_BUS = "FX"
|
||||
# _state keys:
|
||||
const _KEY_MASTER_VOLUME = "master_volume"
|
||||
const _KEY_MUSIC_VOLUME = "music_volume"
|
||||
const _KEY_FX_VOLUME = "fx_volume"
|
||||
|
||||
var _state_defaults: Dictionary = {
|
||||
_KEY_MASTER_VOLUME: 0.0,
|
||||
_KEY_MUSIC_VOLUME: -20.0,
|
||||
_KEY_FX_VOLUME: -6.0
|
||||
}
|
||||
|
||||
var _state: Dictionary
|
||||
|
||||
func _ready():
|
||||
_state = FileManager.load_file(_SETTINGS_PATH, _state_defaults)
|
||||
_set_audio_server_volume(_MASTER_BUS, _state[_KEY_MASTER_VOLUME])
|
||||
_set_audio_server_volume(_MUSIC_BUS, _state[_KEY_MUSIC_VOLUME])
|
||||
_set_audio_server_volume(_FX_BUS, _state[_KEY_FX_VOLUME])
|
||||
|
||||
func get_master_volume() -> float:
|
||||
return _state[_KEY_MASTER_VOLUME]
|
||||
|
||||
func set_master_volume(decebels: float) -> void:
|
||||
var volume = _clamp_volume(decebels)
|
||||
_state[_KEY_MASTER_VOLUME] = volume
|
||||
FileManager.save_file(_SETTINGS_PATH, _state)
|
||||
_set_audio_server_volume(_MASTER_BUS, volume)
|
||||
|
||||
|
||||
func get_music_volume() -> float:
|
||||
return _state[_KEY_MUSIC_VOLUME]
|
||||
|
||||
func set_music_volume(decebels: float) -> void:
|
||||
var volume = _clamp_volume(decebels)
|
||||
_state[_KEY_MUSIC_VOLUME] = volume
|
||||
FileManager.save_file(_SETTINGS_PATH, _state)
|
||||
_set_audio_server_volume(_MUSIC_BUS, volume)
|
||||
|
||||
func get_fx_volume() -> float:
|
||||
return _state[_KEY_FX_VOLUME]
|
||||
|
||||
func set_fx_volume(decebels: float) -> void:
|
||||
var volume = _clamp_volume(decebels)
|
||||
_state[_KEY_FX_VOLUME] = volume
|
||||
FileManager.save_file(_SETTINGS_PATH, _state)
|
||||
_set_audio_server_volume(_FX_BUS, volume)
|
||||
|
||||
func from_db_to_percent(decebels: float) -> float:
|
||||
return 100 - ((decebels / MIN_DB) * 100)
|
||||
|
||||
func from_percent_to_db(percentage: float) -> float:
|
||||
return MIN_DB - ((percentage * .01) * MIN_DB)
|
||||
|
||||
func _clamp_volume(value: float) -> float:
|
||||
return clampf(value, MIN_DB, MAX_DB)
|
||||
|
||||
func _set_audio_server_volume(bus_name: String, volume: float):
|
||||
var bus_index = AudioServer.get_bus_index(bus_name)
|
||||
if bus_index == -1:
|
||||
printerr("Missing AudioServer bus: " + bus_name + ". Please add bus to audio tab.")
|
||||
AudioServer.set_bus_volume_db(bus_index, volume)
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://bg3vm4qgknwdp
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
extends Node
|
||||
|
||||
class_name FileManager
|
||||
|
||||
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()
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://d3x6knvjwvxe1
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
extends Node
|
||||
|
||||
const _TRANSLATIONS_CSV = "res://addons/gd-options/translations/gd_options.csv"
|
||||
# file path
|
||||
const _SETTINGS_PATH = "user://game.settings.json"
|
||||
# _state keys:
|
||||
const _KEY_LOCALE = "locale"
|
||||
|
||||
var _state: Dictionary
|
||||
|
||||
func _ready():
|
||||
_load_addon_translations()
|
||||
var defaults = {
|
||||
_KEY_LOCALE: _resolve_locale(TranslationServer.get_locale())
|
||||
}
|
||||
_state = FileManager.load_file(_SETTINGS_PATH, defaults)
|
||||
TranslationServer.set_locale(_state[_KEY_LOCALE])
|
||||
|
||||
func get_locale() -> String:
|
||||
return _state[_KEY_LOCALE]
|
||||
|
||||
func set_locale(locale: String) -> void:
|
||||
_state[_KEY_LOCALE] = locale
|
||||
FileManager.save_file(_SETTINGS_PATH, _state)
|
||||
TranslationServer.set_locale(locale)
|
||||
|
||||
|
||||
# Maps a system or saved locale to the closest locale we actually ship a
|
||||
# translation for, so the dropdown selection and tr() lookups agree.
|
||||
func _resolve_locale(locale: String) -> String:
|
||||
var available = TranslationServer.get_loaded_locales()
|
||||
if locale in available:
|
||||
return locale
|
||||
var prefix = locale.split("_", false, 1)[0]
|
||||
if prefix in available:
|
||||
return prefix
|
||||
if available.size() > 0:
|
||||
return available[0]
|
||||
return locale
|
||||
|
||||
|
||||
func _load_addon_translations() -> void:
|
||||
var file = FileAccess.open(_TRANSLATIONS_CSV, FileAccess.READ)
|
||||
if file == null:
|
||||
return
|
||||
var header = file.get_csv_line()
|
||||
if header.size() < 2:
|
||||
file.close()
|
||||
return
|
||||
var translations: Array[Translation] = []
|
||||
for i in range(1, header.size()):
|
||||
var t = Translation.new()
|
||||
t.locale = header[i]
|
||||
translations.append(t)
|
||||
while not file.eof_reached():
|
||||
var row = file.get_csv_line()
|
||||
if row.size() < 2 or row[0] == "":
|
||||
continue
|
||||
for i in range(1, header.size()):
|
||||
if i < row.size():
|
||||
translations[i - 1].add_message(row[0], row[i])
|
||||
file.close()
|
||||
for t in translations:
|
||||
TranslationServer.add_translation(t)
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://dl06cqyafn3gh
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
extends Node
|
||||
|
||||
signal screen_count_changed
|
||||
|
||||
# file path
|
||||
const _SETTINGS_PATH = "user://graphics.settings.json"
|
||||
# _state keys:
|
||||
const _KEY_WINDOW_MODE = "window_mode"
|
||||
const _KEY_BORDERLESS = "borderless"
|
||||
const _KEY_USE_PRIMARY_SCREEN = "use_primary_screen"
|
||||
const _KEY_USE_SCREEN = "use_screen"
|
||||
|
||||
var _state: Dictionary
|
||||
var _current_screen_count: int
|
||||
var _loading: bool = false
|
||||
|
||||
func _ready():
|
||||
var current_screen = DisplayServer.window_get_current_screen()
|
||||
var defaults = {
|
||||
_KEY_WINDOW_MODE: DisplayServer.window_get_mode(),
|
||||
_KEY_BORDERLESS: DisplayServer.window_get_flag(DisplayServer.WINDOW_FLAG_BORDERLESS),
|
||||
_KEY_USE_PRIMARY_SCREEN: current_screen == DisplayServer.get_primary_screen(),
|
||||
_KEY_USE_SCREEN: current_screen
|
||||
}
|
||||
_current_screen_count = DisplayServer.get_screen_count()
|
||||
if OS.has_feature("editor"):
|
||||
_state = defaults
|
||||
else:
|
||||
_state = FileManager.load_file(_SETTINGS_PATH, defaults)
|
||||
_loading = true
|
||||
set_screen_and_apply(_state[_KEY_USE_SCREEN])
|
||||
_loading = false
|
||||
|
||||
func _save() -> void:
|
||||
if _loading:
|
||||
return
|
||||
FileManager.save_file(_SETTINGS_PATH, _state)
|
||||
|
||||
func _process(_delta):
|
||||
var screen_count = DisplayServer.get_screen_count()
|
||||
if screen_count < _current_screen_count:
|
||||
var primary_screen = DisplayServer.get_primary_screen()
|
||||
set_screen_and_apply(primary_screen)
|
||||
_current_screen_count = screen_count
|
||||
emit_signal("screen_count_changed")
|
||||
|
||||
|
||||
func get_window_mode() -> int:
|
||||
return _state[_KEY_WINDOW_MODE]
|
||||
|
||||
func set_window_mode(mode: int) -> void:
|
||||
_state[_KEY_WINDOW_MODE] = mode
|
||||
_save()
|
||||
_apply()
|
||||
|
||||
|
||||
func get_borderless() -> bool:
|
||||
return _state[_KEY_BORDERLESS]
|
||||
|
||||
func set_borderless(is_borderless: bool) -> void:
|
||||
_state[_KEY_BORDERLESS] = is_borderless
|
||||
_save()
|
||||
_apply()
|
||||
|
||||
|
||||
func get_use_primary_screen() -> bool:
|
||||
return _state[_KEY_USE_PRIMARY_SCREEN]
|
||||
|
||||
func set_use_primary_screen(use_primary_screen: bool) -> void:
|
||||
_state[_KEY_USE_PRIMARY_SCREEN] = use_primary_screen
|
||||
_save()
|
||||
_apply()
|
||||
|
||||
|
||||
func get_use_screen() -> int:
|
||||
return _state[_KEY_USE_SCREEN]
|
||||
|
||||
func set_screen_and_apply(screen: int) -> void:
|
||||
var old_window_mode = get_window_mode()
|
||||
set_window_mode(0)
|
||||
|
||||
var screen_limit = get_screen_count() - 1
|
||||
_state[_KEY_USE_SCREEN] = clampi(screen, 0, screen_limit)
|
||||
_save()
|
||||
|
||||
DisplayServer.window_set_current_screen(_state[_KEY_USE_SCREEN])
|
||||
DisplayServer.get_window_list()
|
||||
var window = get_window()
|
||||
window.grab_focus()
|
||||
|
||||
set_window_mode(old_window_mode)
|
||||
|
||||
|
||||
func get_screen_count() -> int:
|
||||
return DisplayServer.get_screen_count()
|
||||
|
||||
|
||||
func _apply():
|
||||
var screen = clampi(_state[_KEY_USE_SCREEN], 0, get_screen_count() - 1)
|
||||
DisplayServer.window_set_current_screen(screen)
|
||||
_state[_KEY_USE_SCREEN] = screen
|
||||
|
||||
var window_mode = _state[_KEY_WINDOW_MODE]
|
||||
if window_mode == 0:
|
||||
get_tree().root.content_scale_mode = Window.CONTENT_SCALE_MODE_VIEWPORT
|
||||
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
|
||||
elif window_mode == 2:
|
||||
get_tree().root.content_scale_mode = Window.CONTENT_SCALE_MODE_DISABLED
|
||||
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_MAXIMIZED)
|
||||
elif window_mode == 3:
|
||||
get_tree().root.content_scale_mode = Window.CONTENT_SCALE_MODE_DISABLED
|
||||
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
|
||||
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, _state[_KEY_BORDERLESS])
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://byvx6npgwa47u
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
extends Node
|
||||
|
||||
# file path
|
||||
const _SETTINGS_PATH = "user://input.settings.json"
|
||||
# _state keys:
|
||||
const _KEY_INVERT_VERTICAL_AXIS = "invert_vertical_axis"
|
||||
|
||||
var _state_defaults: Dictionary = {
|
||||
_KEY_INVERT_VERTICAL_AXIS: false
|
||||
}
|
||||
|
||||
var _state: Dictionary
|
||||
|
||||
func _ready():
|
||||
_state = FileManager.load_file(_SETTINGS_PATH, _state_defaults)
|
||||
|
||||
func get_invert_vertical_axis() -> bool:
|
||||
return _state[_KEY_INVERT_VERTICAL_AXIS]
|
||||
|
||||
func set_invert_vertical_axis(value: bool) -> void:
|
||||
_state[_KEY_INVERT_VERTICAL_AXIS] = value
|
||||
FileManager.save_file(_SETTINGS_PATH, _state)
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://d3ow1dxukus2x
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
[gd_resource type="AudioBusLayout" format=3 uid="uid://g36xq7ydus0j"]
|
||||
|
||||
[resource]
|
||||
bus/1/name = &"Music"
|
||||
bus/1/solo = false
|
||||
bus/1/mute = false
|
||||
bus/1/bypass_fx = false
|
||||
bus/1/volume_db = 0.0
|
||||
bus/1/send = &"Master"
|
||||
bus/2/name = &"FX"
|
||||
bus/2/solo = false
|
||||
bus/2/mute = false
|
||||
bus/2/bypass_fx = false
|
||||
bus/2/volume_db = 0.0
|
||||
bus/2/send = &"Master"
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
extends Node
|
||||
|
||||
signal device_changed(device_category: DeviceCategory, device_type: DeviceType, device_id: int, device_name: String)
|
||||
|
||||
enum DeviceCategory {
|
||||
UNKOWN,
|
||||
KEYBOARD,
|
||||
POINTER,
|
||||
CONTROLLER,
|
||||
TOUCH,
|
||||
}
|
||||
|
||||
enum DeviceType {
|
||||
UNKOWN,
|
||||
KEYBOARD,
|
||||
MOUSE,
|
||||
PC_CONTROLLER,
|
||||
XBOX_CONTROLLER,
|
||||
SONY_CONTROLLER,
|
||||
NINTENDO_CONTROLLER,
|
||||
TOUCH,
|
||||
}
|
||||
|
||||
var _state: InputState
|
||||
|
||||
func _init():
|
||||
_state = InputState.new()
|
||||
_state.load_state()
|
||||
|
||||
|
||||
func _ready():
|
||||
_notifify_device_change()
|
||||
|
||||
|
||||
func _input(event: InputEvent):
|
||||
# to help info, on we need to detect the input type
|
||||
var last_device_category = _state.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 = _state.device_id
|
||||
var device_id = event.get_device()
|
||||
var type = _detect_controller(event)
|
||||
var _last_type = _state.device_type
|
||||
|
||||
if (last_device_id == device_id and _last_type == type):
|
||||
return
|
||||
|
||||
_state.device_category = DeviceCategory.CONTROLLER
|
||||
var joy_name = Input.get_joy_name(device_id)
|
||||
|
||||
if type == DeviceType.XBOX_CONTROLLER:
|
||||
_state.device_id = device_id
|
||||
_state.device_type = DeviceType.XBOX_CONTROLLER
|
||||
_state.device_name = joy_name
|
||||
_state.save_state()
|
||||
_notifify_device_change()
|
||||
elif type == DeviceType.SONY_CONTROLLER:
|
||||
_state.device_id = device_id
|
||||
_state.device_type = DeviceType.SONY_CONTROLLER
|
||||
_state.device_name = joy_name
|
||||
_state.save_state()
|
||||
_notifify_device_change()
|
||||
elif type == DeviceType.NINTENDO_CONTROLLER:
|
||||
_state.device_id = device_id
|
||||
_state.device_type = DeviceType.NINTENDO_CONTROLLER
|
||||
_state.device_name = joy_name
|
||||
_state.save_state()
|
||||
_notifify_device_change()
|
||||
if type == DeviceType.PC_CONTROLLER:
|
||||
_state.device_id = device_id
|
||||
_state.device_type = DeviceType.PC_CONTROLLER
|
||||
_state.device_name = "PC Controller"
|
||||
_state.save_state()
|
||||
_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):
|
||||
var device_id = event.get_device()
|
||||
_state.device_category = DeviceCategory.KEYBOARD
|
||||
_state.device_id = device_id
|
||||
_state.device_type = DeviceType.KEYBOARD
|
||||
_state.device_name = "Keyboard"
|
||||
_state.save_state()
|
||||
_notifify_device_change()
|
||||
|
||||
#func _on_pointer_input(event: InputEvent):
|
||||
#var device_id = event.get_device()
|
||||
#_state.device_category = DeviceCategory.POINTER
|
||||
#_state.device_category = DeviceCategory.POINTER
|
||||
#_state.device_id = device_id
|
||||
#_state.device_type = DeviceType.MOUSE
|
||||
#_state.device_name = "Mouse"
|
||||
#_state.save_state()
|
||||
#_notifify_device_change()
|
||||
|
||||
func _on_touch_input(event: InputEvent):
|
||||
var device_id = event.get_device()
|
||||
_state.device_category = DeviceCategory.TOUCH
|
||||
_state.device_category = DeviceCategory.TOUCH
|
||||
_state.device_id = device_id
|
||||
_state.device_type = DeviceType.TOUCH
|
||||
_state.device_name = "Touch"
|
||||
_state.save_state()
|
||||
_notifify_device_change()
|
||||
|
||||
|
||||
func _notifify_device_change():
|
||||
device_changed.emit(_state.device_category, _state.device_type, _state.device_id, _state.device_name)
|
||||
|
||||
|
||||
func get_current_device_category() -> DeviceCategory:
|
||||
return _state.device_category
|
||||
|
||||
|
||||
func get_current_device_type() -> DeviceType:
|
||||
return _state.device_type
|
||||
|
||||
|
||||
func get_current_device_id() -> int:
|
||||
return _state.device_id
|
||||
|
||||
|
||||
class InputState:
|
||||
var device_category: DeviceCategory = DeviceCategory.UNKOWN
|
||||
var device_type: DeviceType = DeviceType.UNKOWN
|
||||
var device_id: int = -2
|
||||
var device_name: String = ""
|
||||
|
||||
func save_state():
|
||||
var save = FileAccess.open("user://controls.save", FileAccess.WRITE)
|
||||
var dict = {
|
||||
device_category = device_category,
|
||||
device_type = device_type,
|
||||
device_id = device_id,
|
||||
device_name = device_name,
|
||||
}
|
||||
|
||||
var json_string = JSON.stringify(dict)
|
||||
save.store_line(json_string)
|
||||
save.close()
|
||||
|
||||
|
||||
func load_state():
|
||||
if not FileAccess.file_exists("user://controls.save"):
|
||||
save_state()
|
||||
var save = FileAccess.open("user://controls.save", FileAccess.READ)
|
||||
var json_string = save.get_line()
|
||||
var parse_result = JSON.parse_string(json_string)
|
||||
if parse_result == null:
|
||||
print("JSON Parse Error: savegame ")
|
||||
var data = parse_result
|
||||
device_category = data["device_category"]
|
||||
device_type = data["device_type"]
|
||||
device_id = data["device_id"]
|
||||
device_name = data["device_name"]
|
||||
save.close()
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://p3hr7e8fi3py
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
extends Control
|
||||
|
||||
signal close
|
||||
|
||||
func _ready() -> void:
|
||||
pass
|
||||
|
||||
func _input(event):
|
||||
if event.is_action_pressed("ui_cancel"):
|
||||
emit_signal("close")
|
||||
|
||||
|
||||
func _on_back_button_pressed() -> void:
|
||||
print_verbose("OptionsMenu->emit_signal('close')")
|
||||
emit_signal("close")
|
||||
|
||||
|
||||
func _on_visibility_changed() -> void:
|
||||
if visible:
|
||||
grab_focus()
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://wrvmx8n6s3lw
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
[gd_scene format=3 uid="uid://b4m67tt3kxa2u"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bmnajdu3p7ibb" path="res://addons/gd-options/src/menus/tabs/game/game.tscn" id="1_5kpk4"]
|
||||
[ext_resource type="Script" uid="uid://wrvmx8n6s3lw" path="res://addons/gd-options/src/menus/options_menu.gd" id="1_j2roj"]
|
||||
[ext_resource type="PackedScene" uid="uid://cfehf2hk2hls4" path="res://addons/gd-options/src/menus/tabs/input/input.tscn" id="1_jiull"]
|
||||
[ext_resource type="PackedScene" uid="uid://n400hyjbel7a" path="res://addons/gd-options/src/menus/tabs/graphics/graphics.tscn" id="1_t5ygu"]
|
||||
[ext_resource type="PackedScene" uid="uid://d03u63g71l71o" path="res://addons/gd-options/src/menus/tabs/audio/audio.tscn" id="2_jiull"]
|
||||
|
||||
[node name="OptionsMenu" type="Control" unique_id=9417709]
|
||||
process_mode = 3
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
focus_mode = 2
|
||||
script = ExtResource("1_j2roj")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="." unique_id=42402491]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_constants/margin_left = 24
|
||||
theme_override_constants/margin_top = 32
|
||||
theme_override_constants/margin_right = 32
|
||||
theme_override_constants/margin_bottom = 64
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer" unique_id=716295331]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="TabContainer" type="TabContainer" parent="MarginContainer/VBoxContainer" unique_id=1505369780]
|
||||
custom_minimum_size = Vector2(2.08165e-12, 400)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
size_flags_stretch_ratio = 11.0
|
||||
focus_mode = 2
|
||||
tab_alignment = 1
|
||||
current_tab = 0
|
||||
|
||||
[node name="Game" parent="MarginContainer/VBoxContainer/TabContainer" unique_id=1350286854 instance=ExtResource("1_5kpk4")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Input" parent="MarginContainer/VBoxContainer/TabContainer" unique_id=409493361 instance=ExtResource("1_jiull")]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Graphics" parent="MarginContainer/VBoxContainer/TabContainer" unique_id=465215553 instance=ExtResource("1_t5ygu")]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Audio" parent="MarginContainer/VBoxContainer/TabContainer" unique_id=1363743964 instance=ExtResource("2_jiull")]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Panel" type="Panel" parent="MarginContainer/VBoxContainer" unique_id=1638010937]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer/Panel" unique_id=1518177746]
|
||||
layout_mode = 1
|
||||
anchors_preset = 4
|
||||
anchor_top = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_top = -20.0
|
||||
offset_right = 49.0
|
||||
offset_bottom = 20.0
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="BackButton" type="Button" parent="MarginContainer/VBoxContainer/Panel/HBoxContainer" unique_id=1205872950]
|
||||
layout_mode = 2
|
||||
focus_next = NodePath("../../../TabContainer")
|
||||
focus_previous = NodePath("../../../TabContainer")
|
||||
text = "Back"
|
||||
|
||||
[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]
|
||||
[connection signal="pressed" from="MarginContainer/VBoxContainer/Panel/HBoxContainer/BackButton" to="." method="_on_back_button_pressed"]
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
extends TabBar
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
_initilize()
|
||||
|
||||
func _initilize() ->void:
|
||||
%MasterFader.set_value_no_signal(AudioSettings.from_db_to_percent(AudioSettings.get_master_volume()))
|
||||
%MusicFader.set_value_no_signal(AudioSettings.from_db_to_percent(AudioSettings.get_music_volume()))
|
||||
%FxFader.set_value_no_signal(AudioSettings.from_db_to_percent(AudioSettings.get_fx_volume()))
|
||||
|
||||
func _on_focus_entered() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_visibility_changed() -> void:
|
||||
pass
|
||||
|
||||
func _on_master_fader_value_changed(value: float) -> void:
|
||||
var volume = AudioSettings.from_percent_to_db(value)
|
||||
AudioSettings.set_master_volume(volume)
|
||||
|
||||
|
||||
func _on_music_fader_value_changed(value: float) -> void:
|
||||
var volume = AudioSettings.from_percent_to_db(value)
|
||||
AudioSettings.set_music_volume(volume)
|
||||
|
||||
|
||||
func _on_fx_fader_value_changed(value: float) -> void:
|
||||
var volume = AudioSettings.from_percent_to_db(value)
|
||||
AudioSettings.set_fx_volume(volume)
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://dldnuk2iq2qth
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
[gd_scene format=3 uid="uid://d03u63g71l71o"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dldnuk2iq2qth" path="res://addons/gd-options/src/menus/tabs/audio/audio.gd" id="1_k0ads"]
|
||||
|
||||
[node name="Audio" type="TabBar" unique_id=1363743964]
|
||||
process_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
focus_neighbor_bottom = NodePath("PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/MasterBus/MasterControl/MasterFader")
|
||||
script = ExtResource("1_k0ads")
|
||||
metadata/_tab_index = 3
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="." unique_id=642262788]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer" unique_id=115895340]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 10
|
||||
theme_override_constants/margin_top = 5
|
||||
theme_override_constants/margin_right = 10
|
||||
theme_override_constants/margin_bottom = 10
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="PanelContainer/MarginContainer" unique_id=1723475598]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer" unique_id=1990975030]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/separation = 10
|
||||
|
||||
[node name="MasterBus" type="VBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer" unique_id=2094937390]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 0
|
||||
|
||||
[node name="Label" type="Label" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/MasterBus" unique_id=1298612268]
|
||||
custom_minimum_size = Vector2(128, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Master"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="MasterControl" type="HBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/MasterBus" unique_id=1383754360]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="MasterFader" type="HSlider" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/MasterBus/MasterControl" unique_id=1000966012]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
size_flags_stretch_ratio = 11.0
|
||||
focus_neighbor_top = NodePath("../../../FxBus/FxControl/FxFader")
|
||||
focus_neighbor_bottom = NodePath("../../../MusicBus/MusicControl/MusicFader")
|
||||
|
||||
[node name="Spacer" type="Control" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer" unique_id=1551453563]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
size_flags_stretch_ratio = 0.05
|
||||
|
||||
[node name="MusicBus" type="VBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer" unique_id=1891481128]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 0
|
||||
|
||||
[node name="Label" type="Label" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/MusicBus" unique_id=2143726600]
|
||||
custom_minimum_size = Vector2(128, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Music"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="MusicControl" type="HBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/MusicBus" unique_id=870240695]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="MusicFader" type="HSlider" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/MusicBus/MusicControl" unique_id=1461713735]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
size_flags_stretch_ratio = 11.0
|
||||
focus_neighbor_top = NodePath("../../../MasterBus/MasterControl/MasterFader")
|
||||
focus_neighbor_bottom = NodePath("../../../FxBus/FxControl/FxFader")
|
||||
|
||||
[node name="Spacer2" type="Control" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer" unique_id=864259381]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
size_flags_stretch_ratio = 0.05
|
||||
|
||||
[node name="FxBus" type="VBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer" unique_id=1379604575]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 2
|
||||
|
||||
[node name="Label" type="Label" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/FxBus" unique_id=1515945810]
|
||||
custom_minimum_size = Vector2(128, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "FX"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="FxControl" type="HBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/FxBus" unique_id=2130252155]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="FxFader" type="HSlider" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/FxBus/FxControl" unique_id=1418984511]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
size_flags_stretch_ratio = 11.0
|
||||
focus_neighbor_top = NodePath("../../../MusicBus/MusicControl/MusicFader")
|
||||
focus_neighbor_bottom = NodePath("../../../MasterBus/MasterControl/MasterFader")
|
||||
|
||||
[connection signal="focus_entered" from="." to="." method="_on_focus_entered"]
|
||||
[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]
|
||||
[connection signal="value_changed" from="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/MasterBus/MasterControl/MasterFader" to="." method="_on_master_fader_value_changed"]
|
||||
[connection signal="value_changed" from="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/MusicBus/MusicControl/MusicFader" to="." method="_on_music_fader_value_changed"]
|
||||
[connection signal="value_changed" from="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/FxBus/FxControl/FxFader" to="." method="_on_fx_fader_value_changed"]
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
extends TabBar
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_initialize()
|
||||
|
||||
func _initialize() -> void:
|
||||
var button: OptionButton = %LanguageOptionButton
|
||||
button.clear()
|
||||
var locales = _get_available_locales()
|
||||
for i in locales.size():
|
||||
var locale = locales[i]
|
||||
button.add_item(TranslationServer.get_locale_name(locale))
|
||||
button.set_item_metadata(i, locale)
|
||||
var current = GameSettings.get_locale()
|
||||
var selected_index = 0
|
||||
for i in button.item_count:
|
||||
if button.get_item_metadata(i) == current:
|
||||
selected_index = i
|
||||
break
|
||||
if button.item_count > 0:
|
||||
button.select(selected_index)
|
||||
|
||||
|
||||
func _get_available_locales() -> PackedStringArray:
|
||||
var locales = TranslationServer.get_loaded_locales()
|
||||
if locales.is_empty():
|
||||
var fallback = ProjectSettings.get_setting("internationalization/locale/fallback", "en_US")
|
||||
locales = PackedStringArray([fallback])
|
||||
return locales
|
||||
|
||||
|
||||
func _on_focus_entered() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_visibility_changed() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_language_option_button_item_selected(index: int) -> void:
|
||||
var locale = (%LanguageOptionButton as OptionButton).get_item_metadata(index)
|
||||
GameSettings.set_locale(locale)
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://cqmylsiqrpge1
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
[gd_scene format=3 uid="uid://bmnajdu3p7ibb"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cqmylsiqrpge1" path="res://addons/gd-options/src/menus/tabs/game/game.gd" id="1_7vn2t"]
|
||||
|
||||
[node name="Game" type="TabBar" unique_id=1350286854]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
focus_neighbor_bottom = NodePath("PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/LanguageControl/LanguageOptionButton")
|
||||
script = ExtResource("1_7vn2t")
|
||||
metadata/_tab_index = 0
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="." unique_id=1741770121]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
focus_mode = 2
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer" unique_id=1884352437]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 10
|
||||
theme_override_constants/margin_top = 5
|
||||
theme_override_constants/margin_right = 10
|
||||
theme_override_constants/margin_bottom = 10
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="PanelContainer/MarginContainer" unique_id=1838175574]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer" unique_id=1818428831]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="LanguageControl" type="HBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer" unique_id=507373924]
|
||||
layout_mode = 2
|
||||
size_flags_stretch_ratio = 2.0
|
||||
|
||||
[node name="Label" type="Label" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/LanguageControl" unique_id=1986420736]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_stretch_ratio = 8.0
|
||||
text = "Language"
|
||||
|
||||
[node name="LanguageOptionButton" type="OptionButton" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/LanguageControl" unique_id=2121649320]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_stretch_ratio = 4.0
|
||||
|
||||
[connection signal="focus_entered" from="." to="." method="_on_focus_entered"]
|
||||
[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]
|
||||
[connection signal="item_selected" from="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/LanguageControl/LanguageOptionButton" to="." method="_on_language_option_button_item_selected"]
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
extends TabBar
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_initialize()
|
||||
|
||||
func _initialize() -> void:
|
||||
_initialize_window_mode()
|
||||
_initialize_borderless()
|
||||
_initialize_display_on()
|
||||
|
||||
func _initialize_window_mode() -> void:
|
||||
var button: OptionButton = %WindowModeOptionButton
|
||||
var current = GraphicsSettings.get_window_mode()
|
||||
for i in button.item_count:
|
||||
if button.get_item_id(i) == current:
|
||||
button.select(i)
|
||||
break
|
||||
|
||||
func _initialize_borderless() -> void:
|
||||
%CheckButton.set_pressed_no_signal(GraphicsSettings.get_borderless())
|
||||
|
||||
func _initialize_display_on() -> void:
|
||||
var button: OptionButton = %DisplayOnOptionButton
|
||||
button.clear()
|
||||
for i in GraphicsSettings.get_screen_count():
|
||||
button.add_item(tr("Screen %d") % i, i)
|
||||
var current = GraphicsSettings.get_use_screen()
|
||||
for i in button.item_count:
|
||||
if button.get_item_id(i) == current:
|
||||
button.select(i)
|
||||
break
|
||||
|
||||
|
||||
func _on_focus_entered() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_visibility_changed() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_window_mode_option_button_item_selected(index: int) -> void:
|
||||
var mode = (%WindowModeOptionButton as OptionButton).get_item_id(index)
|
||||
GraphicsSettings.set_window_mode(mode)
|
||||
|
||||
|
||||
func _on_check_borderless_toggled(toggled_on: bool) -> void:
|
||||
GraphicsSettings.set_borderless(toggled_on)
|
||||
|
||||
|
||||
func _on_display_on_option_button_item_selected(index: int) -> void:
|
||||
var screen = (%DisplayOnOptionButton as OptionButton).get_item_id(index)
|
||||
GraphicsSettings.set_screen_and_apply(screen)
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://qpnlr1xbrqyt
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
[gd_scene format=3 uid="uid://n400hyjbel7a"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://qpnlr1xbrqyt" path="res://addons/gd-options/src/menus/tabs/graphics/graphics.gd" id="1_41qjv"]
|
||||
|
||||
[node name="Graphics" type="TabBar" unique_id=465215553]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
focus_neighbor_bottom = NodePath("PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/WindowMode/WindowModeOptionButton")
|
||||
script = ExtResource("1_41qjv")
|
||||
metadata/_tab_index = 2
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="." unique_id=1780038364]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer" unique_id=943852944]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 10
|
||||
theme_override_constants/margin_top = 5
|
||||
theme_override_constants/margin_right = 10
|
||||
theme_override_constants/margin_bottom = 10
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="PanelContainer/MarginContainer" unique_id=328920069]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer" unique_id=957301241]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="WindowMode" type="HBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer" unique_id=1393620897]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/WindowMode" unique_id=334423763]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_stretch_ratio = 8.0
|
||||
text = "Window Mode"
|
||||
|
||||
[node name="WindowModeOptionButton" type="OptionButton" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/WindowMode" unique_id=738661340]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_stretch_ratio = 4.0
|
||||
focus_neighbor_top = NodePath("../../DisplayOn/DisplayOnOptionButton")
|
||||
focus_neighbor_bottom = NodePath("../../Borderless/CheckButton")
|
||||
button_mask = 3
|
||||
allow_reselect = true
|
||||
item_count = 3
|
||||
popup/item_0/text = "Windowed"
|
||||
popup/item_0/id = 0
|
||||
popup/item_1/text = "Windowed (Maximized)"
|
||||
popup/item_1/id = 2
|
||||
popup/item_2/text = "Fullscreen"
|
||||
popup/item_2/id = 3
|
||||
|
||||
[node name="Borderless" type="HBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer" unique_id=1151972511]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/Borderless" unique_id=531435484]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_stretch_ratio = 8.0
|
||||
text = "Borderless"
|
||||
|
||||
[node name="CheckButton" type="CheckButton" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/Borderless" unique_id=586231003]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_neighbor_top = NodePath("../../WindowMode/WindowModeOptionButton")
|
||||
focus_neighbor_bottom = NodePath("../../DisplayOn/DisplayOnOptionButton")
|
||||
|
||||
[node name="DisplayOn" type="HBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer" unique_id=287471882]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/DisplayOn" unique_id=1857499090]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_stretch_ratio = 8.0
|
||||
text = "Screen"
|
||||
|
||||
[node name="DisplayOnOptionButton" type="OptionButton" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/DisplayOn" unique_id=1008900572]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_stretch_ratio = 4.0
|
||||
focus_neighbor_top = NodePath("../../Borderless/CheckButton")
|
||||
focus_neighbor_bottom = NodePath("../../WindowMode/WindowModeOptionButton")
|
||||
selected = 0
|
||||
item_count = 1
|
||||
popup/item_0/text = "0"
|
||||
popup/item_0/id = 0
|
||||
|
||||
[connection signal="focus_entered" from="." to="." method="_on_focus_entered"]
|
||||
[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]
|
||||
[connection signal="item_selected" from="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/WindowMode/WindowModeOptionButton" to="." method="_on_window_mode_option_button_item_selected"]
|
||||
[connection signal="toggled" from="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/Borderless/CheckButton" to="." method="_on_check_borderless_toggled"]
|
||||
[connection signal="item_selected" from="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/DisplayOn/DisplayOnOptionButton" to="." method="_on_display_on_option_button_item_selected"]
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
extends TabBar
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_initialize()
|
||||
|
||||
func _initialize() -> void:
|
||||
%InvertVerticalAxisCheckButton.set_pressed_no_signal(InputSettings.get_invert_vertical_axis())
|
||||
|
||||
|
||||
func _on_focus_entered() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_visibility_changed() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_invert_vertical_axis_check_button_toggled(toggled_on: bool) -> void:
|
||||
InputSettings.set_invert_vertical_axis(toggled_on)
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://bwflvl6t3k0hc
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
[gd_scene format=3 uid="uid://cfehf2hk2hls4"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bwflvl6t3k0hc" path="res://addons/gd-options/src/menus/tabs/input/input.gd" id="1_26ax5"]
|
||||
|
||||
[node name="Input" type="TabBar" unique_id=409493361]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
focus_neighbor_bottom = NodePath("PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/InvertVerticalAxisControl/InvertVerticalAxisCheckButton")
|
||||
script = ExtResource("1_26ax5")
|
||||
metadata/_tab_index = 1
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="." unique_id=1987401442]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer" unique_id=1919944062]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 5
|
||||
theme_override_constants/margin_top = 10
|
||||
theme_override_constants/margin_right = 5
|
||||
theme_override_constants/margin_bottom = 10
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="PanelContainer/MarginContainer" unique_id=549462347]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer" unique_id=604645589]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="InvertVerticalAxisControl" type="HBoxContainer" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer" unique_id=1832651151]
|
||||
layout_mode = 2
|
||||
size_flags_stretch_ratio = 2.0
|
||||
|
||||
[node name="Label" type="Label" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/InvertVerticalAxisControl" unique_id=920012428]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_stretch_ratio = 8.0
|
||||
text = "Invert Vertical Axis"
|
||||
|
||||
[node name="InvertVerticalAxisCheckButton" type="CheckButton" parent="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/InvertVerticalAxisControl" unique_id=1008018201]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[connection signal="focus_entered" from="." to="." method="_on_focus_entered"]
|
||||
[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]
|
||||
[connection signal="toggled" from="PanelContainer/MarginContainer/ScrollContainer/VBoxContainer/InvertVerticalAxisControl/InvertVerticalAxisCheckButton" to="." method="_on_invert_vertical_axis_check_button_toggled"]
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
keys,en,es,fr,de,ja,zh_CN
|
||||
Game,Game,Juego,Jeu,Spiel,ゲーム,游戏
|
||||
Input,Input,Entrada,Entrée,Eingabe,入力,输入
|
||||
Graphics,Graphics,Gráficos,Graphismes,Grafik,グラフィック,图像
|
||||
Audio,Audio,Audio,Audio,Audio,オーディオ,音频
|
||||
Back,Back,Atrás,Retour,Zurück,戻る,返回
|
||||
Master,Master,General,Principal,Master,マスター,主音量
|
||||
Music,Music,Música,Musique,Musik,音楽,音乐
|
||||
FX,FX,Efectos,Effets,Effekte,効果音,音效
|
||||
Window Mode,Window Mode,Modo de ventana,Mode de fenêtre,Fenstermodus,ウィンドウモード,窗口模式
|
||||
Borderless,Borderless,Sin bordes,Sans bordure,Randlos,ボーダーレス,无边框
|
||||
Screen,Screen,Pantalla,Écran,Bildschirm,画面,屏幕
|
||||
Windowed,Windowed,Ventana,Fenêtré,Fenster,ウィンドウ,窗口
|
||||
Windowed (Maximized),Windowed (Maximized),Ventana (Maximizada),Fenêtré (Maximisé),Fenster (Maximiert),ウィンドウ(最大化),窗口(最大化)
|
||||
Fullscreen,Fullscreen,Pantalla completa,Plein écran,Vollbild,フルスクリーン,全屏
|
||||
Invert Vertical Axis,Invert Vertical Axis,Invertir eje vertical,Inverser l'axe vertical,Vertikale Achse umkehren,縦軸を反転,反转垂直轴
|
||||
Language,Language,Idioma,Langue,Sprache,言語,语言
|
||||
Screen %d,Screen %d,Pantalla %d,Écran %d,Bildschirm %d,画面 %d,屏幕 %d
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
[remap]
|
||||
|
||||
importer="csv_translation"
|
||||
type="Translation"
|
||||
uid="uid://ve0c3i7bkxwt"
|
||||
|
||||
[deps]
|
||||
|
||||
files=["res://addons/gd-options/translations/gd_options.en.translation", "res://addons/gd-options/translations/gd_options.es.translation", "res://addons/gd-options/translations/gd_options.fr.translation", "res://addons/gd-options/translations/gd_options.de.translation", "res://addons/gd-options/translations/gd_options.ja.translation", "res://addons/gd-options/translations/gd_options.zh_CN.translation"]
|
||||
|
||||
source_file="res://addons/gd-options/translations/gd_options.csv"
|
||||
dest_files=["res://addons/gd-options/translations/gd_options.en.translation", "res://addons/gd-options/translations/gd_options.es.translation", "res://addons/gd-options/translations/gd_options.fr.translation", "res://addons/gd-options/translations/gd_options.de.translation", "res://addons/gd-options/translations/gd_options.ja.translation", "res://addons/gd-options/translations/gd_options.zh_CN.translation"]
|
||||
|
||||
[params]
|
||||
|
||||
compress=1
|
||||
delimiter=0
|
||||
unescape_keys=false
|
||||
unescape_translations=true
|
||||